1. Todo 规划与 SubAgent 委派
1.1 多智能体解决什么问题
可以用“项目经理带专业团队”理解 Multi-Agent:主 Agent 接收目标、拆分任务,把不同工作交给合适的 SubAgent,最后校验并汇总结果。
这个比喻只能解释角色关系。工程实现还要回答:
- 哪些任务需要规划,哪些任务应直接调用 Tool?
- SubAgent 能看到父 Agent 的哪些信息?
- Model、Tool、Skills、权限和 Runtime Context 怎样继承?
- 子任务失败、超时或结果冲突时由谁处理?
- 并行委派是否真的降低延迟?
- 主 Agent 如何证明最终答案采用了经过验证的证据?
Deep Agents 提供两个容易混淆的工具:write_todos 管理主 Agent 当前工作计划,task 启动一次同步 SubAgent 执行。前者不创建子 Agent,后者也不会自动替主 Agent维护完整项目计划。
1.2 write_todos 与 task 的分工
| Tool | 作用 | 更新对象 | 是否产生新上下文 |
|---|---|---|---|
| write_todos | 拆分任务、记录进度、动态调整 | 父 Agent State 中的 todos | 否 |
| task | 把一项独立复杂工作交给 SubAgent | 子图运行并返回 ToolMessage | 是 |
一个常见流程是:主 Agent 先创建 Todo,完成输入检查后调用 task 委派分析,再把审核结果写回 Todo,最后自己生成交付内容。Todo 是计划面,SubAgent 是执行面。
1.3 Todo State 与使用建议
Todo Item 只有两个核心字段:
| 字段 | 类型 / 可选值 | 含义 |
|---|---|---|
| content | 非空字符串 | 可执行的任务描述 |
| status | pending / in_progress / completed | 当前状态 |
默认 Tool Description 建议复杂任务、尤其是包含三个及以上明显步骤的任务使用 Todo。这是给模型的使用指导,不是 API 校验硬规则:两步任务也能调用 write_todos,三步任务也不会被框架强制调用。
计划应描述可验证结果,而不是抽象动作:
不清晰:分析数据
可执行:核对 revenue、cost 的口径与时间范围,并记录输入证据
不清晰:审核结果
可执行:复算毛利率,检查 revenue/cost 证据是否齐全,输出通过或失败原因
默认指引允许互相独立、可并行的任务同时处于 in_progress,但这仍是 Prompt 建议,不是 State Schema 强制约束。业务系统若要求“任何时刻只有一个进行中任务”,需要额外校验。
1.4 计划是动态状态
执行过程中可以增加、删除、重排或修改 Todo。遇到阻塞时不应把未完成任务标记为 completed,而应保留进行中状态,并增加解决依赖的任务。
write_todos 每次替换整个列表,因此同一模型轮次并行调用多次会产生覆盖歧义。锁定版本的 Middleware 会限制同一轮重复并行写计划,主 Agent 应在新证据出现后串行更新。
1.5 底层契约测试与完整 Agent 测试
本文保留一个不调用模型的版本契约测试:
def write_plan(todos: list[TodoItem]) -> Command:
middleware = TodoListMiddleware()
write_todos = next(
tool for tool in middleware.tools if tool.name == "write_todos"
)
runtime = ToolRuntime(
state={"messages": [HumanMessage(content="prepare analysis report")]},
context=None,
config={},
stream_writer=lambda _: None,
tool_call_id="todo-call-001",
store=None,
)
return cast("Command", write_todos.func(runtime, todos))
直接调用 StructuredTool.func 会绕过 Agent Loop、ToolNode、HITL、完整 Trace 和部分错误包装,因此只用于锁定 deepagents==0.6.12 与当前 LangChain 的底层 Tool 契约,不是业务调用方式。
真正的集成测试使用 Scripted Model 产生 write_todos Tool Call,并断言:
- 模型实际绑定了 write_todos;
- ToolMessage 写入父消息;
- State 中 todos 被更新;
- 下一轮模型仍返回最终文本。
这样可以分别定位 Tool 内部契约和完整 Agent 编排故障。
2. 同步 SubAgent 的运行机制
2.1 Supervisor 拓扑

