Skip to content
Published at:

第 10 章:工作原理

前九章,我们学会了 Claude Code 的"术"——它能做什么、怎么用它完成日常开发任务。从本章开始,我们进入第三篇,掌握 Claude Code 的"道"——它为什么这样工作、内部机制如何运转、怎样利用这些理解让它为你发挥最大效能。

本章是第三篇的基石。当你理解了 Agent Loop、工具系统、上下文管理和权限模型的底层逻辑,你就从"会用 Claude Code"跨入了"精通 Claude Code"的阶段。你将能:

  • 预测 Claude 的下一步行为,而不是被动等待
  • 在 Claude 卡住时精准介入,而不是茫然重试
  • 设计更好的 CLAUDE.md 和项目结构,因为你知道 Claude 如何"看"你的项目
  • 写出更高效的提示,因为你理解提示之后的整个执行链路

本章目标:理解 Agent Loop 的完整执行流程、掌握每个工具的原理与选择逻辑、能阅读工具调用日志并判断 Claude 的工作状态、建立对 Claude Code 内部运作的完整心智模型。

10.1 Agent Loop:核心运转模型

Claude Code 的一切行为都围绕 Agent Loop(代理循环)展开。这不是一个抽象概念——每一次你发送消息,Claude Code 都会经历这个循环,直到任务完成、需要你输入、或触及上限。

flowchart TB A["理解意图"] --> B["制定计划"] B --> C["调用工具"] C --> D{"观察结果"} D -->|"未完成"| B D -->|"完成 / 需输入 / 达上限"| END["退出循环"] style A fill:#e1f5fe style B fill:#e8f5e9 style C fill:#fff3e0 style D fill:#f3e5f5 style END fill:#ffebee

Agentic Loop

循环的五个阶段

阶段一:理解意图(Intent Understanding)

当你发送"帮我重构 src/api/auth.ts,把回调改成 async/await",Claude Code 不只是看到一串文字。它在理解层做了以下工作:

  1. 语义解析:识别核心动作是"重构"(不是新建、不是修复),目标是"auth.ts",约束是"回调改 async/await"
  2. 上下文注入:自动加载当前项目的 CLAUDE.md、git status、系统提示词中被注入的目录结构信息
  3. 歧义消解:如果 auth.ts 中有多处回调模式,Claude 会优先读取文件确认范围
  4. 风险评估:重构 auth 模块属于中高风险操作,需要确认权限

这个阶段决定了后续所有行为的方向。如果意图理解出现偏差(比如把它当成"新建一个 auth 模块"),整个循环都会跑偏。

阶段二:制定计划(Planning)

Claude 不会一上来就改代码。它会先在"思维"中制定执行计划:

计划示例:
1. 用 Read 读取 src/api/auth.ts,理解当前回调结构
2. 用 Grep 搜索项目中所有调用 auth 函数的地方(评估影响面)
3. 逐个函数改写:callback(err, result) → try { result = await ... } catch(err)
4. 用 Edit 工具逐个修改
5. 用 Bash 运行测试确保没有破坏现有逻辑
6. 向用户报告修改摘要

这个计划不是写死的——每次迭代后 Claude 会根据结果调整。计划的质量直接决定了执行效率:好的计划让 Claude 用最少的工具调用完成任务,差的计划导致反复读写、来回修补。

阶段三:调用工具(Tool Execution)

这是你作为用户能看到的最直观的阶段。Claude 输出工具调用请求(JSON 格式),由 CLI/IDE 层在本地执行。你在聊天面板中看到的就是这个阶段的产物——Read 的代码块、Bash 的命令输出、Edit 的 diff 预览。

每次工具调用都是原子的:成功则返回结果,失败则返回错误信息。Claude 必须等待一个工具调用返回后,才能发起下一个(只有少数情况例外,如后台 Task)。

阶段四:观察结果(Result Observation)

这是循环的"决策点"。Claude 读取工具返回的结果,然后做出判断:

  • "结果符合预期,任务完成" → 退出循环,向你报告
  • "结果符合预期,但还有下一步" → 回到阶段二,更新计划
  • "结果不符合预期" → 回到阶段二,调整策略(比如换个搜索关键词、换个修改方式)
  • "需要用户决策" → 暂停循环,弹窗请求你的输入
  • "遇到无法处理的情况" → 退出循环,向你说明问题

这个阶段考验的是 Claude 的"自我评估"能力。低质量的模型可能在结果不符合预期时仍然硬着头皮继续,而高质量的模型会及时调整方向。

阶段五:迭代(Iteration)

一次典型的对话中,Agent Loop 可能循环 5-50 次不等。简单的"解释这段代码"可能只需要 1-2 次循环(Read → 分析 → 输出),而"重构整个模块"可能需要几十次循环。

循环次数受以下因素影响:

  • 任务复杂度:改动范围越大,循环越多
  • 上下文清晰度:项目结构越清晰,Claude 定位目标越精准,循环越少
  • 提示质量:指令越具体,Claude 越少走弯路
  • 模型能力:强模型能用更少的循环完成任务

