Featured image of post 多 Agent 系统设计详解:从任务分解到协作调度

多 Agent 系统设计详解:从任务分解到协作调度

重新梳理多 Agent 系统的工程设计方法:Agent 边界、协作拓扑、调度策略、共享状态、通信协议、失败恢复与评估指标

引言

多 Agent 不是把多个聊天机器人放在一起开会。

真正有价值的多 Agent 系统,是把一个复杂任务拆成多个相对独立的责任单元,让每个 Agent 在清晰边界内完成判断、执行或审查,再由调度层把结果组织成一个可靠的整体。

单 Agent 的工作方式通常是:

1
用户任务 → 一个 Agent 理解、规划、执行、验证、总结

多 Agent 的工作方式更像一个小型组织:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
用户任务
协调者拆解目标
多个专业 Agent 并行或串行处理
共享状态汇总
审查者校验
最终交付

它的核心不是“数量更多”,而是边界更清楚、上下文更聚焦、反馈更可控

为什么需要多 Agent

上下文隔离

复杂任务最大的问题不是模型不够聪明,而是上下文太杂。

例如“审查一个后端服务的性能问题”可能涉及:

  • API 入口
  • 数据库查询
  • 缓存策略
  • 日志和监控
  • 并发模型
  • 部署配置

如果全部塞给一个 Agent,它会在大量信息中来回切换,注意力被稀释。

多 Agent 可以把上下文隔离:

1
2
3
4
Database Agent 只看 SQL 和索引
Runtime Agent 只看并发和内存
API Agent 只看接口链路
Reviewer Agent 只看最终结论是否自洽

每个 Agent 看到的信息更少,但更相关。

专业化分工

Agent 的“专业化”并不一定来自不同模型,也可以来自不同的系统提示、工具权限、上下文来源和评估标准。

同一个基础模型,给它不同角色边界,就会表现出不同工作方式:

Agent 关注点
Planner 任务拆解、依赖关系、执行顺序
Researcher 搜索资料、读取上下文、整理证据
Executor 调用工具、修改文件、运行命令
Reviewer 检查风险、找漏洞、验证结果
Summarizer 汇总信息、压缩上下文、输出结论

这比让一个 Agent 在同一轮对话里同时扮演所有角色更稳定。

并行探索

很多任务可以天然并行:

1
2
3
4
5
查日志
查代码
查配置
查历史提交
查监控指标

单 Agent 串行执行会很慢;多 Agent 可以同时探索多个方向。

但并行不是免费午餐。它会带来合并成本、冲突处理和更高 token 消耗。只有当子任务之间依赖较弱时,并行才真正划算。

交叉验证

单 Agent 容易陷入自己的假设。多 Agent 可以通过独立判断降低错误概率。

例如:

1
2
3
4
Implementer:给出修复方案
Reviewer:从回归风险角度审查
Security Agent:从权限和注入角度审查
Test Agent:从可验证性角度审查

这种机制的价值不是让 Agent “辩论得更热闹”,而是让不同失败模式被不同视角捕捉。

多 Agent 的基本构件

一个多 Agent 系统通常由五个构件组成。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
┌──────────────────────────────────────────────┐
                  Orchestrator                 
        任务拆解、调度、终止条件、合并结果      
└───────────────┬───────────────┬──────────────┘
                               
        ┌───────▼───────┐ ┌────▼────────┐
         Agent A         Agent B      
         role + tools    role + tools 
        └───────┬───────┘ └────┬────────┘
                              
        ┌───────▼──────────────▼───────┐
         Shared State / Memory / Trace 
        └───────────────────────────────┘

Agent

Agent 是最小工作单元。

一个 Agent 不应该只用名字定义,例如“安全专家”。更完整的定义应该包含:

  • 目标:它负责解决什么问题
  • 输入:它能看到哪些上下文
  • 工具:它能调用哪些工具
  • 输出:它必须返回什么结构
  • 边界:它不能做什么
  • 评价标准:怎样算完成得好

例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
name: database-reviewer
goal: 找出数据库访问层的性能风险
input:
  - SQL 文件
  - ORM 调用代码
  - 慢查询日志
tools:
  - read_file
  - search_code
  - explain_sql