用户只与 Supervisor 交互。Supervisor 调用同步 task 后会等待 SubAgent 完成,再读取 ToolMessage 并继续推理。SubAgent 不是一个独立聊天入口,也不会自动与其他 SubAgent 共享消息。
2.2 task 生命周期

在 deepagents==0.6.12 中,一次同步委派大致经历:
- 主模型输出 task(description, subagent_type);
- Task Middleware 根据类型选择 Runnable;
- 过滤父 State 中不应传播的字段;
- 用 description 构造一条新的 HumanMessage;
- SubAgent 在独立消息上下文运行 Model / Tool Loop;
- Middleware 优先读取 structured_response,否则提取最终文本;
- 结果包装成父 Agent 的 ToolMessage;
- 主 Agent 校验、整合或继续委派。
task 的模型可见 Schema 只有两个字段:
| 字段 | 含义 |
|---|---|
| description | 完整目标、输入、约束、证据位置和输出格式 |
| subagent_type | 从已注册名称中选择一个 SubAgent |
Runtime、Store、State 和 Tool Call ID 由框架注入,不应让模型填写。
2.3 Description 是交接合同,也是软约束
父 messages 不会完整复制给 SubAgent,因此 Description 必须自包含:
目标:计算 revenue=120、cost=75 的毛利率。
口径:毛利率 = (revenue - cost) / revenue。
要求:必须使用 calculate,不允许心算。
输出:metric、value、evidence、risks。
Description 中写“禁止修改文件”只是模型指令,不是安全边界。强制限制必须由 Tool 集合、Filesystem Permissions、Backend、Sandbox 和服务端 ACL 实现。
2.4 State 过滤与传播前提
当前 Task Middleware 明确从输入和返回更新中排除:
- messages;
- todos;
- structured_response;
- Middleware 标记为 Private State 的字段。
其他父 State 字段可以进入 SubAgent 输入,但前提是子图 State Schema 能接收,字段满足序列化和 Reducer 约束。对于 CompiledSubAgent,兼容 Schema 由调用方负责。
本文 Compiled Reviewer 声明了 shared_report_path,所以该字段可以进入子图;父 messages 被替换成一条 Description,private_token 被过滤。
observed_message_count = 1
observed_private_token = false
shared_report_path = /reports/summary.md
这只验证当前版本、当前 Task Tool、当前 Schema 和测试输入的 State 过滤,不代表所有数据通道都已隔离:
| 通道 | 是否由 Task State 过滤控制 |
|---|---|
| 父 messages | 是 |
| todos | 是 |
| structured_response | 是 |
| Private State | 是 |
| 兼容的普通 State 字段 | 会传播 |
| Runtime Context | 否,按设计传播 |
| 共享 Backend 文件 | 否 |
| Store | 否 |
| 自定义 Tool / 外部 API | 否 |

