03.2 子智能体运行时
关注源码
src/tools/AgentTool/AgentTool.tsxsrc/tools/AgentTool/runAgent.tssrc/utils/forkedAgent.tssrc/utils/agentContext.ts
AgentTool 做的事远超“再起一个模型调用”
AgentTool 要同时处理:
- 选择 agent definition
- 解析运行模式与隔离方式
- 解析允许工具集
- 创建子上下文
- 选择同步、后台、worktree、remote 或 teammate 运行
- 注册任务
- 汇总结果、更新进度、发通知
所以它本质上是“多智能体运行时的桥接层”。
runAgent() 的核心作用
runAgent.ts 把一个 agent definition 变成可运行回合,主要负责:
- 解析 agent 专属 system prompt
- 解析 agent frontmatter 中的 MCP servers
- 组装 agent 可见 commands / tools
- 创建专属 transcript subdir
- 调用通用
query() - 记录 sidechain transcript
- 做 agent 生命周期清理
它并没有复制一套 query 逻辑,而是复用主循环。
forkedAgent.ts 决定了隔离边界
这个文件最关键的设计是“默认隔离,显式共享”。创建 subagent context 时,默认会:
- clone
readFileState - clone
contentReplacementState - 为子 agent 创建自己的 abort controller
- 让大部分父级 mutation callback 失效
- 为后台 agent 设置
shouldAvoidPermissionPrompts
只有在显式 opt-in 时,才共享:
setAppStatesetResponseLength- 父级 abort controller
这使后台 agent 不容易污染主线程状态。
cache-safe fork 是这层的隐含主线
forkedAgent.ts 里专门定义了 CacheSafeParams,强调以下参数必须与父请求保持一致:
systemPromptuserContextsystemContexttoolUseContextforkContextMessages
说明子智能体系统不是只追求“跑起来”,而是追求:
- 共享 prompt cache
- 复用父上下文前缀
- 降低 fork 成本
agent 身份如何传播
utils/agentContext.ts 使用异步上下文传递 agent identity,而不是把 agent 身份硬塞进单一全局状态。这样可以在:
- 多个后台 agent 并发
- 远端与本地 agent 混跑
- telemetry / hooks / logging 并发
时仍能正确归因。
典型子智能体路径
AgentTool.call()解析输入和 agent definition。- 根据
run_in_background、isolation、team/worktree/remote 选择执行策略。 runAgent()组装 agent 专属上下文和工具池。- 复用
query()执行。 - 通过任务层或同步结果把输出送回主会话。
这层的设计结论
1. 子智能体不是特判分支,而是主运行时的 fork
这样主线程和子线程共享同一套:
- prompt 语义
- 工具契约
- transcript 结构
- 统计与 telemetry
2. 隔离边界是按状态能力切的,不只是按进程切
即使仍在同进程内,subagent 也可以通过 ToolUseContext 裁掉写回能力。
3. agent frontmatter 可以扩展平台面
runAgent.ts 支持 agent 自带 MCP server 定义,说明 agent 不只是 prompt 模板,也可以携带执行环境要求。