子智能体(subagent) 核心概念
别名:
子 Agent · worker
被委派执行独立子任务的 Agent 实例:同一个循环函数的另一份实例,喂全新消息历史、裁剪过的工具白名单与独立预算。隔离是构造性的,结果以终答字符串回填给主 Agent。见[第 22 章](/chapters/22-multi-agent-v09/)。
它是什么
子智能体(subagent)是被委派执行独立子任务的 Agent 实例:同一个循环函数的另一份实例。ch07 手写的 runAgent 再调用一次,喂全新的消息历史、裁剪过的工具白名单、独立的迭代预算、自己的 sessionId,它就是 subagent——同一个函数,两个实例,互不相识。四个隔离维度:
| 维度 | 主 Agent | subagent |
|---|---|---|
| 消息上下文 | 会话历史(含所有工具结果) | 全新 [system(SUBAGENT_PROMPT), user(task)] |
| 工具集 | 全部注册工具 + delegate 元工具 |
白名单(默认 get_weather/add) |
| 预算 | maxIterations |
subagentMaxIterations(独立保险丝) |
| 会话/事件 | 主 sessionId + 主事件流 | sub_N sessionId + 独立观察者 |
隔离是构造性的
工厂刻意只接受 { task, context? }:subagent 从 [system, user(task)] 开始,没有入口自然串不了。判断标准一句话:把主历史删掉,subagent 还能不能独立跑? 能,才是隔离。这与 Claude Code 的 subagent 机制同源——子代理拥有自己的 messages[] 与工具 allowlist,向父 Agent 返回摘要而不是原始上下文。
结果回收
subagent 的终答是字符串,主循环把它塞进主对话的 tool 消息——主 Agent 下一轮看到「delegate 返回了 上海:晴,27°C…」,就像看到一个普通工具的执行结果。主 Agent 不需要知道这个结果来自一个完整的 subagent。隔离的反面是结果要穿过边界回填(终答字符串),细节(完整历史)留在 subagent 自己的 session 里。注意预算截断:没跑完(budgetExceeded)就返回失败可见的错误,半成品不当作真话回填。
在本教程的位置
第 22 章的 lib/orchestrate.mjs 用 buildSubagent 工厂决定隔离的一切(白名单构建 + runAgent 实例化),主循环只认签名 ({ task, context? }) => Promise<{ ok, result?, error?, iterations? }>——和 ch18 的 getApproval 是同一个注入模式。