2.5 默认 general-purpose 不是主 Agent 的完整副本
create_deep_agent 默认自动加入 general-purpose 同步 SubAgent,除非 Harness Profile 显式禁用,或调用方提供同名定义替换它。
在本文锁定版本中,它复用主模型、主自定义 Tools、Backend、Skills、Permissions 和 HITL 配置,并获得自己的 Todo、Filesystem、Summarization、Patch Tool Calls、Profile 与 Provider Cache Middleware。
它仍然不是父 Agent 的完整 State 克隆:
- 父消息和 Todo 被隔离;
- Runtime Context 传播;
- 使用独立的 general-purpose Prompt,而不是简单复制调用方自定义 System Prompt 文本;
- 父 Agent 的任意自定义 Middleware 不会整体照搬。
当前官方文档与不同版本对 general-purpose Prompt 的表述可能变化,依赖精确 Prompt 的系统应拦截实际 Model Request。
3. 声明式 SubAgent
3.1 最小定义与路由质量
声明式 SubAgent 使用字典配置:
class AnalysisResult(BaseModel):
metric: str
value: Decimal
evidence: list[str]
risks: list[str] = Field(default_factory=list)
analyst: SubAgent = {
"name": "analyst",
"description": (
"当任务需要定量计算、指标口径核对或数据异常分析时使用;"
"返回结构化指标、证据和风险,不负责润色最终报告。"
),
"system_prompt": (
"先核对输入口径,再调用 calculate。禁止心算和补造数据;"
"结果必须包含指标、数值、证据与风险。"
),
"tools": [calculate],
"response_format": AnalysisResult,
}
name 是 task.subagent_type 的运行标识,也会写入 lc_agent_name Trace Metadata。description 决定 Supervisor 什么时候选择它;system_prompt 决定子 Agent 内部怎样工作。三者不能互相替代。
lc_agent_name 适合 LangSmith 过滤、延迟统计和日志标识,不是认证或业务授权接口。强业务角色应来自可信 Runtime Context,例如 agent_role 或按 SubAgent Name 命名的 Context 字段。
3.2 声明式能力继承矩阵

