概述
Agent 的 run 函数实现了一个 ReAct (Reasoning + Acting) 模式的 AI Agent,通过迭代的方式与 Claude API 交互,执行工具调用并最终返回答案。
消息流转
sequenceDiagram
participant User
participant Agent
participant Claude API
participant Tools
User->>Agent: 发送问题
Agent->>Claude API: messages + tools schemas
loop 直到 end_turn 或达到最大迭代
Claude API->>Agent: 响应 (思考 + tool_use)
Agent->>Agent: 打印思考过程
alt stop_reason = tool_use
par 并行执行工具
Agent->>Tools: 执行工具1
Agent->>Tools: 执行工具2
Agent->>Tools: 执行工具N
end
Tools->>Agent: 返回结果
Agent->>Claude API: 工具结果作为 user 消息
else stop_reason = end_turn
Agent->>User: 返回最终答案
end
end
详细流程图
flowchart TD
Start([开始: run函数])
Start --> Init[初始化消息列表<br/>添加用户消息]
Init --> Loop{迭代次数 < maxIterations?}
Loop -->|是| CallAPI[调用 Claude API<br/>传入 messages 和 tools]
Loop -->|否| MaxIter[抛出错误:<br/>到达最大迭代次数]
CallAPI --> AddMsg[将 API 响应添加到<br/>messages 作为 assistant 消息]
AddMsg --> ProcessContent[处理响应内容]
ProcessContent --> PrintThought[打印所有 text 类型的<br/>思考过程内容]
PrintThought --> CheckStop{检查 stop_reason}
CheckStop -->|end_turn| HandleFinal[处理最终答案]
CheckStop -->|tool_use| HandleTool[处理工具调用]
HandleFinal --> ExtractText[提取所有 text 类型内容]
ExtractText --> PrintFinal[打印最终答案]
PrintFinal --> End([结束])
HandleTool --> FilterTools[过滤出所有<br/>tool_use 类型的 blocks]
FilterTools --> ParallelExec[并行执行所有工具调用<br/>Promise.all]
ParallelExec --> CallTool[对每个 tool_use block:<br/>call_tool函数]
CallTool --> TryExecute{尝试执行工具}
TryExecute -->|成功| ToolSuccess[创建成功的<br/>tool_result]
TryExecute -->|失败| ToolError[创建错误的<br/>tool_result<br/>is_error: true]
ToolSuccess --> CollectResults[收集所有工具结果]
ToolError --> CollectResults
CollectResults --> AddToolResults[将工具结果作为<br/>user 消息添加到 messages]
AddToolResults --> Loop
MaxIter --> End
关键步骤
1. 初始化阶段
- 打印 Agent 标题和用户消息
- 创建消息列表,包含初始用户消息
2. 迭代循环
- 最多执行
maxIterations次 - 每次迭代都会调用 Claude API
3. API 调用
- 使用当前的 messages 历史
- 传入注册的工具 schemas
- 获取 Claude 的响应
4. 响应处理
- 思考过程: 打印所有
text类型的内容块 - 停止原因判断:
end_turn: 表示 Agent 完成思考,返回最终答案tool_use: 表示 Agent 需要调用工具
5. 工具调用处理
- 提取所有
tool_use类型的内容块 - 并行执行所有工具调用
- 每个工具调用:
- 打印工具名称和参数
- 执行工具函数
- 捕获错误并标记
is_error: true
- 将所有工具结果作为新的
user消息添加到历史中
6. 最终答案处理
- 提取所有
text类型内容 - 打印最终答案
- 结束执行