output:
  - risk_level
  - evidence
  - recommendation
boundary:
  - 不修改代码
  - 不评估业务逻辑

边界越清楚,协作越稳定。

Orchestrator

Orchestrator 是调度者。它决定:

  • 任务如何拆解
  • 哪些 Agent 参与
  • 谁先执行,谁后执行
  • 哪些任务可以并行
  • 结果如何合并
  • 什么时候停止
  • 失败时如何恢复

Orchestrator 可以是代码规则,也可以是一个 LLM Agent。

规则调度稳定、可控,但灵活性弱;LLM 调度适应性强,但更难预测。生产环境常见做法是混合:

1
2
3
固定流程用代码控制
开放式判断交给 LLM
高风险节点加人工确认

Shared State

多 Agent 必须共享状态,否则每个 Agent 都在自己的上下文里自说自话。

共享状态可以包括:

  • 原始任务
  • 子任务列表
  • Agent 输出
  • 已验证事实
  • 待解决问题
  • 决策记录
  • 工具调用 Trace
  • 最终交付草稿

共享状态不是越多越好。应该区分三类信息:

类型 说明
私有上下文 单个 Agent 内部推理使用
共享事实 多个 Agent 都需要依赖的结论
最终产物 面向用户输出的结果

不要把每个 Agent 的完整思考过程全部广播出去。那会让系统变得嘈杂,也会放大错误。

Communication

通信机制决定 Agent 之间如何传递信息。

常见方式有三种:

方式 说明 适用场景
直接消息 Agent A 把结果发给 Agent B 串行流水线
共享黑板 所有 Agent 读写同一个状态区 探索和汇总
事件流 Agent 订阅任务事件并响应 长流程、异步系统

直接消息简单,但容易形成强耦合。共享黑板灵活,但需要冲突控制。事件流适合复杂系统,但实现成本最高。

Evaluator

Evaluator 是评估者。它不一定参与执行,而是检查系统是否真的完成任务。

它可以检查:

  • 子任务是否全部完成
  • 输出是否符合格式
  • 结论是否有证据
  • 不同 Agent 是否互相矛盾
  • 是否需要重试或人工接管
  • 成本和延迟是否超标

没有 Evaluator 的多 Agent 系统,很容易变成“每个 Agent 都说自己完成了,但整体没人负责”。

协作拓扑

多 Agent 系统的核心设计问题之一是:Agent 之间如何组织。

流水线

流水线是最简单的拓扑。

1
Researcher → Planner → Executor → Reviewer → Summarizer

优点:

  • 流程清晰
  • 容易调试
  • 状态传递简单
  • 适合标准化任务

缺点:

  • 前面步骤出错会传递到后面
  • 不适合开放式探索
  • 并行能力有限

适合场景:

  • 文档生成
  • 代码审查
  • 数据清洗
  • 固定审批流

星型

星型拓扑由一个中心调度者连接多个专业 Agent。

1
2
3
        ┌→ Agent A
User → Orchestrator → Agent B
        └→ Agent C

优点:

  • 调度集中
  • 易于权限控制
  • 子任务可以并行
  • 最终合并更可控

缺点:

  • Orchestrator 压力大
  • 中心节点判断失误会影响全局
  • 子 Agent 之间缺少直接协作

适合场景:

  • 代码库分析
  • 多资料检索
  • 并行方案评估
  • 后端排障

层级

层级拓扑适合大任务。

1
2
3
4
5
6
7
Manager Agent
  ├── Backend Lead
  │     ├── API Agent
  │     └── DB Agent
  └── QA Lead
        ├── Test Agent
        └── Review Agent

优点:

  • 能承载复杂任务
  • 每层只处理局部复杂度
  • 适合动态分解

缺点:

  • 调度链路长
  • 信息容易在层级间损耗
  • 成本高
  • 难调试

适合场景:

  • 大型代码迁移
  • 长周期研究任务
  • 复杂产品需求拆解
  • 多团队模拟协作

网络

网络拓扑允许 Agent 之间自由通信。

1
2
3
Agent A ↔ Agent B
   ↕        ↕
Agent C ↔ Agent D

