Claude Code Harness Chapter 3: Agent Loop:从用户输入到模型响应的完整生命周期
Claude Code Harness Chapter 3: Agent Loop:从用户输入到模型响应的完整生命周期
引言:AI 决策的核心引擎
如果说工具是 AI 的双手,那么 Agent Loop 就是它的大脑——一个持续运行的决策引擎,分析情况、选择行动、观察结果,并决定下一步做什么。
Agent Loop 不是简单的"输入→输出"流程。它是一个复杂的、迭代的推理过程,能够:
- 🧠 理解用户意图和 Context
- 🎯 规划多步骤策略
- 🔧 执行工具并观察结果
- 🔄 适应基于反馈调整策略
- ⏸️ 响应用户的中断和指导
本章将深入剖析 Claude Code 的 Agent Loop 架构,揭示如何通过精心设计的循环机制,将简单的用户请求转化为复杂的多步骤问题解决过程。
Agent Loop 的核心架构
什么是 Agent Loop?
Agent Loop 是 Claude Code 的中央决策引擎,实现了"感知→决策→行动→观察"的循环:
flowchart TD
A[Receive user input] --> B[Build context]
B --> C[Call Claude API]
C --> D{Analyze response}
D -->|Need tool| E[Execute tool]
D -->|Need more info| F[Ask user]
D -->|Task complete| G[Generate final response]
E --> H[Get tool result]
H --> I[Update context]
I --> C
F --> J[Receive user answer]
J --> C
G --> K[Stream to user]
style C fill:#e1f5ff
style E fill:#e1f5ff图:Agent Loop 核心流程
这个循环持续进行,直到任务完成、用户干预或出现错误。
Query Engine:循环的协调者
QueryEngine 类是 Agent Loop 的核心实现:
export class QueryEngine {
// 消息状态管理
private mutableMessages: Message[]
// 控制机制
private abortController: AbortController
// 权限跟踪
private permissionDenials: SDKPermissionDenial[]
// 使用追踪
private totalUsage: NonNullableUsage
// 发现和记忆
private discoveredSkillNames = new Set()
private loadedNestedMemoryPaths = new Set()
} QueryEngine 负责管理对话的完整生命周期,包括消息流、工具执行、权限检查和错误恢复。
完整的生命周期流程
阶段 1:输入处理和 Context 构建
当用户发送消息时,系统首先构建完整的 Context:
flowchart LR
A[User input] --> B[Parse message]
B --> C[Collect system context]
C --> D[Load related files]
D --> E[Get conversation history]
E --> F[Check memory files]
F --> G[Build complete request]
C --> C1[Git status]
C --> C2[Project structure]
C --> C3[System info]
style G fill:#e1f5ff图:Context 构建流程
Context 组成部分:
| Context 类型 | 来源 | 作用 |
|---|---|---|
| 系统 Context | Git 状态、项目结构 | 提供环境和项目信息 |
| 对话历史 | 之前的消息轮次 | 维护对话连续性 |
| 文件 Context | 打开的文件、代码库 | 理解代码内容 |
| 工具 Context | 可用工具和 schemas | 知道能做什么 |
| 内存 Context | CLAUDE.md、记忆文件 | 学习用户偏好 |
阶段 2:API 调用和流式响应
Context 构建完成后,系统调用 Claude API:
sequenceDiagram
participant User
participant QueryEngine
participant ClaudeAPI
participant Tools
User->>QueryEngine: Send message
QueryEngine->>QueryEngine: Build context
QueryEngine->>ClaudeAPI: Send request
ClaudeAPI-->>QueryEngine: Start streaming response
loop Stream tokens
ClaudeAPI-->>QueryEngine: content delta
QueryEngine-->>User: Display in real-time
end
ClaudeAPI-->>QueryEngine: Detect tool use
QueryEngine->>Tools: Execute tool
Tools-->>QueryEngine: Tool result
QueryEngine->>ClaudeAPI: Continue conversation
ClaudeAPI-->>QueryEngine: Final response
QueryEngine-->>User: Complete图:API 调用和流式响应流程
这种流式方法实现了:
- 实时反馈:用户立即看到响应
- 可中断性:用户可以随时停止
- 动态调整:根据工具结果调整响应
阶段 3:工具执行和结果处理
当模型决定使用工具时:
stateDiagram-v2
[*] --> Ready to execute: Model requests tool
Ready to execute --> Verify permissions: Check permissions
Verify permissions --> Awaiting approval: Needs user confirmation
Verify permissions --> Executing: Permission granted
Awaiting approval --> Executing: User approved
Awaiting approval --> Cancelled: User denied
Executing --> Executing: Tool running
Executing --> Completed: Tool succeeded
Executing --> Failed: Tool error
Completed --> [*]
Failed --> [*]
Cancelled --> [*]
note right of Executing
Stream progress
Update UI status
Track resource usage
end note图:工具执行状态机
工具执行的类型:
| 执行类型 | 描述 | 示例 |
|---|---|---|
| 顺序执行 | 工具按顺序运行 | 读取文件 → 编辑 → 保存 |
| 并发执行 | 多个工具同时运行 | 并行搜索多个目录 |
| 条件执行 | 基于结果决定下一步 | 测试通过 → 部署,失败 → 修复 |
| 循环执行 | 重复直到条件满足 | 迭代修复直到测试通过 |
阶段 4:响应生成和输出
最后,模型生成最终响应:
flowchart TD
A[All tools complete] --> B{More info?}
B -->|Yes| C[Continue reasoning]
B -->|No| D[Generate final response]
C --> E{Need more tools?}
E -->|Yes| F[Execute more tools]
E -->|No| D
F --> G[Process results]
G --> B
D --> H[Stream output]
H --> I[Complete]图:响应生成流程
高级 Loop 特性
1. 动态重新规划
Agent Loop 不是僵化的计划执行器。它会根据新信息动态调整:
flowchart TD
A[Initial plan] --> B[Execute step 1]
B --> C{Result as expected?}
C -->|Yes| D[Execute step 2]
C -->|No| E[Analyze failure]
E --> F[Revise plan]
F --> G[Execute new step]
G --> H{Better result?}
H -->|Yes| D
H -->|No| E
style E fill:#fc6
style F fill:#fc6图:动态重新规划流程
实战示例:调试失败
用户: "修复登录 bug"
Loop 迭代 1:
- 计划: 读取 auth.js → 查找错误 → 修复
- 执行: 读取 auth.js,发现错误不明显
- 重新规划: 需要运行测试来定位问题
Loop 迭代 2:
- 计划: 运行测试 → 分析失败 → 修复代码
- 执行: 测试显示 token 验证失败
- 重新规划: 检查 token 生成逻辑
Loop 迭代 3:
- 计划: 读取 token.js → 修复生成逻辑 → 重新测试
- 执行: 修复成功,测试通过
- 完成: 提交修复2. 多轮对话管理
Agent Loop 管理完整的对话历史:
graph LR
A[Round 1
User: Help write function] --> B[Round 2
AI: Here's code]
B --> C[Round 3
User: Add error handling]
C --> D[Round 4
AI: Added]
D --> E[Round 5
User: Now add logging]
E --> F[Round 6
AI: Complete]
style A fill:#e1f5ff
style C fill:#e1f5ff
style E fill:#e1f5ff图:多轮对话流程
消息压缩策略:
| 策略 | 触发条件 | 方法 |
|---|---|---|
| 直接传递 | < 50K tokens | 保持所有消息 |
| 选择性压缩 | 50K-100K tokens | 压缩旧工具结果 |
| 摘要压缩 | 100K-150K tokens | 摘要早期轮次 |
| 激进压缩 | > 150K tokens | 只保留关键信息 |
3. 错误恢复和重试
Agent Loop 实现了强大的错误处理:
flowchart TD
A[Execute operation] --> B{Success?}
B -->|Yes| C[Continue]
B -->|No| D{Error type}
D -->|Retryable| E[Wait and retry]
D -->|Permission issue| F[Request permission]
D -->|Logic error| G[Analyze and adjust]
D -->|Fatal error| H[Report and stop]
E --> A
F --> I{User approved?}
I -->|Yes| A
I -->|No| H
G --> J[Modify approach]
J --> A
style C fill:#6f6
style H fill:#f66图:错误恢复流程
错误分类:
| 错误类型 | 处理策略 | 示例 |
|---|---|---|
| 网络错误 | 重试(最多 3 次) | API 超时 |
| 权限错误 | 请求用户批准 | 文件写入被拒绝 |
| 验证错误 | 修正参数 | 无效文件路径 |
| 逻辑错误 | 分析并调整计划 | 测试失败 |
4. 用户中断处理
用户可以随时中断 Loop:
sequenceDiagram
participant User
participant Loop
participant Tool
Loop->>Tool: Execute long operation
User->>Loop: Ctrl+C (interrupt)
Loop->>Tool: Send cancel signal
Tool-->>Loop: Cancelled
Loop->>User: Current state summary
Loop->>User: "Continue or stop?"图:用户中断处理流程
中断模式:
| 中断类型 | 行为 | 恢复选项 |
|---|---|---|
| 软中断 | 完成当前工具后停止 | 继续 / 停止 |
| 硬中断 | 立即停止所有操作 | 重新开始 / 退出 |
| 引导中断 | 停止并请求指导 | 修改方向 / 继续原始计划 |
Loop 的性能优化
1. 智能缓存
flowchart LR
A[Request file content] --> B{In cache?}
B -->|Yes| C[Return cache]
B -->|No| D[Read file]
D --> E[Store in cache]
E --> F[Return content]
style C fill:#6f6
style E fill:#e1f5ff图:智能缓存流程
缓存策略:
| 资源类型 | 缓存时长 | 失效条件 |
|---|---|---|
| Git 状态 | 5 分钟 | 文件系统变化 |
| 文件内容 | 会话期间 | 文件被修改 |
| 项目结构 | 会话期间 | 目录变化 |
| 工具结果 | 5 分钟 | 手动刷新 |
2. 并行工具执行
sequenceDiagram
participant Loop
participant Tool1
participant Tool2
participant Tool3
par Concurrent execution
Loop->>Tool1: Execute
Loop->>Tool2: Execute
Loop->>Tool3: Execute
end
Tool2-->>Loop: Complete (1st)
Tool3-->>Loop: Complete (2nd)
Tool1-->>Loop: Complete (3rd)
Loop->>Loop: Collect all results图:并行工具执行
并行决策:
| 条件 | 并行执行 | 顺序执行 |
|---|---|---|
| 工具独立 | ✅ | ❌ |
| 有依赖关系 | ❌ | ✅ |
| 资源密集 | ❌ | ✅ |
| 需要实时反馈 | ❌ | ✅ |
3. 增量 Context 更新
flowchart TD
A[Full context] --> B{Update only changes?}
B -->|Yes| C[Incremental update]
B -->|No| D[Full rebuild]
C --> E[Smaller request]
D --> F[Larger request]
E --> G[Faster response]
F --> H[Slower response]
style C fill:#6f6
style D fill:#fc6图:增量更新策略
实战案例:完整的 Loop 执行
让我们通过一个完整的例子看看 Agent Loop 如何工作:
用户请求: "修复前端测试失败"
Loop 执行流程:
flowchart TD
Start[User: Fix tests] --> A1[Loop starts]
A1 --> A2[Collect context:
Read test files]
A2 --> A3[Call Claude API]
A3 --> B1{Model decision}
B1 -->|Need more info| B2[Run tests to see failures]
B1 -->|Fix directly| B3[Edit code]
B2 --> C1[Execute: npm test]
C1 --> C2{Tests pass?}
C2 -->|Yes| C3[Tests already pass]
C2 -->|No| C4[Analyze failures]
C4 --> D1[Identify failure cause]
D1 --> D2[Plan fix]
D2 --> E1[Edit: Fix code]
E1 --> E2[Re-run tests]
E2 --> F1{Pass now?}
F1 -->|No| F2[Analyze new failure]
F1 -->|Yes| F3[Fix successful]
F2 --> D1
F3 --> G1[Commit changes]
G1 --> End[Loop ends]
C3 --> End
style A1 fill:#e1f5ff
style E1 fill:#e1f5ff
style G1 fill:#e1f5ff图:测试修复的完整 Loop 执行
详细执行日志:
=== Loop 迭代 1 ===
Context: 读取 3 个测试文件
决策: 需要运行测试来查看失败
工具: BashTool("npm test")
结果: 2 个测试失败
=== Loop 迭代 2 ===
Context: 测试失败输出
决策: 分析失败原因,识别断言错误
工具: ReadTool("src/auth.test.js")
结果: 找到预期值错误
=== Loop 迭代 3 ===
Context: 失败分析
决策: 修复断言的预期值
工具: EditTool("src/auth.test.js", 修改预期值)
结果: 编辑成功
=== Loop 迭代 4 ===
Context: 之前失败,现在重新测试
决策: 验证修复
工具: BashTool("npm test")
结果: 所有测试通过 ✓
=== Loop 迭代 5 ===
Context: 测试通过
决策: 提交修复
工具: GitTool("commit", "修复测试断言")
结果: 提交成功
=== Loop 完成 ===
最终响应: "已修复测试失败!问题是预期值不正确。
所有测试现在都通过了,更改已提交。"Loop 的调试和可观察性
1. 详细的执行日志
flowchart LR
A[Loop execution] --> B[Log each step]
B --> C[Capture tool calls]
C --> D[Track state changes]
D --> E[Generate execution trace]
E --> F[Visualize timeline]
E --> G[Performance analysis]
E --> H[Error diagnostics]
style B fill:#e1f5ff
style E fill:#e1f5ff图:执行日志系统
2. 状态可视化
| 状态指标 | 实时显示 | 用途 |
|---|---|---|
| 活跃工具 | 当前运行的工具 | 监控进度 |
| Token 使用 | 当前/最大 token | 管理 context |
| Loop 迭代 | 迭代计数 | 了解复杂度 |
| 执行时间 | 已用时间 | 性能分析 |
3. 错误追踪
graph TD
A[Error occurs] --> B[Capture error info]
B --> C[Record context]
C --> D[Generate error report]
D --> E[Provide recovery suggestions]
E --> F[Auto retry?]
E --> G[User intervention?]
E --> H[Revise plan?]
style B fill:#e1f5ff
style D fill:#e1f5ff图:错误追踪系统
Loop 的限制和挑战
当前限制
| 限制 | 影响 | 未来改进 |
|---|---|---|
| 线性推理 | 一次一个想法 | 并行推理路径 |
| 有限记忆 | 可能忘记早期信息 | 更好的压缩算法 |
| 固定策略 | 预定义的 Loop 行为 | 自适应 Loop 策略 |
| 单模型 | 一次使用一个模型 | 多模型集成 |
挑战和解决方案
flowchart TD
A[Challenge: Context limit] --> B[Solution: Smart compression]
A2[Challenge: Tool cost] --> B2[Solution: Cache and reuse]
A3[Challenge: User wait] --> B3[Solution: Streaming output]
A4[Challenge: Error recovery] --> B4[Solution: Auto retry]
style B fill:#6f6
style B2 fill:#6f6
style B3 fill:#6f6
style B4 fill:#6f6图:挑战和解决方案映射
结论:Loop 的艺术
Agent Loop 不是简单的循环——它是一个精密的决策引擎,使 Claude Code 能够:
- 理解意图:从用户输入中提取真实需求
- 规划策略:制定多步骤行动计划
- 执行行动:使用工具完成实际工作
- 适应变化:根据结果动态调整
- 处理错误:优雅地从失败中恢复
- 管理 Context:高效使用 token 预算
Loop 的核心原则:
| 原则 | 实现 | 价值 |
|---|---|---|
| 持续推理 | 每次迭代都重新评估 | 更好的决策 |
| 工具优先 | 使用工具而非猜测 | 可靠的结果 |
| 用户控制 | 可中断和引导 | 保持用户主导 |
| 透明性 | 详细的日志和状态 | 可调试和信任 |
| 适应性 | 根据反馈调整 | 处理复杂情况 |
Agent Loop 展示了 Harness Engineering 的精髓:不是构建一个"聪明的 AI",而是构建一个让 AI 智能与实际能力无缝协作的系统。
在下一章中,我们将探讨 工具执行编排——如何管理多个工具的并发执行、处理流式输出和实现细粒度的中断控制。
关键要点
- Agent Loop 是决策引擎:它实现"感知→决策→行动→观察"的循环
- 多阶段流程:从输入处理到响应生成的完整生命周期
- 动态重新规划:根据新信息调整策略
- 强大的错误处理:多种错误类型的分类处理
- 性能优化:缓存、并行执行、增量更新
- 可观察性:详细的日志和状态追踪
延伸阅读
- 第 4 章:工具执行编排——并发、流式和中断
- 第 5 章:系统提示词架构——如何通过 Prompts 引导行为
- QueryEngine 源码:
src/QueryEngine.ts - Query 系统源码:
src/query.ts