下表以 deepagents==0.6.12 为基线:
| 能力 | 自定义声明式 SubAgent | 默认 general-purpose | CompiledSubAgent |
|---|---|---|---|
| Model | 默认继承,可覆盖 | 复用主模型 | Runnable 自己配置 |
| 主 tools= | 省略时继承;提供后整体替换 | 继承 | Runnable 自己配置 |
| Backend | 默认栈共享 | 共享 | 取决于 Runnable |
| System Prompt | 必须自己定义 | 使用 GP Prompt / Profile | Runnable 自己定义 |
| Skills | 不继承,需显式配置 | 继承主 Skills | 自己配置 |
| Permissions | 省略继承;提供后整体替换 | 继承 | 不自动继承 |
| interrupt_on | 省略继承;提供后覆盖 | 继承 | 不自动继承 |
| 自定义 Middleware | 不继承父列表 | 不整体继承 | Runnable 自己配置 |
| Runtime Context | 传播 | 传播 | 取决于 Runnable 对 Runtime 的接入 |
| 父 State | 按 Task 过滤并受子 Schema 限制 | 同左 | 同左且 Schema 自负 |
| Checkpointer | 由创建后的子 Agent运行方式决定 | 同左 | 自己负责 |
3.3 默认 Middleware 栈的版本边界
锁定版本为声明式 SubAgent 组装以下分组:
| 分组 | 0.6.12 典型 Middleware |
|---|---|
| 核心能力 | Todo、Filesystem、Summarization、Patch Tool Calls |
| 可选上下文 | 显式配置时加入 Skills |
| 自定义扩展 | SubAgent middleware= 中的额外 Middleware |
| 模型适配 | Harness Profile、Tool Exclusion、Provider Prompt Cache |
| 控制层 | Permissions 生成的中断与 interrupt_on 合并后加入 HITL |
SubAgent 在 0.6.12 没有 memory= 字段,父 AGENTS.md Memory 也不会自动成为自定义 SubAgent 的 Middleware。若子 Agent 需要长期上下文,应通过明确的 System Prompt、Tool、Backend 文件或自定义 Middleware 提供,并增加真实 Prompt 测试。
当前源码是“核心栈 + Skills + 自定义 Middleware + Profile/Cache + HITL”的装配过程。不要把精确顺序或重复 Middleware 的处理泛化成跨版本规则,升级后应检查源码或 Trace。
默认声明式 SubAgent 栈不再自动加入同步 SubAgentMiddleware,因此默认情况下不能通过原生 task 继续递归委派。若显式加入嵌套图、Agent Tool、动态编排或外部协议,仍需限制深度、预算和超时。
3.4 tools=[] 与文件工具不是一回事
tools=[] 只替换从主 Agent tools= 继承的自定义 Tool。Todo 和文件 Tool 来自默认 Middleware,因此 Reviewer 即使写 tools=[],仍可能拥有 write_todos、ls、read_file 等能力。
文件能力至少分三层控制:
| 目标 | 0.6.12 控制方式 |
|---|---|
| 模型是否看到某个内置 Tool | Harness Profile excluded_tools 或经过测试的自定义 Tool 过滤 Middleware |
| 文件 Tool 可访问哪些路径 | FilesystemPermission,首条匹配生效 |
| Shell 和执行环境边界 | Backend、Sandbox、命令策略和服务端 ACL |
FilesystemMiddleware(tools=…) 不适用于本文锁定的 0.6.12:该版本构造函数没有公开 tools 参数。升级到提供该能力的版本后可以重新采用,但不能把未来 API 写进当前可运行代码。
Permissions 只约束内置文件 Tool,不覆盖自定义 Tool、MCP、Store 和 execute。如果 Backend 提供 Shell,文件路径 deny 规则也不能阻止 Shell 绕过,必须依赖 Sandbox 或 Backend Policy。
3.5 Skills、Runtime Context 与 Backend 交接
自定义 SubAgent 不继承主 Skills,必须显式设置 skills=[…];默认 general-purpose 是例外,会获得主 Skills。父子 Skills State 相互隔离。
Runtime Context 会传播到 SubAgent。需要角色专用配置时,可以使用扁平命名空间字段,例如 analyst:max_rows、reviewer:strict_mode,但身份和权限值仍必须来自服务端认证结果。
大型产物适合写入共享 Backend,再在最终结果中返回路径。路径可见不等于租户归属合法:Backend 或外部 Artifact Service 必须根据可信身份、Namespace、路由、ACL 或签名元数据强制校验,不能让主 Agent 根据字符串路径自行判断。
3.6 结构化输出减少二次解析
配置 response_format=AnalysisResult 后,SubAgent 返回 State 中的 structured_response 会优先序列化成 JSON ToolMessage;父 Agent 无需从自然语言中提取数值。
本例 Pydantic 字段使用 Decimal,model_dump_json() 输出:
{
"metric": "margin_rate",
"value": "0.375",
"evidence": ["revenue=120", "cost=75"],
"risks": []
}
value 是字符串来自当前 Pydantic 的 Decimal JSON 序列化,不是 Deep Agents 对所有数值字段的统一转换。不同 Schema、Pydantic 配置、Provider Strategy 或 Tool Strategy 可能产生不同表示。
4. CompiledSubAgent
4.1 什么时候使用
声明式 SubAgent 适合“模型 + Tool + Prompt”的专业角色。需要确定性节点、分支、循环、专用 State Schema 或已有 LangGraph 时,应使用 CompiledSubAgent:
def build_compiled_reviewer() -> CompiledSubAgent:
builder = StateGraph(ReviewState)
builder.add_node("review", review_node)
builder.add_edge(START, "review")
builder.add_edge("review", END)
return {
"name": "compiled-reviewer",
"description": "离线审核共享报告文件并返回简洁结论。",
"runnable": builder.compile(),
}
State Schema 必须包含 messages,否则 Task Middleware 无法向父 Agent 交付结果。需要接收父 State 的其他字段,也必须在子图 Schema 中明确声明。
4.2 结果提取优先级
deepagents==0.6.12 的当前实现按以下顺序构造 ToolMessage:
- structured_response 非空时,按 Pydantic、dataclass 或 JSON 对象序列化;
- 否则从返回 State 中向前寻找最后一个非空 AIMessage 文本;
- 找不到非空文本时返回空 ToolMessage;
- 子图其他允许返回的 State 字段合并到父更新,排除 messages、todos、structured_response 和 Private State。
“向前寻找非空 AIMessage”是当前 Task Middleware 为尾部空 end_turn 消息提供的兼容逻辑,不是所有版本和多模态内容的永久保证,应通过契约测试锁定。
4.3 CompiledSubAgent 不自动继承声明式能力
Compiled Runnable 按原样使用。它不会自动获得:
- 主 Agent Model 和自定义 Tool;
- Todo、Filesystem、Summarization、Skills 和 Memory Middleware;
- Permissions 和 HITL;
- 主 System Prompt;
- Checkpointer。
Task Middleware 仍负责父 State 过滤和结果包装,但子图内部能力由构建者负责。
4.4 Persistence 与嵌套 HITL
同步 task 每次启动一次短生命周期执行,不意味着 SubAgent 天然拥有跨调用记忆。需要持久状态时,Compiled Runnable 必须显式使用 Store 或 Checkpointer,并设计父 thread_id、子图线程和 Namespace 的映射。
CompiledSubAgent 的审批需要在子图内部配置,但仅验证子图单独中断还不够。必须通过完整父 Agent 集成测试确认:
- 子图 Interrupt 如何暴露给外层;
- 应用怎样提交 decisions;
- 等待中的同步 task 如何恢复;
- 外层线程与子图 Checkpoint 如何关联;
- 重复 Resume 是否产生副作用。
本文没有完成嵌套 HITL 在线验证,因此只说明架构边界,不声称配置后一定可恢复。
5. 多智能体编排模式
5.1 串行与并行委派
Analyst 的结果是 Reviewer 输入时,必须串行:
Analyst → 主 Agent 校验/交接 → Reviewer → 主 Agent 汇总
多个任务彼此独立时,主模型可以在同一 AIMessage 中发出多个 task Tool Call。在支持并行 Tool 执行的当前 Runtime 中,它们可以并发运行;实际并发度仍受同步/异步路径、线程安全、连接池、Rate Limit、Backend 和应用配置限制。
模型发出多个 Tool Call 不等于所有部署环境都一定并行,也不意味着有数据依赖的任务应该并行。
5.2 常见模式
| 模式 | 流程 | 适用情况 |
|---|---|---|
| Router | 判断任务类型后选择一个 Agent | 领域明确、单路由 |
| Fan-out / Fan-in | 多个 Agent 独立处理,主 Agent 汇总 | 可并行的多来源研究 |
| Pipeline | 前一 Agent 产物作为后一 Agent 输入 | 分析→审核→发布 |
| Generator / Reviewer | 一个生成,一个独立检查 | 质量控制 |
| Map / Reduce | 按分片处理,再聚合 | 大量同构输入 |
Generator / Reviewer 只有在 Reviewer 获得原始证据或可复算 Tool、并对正确与错误输入表现出差异时,才有“独立审核”的证据。只多输出一条风险提示不能证明独立验证。
5.3 Tool、Skill、SubAgent、Workflow 怎么选

