mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-17 22:05:50 +00:00
移除所有源码行号、TypeScript 类型定义和函数签名, 聚焦循环四个阶段的设计考量、错误恢复哲学和状态管理原理, 增加"为什么不是批量执行"的设计论证。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
167 lines
7.1 KiB
Plaintext
167 lines
7.1 KiB
Plaintext
---
|
||
title: "Agent Loop"
|
||
description: "理解 Claude Code 的核心循环机制——AI 如何自主决定工具调用、处理错误、管理上下文,直到任务完成。"
|
||
keywords: ["Agentic Loop", "tool_use", "状态机", "auto-compact", "streaming"]
|
||
---
|
||
|
||
## 什么是 Agentic Loop
|
||
|
||
传统聊天机器人:你问一句,它答一句。
|
||
Claude Code 不一样:你说一个需求,它可能连续执行十几步操作才给你最终结果。
|
||
|
||
这背后的机制叫做 **Agentic Loop**(智能体循环)。它是一个"思考→行动→观察"的不断循环,直到任务完成或遇到终止条件。
|
||
|
||
<Frame caption="Agentic Loop 循环示意">
|
||
<img src="/docs/images/agentic-loop.png" alt="Agentic Loop 循环图" />
|
||
</Frame>
|
||
|
||
### 为什么需要循环而非一次回答
|
||
|
||
因为软件工程任务本质上是**探索性**的。AI 不可能在第一步就知道所有信息:
|
||
|
||
- 它需要先读代码才能知道怎么改
|
||
- 它需要先运行命令才能知道结果
|
||
- 它需要先搜索才能找到相关文件
|
||
- 它需要先修改才能验证是否正确
|
||
|
||
每一步工具执行都产生**真实信息**——命令输出、文件内容、错误信息——这些是 AI 在执行前不可能预知的。因此,AI 必须在每一步后根据新信息重新决策。
|
||
|
||
## 循环的四个阶段
|
||
|
||
每次循环迭代包含四个阶段,形成一个完整的"感知→决策→执行→反馈"周期。
|
||
|
||
### 阶段一:上下文预处理
|
||
|
||
在调用 API 之前,系统会依次检查和处理上下文。这是一个串行管道,每一步的输出是下一步的输入:
|
||
|
||
```
|
||
原始消息
|
||
→ 工具结果截断(单条输出过长时截断)
|
||
→ 历史压缩(Snip 压缩旧消息)
|
||
→ 微压缩(工具结果摘要化)
|
||
→ 自动压缩(对话接近 token 上限时触发 AI 摘要)
|
||
处理后的消息 → 发往 API
|
||
```
|
||
|
||
**设计考量**:为什么是串行管道而非一次性处理?因为每个步骤释放的 token 数会影响下一步的决策。例如,如果 Snip 压缩已经释放了足够的 token,自动压缩就不需要触发了。
|
||
|
||
### 阶段二:流式 API 调用
|
||
|
||
系统以流式方式调用 Claude API。流式传输不是"锦上添花"——它是核心设计决策:
|
||
|
||
- **用户体验**:用户看到 AI 逐字输出,而非等待数秒后一次性显示
|
||
- **工具并行执行**:AI 在流式输出过程中就可能发出工具调用,系统可以立即开始执行,不必等流结束
|
||
- **可取消性**:用户随时可以中断正在进行的流式响应
|
||
|
||
### 阶段三:工具执行
|
||
|
||
如果 AI 请求了工具调用,系统执行工具并将结果回传。这里有两个关键设计:
|
||
|
||
**并行执行**:当 AI 在一次响应中请求多个独立工具调用时(如同时读两个文件),系统并行执行它们。这直接减少了用户等待时间。
|
||
|
||
**权限检查**:每个工具执行前都经过权限验证。危险操作(如执行 shell 命令)需要用户确认,安全操作(如读文件)可以自动放行。
|
||
|
||
### 阶段四:终止或继续
|
||
|
||
每次迭代结束时,系统判断是否需要继续:
|
||
|
||
| 条件 | 结果 |
|
||
|------|------|
|
||
| AI 请求了工具调用 | 继续(下一轮迭代) |
|
||
| AI 只返回文本,没有工具调用 | 终止(任务完成) |
|
||
| 用户中断 | 终止(用户取消) |
|
||
| 达到最大 turn 数 | 终止(安全限制) |
|
||
| Token 预算耗尽 | 终止(成本控制) |
|
||
|
||
## 错误恢复:自愈的状态机
|
||
|
||
Agentic Loop 不是"正常路径走完就结束"的简单循环。它包含了多层错误恢复机制,使系统在各种异常情况下都能优雅处理。
|
||
|
||
### 输出截断恢复
|
||
|
||
当 AI 的响应被 token 上限截断时(AI 话说了一半被切断):
|
||
|
||
1. **首次截断**:静默提升输出 token 上限,重试
|
||
2. **仍然截断**:注入提示消息让 AI "接着说",最多重试 3 次
|
||
3. **恢复耗尽**:将截断的响应作为最终结果返回
|
||
|
||
### 上下文过长恢复
|
||
|
||
当对话历史超过 API 的 token 限制时(413 错误):
|
||
|
||
1. **压缩重试**:即时压缩对话历史,生成摘要后重试
|
||
2. **压缩后仍过长**:返回错误信息,让用户决定如何处理
|
||
|
||
关键设计:系统通过标志位防止无限循环——每种恢复路径只尝试一次,不会在"压缩→失败→压缩"之间死循环。
|
||
|
||
### 模型降级
|
||
|
||
当主模型不可用时(过载、维护等):
|
||
|
||
1. 已收集的响应被保留为历史记录
|
||
2. 自动切换到备用模型
|
||
3. 通知用户发生了降级
|
||
4. 从中断点继续,而不是从头开始
|
||
|
||
## 状态管理
|
||
|
||
每次迭代的状态是不可变更新的——系统创建新的状态对象而非就地修改。状态中包含:
|
||
|
||
- **对话消息**:当前所有消息的数组
|
||
- **压缩跟踪**:压缩操作的累计状态
|
||
- **恢复计数**:各种错误恢复已尝试的次数
|
||
- **继续原因**:上一轮为什么继续(用于检测和避免循环)
|
||
|
||
**设计考量**:状态中记录"继续原因"是一个关键的防循环机制。系统可以在后续迭代中检查"上一轮是因为压缩重试而继续的",从而避免在同一个恢复路径上反复尝试。
|
||
|
||
## 为什么不是"一次规划,批量执行"
|
||
|
||
一个自然的疑问是:为什么不先让 AI 规划好所有步骤,然后一次性批量执行?
|
||
|
||
答案在于软件工程的**不确定性**:
|
||
|
||
- **每步结果影响下一步**:搜索结果决定了要改哪些文件,修改后的编译结果决定了是否需要进一步调整
|
||
- **错误需要即时修正**:如果某步失败,AI 需要立即调整策略,而非继续执行无效计划
|
||
- **用户可能中途干预**:循环架构允许用户随时打断和修正方向
|
||
|
||
这不是说 AI 不做规划——事实上系统内置了规划模式(Plan Mode)用于复杂任务。但规划的结果仍然是逐步执行的,每一步都有机会根据新信息调整。
|
||
|
||
## 一个完整的迭代示例
|
||
|
||
> 用户:"帮我找到项目里所有未使用的导入语句,然后删掉它们"
|
||
|
||
```
|
||
迭代 1: 探索
|
||
AI: 先找到所有 TypeScript 文件
|
||
工具: Glob("**/*.ts") → 返回 42 个文件
|
||
决策: 需要进一步分析 → 继续
|
||
|
||
迭代 2: 分析
|
||
AI: 搜索这些文件中的 import 语句
|
||
工具: Grep("import.*from") → 在 15 个文件中找到 120 条 import
|
||
决策: 结果太多,需要进一步筛选 → 继续
|
||
|
||
迭代 3: 精确修改
|
||
AI: 分析哪些 import 未被使用,删除它们
|
||
上下文预处理: 120 条结果被微压缩为摘要
|
||
工具: FileEdit × 3 → 删除 5 条未使用导入
|
||
决策: 需要验证 → 继续
|
||
|
||
迭代 4: 验证与总结
|
||
AI: 验证修改后编译通过
|
||
工具: Bash("tsc --noEmit") → 编译通过
|
||
决策: 任务完成 → 终止
|
||
```
|
||
|
||
注意这个过程中的关键特征:
|
||
- AI 在每一步后根据结果自主决定下一步
|
||
- 上下文在迭代过程中动态调整(微压缩被触发)
|
||
- 用户全程无需介入
|
||
|
||
## 接下来
|
||
|
||
- **流式响应** — 理解流式传输的设计细节和用户体验考量
|
||
- **多轮对话** — 跨迭代的上下文管理和会话持久化
|
||
- **上下文压缩** — 深入理解自动压缩的触发条件和策略
|
||
- **工具系统** — 了解 AI 可以调用哪些工具及其设计
|