Agent 调用链

一句话结论

agent 调用 = 模型触发一次 AgentTool 的 tool call,而 AgentTool 内部再启动一个新的 query() 循环来运行子 agent。

总链路

用户输入
  → QueryEngine.submitMessage()
  → query(...)
  → assistant 输出 tool_use(name=Agent)
  → 工具执行器分发到 AgentTool.call(...)
  → AgentTool 路由执行模式
  → runAgent(...)
  → 子 agent 再次进入 query(...)
  → 产生结果
  → 返回给父 agent

关键文件

  • src/QueryEngine.ts
  • src/query.ts
  • src/Tool.ts
  • src/tools.ts
  • src/tools/AgentTool/AgentTool.tsx
  • src/tools/AgentTool/runAgent.ts

拆解

1. QueryEngine 不直接运行 agent

QueryEngine.submitMessage() 负责准备:

  • messages
  • systemPrompt
  • userContext
  • toolUseContext

然后把控制权交给 query()

2. query() 识别 tool_use

query.ts 中可以看到:

  • StreamingToolExecutor
  • runTools
  • findToolByName

这说明主循环会在收到模型的 tool_use 后,进入统一工具执行流程。

3. Agent 是 built-in tool

tools.tsgetAllBaseTools()AgentTool 注册进 built-in tool 列表。

所以调用 agent 在框架视角里只是:

  • 一个名字叫 Agent 的工具

4. AgentTool.call() 决定路由

AgentTool.call() 会根据输入参数和环境,决定走哪条路径:

  • teammate spawn
  • fork subagent
  • remote agent
  • local sync agent
  • local async/background agent
  • worktree-isolated agent

5. runAgent() 是真正的子 agent 启动器

runAgent() 会:

  • 生成 agentId
  • 构造初始消息
  • 构造 agent-specific system prompt
  • 组装 agent-specific tools / permissions / appState 视图
  • 创建 agent-specific ToolUseContext
  • 最终再次调用 query()

结构意义

这个设计说明:

  • agent 不是“主循环之外”的特例
  • 子 agent 和主 agent 是同构的
  • 系统通过“上下文再实例化”实现多 agent,而不是复制一套独立 runtime

后续待追

  • StreamingToolExecutor
  • toolOrchestration
  • createSubagentContext
  • agentToolUtils