你是谁:人在循环中的角色

Agent Loop 是自主进行的,但你不是旁观者。你在循环中扮演三个关键角色:

flowchart LR P["你的提示"] subgraph Loop["agentic loop"] direction LR GC["收集上下文"] --> TA["执行操作"] --> VR["验证结果"] VR -."循环".-> GC end D["完成"] H["你:中断、引导<br>或补充上下文"] P --> GC VR --> D H -."介入".-> TA style P fill:#e8e8e4,stroke:#999 style D fill:#e8e8e4,stroke:#999 style GC fill:#d4e4d8,stroke:#8ab style TA fill:#d4e4d8,stroke:#8ab style VR fill:#d4e4d8,stroke:#8ab style H fill:#fdf6f2,stroke:#d4a27f
  1. 启动者(Initiator):你发出提示,设定目标方向和约束条件
  2. 监督者(Supervisor):你在权限弹窗中批准或拒绝高风险操作,在 Claude 跑偏时纠正
  3. 验收者(Reviewer):你审查最终结果,决定接受还是要求修改

这三个角色不是你"可以做"的事情,而是 Claude Code 设计上就依赖你承担的角色。如果你只当"启动者"而放弃监督和验收,就等于把方向盘完全交给了一个没有业务判断力的助手。

一个真实的循环示例

假设你输入:"给 README.md 加一个安装步骤说明"。

循环次数阶段Claude 行为你的角色
1理解意图识别目标文件 README.md,任务类型为"文档编辑"
1制定计划计划:先读文件,再编辑插入内容
1调用工具Read README.md
1观察结果读到文件内容,找到合适插入位置
2制定计划在"Usage"章节前插入"Installation"章节
2调用工具Edit README.md(插入 Installation 内容)可能触发权限确认
2观察结果Edit 成功,文件已更新
3制定计划验证:重新读取文件确认内容正确
3调用工具Read README.md
3观察结果内容正确,格式无误
退出循环向你报告:"已在 README.md 中添加安装步骤"审查结果

一个看似简单的"加一句话"操作,背后 Claude 经历了 3 次循环。理解这一点,你就能理解为什么复杂任务需要那么多工具调用——这不是效率低,而是通过小步验证来保证质量

10.2 工具系统详解

工具是 Claude Code 与现实世界交互的"手脚"。没有工具,Claude Code 只是一只关在笼子里的聪明鹦鹉——能说会道,但碰不到你的代码。有了工具,它就成了能实际行动的 Agent。

理解每个工具的原理、使用场景和限制,是你精准使用 Claude Code 的基础。

10.2.1 文件工具

文件工具是 Claude Code 最常用的工具组。它们直接操作你项目中的文件,是 Claude 理解代码和修改代码的基础。