| 需求 | 优先选择 |
|---|---|
| 单一步确定性动作 | Tool |
| 只需按需加载流程知识和脚本 | Skill |
| 需要隔离大量中间上下文 | 同步 SubAgent |
| 需要固定分支、循环和可预测顺序 | LangGraph Workflow / CompiledSubAgent |
| 需要后台执行、查询、更新和取消 | Async SubAgent |
| 需要运行时生成角色或嵌套策略 | Dynamic SubAgent,并设置资源边界 |
Skills 与 Multi-Agent 都包含“识别需求、选择能力”,但 Skill 主要减少说明常驻上下文,SubAgent 主要隔离执行上下文和角色能力。
5.4 什么时候不要委派
不适合 SubAgent 的场景:
- 一次 Tool Call 能完成的确定性动作;
- 子任务必须持续读取父 Agent 每一条中间消息;
- 交接成本高于任务本身;
- 延迟预算无法容纳额外模型轮次;
- 权限边界尚未实现;
- 结果没有可校验 Schema 或证据。
多智能体不是质量自动提升器。职责、输入和校验都不清晰时,只会把一个不确定模型调用扩展成多个不确定调用。
6. 成本、失败与安全
6.1 成本与延迟模型
同步串行委派的 Token 成本近似为主 Agent 多轮请求、所有 SubAgent 请求和汇总请求之和。并行只能降低墙钟等待,不能自动降低 Token。
墙钟延迟 ≈ 路由 + 调度开销 + 最慢关键路径 + 汇总 + 重试
还要计算排队、Backend I/O、Structured Output Retry、Rate Limit 和冷启动。没有分 Agent Trace 时,仅凭总耗时无法定位瓶颈。
6.2 重试与幂等
失败策略应按副作用分类:
- 纯读取和确定性计算可有限重试;
- 文件写入使用临时文件、校验后原子发布;
- 外部消息、支付或工单操作使用幂等键;
- Structured Output 错误限制重试次数,并保存最后一次验证错误;
- SubAgent 超时后主 Agent不能把 Todo 标为完成。
不要让主 Agent无限递归委派另一个 Agent处理每个错误。需要设置最大深度、总 Tool Call、总 Token、墙钟时间和并发数。
6.3 主 Agent 必须校验和整合
主 Agent不能直接拼接所有返回值。至少检查:
- 结构化结果是否通过 Schema;
- 数值是否由确定性 Tool 复算;
- 证据文件是否存在、哈希是否一致;
- 数据口径与日期范围是否一致;
- 多个 Agent 结论冲突时是否报告;
- 产物租户归属是否由 Backend / ACL 强制验证。
路径字符串不是所有权证明。租户归属必须由可信 Runtime Context、Backend Namespace、Store Namespace、Signed Artifact Metadata 或服务端 ACL 强制执行。
6.4 受限 Decimal 计算 Tool
本文计算器不使用 eval,仅允许 + - * /、括号和有限数。整改后增加:
- 表达式长度不超过 200;
- AST 节点不超过 64;
- AST 深度不超过 16;
- Decimal 有效数字不超过 50;
- 数量级不超过配置边界;
- Decimal Context 精度固定为 50;
- 拒绝变量、调用、属性、幂运算、布尔值、无限数和除零。
def evaluate_expression(expression: str) -> Decimal:
if len(expression) > 200:
raise ValueError("expression is too long")
tree = ast.parse(expression, mode="eval")
if sum(1 for _ in ast.walk(tree)) > _MAX_AST_NODES:
raise ValueError("expression has too many AST nodes")
if _tree_depth(tree) > _MAX_AST_DEPTH:
raise ValueError("expression is too deeply nested")
with localcontext() as context:
context.prec = _DECIMAL_PRECISION
return _evaluate_node(tree)
对完全不可信输入,仍应在有 CPU/墙钟限制的独立进程或 Sandbox 中运行;AST 白名单不是操作系统级资源隔离。
6.5 Reviewer 必须读取证据并做负向测试
新版 Reviewer 获得 verify_margin Tool,必须基于 revenue、cost、claimed 和 evidence 复算。离线对照测试覆盖:
| 输入 | 预期 |
|---|---|
| 0.375 + 完整 revenue/cost 证据 | 通过 |
| 故意错误的 0.4 + 完整证据 | 失败:数值不一致 |
| 正确 0.375 + 缺少 cost 证据 | 失败:证据不完整 |
这验证的是确定性审核 Tool 能区分三种情况。真实模型是否始终调用、是否正确传参,仍需单独 E2E Trace 验证。
7. 测试、可观测性与在线边界
7.1 可观测性
至少记录:
- 主 Agent 与 SubAgent Name;
- Todo 创建、修改和完成时间;
- 每个 task 的类型、耗时、状态与重试;
- 每个 Agent 的输入 / 输出 Token;
- Tool 错误、Structured Output 校验错误和超时;
- 交接文件路径、Namespace 与校验值;
- 最终答案采用或拒绝了哪些 SubAgent 结论。
lc_agent_name 可以用于 LangSmith Trace 过滤和非安全统计,不能用于认证和授权。
7.2 离线测试环境与结果
| 项目 | 版本 |
|---|---|
| Python | 3.12.11 |
| deepagents | 0.6.12 |
| langchain-core | 1.4.9 |
| langgraph | 1.2.9 |
| langgraph-checkpoint | 4.1.1 |
| langchain-openai | 1.3.5 |
| pydantic | 2.13.4 |
| 操作系统 | macOS 15.7.3 arm64 |
cd source/_posts/deepagent/examples
source .venv_deepagent/bin/activate
python -m compileall -q p08_subagents
python -m ruff check p08_subagents
pytest -o addopts='' p08_subagents -q
PYTHONPATH=. python p08_subagents/planning.py
All checks passed!
...................... [100%]
22 passed
22 个 Test Item 覆盖:
- Decimal 正确性、危险语法、AST 数量、深度和数值规模;
- 声明式 SubAgent Name、Tool 与 Response Format;
- write_todos 底层契约;
- Scripted Model 完整 Tool Calling、ToolMessage、Todo State 和最终文本;
- Task Schema、已注册 SubAgent 和未知类型错误;
- 父消息、Private State 与共享 State 传播;
- 结构化响应 JSON ToolMessage;
- Reviewer 正确值、错误值与缺失证据对照;
- 完整 Deep Agent 构造。
.func 测试属于 Middleware 契约测试;Scripted Model 测试属于 Agent 集成测试;网关调用属于在线 E2E。三者覆盖范围不同。
7.3 真实模型委派结果
下面是保存的在线结果。qwen3.7-plus 是第三方 OpenAI-compatible Gateway 返回的模型 ID / 别名,不代表所有 Qwen Provider 都提供同名模型。
| 项目 | 值 |
|---|---|
| Endpoint 类型 | 第三方 OpenAI-compatible Gateway |
| 模型 ID / 别名 | qwen3.7-plus |
| deepagents | 0.6.12 |
| langchain-openai | 1.3.5 |
| Response Format 输入 | Pydantic AnalysisResult,裸类型对应 AutoStrategy |
| 实际 Provider / Tool Strategy | 结果文件未记录,不能事后断言 |
| Thinking 设置 | Qwen-compatible Profile 下请求 enable_thinking=false |
| 错误 HTTP 码 | 未保存,不作推断 |
{
"scene": "p08_real_subagent_delegation",
"status": "passed",
"model": "qwen3.7-plus",
"latency_ms": 39510,
"subagents": ["analyst", "reviewer"],
"metric": "gross_margin_percentage",
"value": "37.5%",
"review": "calculation passed; source, currency and accounting scope need disclosure"
}
该记录证明特定端点、模型别名和依赖组合中完成过 Analyst 与 Reviewer 委派,并得到 37.5% 结果。它不能证明:
- 所有 Qwen 模型的思考模式都拒绝强制 Tool Choice;
- 实际 Structured Output 使用了哪一种 Strategy;
- Reviewer 独立读取了原始证据;
- 39,510ms 中每个 Agent 分别耗时多少。
总延迟包含 Supervisor 多轮路由、两个 SubAgent、结构化输出、汇总和网络等待,但结果文件没有保存子 Span,不能可靠拆分。Reviewer 多给出风险提示也不足以证明独立审核。
Reviewer 的确定性复算 Tool 与三组负向测试由离线测试覆盖;前述在线记录不用于证明这些路径已在线重跑。
8. 总结
write_todos 提供主 Agent 的计划和进度,task 提供同步、短生命周期的隔离执行。主 Agent 负责拆分、路由、依赖排序、结果校验和最终交付;SubAgent 在明确的 Description、Tool 和权限边界内完成一项复杂工作。
声明式 SubAgent 适合快速配置专业角色,CompiledSubAgent 适合复用确定性 LangGraph。两者的 Model、Tool、Skills、Middleware、State、权限和 Checkpointer 边界不同,必须按锁定版本测试,不能仅凭名称推断继承关系。
State 过滤不等于完整安全隔离,Description 也不是权限系统。Runtime Context、Backend、Store、Shell 和外部服务都需要独立的身份与资源边界。
多智能体系统的目标不是增加 Agent 数量,而是把复杂任务转化成输入明确、上下文受控、结果可验证、失败可恢复的协作过程。