优点:

  • 灵活
  • 适合开放式协作
  • 可以形成自组织讨论

缺点:

  • 难控制
  • 容易循环
  • 成本不可预测
  • 结果合并困难

生产系统里要谨慎使用网络拓扑。它适合研究和原型,不适合默认作为业务系统架构。

调度策略

拓扑决定“谁能和谁说话”,调度策略决定“什么时候谁做什么”。

静态调度

静态调度把流程提前写死:

1
2
3
4
1. Researcher 收集资料
2. Planner 制定方案
3. Executor 实现
4. Reviewer 审查

优点是可预测,适合重复任务。缺点是遇到新情况不灵活。

动态调度

动态调度由 Orchestrator 根据中间结果决定下一步。

例如:

1
2
3
4
如果测试失败 → 派 Debug Agent
如果发现安全风险 → 派 Security Agent
如果资料不足 → 派 Research Agent
如果结果冲突 → 派 Reviewer 仲裁

动态调度更像真实工作流,但必须设置边界:

  • 最大轮次
  • 最大成本
  • 最大并发数
  • 终止条件
  • 人工接管条件

否则系统可能陷入无限循环。

投票与仲裁

当多个 Agent 给出不同结论时,需要仲裁机制。

常见方式:

方式 说明
多数投票 多个独立 Agent 给答案,取多数
加权投票 按 Agent 可靠性或领域权重投票
仲裁者 单独 Reviewer 基于证据裁决
规则优先 安全、权限、测试结果等硬规则优先

不要迷信投票。多个 Agent 如果共享同一个错误上下文,投票只会放大错误。

更好的仲裁方式是要求每个结论带证据:

1
2
3
4
5
6
7
8
9
{
  "claim": "瓶颈在数据库索引缺失",
  "evidence": [
    "slow.log 显示 user_id 查询耗时 2.3s",
    "users 表缺少 user_id 索引",
    "EXPLAIN 显示全表扫描"
  ],
  "confidence": 0.82
}

证据比票数更重要。

共享状态设计

多 Agent 系统最容易失败的地方不是模型能力,而是状态管理。

状态应该结构化

不要只让 Agent 互相传一段自然语言总结。自然语言灵活,但不适合作为系统状态。

更好的方式是结构化状态:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
{
  "task": "排查订单接口超时",
  "facts": [
    {
      "id": "f1",
      "text": "payment-service p95 延迟在 14:00 后升高",
      "source": "metrics/payment.json",
      "confidence": 0.93
    }
  ],
  "open_questions": [
    "延迟升高是否和发布有关?"
  ],
  "decisions": [
    {
      "decision": "优先检查 payment-service 最近发布",
      "reason": "时间点与延迟升高一致"
    }
  ]
}

结构化状态方便合并、过滤、评估和回放。

区分事实和观点

Agent 输出里常混杂事实、推测和建议。

共享状态必须区分:

1
2
3
事实:日志显示 500 错误增加
推测:可能是连接池耗尽
建议:增加连接池监控并检查慢查询

如果不区分,后续 Agent 可能把推测当事实,错误会被逐层放大。

保留来源

每个关键结论都应该带来源:

  • 文件路径
  • 日志行
  • URL
  • SQL 查询结果
  • 工具调用 ID
  • Agent 名称

没有来源的结论只能作为参考,不能作为最终交付依据。

通信协议

多 Agent 通信不能只靠“你说一句我说一句”。需要约定消息格式。

一个简单的消息结构:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{
  "from": "database-agent",
  "to": "orchestrator",
  "type": "finding",
  "task_id": "debug-timeout",
  "payload": {
    "claim": "orders 表缺少 status + created_at 复合索引",
    "evidence": ["EXPLAIN 输出显示 filesort"],
    "risk": "medium"
  }
}

常见消息类型

类型 含义
task 分配子任务
finding 返回发现
question 请求补充信息
evidence 提交证据
decision 记录决策
critique 审查意见
final 最终输出
error 执行失败

有了消息类型,Orchestrator 才能做路由、重试和统计。

控制消息长度

多 Agent 系统很容易被消息淹没。

