1. 先判断,该用智能体还是工具
主智能体先通过 task 派活,子智能体拿到独立任务后自己完成推理和工具调用,最后只把结果交回主智能体。这样主智能体不用背着所有细节继续往下推理。
写子智能体之前,先问一个很实际的问题:这件事是否值得单独拆出一个助手?
如果答案是“是”,才继续配置它的 name、description、system_prompt 和 tools
2. 适合拆成子智能体的任务
| 场景 | 说明 | 示例 |
|---|---|---|
| 多步骤任务上下文很乱 | 中间过程多,主智能体容易被大量信息干扰 | 深度研究、多轮搜索、多源资料整合 |
| 存在不同专业领域 | 不同任务需要不同知识和工具 | 金融分析、法律检索、数据库查询 |
| 需要不同模型能力 | 某些任务可能需要多模态或更强模型 | 图片理解、长文档分析、代码生成 |
| 主智能体只做统筹 | 主智能体像项目经理,只负责分派和汇总 | 「深度研搜」的 Main Agent |
3. 普通工具和子智能体的选择边界
| 任务类型 | 更适合的形式 | 原因 |
|---|---|---|
| 一次函数调用就能完成 | 普通工具 | 成本低、链路短、结果更稳定 |
| 查询天气、简单计算、格式转换 | 普通工具 | 逻辑边界清楚,不需要独立上下文 |
| 多步搜索、阅读、分析、归纳 | 子智能体 | 需要独立提示词、独立上下文和多步执行 |
| 带专属工具和复杂策略的任务 | 子智能体 | 方便限制工具权限,也方便单独调试 |
所以写代码前,更准确的判断标准不是“步骤多不多”,而是下面三个问题:
- 这些步骤是否需要不同专业能力?
- 这些步骤之间是否可以隔离上下文?
- 拆开以后收益是否大于额外成本?
一句话总结:工具适合做确定的小动作,子智能体适合做需要思考的一段小任务
配置子智能体方式
- 字典子智能体:配置一个简单助手。
CompiledSubAgent:把一个完整 Agent / Graph 封装成子智能体。
字典子智能体基本字段:
| 字段 | 作用 | 是否必填 |
|---|---|---|
name |
子智能体名称,主智能体调用时会使用 | 必填 |
description |
子智能体职责描述,主智能体靠它判断是否调用 | 必填 |
system_prompt |
子智能体自己的系统提示词 | 常用 |
tools |
子智能体可使用的工具列表 | 常用 |
model |
子智能体使用的模型,不填则通常继承主智能体模型 | 可选 |
name 是子智能体的唯一标识。后面流式输出里看到 task 调用时,subagent_type 就会对应这个名称。
description 是主智能体判断任务归属的依据。如果描述写得模糊,主智能体就容易分派错。
本案例中定义了三个简单助手:天气助手、数学助手、翻译助手:
# 字典式子智能体的核心字段:
# name 是子智能体唯一标识,流式输出里的 subagent_type 会对应它;
# description 主要给主智能体看,用来判断什么时候应该调用该助手;
# system_prompt 是子智能体自己的角色和行为约束;
# tools 是该子智能体可用的工具列表,不填 model 时通常继承主智能体模型。
weather_agent = {"name": "weather_helper","description": "用于查询天气信息。当用户询问天气时,请调用此助手。","system_prompt": """你是一个天气查询助手。无论用户查询哪个城市,请统一回复:今天天气晴朗,温度25度。""","tools": [],
}math_agent = {"name": "math_helper","description": "用于处理数学计算问题。当用户询问加减乘除、数字计算、算数题时,请调用此助手。","system_prompt": """你是一个严谨的数学助手。请帮助用户完成数学计算,并给出清晰、准确的答案。""","tools": [],
}translate_agent = {"name": "translate_helper","description": "用于处理中英互译任务。当用户需要中文和英文之间的翻译时,请调用此助手。","system_prompt": """你是一个中英翻译助手。如果输入是中文,请翻译成英文;如果输入是英文,请翻译成中文。""","tools": [],
}
注册到主智能体:
创建主智能体时,把这些字典放进 subagents 即可。
# 主智能体自己不挂普通工具,重点负责根据用户问题分派给合适的子智能体
main_agent = create_deep_agent(model=llm,tools=[],subagents=[weather_agent, math_agent, translate_agent],system_prompt="""你是一个负责统筹任务的主智能体。请根据用户需求选择合适的子智能体完成任务。你不直接执行天气查询、数学计算或翻译任务,而是通过子智能体完成。""",
)
系统提示词要说清楚主智能体的边界:它不是天气助手、数学助手或翻译助手本身,而是负责把任务交给合适的子智能体
以天气查询这组输出为例,三行日志分别对应三件事:
| 输出片段 | 代表的含义 |
|---|---|
【model】决定调用子智能体weather_helper |
主智能体判断这个问题应该交给天气助手处理 |
【agent】调用了具体的工具task |
DeepAgents 执行 task,也就是实际去调用子智能体 |
【model】返回最终结果 |
主智能体拿到子智能体结果后,再整理成最终回复给用户 |
后面分析 task 工具调用时,心里先记住这条线就可以: 用户问题 -> 主智能体选择子智能体 -> task 执行 -> 子智能体返回结果 -> 主智能体整理最终回复
子智能体本质上是task工具调用
主智能体并不是直接跳到某个子智能体里执行,而是先由模型做一次决策,在 DeepAgents 中,主智能体调用子智能体时,通常会表现为一次特殊工具调用: tool_call["name"] == "task"
它的参数里会说明两件事:
subagent_type:要调用哪个子智能体,对应前面配置里的name。description:交给这个子智能体的具体任务。
也就是说,从主智能体视角看,子智能体是一种可调度能力。它不是普通 Python 函数工具,而是一个拥有独立提示词、独立工具集和独立上下文的 Agent。

子智能体并不是“凭空被调用”的。主智能体先请求模型判断下一步,模型返回 task 工具调用,DeepAgents 再根据 subagent_type 找到对应子智能体执行
还要补一个容易混淆的细节:子智能体不是普通工具,但它在主智能体眼里会像工具一样返回结果
原因是主智能体调用子智能体时,走的是 task 这个特殊工具。子智能体执行完以后,它的结果会回到主智能体这边,并且通常表现为一条 ToolMessage
一个“主智能体调用子智能体再回答”的简单流程,常见链路是:
主智能体模型:判断调用哪个子智能体 -> 子智能体模型:完成被分派的局部任务 -> 主智能体模型:整合子智能体结果并输出最终答案
这也是为什么子智能体比普通工具成本更高:普通工具通常只是一次函数或 API 调用,而子智能体本身还会走一段 Agent 执行过程
如何在流式输出里识别Task:
重点看 model 节点里最后一条消息的 tool_calls。普通工具调用和子智能体调用都会出现在这里,区别主要看工具名.
| 观察位置 | 普通工具调用 | 子智能体调用 |
|---|---|---|
tool_call["name"] |
工具自己的名字,例如 internet_search |
固定是 task |
tool_call["args"] |
普通工具的入参 | 包含 subagent_type 和 description |
| 返回结果所在节点 | tools |
也是 tools,因为 task 本身表现为一个工具结果 |
所以在流式解析代码里,只要判断工具名是不是 task,就能区分“调用普通工具”和“分派子智能体”:
if tool_call["name"] == "task":print(f"调用子智能体:{tool_call['args']['subagent_type']}")
else:print(f"调用普通工具:{tool_call['name']}")
