跳到正文
Agent 工程实践Multi-Agent 协作
返回课程/Agent 工程实践
第 10 / 15 章 约 7 分钟

Multi-Agent 协作

拆分子任务,处理上下文隔离、并发和失败。

这个模块在 Agent 里的位置

SubAgent 不是“多调几个模型”,而是上下文隔离和职责拆分。

它解决的是:

  • 大任务导致 parent 上下文膨胀。
  • 不同子任务需要不同工具和模型。
  • 检索、分析、校验可以并行。
  • 某个子任务失败不应拖垮全部结论。

如果只是让多个 Agent 各说一段话再拼接,通常只会增加成本和失败面。

先记住几个概念

概念含义为什么重要
Parent Agent负责任务拆分和综合保存任务主线
Child Agent负责一个受限子任务隔离上下文和工具
parentSummarychild 给 parent 的结论摘要控制 parent 上下文
refs稳定引用 ID支持证据校验
Terminal statuscompleted / failed / cancelled防止子任务被静默丢弃
Concurrency cap并发上限控制资源和成本
Tool allowlistchild 可用工具缩小攻击面和误用面

从一个真实问题开始:parent 被三个 child 的“完整过程”淹没

任务:

分析 30 天、50 万实体,输出 Top 10 风险实体和证据。

系统拆了三个 child:

  1. Child A:Top 实体检索。
  2. Child B:证据窗口分析。
  3. Child C:引用一致性校验。

每个 child 都把完整推理过程返回给 parent:

{
  "reasoning": [
    "我先查了 50 万实体",
    "然后过滤了 3 万条",
    "又看了 20 个窗口",
    "最后得出结论"
  ],
  "toolResults": [...]
}

结果:

  1. parent 上下文迅速膨胀。
  2. parent 也触发 compaction。
  3. 引用被摘要丢失。
  4. parent 重复查询。

这说明 child 的价值不在“多一个模型”,而在隔离探索成本,只回传可消费的结论。

child 应该返回什么

一个合格的 child 输出:

{
    "parentSummary": "Top 10 实体中 3 个风险显著上升",
    "refs": ["win-1001", "win-1002"],
    "confidence": 0.86,
    "unresolvedQuestions": []
}

不应返回:

  • 完整推理过程。
  • 全量工具结果。
  • 原始 JSON。
  • 和 parent 无关的中间状态。

什么时候适合拆 SubAgent

适合拆的条件:

  1. 子任务上下文天然隔离。
  2. 子任务可以独立校验。
  3. parent 只需要结论。
  4. 子任务可以并行。
  5. 失败状态可以单独表达。

不适合的情况:

场景不适合的原因
任务很短调度成本大于收益
强依赖同一上下文拆开会丢共享状态
输出只是文本拼接没有隔离收益
需要实时人机交互子任务会引入延迟和状态同步

每个 child 必须有独立边界

一个 child 至少要有:

  1. 独立 session。
  2. 独立 tool allowlist。
  3. 独立 timeout。
  4. 独立 output schema。
  5. 独立 usage 记录。
  6. 独立失败状态。

例如:

Child工具模型timeout
Top 实体检索query_top_risk_entitiesfast60s
证据分析query_evidence_windowsmain120s
引用校验get_source_by_idfast30s

不要让 child 继承 parent 的全部工具,尤其是写工具。

数据库设计

create table agent_subtask_runs (
  id bigint primary key,
  parent_run_id bigint not null,
  agent_name text not null,
  status text not null,
  input_ref text not null,
  output_ref text,
  started_at timestamptz not null,
  ended_at timestamptz,
  unique (parent_run_id, agent_name)
);

create index agent_subtask_parent_idx
  on agent_subtask_runs (parent_run_id, status);

设计要点:

  1. parent 和 child 分表。
  2. agent_name 唯一,避免同一子任务重复执行。
  3. status 必须有终态。
  4. input/output 存对象存储指针,不塞 JSONB。

child 失败不能被静默丢弃

一个典型错误:

{
    "parentSummary": "已生成报告",
    "children": [
        { "agent": "A", "status": "completed" },
        { "agent": "B", "status": "failed" }
    ]
}

如果 parent 忽略 B 的失败,报告看起来完成了,但缺少证据依据。

正确做法:

  1. parent 收到 failed child。
  2. 报告中明确“证据分析缺失”。
  3. 输出 unresolvedQuestions。
  4. 不把缺失写成零。

防止 child 重复查询

三个 child 同时查同一时间窗,是常见浪费。

解决方式:

  1. parent 先做共享事实查询。
  2. 把共享 refs 传给 child。
  3. child 只做各自专项分析。
  4. 相同工具调用可以共享 cache。

示例:

{
    "sharedFocusWindows": [
        {
            "windowId": "win-1001",
            "reason": "风险峰值"
        }
    ]
}

child 基于共享窗口继续分析,而不是各自重新查一遍。

取消必须传播到 child

parent 被取消时,不能只取消 parent 自己。

必须:

  1. 停止所有 child。
  2. 释放 child 持有的工具和资源。
  3. 将 child 标记为 cancelled。
  4. 阻断 pending action。

否则会出现 parent 已取消,child 还在后台继续查库和耗 token。

和传统后端的关系

Multi-Agent 协作可以类比成后端里的服务编排:

Agent 里的概念传统后端里的对应物
Parent Agent编排服务 / workflow engine
Child Agent子任务 worker
parentSummaryRPC 返回值
refs共享主键 / 外键引用
Concurrency cap线程池 / worker pool
Child failure子任务失败 / 熔断

区别在于,child 的输出不仅要给人看,还要能进入 parent 的模型上下文,所以必须额外控制输出大小和引用稳定性。

常见工程错误

错误实际后果正确做法
child 返回完整过程parent 上下文膨胀parentSummary + refs
child 无 output schemaparent 无法校验强制 schema
child 失败被忽略报告缺依据terminal status + unresolvedQuestions
child 继承全部工具越权和误用tool allowlist
child 重复查询成本浪费shared refs / cache
无并发上限资源失控max concurrent
parent 取消不传播child 继续执行AbortSignal

上线前检查

  1. 每个 child 有明确职责。
  2. 输出 schema 强制。
  3. child 有 timeout。
  4. 失败不能静默丢弃。
  5. parent 可取消 child。
  6. 并发有上限。
  7. 共享数据通过 refs 传递。
  8. 每个 child 独立记录 usage 和工具调用。