通信应该遵循:

  • 默认传摘要,不传全文
  • 关键证据用引用指向原文
  • 大文件放 Resource,不直接塞消息
  • 每条消息只表达一个意图
  • Agent 不需要知道无关子任务细节

上下文越干净,系统越稳定。

工具权限

不同 Agent 应该拥有不同工具权限。

例如:

Agent 工具权限
Researcher search、read、fetch
Executor read、edit、run_test
Reviewer read、diff、test_result
Security read、scan、policy_check
Orchestrator dispatch、merge、stop

不要让每个 Agent 都能调用所有工具。工具越多,模型越容易选错;权限越大,风险越高。

最小权限原则

给 Agent 的工具权限应该刚好够完成任务。

1
2
3
4
需要审查代码 → 给 read 和 diff
需要修改代码 → 给 edit,但限制路径
需要运行测试 → 给 test 命令,不给任意 shell
需要查数据库 → 给只读 SQL,不给写权限

多 Agent 系统的安全性,很大程度取决于权限划分是否清楚。

失败模式

多 Agent 看起来强大,但失败模式也更多。

目标漂移

Agent 在协作过程中逐渐偏离原始任务。

防护:

  • 共享状态里保留原始目标
  • 每轮输出都检查是否服务目标
  • Orchestrator 控制范围

重复工作

多个 Agent 同时搜索同一批文件、重复分析同一个问题。

防护:

  • 任务分配前检查已有发现
  • 共享已访问资源
  • 对子任务设定明确边界

冲突结论

不同 Agent 得出互相矛盾的结论。

防护:

  • 结论必须带证据
  • 引入仲裁者
  • 让冲突进入 open_questions
  • 必要时重新收集证据

无效循环

Agent 之间反复请求对方补充信息,系统停不下来。

防护:

  • 最大轮次
  • 最大消息数
  • 最大成本
  • 停止条件
  • 人工接管

责任稀释

每个 Agent 都完成了自己的部分,但最终结果没人负责。

防护:

  • Orchestrator 对最终交付负责
  • Evaluator 检查整体质量
  • 明确 final owner

评估指标

多 Agent 系统不能只看最终回答。

任务指标

指标 含义
Task Success Rate 任务成功率
First-pass Success 首轮成功率
Human Acceptance Rate 人工验收通过率
Regression Pass Rate 回归样本通过率

协作指标

指标 含义
Handoff Success Rate 交接成功率
Conflict Rate 结论冲突率
Duplicate Work Rate 重复工作比例
Replan Count 重新规划次数
Message Count Agent 间消息数量

成本指标

指标 含义
Token per Task 每个任务 token 消耗
Tool Calls per Task 每个任务工具调用次数
Wall-clock Time 端到端耗时
Parallel Efficiency 并行节省的时间比例

多 Agent 的关键评估问题是:

1
2
3
它比单 Agent 更好吗?
提升的成功率是否值得额外成本?
失败时是否更容易定位原因?

如果答案是否定的,就没有必要使用多 Agent。

什么时候不该用多 Agent

多 Agent 很酷,但不是默认选项。

以下情况更适合单 Agent:

  • 任务很短
  • 上下文很小
  • 成功标准简单
  • 不需要并行
  • 不需要多视角审查
  • 工具调用链路简单
  • 成本和延迟敏感

例如:

1
2
3
4
解释一段代码
改一个小 bug
总结一篇短文
生成一个配置文件

这些任务上多 Agent 只会增加复杂度。

设计多 Agent 的步骤

第一步:先定义任务边界

不要一开始就问“需要几个 Agent”。先问:

1
2
3
4
这个任务有哪些可分离的责任?
哪些责任需要不同上下文?
哪些责任可以并行?
哪些责任需要互相审查?

Agent 数量来自责任边界,而不是拍脑袋。

第二步:定义每个 Agent 的契约

每个 Agent 都要有明确契约:

1
2
3
4
5
6
输入是什么?
输出是什么?
能用哪些工具?
不能做什么?
完成标准是什么?
失败时怎么报告?

没有契约的 Agent 越多,系统越混乱。

第三步:选择拓扑

按任务选择拓扑:

任务特征 推荐拓扑
固定流程 流水线
多方向探索 星型
大型复杂任务 层级
开放式研究 受控网络