工具作用典型场景何时触发返回内容限制与须知
Read读取文件内容理解代码、查看配置、确认修改结果需要了解文件内容时;几乎每次修改前都会先用 Read带行号的文件内容(如 cat -n大文件可能只读部分(默认约 2000 行);图片文件返回视觉描述;PDF 需指定页码范围
Write创建或覆写文件新建文件、完全重写内容需要创建全新文件,或文件内容需要彻底替换时操作确认信息会覆盖已有内容而不警告;Write 前必须先 Read 同名文件(系统强制);不适合局部修改
Edit精准文本替换修改文件特定位置、插入代码片段需要局部修改,不改动其他部分时;这是最常用的修改工具修改确认信息(成功/失败)需要 exact match(精确匹配原文);如果旧文本不唯一或找不到,编辑会失败;不支持正则替换
Bash执行 Shell 命令运行构建、测试、Git 操作、安装依赖需要执行任何 Shell 命令时stdout + stderr + exit code高风险命令需用户确认(如 rm -rf、git push --force、sudo);环境非持久化(每个命令在新 Shell 中执行);超时默认 120 秒
Glob文件模式匹配按通配符查找文件(如 **/*.test.ts需要找到满足特定命名模式的一组文件时匹配的文件路径列表不支持正则,仅支持 glob 通配符(*、**、?、[])
Grep内容搜索搜索代码中的特定字符串、正则模式需要找到包含特定代码模式的所有文件时匹配的行及所在文件和行号大项目可能返回大量结果;正则语法与标准 grep 一致

Read 的工作方式:Read 是 Claude Code 使用最频繁的工具。它返回的内容带行号前缀,Claude 后续做 Edit 时可以直接引用行号范围。对于超长文件,Claude 会分段读取——先读头部了解结构,再根据需要跳到特定区域。如果你发现 Claude 反复读同一个文件的不同部分,说明它正在拼凑对文件全貌的理解。

Edit 的精确匹配机制:Edit 不是"找到相似内容然后替换",而是严格字符串匹配。这意味着:

  • 空格和缩进必须完全相同
  • 换行符格式必须一致
  • old_string 必须是文件中的唯一片段(除非 replace_all: true

这是 Edit 最常见的失败原因——Claude 以为文件中有某段代码,但实际上缩进差了 2 个空格。

Bash 的执行模型:每次 Bash 调用都是隔离的 Shell 会话。状态(环境变量、当前目录、后台进程)不会在两次 Bash 调用之间保留。如果你需要多步命令共享状态,要么用 && 串联,要么用分号 ; 在同一次调用中执行。此外,Bash 默认在项目根目录执行,而非你当前在终端中的目录。

10.2.2 搜索工具:Glob 与 Grep

这两个工具看似简单,但在 Claude 的"理解项目"流程中至关重要。Claude 不依赖 IDE 的项目索引——它通过 Glob 和 Grep 来发现项目结构。

Glob 的典型使用模式

场景一:查找所有测试文件
Claude 调用: Glob pattern="**/*.test.ts"
用途:确定测试文件分布,决定修改哪些测试

场景二:理解项目结构
Claude 调用: Glob pattern="src/**/*"
用途:快速了解 src 目录下的文件布局

场景三:查找特定类型文件
Claude 调用: Glob pattern="**/*.config.*"
用途:找到所有配置文件,理解项目配置体系

Grep 的典型使用模式

场景一:找到函数的所有调用点
Claude 调用: Grep pattern="authenticate\("
用途:重构前评估影响范围

场景二:搜索错误日志中的关键词
Claude 调用: Grep pattern="ERR_MODULE_NOT_FOUND"
用途:定位错误来源

场景三:找到所有 TODO 注释
Claude 调用: Grep pattern="TODO|FIXME|HACK"
用途:发现遗留的技术债务

组合使用:Claude 经常先 Glob 确定范围,再 Grep 精确定位——这和人类开发者的工作流完全一致。

10.2.3 高级工具

工具作用典型场景何时触发返回内容限制与须知
Agent启动子代理,独立执行子任务并行执行多个独立任务、大规模代码搜索任务可拆分为互不依赖的子任务时子代理的完整输出子代理有独立上下文,不共享主对话状态;子代理之间不能通信
WebSearch搜索网络获取最新技术文档、API 变更、版本兼容性问题需要当前信息(训练数据截止后的内容)时搜索结果列表(标题 + URL + 摘要)仅限美国区域搜索结果;可能需要用户确认
WebFetch抓取网页内容并提取查阅在线文档、阅读 GitHub Issue、获取 API 参考需要获取特定 URL 的完整内容时页面内容的 Markdown 格式提取无法处理需认证的页面;跨域重定向不会自动跟随;结果缓存 15 分钟
TodoWrite管理任务列表跟踪复杂多步骤任务、向用户展示进度任务超过 3 个独立步骤时任务列表更新确认是 Claude 内部使用,但你可以在聊天面板中看到
TaskOutput获取后台任务结果查询异步执行的后台命令状态启动了后台 Bash 任务后需要查看结果时后台任务的 stdout/stderr仅用于后台任务;前台任务直接返回结果
NotebookEdit编辑 Jupyter Notebook数据科学场景中修改 notebook 单元格操作 .ipynb 文件时单元格编辑确认仅支持 Jupyter Notebook 格式;需要指定 cell 编号
Task启动后台长时间任务运行可能超时的命令、并行执行命令预计运行时间超过默认超时(120秒)时任务 ID,后续用 TaskOutput 查询后台运行,不阻塞对话;需要主动查询结果

Agent 工具的核心价值:Agent 工具是 Claude Code 实现并行工作流的关键。当你要求"同时修复所有测试文件的 lint 错误"时,Claude 可以启动多个子代理,每个负责一个测试文件。每个子代理在自己的沙箱中运行完整的 Agent Loop,独立完成任务后返回结果。

Agent 工具的使用原则:

  • 子任务之间必须无依赖关系——子代理不共享上下文
  • 每个子代理消耗独立的 token 配额
  • 子代理有与主对话相同的工具权限(受权限配置约束)

WebSearch 与 WebFetch 的配合:这两个工具经常协同工作——先用 WebSearch 找到相关页面,再用 WebFetch 获取详细内容。例如:

你:"这个项目的 React 版本和最新版 React 有什么 Breaking Changes?"
Claude: WebSearch(query="React latest version breaking changes 2026")
        → 找到官方 Migration Guide URL
        WebFetch(url="https://react.dev/blog/...")
        → 提取完整变更列表

10.2.4 工具选择决策树

Claude 如何决定使用哪个工具?以下决策逻辑可以帮助你理解(和预测)它的行为:

需要获取信息?
├── 文件内容 → Read
├── 文件位置 → Glob
├── 代码中的模式 → Grep
├── 在线信息 → WebSearch → WebFetch
└── 后台任务状态 → TaskOutput

需要修改内容?
├── 新建文件 → Write
├── 局部修改 → Edit
└── 执行命令 → Bash

需要组织工作?
├── 多步骤任务 → TodoWrite
├── 并行子任务 → Agent
└── 长时间命令 → Task

理解这个决策树,你就能预判 Claude 的行为。当你发现 Claude 选择了"错误"的工具——比如用 Read 去搜代码而不是用 Grep——你可以直接告诉它"用 Grep 搜索",它会立即调整。

10.3 工具调用机制

工具调用不是 Claude Code 独有的概念——它是 Anthropic API 的标准能力。但 Claude Code 对工具调用的处理方式决定了你的使用体验。理解这个机制,你就能读懂聊天面板中的工具调用日志,也能在出现问题时精准定位。

调用流程

每次 Claude Code 决定使用工具时,经历以下流程:

模型                     CLI/IDE 层                 你的电脑
 │                          │                         │
 │  1. 输出工具调用请求      │                         │
 │  (JSON 格式)             │                         │
 │─────────────────────────>│                         │
 │                          │  2. 解析 JSON            │
 │                          │  3. 权限检查             │
 │                          │     ├── 自动允许 → 直接执行│
 │                          │     └── 需确认 → 弹窗等待 │
 │                          │                         │
 │                          │  4. 执行工具           │
 │                          │─────────────────────────>│
 │                          │                         │
 │                          │  5. 返回执行结果        │
 │                          │<─────────────────────────│
 │                          │                         │
 │  6. 分析结果              │                         │
 │  7. 决定下一步            │                         │
 │<─────────────────────────│                         │

JSON 工具调用格式

每种工具的调用请求都是一个结构化的 JSON 对象。以下是几个典型示例:

Read 调用

json
{
  "tool": "Read",
  "parameters": {
    "file_path": "/home/user/project/src/api/auth.ts",
    "offset": 45,
    "limit": 60
  }
}

Edit 调用

json
{
  "tool": "Edit",
  "parameters": {
    "file_path": "/home/user/project/src/api/auth.ts",
    "old_string": "function authenticate(user, password, callback) {",
    "new_string": "async function authenticate(user, password) {"
  }
}

Bash 调用

json
{
  "tool": "Bash",
  "parameters": {
    "command": "cd /home/user/project && pnpm test -- --testPathPattern=auth",
    "description": "Run auth-related tests",
    "timeout": 120000
  }
}

你不需要手动编写这些 JSON——Claude 自动生成。但理解这个格式有助于你阅读工具调用日志。

权限检查的位置

在调用流程的第 3 步,CLI/IDE 层会对照你的权限配置(四层配置体系,详见第 14 章)做出判断:

  • 匹配 allow 规则 → 自动执行,不弹窗
  • 匹配 deny 规则 → 拒绝执行,Claude 收到"Permission denied"并尝试其他方式
  • 匹配 ask 规则 → 弹出确认窗口,等待你的 Allow/Deny 决策
  • 无匹配规则 → 使用默认策略(Read/Glob/Grep 自动允许;Edit/Write 默认确认;高危 Bash 始终确认)

权限检查发生在工具执行前,而非调用前——Claude 已经做出了调用决策,只是被权限关卡拦截。这解释了为什么你在权限弹窗中看到的工具调用信息已经很具体。

结果返回格式

工具执行结果返回给模型时,包含:

工具名: Read
状态: success / error
输出: <工具的具体输出内容>
耗时: 234ms

对于 error 状态,Claude 会:

  1. 读取错误信息
  2. 判断错误原因(权限不足?文件不存在?语法错误?)
  3. 调整方案(换个工具?换个参数?向你求助?)

这就是 Claude "自我纠正"能力的关键——它不是一次调用失败就放弃,而是像人类开发者一样根据错误信息调整策略。

工具调用的组合模式

在实际对话中,工具调用很少单独使用。以下是几种常见的组合模式:

模式一:Read → Edit → Read(理解-修改-验证)

Read auth.ts      → 理解当前代码
Edit auth.ts      → 修改特定函数
Read auth.ts      → 验证修改正确

模式二:Glob → Grep → Read(定位-搜索-细读)

Glob src/**/*.ts   → 找到所有 TypeScript 文件
Grep "authService" → 在结果中搜索引用
Read 命中文件       → 仔细阅读关键文件

模式三:Bash → Read → Edit(执行-分析-修复)

Bash pnpm test     → 运行测试 → 测试失败
Read 错误日志      → 理解失败原因
Edit 源代码        → 修复问题
Bash pnpm test     → 再次运行 → 测试通过

识别这些模式,你就能快速判断 Claude 当前处于什么工作阶段。

10.4 从输入到输出的完整生命周期

你发出一个请求,Claude Code 做了什么?本节跟踪一个完整请求从输入到输出的每一步。以"帮我重构 src/api/auth.ts,把回调改成 async/await"为例。

生命周期时间线

时间轴

 ├── 0ms   [你] 在聊天框输入:"帮我重构 src/api/auth.ts,把回调改成 async/await"

 ├── 0ms   [系统] 收集上下文
 │          ├── 加载 System Prompt(行为准则、平台信息、工具说明)
 │          ├── 读取 CLAUDE.md(项目架构、命名规范、常用命令)
 │          ├── 读取 Git Status(当前分支、未提交变更、远程状态)
 │          └── 注入 Memory(之前的偏好和约定)

 ├── ~200ms [模型] 理解意图
 │          ├── 语义分析:任务类型="重构",目标="auth.ts",约束="回调改 async/await"
 │          ├── 上下文匹配:auth.ts 属于 API 层,可能依赖数据库模块和中间件
 │          └── 风险评估:auth 是高敏感模块,需要谨慎操作

 ├── ~500ms [模型] 制定初步计划
 │          ├── 步骤1:Read auth.ts 完整内容
 │          ├── 步骤2:Grep 搜索所有调用 auth 的地方
 │          ├── 步骤3:逐个识别回调模式的函数
 │          ├── 步骤4:Edit 逐个改写
 │          └── 步骤5:Bash 运行测试验证

 ├── ~600ms [工具] Read src/api/auth.ts
 │          ├── 权限检查:Read 属于自动允许级别
 │          ├── 文件系统:读取 /home/user/project/src/api/auth.ts
 │          └── 返回:带行号的 320 行代码

 ├── ~800ms [模型] 分析文件结构
 │          ├── 识别出 8 个导出函数
 │          ├── 其中 4 个使用了 callback 模式
 │          │   ├── authenticate(user, pass, callback)
 │          │   ├── refreshToken(token, callback)
 │          │   ├── revokeToken(token, callback)
 │          │   └── validateSession(sessionId, callback)
 │          ├── 理解错误处理模式:callback(err, result)
 │          └── 决定改写策略:async function + try/catch

 ├── ~900ms [工具] Grep pattern="authenticate\(|refreshToken\(|revokeToken\(|validateSession\("
 │          ├── 权限检查:Grep 属于自动允许级别
 │          ├── 执行搜索:遍历 src/ 目录
 │          └── 返回:12 处调用,分布在 src/api/、src/middleware/、src/routes/

 ├── ~1100ms [模型] 评估影响面
 │          ├── 所有调用方都需要更新(从 callback 改为 await)
 │          ├── middleware/auth.ts 的改动最复杂(有条件分支)
 │          └── 更新计划:先改 auth.ts 定义,再批量更新调用方

 ├── ~1200ms [工具] Edit auth.ts(第1处:authenticate 函数签名)
 │          ├── 权限检查:Edit 需用户确认 → 弹出权限窗口
 │          ├── [你] 看到 diff 预览,点击 Allow
 │          ├── 执行替换:callback 签名 → async function
 │          └── 返回:success

 ├── ~1400ms [工具] Edit auth.ts(第2处:authenticate 函数体)
 │          ├── 权限检查:在 Ask 模式下,每次 Edit 都需确认
 │          ├── [你] Allow
 │          ├── 执行替换:callback(err, user) → return user
 │          └── 返回:success

 ├── ...重复 6 次 Edit 操作...

 ├── ~4000ms [工具] Edit auth.ts(第8处:新增 try/catch 包裹)
 │          └── 返回:success

 ├── ~4100ms [工具] Read auth.ts(重新读取,验证修改正确)
 │          └── 返回:修改后的完整文件

 ├── ~4300ms [模型] 验证 auth.ts 修改
 │          ├── 检查所有 4 个函数已正确改写
 │          ├── 检查 try/catch 覆盖所有错误路径
 │          └── 发现:validateSession 缺少数据库连接失败的异常处理 → 补充 Edit

 ├── ...继续迭代调用方文件的修改...

 ├── ~12000ms [模型] 所有修改完成
 │          ├── 最终验证:重新 Read 所有修改过的文件
 │          ├── 确认无遗漏
 │          └── 生成修改摘要

 ├── ~12500ms [工具] Bash "cd /home/user/project && pnpm test"
 │          ├── 权限检查:Bash 运行测试,需确认或匹配 allow 规则
 │          ├── [你] 已配置 "allow": ["Bash(pnpm:test)"] → 自动允许
 │          └── 返回:Test Suites: 8 passed, 0 failed

 ├── ~13000ms [模型] 最终确认
 │          └── 所有测试通过,重构成功

 └── ~13200ms [你] 看到报告:
            "已完成 auth.ts 的回调转 async/await 重构:
             - 修改 4 个函数定义(authenticate, refreshToken, revokeToken, validateSession)
             - 更新 12 处调用点(middleware/auth.ts, routes/session.ts, ...)
             - 所有 8 个测试套件通过
             是否需要进一步的调整?"

生命周期中的关键节点

从这个时间线中,你可以识别出几个关键的"接入点"——在这些节点上,你的干预最有效:

  1. 计划阶段(~500ms):如果你对计划有异议,立即在权限弹窗中 Deny 并给出修正指令。这是成本最低的纠偏时机。

  2. 权限检查点(每个 Edit/Bash 调用前):这是你逐步骤审查的机会。不要一路 Allow——至少看前 2-3 个 Edit 确认方向正确。

  3. 自我纠错点(~4300ms):注意 Claude 在读取自己的输出后发现并修复了遗漏(validateSession 缺少异常处理)。这说明它在做 self-review。如果你发现它忽略了某个明显问题,可以提醒它"再检查一下"。

  4. 最终验证点(~12000ms):测试通过不代表完全正确。功能测试可能没覆盖边界情况。你的最终审查仍然是不可或缺的。

10.5 理解工具调用日志

在 VSCode 的聊天面板中,每一次工具调用都有一条可见的日志记录。学会阅读这些日志,是判断 Claude 工作状态的基础技能。

日志的结构

一条典型的工具调用日志包含以下信息:

┌─ Tool: Read ──────────────────────────────┐
│ 📄 文件: src/api/auth.ts                   │
│ 📏 范围: 行 45-104 (共 320 行)              │
│ ⏱️  耗时: 234ms                            │
│ 🔓 权限: 自动允许                           │
│ ✅ 状态: success                           │
└────────────────────────────────────────────┘

各类工具的日志特征

Read 日志特征:最频繁出现。注意它的读取范围——如果 Claude 反复读同一文件的不同区域,说明它正在拼凑理解。如果它反复读同一文件的同一区域,说明它可能陷入了"读-不理解-再读"的死循环。

Edit 日志特征:每次 Edit 都会展示 diff preview。关键信息:

  • 修改的文件路径
  • 替换的文本摘要(old → new)
  • 替换的行数
  • 权限确认状态(Allowed / Denied / Auto-allowed)

Bash 日志特征

  • 执行的完整命令
  • exit code(0 = 成功,非 0 = 失败)
  • stdout 内容
  • stderr 内容(如果有)
  • 执行耗时

错误日志的特殊标记:当工具调用失败时,日志会显示:

  • ❌ 错误类型(FileNotFound / PermissionDenied / Timeout / ...)
  • ❌ 错误详情
  • 🔄 Claude 的应对:调整参数重试 / 换用其他工具 / 请求用户帮助

识别异常模式

通过日志,你可以识别以下异常模式:

模式一:重复调用(Stuck Loop)

Read auth.ts (行 1-100)
Read auth.ts (行 1-100)  ← 相同调用,重复了!
Read auth.ts (行 1-100)  ← 第三次...

含义:Claude 在重复相同的操作,可能因为:

  • 输出被截断,它不记得已经读过
  • 对结果不满意但不知道如何调整
  • 上下文窗口接近限制,出现"健忘"

你的应对:直接告诉它"你已经读过 auth.ts 了,请继续下一步"。

模式二:频繁切换(Thrashing)

Read auth.ts
Read middleware.ts
Read auth.ts        ← 又回来读
Read routes.ts
Read auth.ts        ← 第三次

含义:Claude 在多个文件间来回跳转,但无法形成完整理解。可能是因为文件间的关系比它预期的更复杂。

你的应对:提供结构信息——"auth.ts 被 middleware/auth.ts 和 routes/session.ts 调用,先看这三个文件就够了"。

模式三:过度搜索(Search Obsession)

Grep "authenticate"
Grep "authenticate\(.*callback\)"
Grep "auth.*callback"
Grep "callback.*auth"

含义:Claude 不确定用什么搜索模式能找到目标,不断更换关键词尝试。

你的应对:直接告诉它精确的搜索词,或告诉它目标文件路径。

模式四:健康的执行流

Read auth.ts
Grep "authenticate\("
Read middleware/auth.ts  (grep 命中)
Read routes/session.ts   (grep 命中)
Edit auth.ts
Edit middleware/auth.ts
Read auth.ts  (验证)
Bash pnpm test

含义:工作流健康——先理解,再搜索影响面,再有条理地修改,最后验证。这是你应该看到的模式。

如何利用日志优化协作

  1. 关注重复模式:看到 3 次以上相同工具调用,立即介入
  2. 关注耗时:如果某个工具调用耗时异常(如超过 10 秒的 Read),可能是文件太大或网络问题
  3. 关注错误恢复:观察 Claude 从错误中恢复的策略——如果它调整得好(如 Read 失败后换用 Grep 定位),继续让它自主;如果调整无效,介入指导
  4. 利用 TodoWrite 日志:当 Claude 使用 TodoWrite 时,日志中会显示任务进度。这是了解它当前阶段的最佳窗口

10.6 模型选择与 Thinking 机制

工具系统决定了 Claude Code 能"做什么",而模型决定了它能"做得多好"。同样的 Agent Loop,用不同的模型跑,结果可能天差地别。

可用模型

Claude Code 支持多模型切换,当前可用的模型包括:

模型定位推理能力响应速度最佳场景
Opus 4.7旗舰最强较慢复杂架构设计、大规模重构、深度代码分析
Sonnet 4.6主力中等日常编程、代码审查、Bug 修复 —— 推荐默认
Haiku 4.5轻量一般最快简单问答、格式化、注释生成
DeepSeek V4 Pro替代旗舰中等偏慢复杂任务的经济选择
DeepSeek V4 Flash替代轻量中等日常任务的性价比选择

模型选择对 Agent Loop 的影响

  • 计划质量:Opus 制定的计划通常更周全(更少遗漏、更合理的步骤顺序),减少不必要的循环迭代
  • 工具选择准确性:更强的模型更少出现"用错工具"的情况——比如不会用 Read 去搜索代码
  • 自我纠正能力:Opus 在发现错误后能更快地调整策略,而 Haiku 可能需要更多次迭代
  • 代码生成质量:同样的 Edit 操作,Opus 生成的代码通常更符合项目风格、考虑更多边界情况

模型选择的决策框架

任务类型                    推荐模型           备选模型
─────────────────────────────────────────────────────
简单问答 / 代码解释         Haiku / V4 Flash    Sonnet
日常功能开发               Sonnet             Opus / V4 Pro
Bug 修复(范围明确)        Sonnet             Opus
Bug 修复(根因不明)        Opus               Sonnet
架构设计 / 重构规划        Opus               Sonnet + thinking
Code Review               Sonnet             Opus
测试编写                   Sonnet             Haiku
文档生成                   Sonnet / Haiku     —
大量文件的批量修改          Opus               Sonnet + 分步

Thinking 模式

Claude Code 支持 Extended Thinking(深度思考模式)。这是 Claude 模型的一个独特能力——在进行复杂操作前,模型会进行额外的内部推理,这些推理不占用输出的 token 配额

Thinking 的工作原理

普通模式:
你的提示 → [模型直接生成响应]

Thinking 模式:
你的提示 → [模型内部推理链] → [模型生成响应]

         这部分你看不到(不占 output token)
         但它让最终输出质量显著提升

Thinking 模式下的工具选择变化

当 Thinking 激活时,Claude 在调用工具前会"多想一步":

  • 这个工具是不是最优选择?有没有更高效的方式?
  • 这个 Read 的 offset/limit 范围是否合理?
  • 这次 Edit 会不会破坏其他地方的逻辑?
  • 是否需要先用 Grep 确认影响面?

结果就是:Thinking 模式下的工具调用更少但更精准。你可能看到 Claude 用 5 次工具调用完成 Sonnet 普通模式需要 10 次调用才能完成的任务。

何时使用 Thinking

  • ✅ 复杂重构(跨多个文件、涉及架构变更)
  • ✅ 难以定位的 Bug(需要深度推理数据流)
  • ✅ 新项目的架构设计(需要权衡多种方案)
  • ✅ 你发现 Claude 频繁走弯路时(开启 thinking 让它慢下来多想)
  • ❌ 简单的 CRUD 操作(浪费,增加延迟)
  • ❌ 格式化、注释、文档生成(不需要深度推理)
  • ❌ 你已经提供详细步骤的任务(不需要它自己想太多)

Fast Mode

VSCode 扩展支持 Fast Mode——通过 /fast 命令切换。Fast Mode 在 Opus 模型上提供更快的输出速度,代价是略低的推理深度。

适用场景:你需要 Opus 的推理质量,但不需要最深的分析——比如已经明确了修改方案,只是需要 Opus 的执行质量来生成代码。

模型对工具选择质量的实证影响

在实际使用中,不同模型在工具使用上表现出明显的差异:

指标OpusSonnetHaiku
工具选择正确率95%+90%+80%+
每次任务平均工具调用数中等
遇到错误后自我纠正率中高
重复调用率
适合的子代理任务复杂分析常规开发简单搜索

这个表揭示了一个重要洞察:更强的模型不仅代码质量更高,而且"用得更省"——更少的工具调用完成任务,更少的重复操作,更高的错误恢复率。这在你按 token 计费时尤其值得考虑。

10.7 关键设计原则

Claude Code 的行为不是随机的——它遵循一组设计原则。理解这些原则,你就能预测它的行为,也能在它"违反"原则时判断是 bug 还是另有原因。

原则一:宁可不做也不错做(Default to Safety)

对于高风险操作,默认需要确认。

这是 Claude Code 设计哲学的基石。它宁愿多弹一次确认窗拖慢你的节奏,也不希望一个误操作毁掉你的代码。

体现在:

  • Bash rm -rf 执行前一定确认
  • Git push --force 一定确认
  • 项目外文件访问一定确认
  • 首次安装的插件需要权限审批

设计意图:AI 不应该被盲目信任。Claude Code 的设计者假设 Claude 可能犯错,所以把"最终决定权"保留给你。这不是对 AI 的不信任,而是对开发者负责。

原则二:上下文优先(Context First)

先读文件理解,再动手修改。

Claude 不会在看到你的提示后立即开始写代码。它会先建立对目标代码的理解——读取相关文件、搜索调用关系、理解项目结构——然后才开始修改。

这解释了为什么即使你要求"把 auth.ts 第 45 行的 var 改成 const"这种一行修改,Claude 可能也会先 Read 整个文件。它不是在浪费 token,而是在确保自己理解了上下文后才动手。

对你意味着:在 CLAUDE.md 和 Memory 中尽可能多地提供项目结构信息,减少 Claude "探索"所需的工具调用次数。

原则三:渐进式变更(Incremental Change)

小步迭代,而非一次性大改。

Claude 倾向于把大的重构拆成多个小步骤,每步都验证确认后再继续。这不是效率低,而是:

  • 每个小步骤的风险可控
  • 出错时回滚范围小
  • 你可以在任意一步介入调整方向

对比

  • ❌ "一口气把 auth.ts 全部重写成 async/await" → 200 行改动,一个 Edit,中间出错就全废
  • ✅ "先改 authenticate,验证;再改 refreshToken,验证;再改..." → 10 个 Edit,每个都独立验证

原则四:可逆性考量(Reversibility)

优先选择可撤销的操作路径。

当有多种方式完成任务时,Claude 倾向于选择更容易撤销的方式:

  • 优先用 Edit(可精确追踪改动)而非 Write(覆写整个文件)
  • 优先用 Git 分支操作而非直接修改主干
  • 优先生成新文件而非覆盖已有文件

对你意味着:在要求 Claude 做大规模改动前,建议它"先新建一个分支"或"先备份原文件",这与 Claude 自身的设计偏好一致。

原则五:透明化(Transparency)

所有工具调用和结果对你可见。

Claude 不会背着你做任何事。每一次文件读取、每一次代码修改、每一次命令执行,都在聊天面板中有完整的日志记录。这不是技术限制,而是有意的设计选择——让你随时了解 Claude 在做什么、为什么这样做。

这与你使用其他 AI 工具(如 ChatGPT)的体验截然不同。ChatGPT 的"思考过程"是黑盒的,而 Claude Code 通过工具调用日志把整个执行链白盒化

原则六:工具最小化(Minimal Tool Use)

用最少的工具调用完成任务。

Claude 被训练为选择最高效的工具组合。如果一次 Grep 就能找到目标,它不会先 Glob 再逐个 Read;如果一次 Edit 能覆盖修改范围,它不会拆成 5 次。但"最少"不等于"省 token"——Claude 不会为了省一次 Read 而去猜代码内容,那会违反原则二(上下文优先)。

原则七:自我纠正(Self-Correction)

读取自己的输出,发现并修复错误。

Claude 在完成修改后,几乎总是会重新 Read 修改过的文件来验证。如果发现错误——比如编辑没有正确应用、缩进不对、漏了某个条件——它会主动修复。

这不是 Claude "不自信",而是设计上鼓励的自检行为。你应该把这种"回头看"视为质量信号——如果 Claude 改完代码后没有再读取验证,那才值得警惕。

原则的优先级与冲突

这七条原则不是平行的。当它们发生冲突时,优先级是:

安全性(原则一)> 上下文准确性(原则二)> 可逆性(原则四)> 渐进性(原则三)> 透明性(原则五)> 自我纠正(原则七)> 效率(原则六)

理解这个优先级,你就能解释 Claude Code 的一些"看似矛盾"的行为:为什么 Claude 能在某些场景下选择 Write 而非 Edit?因为在这个场景下,Write 反而更可逆(原则四覆盖了原则六)。

10.8 本章小结

本章深入剖析了 Claude Code 的内部工作机制。以下是核心要点:

Agent Loop:Claude Code 通过"理解意图 → 制定计划 → 调用工具 → 观察结果 → 迭代"的循环完成所有任务。你在这个循环中扮演启动者、监督者和验收者三个角色。理解循环的每个阶段,你就能预测 Claude 的行为。

工具系统:Claude Code 拥有 13 个核心工具,分为文件工具(Read/Write/Edit/Bash/Glob/Grep)和高级工具(Agent/WebSearch/WebFetch/TodoWrite/TaskOutput/NotebookEdit/Task)。每个工具有其特定的触发条件、使用方式和限制。学会阅读工具调用日志,你能判断 Claude 的工作状态是否健康。

完整生命周期:从你发出提示到 Claude 给出结果,中间经历了上下文收集、意图理解、计划制定、多轮工具调用、自我验证等至少 10 个步骤。理解这个流程,你就知道在哪些节点介入最有效。

模型与 Thinking:不同模型的推理能力直接影响工具选择质量、计划质量和自我纠正能力。Thinking 模式通过内部推理提升工具调用的精准度。选择合适的模型组合可以显著提升效率。

设计原则:宁可不做也不错做、上下文优先、渐进式变更、可逆性考量、透明化、工具最小化、自我纠正——这七条原则共同定义了 Claude Code 的行为模式。把它们内化为你的心智模型,你就能从"会用 Claude Code"升级为"精通 Claude Code"。


从本章开始,后续章节将逐一深入本章提到的每个核心系统:第 11 章深入上下文管理的细节,第 12 章学习如何编写 CLAUDE.md 来最大化 Claude 的理解能力,第 13 章完整解析四层配置体系,第 14 章掌握权限系统的进阶用法。