1. 为什么 Multi-Agent 设计里,主从模式正在变成“默认答案”
做 Agent 应用做得越久,越能体会一个趋势:当任务稍微复杂一点,单 Agent 很难稳定把活干完。你给它一个“全知全能”的角色,它要么在长上下文里迷失重点,要么把工具调用链条拉得巨长,最后结果看起来像模像样,细看全是幻觉。这也是我为什么在 Microsoft Agent Framework 的项目里,越来越倾向于用 SubAgent 把任务拆开——不是赶时髦,是被逼的。
1.1 主从模式到底解决了什么问题
先说个最简单但最核心的判断:Multi-Agent 不是为了“让多个模型聊天”而存在的,它存在的理由是职责分离。
单 Agent 在面对一条复杂链路时,指令越长,冲突越多。比如让同一个 Agent 既做行业调研,又做数据分析,还要写总结,它会在这几件事之间来回横跳。你把提示词写得再详细,也很难保证每一次输出的格式和深度都一致。而主从模式(master-subagent)等于在最外层放一个“调度大脑”,让子 Agent 各自只做一件事。主控 Agent 负责判断“这件事该找谁”,子 Agent 负责“把这件事做透”。
把任务拆给子 Agent 后,还有两个隐性收益:
- 上下文长度被摊薄了。子 Agent 只需要接收与自身任务相关的上下文,不需要把整段历史都背在身上。
- 失败影响被隔离了。某一路子 Agent 跑偏,主控 Agent 可以把它的结果打回重做,而不是整条链路从头再来。
在 Microsoft Agent Framework 这样的框架里,实现主从模式并不复杂。真正让人容易绕晕的,是下面这个问题:SubAgent 和最常见的 Tool 函数调用,到底应该怎么分?
1.2 子 Agent 不是“再开一个聊天窗口”
很多人在刚上手时会犯一个理解性错误:把 SubAgent 当成“嵌套聊天框”。主 Agent 问一句,子 Agent 回答一句,再把回答拿回来拼进主对话。这种方式不是不行,但在真实项目里你会很快发现,它会出现三个问题:
- 缺少明确的输入输出边界。主 Agent 不知道子 Agent 需要什么格式的输入,也不知道返回的结果可信度如何。
- 上下文越滚越大。每次子 Agent 的完整对话记录都被塞回主线程,主 Agent 的上下文快速膨胀。
- 框架没法替你兜底。一旦子 Agent 调用链比较深,错误和 token 消耗都会翻倍。
如果你把 SubAgent 当成一种调用单元,而不再是一个“聊天对象”,问题会瞬间清晰很多。这也是目前社区里讨论最多的观点:本质上就是把 SubAgent 视作另一种 Tool,用同一套接口去注册、去调用、去接收结果。
把这个心智模型理清了,后面搭什么架构都顺。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 看透本质:SubAgent 就是另类 Tool 的调用
做 Agent Framework 相关开发,最难的不是怎么写代码,而是怎么理解 Agent 和 Tool 的边界。官方文档里通常会把 Tool 定义成“可以被模型调用的外部能力”,把 Agent 定义成“具备记忆、规划、工具调用能力的执行体”。听起来像是两种完全不同的东西,但在主从模式下,你完全可以换个视角:
SubAgent 就是一个 Tool,只不过这个 Tool 的执行引擎是一个完整的 Agent。
这个视角不是我发明的,而是很多多 Agent 设计里的通行做法。Microsoft Agent Framework 这类框架在设计底层抽象时,也遵循了类似的逻辑:无论是普通的 Function Call,还是拉起一个 SubAgent,都需要走“给模型暴露调用入口 -> 模型决定何时调用 -> 框架执行并把结果返回给模型”这条闭环。
2.1 从函数签名看它们的共同点
先看一个最普通的工具定义。假设你有一个查天气的函数:
json复制{
"type": "function",
"function": {
"name": "get_weather",
"description": "查询指定城市的当前天气",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称"
}
},
"required": ["city"]
}
}
}
模型在推理时,会看到这样一段 schema。它不需要真正执行 Python 或 C# 代码,只需要产出一次具名参数调用:
json复制{
"function": "get_weather",
"arguments": "{\"city\": \"杭州\"}"
}
现在你再来看一个子 Agent 的注册信息,例如一个负责对标分析的子代理:
json复制{
"type": "subagent",
"agent": "competitive_analyst",
"description": "分析竞品的定价、功能与市场定位,返回结构化洞察",
"