多数工程场景里,星型 + Reviewer 是最稳的起点。

第四步:设计共享状态

共享状态至少要包含:

  • 原始任务
  • 子任务状态
  • 已验证事实
  • 待解决问题
  • 决策记录
  • 最终输出草稿

并且要把事实、推测、建议分开。

第五步:加终止和回滚机制

多 Agent 必须能停下来。

终止条件可以是:

  • 所有子任务完成
  • Evaluator 通过
  • 达到最大轮次
  • 达到成本上限
  • 出现高风险动作
  • 人工接管

没有终止机制的多 Agent 系统,不是智能,是失控。

一个完整例子:代码库性能排查

假设用户任务是:

1
帮我排查订单服务最近接口变慢的原因,并给出修复建议。

可以设计成:

1
2
3
4
5
6
Orchestrator
  ├── Log Agent:分析错误日志和慢请求
  ├── DB Agent:检查 SQL、索引、慢查询
  ├── Code Agent:分析接口链路和代码变更
  ├── Deploy Agent:检查最近发布和配置变更
  └── Reviewer:合并证据,排除不可靠结论

共享状态:

1
2
3
4
5
6
7
{
  "facts": [],
  "hypotheses": [],
  "evidence": [],
  "open_questions": [],
  "recommendations": []
}

执行流程:

1
2
3
4
5
6
1. Orchestrator 拆分任务
2. 四个 Agent 并行收集证据
3. Orchestrator 合并发现
4. Reviewer 检查矛盾和证据缺口
5. 必要时追加调查
6. 输出根因、证据、修复建议和验证方式

最终输出不应该只是:

1
可能是数据库慢。

而应该是:

1
2
3
4
5
6
7
8
9
根因:orders 查询缺少 status + created_at 复合索引。
证据:
1. 慢查询日志中该 SQL p95 从 120ms 上升到 2.4s。
2. EXPLAIN 显示 Using filesort。
3. 最近发布将查询条件从 user_id 改为 status + created_at。
建议:
1. 增加复合索引。
2. 回放线上查询验证执行计划。
3. 加入慢查询告警。

这就是多 Agent 应该交付的价值:不是更多对话,而是更清楚的证据链。

实践建议

从两个 Agent 开始

最小有价值组合通常是:

1
Executor + Reviewer

一个负责完成任务,一个负责检查结果。这个组合简单但收益很高。

先做只读多 Agent

早期不要让多个 Agent 同时写文件或执行高风险工具。

先让它们并行分析、审查、总结,等状态管理和权限边界稳定后,再开放写操作。

让输出结构化

每个 Agent 的输出最好固定格式:

1
2
3
4
5
6
7
{
  "status": "done",
  "findings": [],
  "evidence": [],
  "risks": [],
  "next_actions": []
}

结构化输出比自然语言更容易合并和评估。

记录完整 Trace

多 Agent 的调试必须依赖 Trace:

  • 谁被调度了
  • 输入是什么
  • 调用了什么工具
  • 输出是什么
  • 谁采纳了谁的结论
  • 哪里发生冲突
  • 为什么停止

没有 Trace,失败时很难定位问题。

每增加一个 Agent 都要证明收益

新增 Agent 应该回答:

1
2
3
4
它解决了哪个单 Agent 解决不好的问题?
它是否提高成功率?
它是否降低风险?
它增加的成本是否值得?

答不上来,就不要加。

小结

多 Agent 系统的重点不是“多个模型一起聊天”,而是工程化组织多个智能单元。

它的核心设计问题可以概括为:

1
2
3
4
5
6
边界:每个 Agent 负责什么?
调度:谁决定下一步?
状态:哪些信息共享?
通信:Agent 如何交换结果?
权限:谁能调用哪些工具?
评估:整体是否真的更好?

最好的多 Agent 系统往往不是最热闹的,而是最克制的:Agent 少而精,职责清楚,状态结构化,调度可追踪,失败能恢复。

当任务可以被清晰拆分、子任务能并行推进、结果需要多视角审查时,多 Agent 才真正值得使用。否则,一个设计良好的单 Agent 往往更简单、更便宜,也更可靠。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计