拆解 Claude Code:从底层机制到 10 倍效率的实战指南

42 阅读33分钟

为什么有人用它效率翻十倍,有人却觉得不过如此?答案藏在它的工作原理里。


第一章:两个程序员的故事

先讲个我身边真实发生的事。

上个月,团队接到一个需求:把项目里所有 REST API 的鉴权方式从 session-based 迁移到 JWT。涉及十几个路由文件、中间件改造、测试用例更新——典型的中等规模重构。

程序员 A 的做法是这样的:

> 打开 src/middleware/auth.ts,把 session 验证逻辑替换成 JWT 验证
(Claude Code 改完了)
> 现在打开 src/routes/user.ts,把里面的 req.session.userId 改成从 JWT 中解析
(改完了,但报错了)
> 报错了,req.user 是 undefined,你帮我修一下
(修了,又报错了)
> 测试也挂了,帮我修测试...

两个小时后,A 终于改完了。过程中他发了 30 多条消息,每次都在告诉 Claude Code 下一步该做什么,像在操控一个遥控车——左转、右转、前进、停。

程序员 B 只发了一条消息:

> 将项目的认证方式从 session-based 迁移到 JWT。要求:
> 1. 使用 jose 库替代现有的 session 逻辑
> 2. 保持所有现有 API 的接口契约不变
> 3. 确保所有测试通过
> 4. 参考 CLAUDE.md 中的错误处理规范

Claude Code 进入了规划模式,先扫描了整个项目结构,列出了所有需要改动的文件,给出了迁移方案。B 审批后,它自主执行——读文件、改代码、跑测试、发现问题、自己修复——20 分钟搞定。

差距不在 prompt 技巧。

A 和 B 的区别在于:A 把 Claude Code 当作了一个"更聪明的自动补全",而 B 把它当作一个自主代理系统(Agentic System)

这个区别至关重要。

想象一下:你的团队来了一位新同事。他是个资深工程师——能力极强、精力无限、学习速度惊人,但刚入职第一天,还不了解你们的代码库、规范和偏好。

你会怎么和他协作?

你绝对不会站在他身后,指着屏幕说"在第 42 行加一个 if 语句"。你会给他看架构文档、告诉他项目规范、描述要实现的目标,然后让他自己去探索、规划、执行。

Claude Code 就是这位新队友。

本文的一切,都是关于如何与这位新队友高效协作。我会拆解它的每一个核心工作机制,然后从机制推导出最佳实践。读完后,你不只知道"该怎么做",更知道"为什么要这么做"。


第二章:核心机制剖析

2.1 Agent Loop — 心跳循环

它不是搜索引擎,它是一个循环

大多数人第一次用 Claude Code,脑子里的模型是这样的:

输入 prompt → 获得输出

就像 Google 搜索一样,一问一答。

但 Claude Code 的真实工作方式完全不同。它的核心是一个 Agent Loop(代理循环)

flowchart LR
    A["🎯 理解任务"] --> B["🔍 收集上下文"]
    B --> C["📋 制定计划"]
    C --> D["⚡ 执行行动"]
    D --> E{"✅ 验证结果"}
    E -- "通过" --> F["🏁 任务完成"]
    E -- "失败/发现问题" --> B

    style A fill:#4A90D9,color:#fff,stroke:none
    style B fill:#7B68EE,color:#fff,stroke:none
    style C fill:#E67E22,color:#fff,stroke:none
    style D fill:#27AE60,color:#fff,stroke:none
    style E fill:#F39C12,color:#fff,stroke:none
    style F fill:#2ECC71,color:#fff,stroke:none

Agent Loop 的核心:不是"一问一答",而是"自主迭代直到完成"。失败后不会停下来等你——它会自己回到收集上下文阶段重新来过。

这个循环会一直转下去,直到任务完成或者需要你的输入。

一个看起来简单的用户请求——"给用户列表页面加个搜索功能"——在背后可能触发 50 次以上的工具调用

sequenceDiagram
    participant U as 👤 用户
    participant CC as 🤖 Claude Code
    participant FS as 📁 文件系统
    participant T as 🧪 测试

    U->>CC: "给用户列表加搜索功能"

    rect rgb(240, 245, 255)
    Note over CC,FS: 🔍 第一阶段:探索
    CC->>FS: Glob("**/user*.*")
    FS-->>CC: 找到 5 个相关文件
    CC->>FS: Grep("UserList")
    FS-->>CC: 定位组件位置
    CC->>FS: Read(UserList.tsx)
    FS-->>CC: 理解现有代码结构
    end

    rect rgb(240, 255, 240)
    Note over CC,FS: ✏️ 第二阶段:执行
    CC->>FS: Edit(UserList.tsx) — 添加搜索组件
    CC->>FS: Edit(useUsers.ts) — 添加过滤逻辑
    CC->>FS: Write(SearchBar.tsx) — 创建搜索栏组件
    end

    rect rgb(255, 245, 240)
    Note over CC,T: 🧪 第三阶段:验证 + 自动修复
    CC->>T: Bash("pnpm test")
    T-->>CC: ❌ 类型错误
    CC->>FS: Read(错误日志)
    CC->>FS: Edit(types.ts) — 修复类型
    CC->>T: Bash("pnpm test")
    T-->>CC: ✅ 全部通过
    end

    CC->>U: "搜索功能已完成,所有测试通过 ✅"

整个过程用户只发了一条消息,Claude Code 自主完成了探索→执行→验证→修复→再验证的完整循环。

回到新队友的比喻:一个优秀的工程师拿到任务后,不会闷头就写代码。他会先看现有代码怎么写的,理解项目结构,想个方案,写代码,跑测试,发现问题再调整。Agent Loop 就是在模拟这个过程。

所以:用意图描述任务,而非指令式步骤

理解了 Agent Loop,你就明白为什么 B 程序员的做法更好了。

当你给出指令式步骤("打开这个文件,改第 42 行"),你实际上在短路 Agent Loop。你把一个能自主迭代的系统降级成了一个执行机器人。

当你给出意图式描述("迁移到 JWT,保持测试通过"),你在激活完整的 Agent Loop。Claude Code 会自主决定该读哪些文件、该以什么顺序修改、该怎么验证。

反例 ❌:

打开 src/auth.ts,找到第 23 行的 validateToken 函数,
把 jsonwebtoken 的 verify 调用换成 jose 的 jwtVerify,
然后打开 src/types.ts 更新类型定义...

正例 ✅:

将 token 验证从 jsonwebtoken 迁移到 jose 库。
要求:保持现有的 validateToken 接口不变,确保所有测试通过。

第二种写法更短,但效果更好。因为你把"怎么做"的决策权交给了 Agent Loop——它比你更清楚当前代码的具体状态。

口诀:说目的地,不说路线。


2.2 工具系统 — 十八般武艺

它带了一整套工具箱

你的新队友第一天上班,不是空手来的。他带了一整套专业工具箱,里面有十几种精挑细选的工具:

graph TB
    subgraph explore["🔍 探索类 — 了解情况"]
        Read["Read<br/>读文件"]
        Glob["Glob<br/>找文件"]
        Grep["Grep<br/>搜内容"]
    end

    subgraph modify["✏️ 修改类 — 改东西"]
        Write["Write<br/>创建文件"]
        Edit["Edit<br/>精确编辑"]
    end

    subgraph orchestrate["🎭 编排类 — 组织工作"]
        Task["Task<br/>子代理"]
        TaskCreate["TaskCreate<br/>任务跟踪"]
    end

    subgraph execute["⚡ 执行类 — 外界交互"]
        Bash["Bash<br/>运行命令"]
        Web["Web<br/>网络访问"]
        MCP["MCP<br/>外部工具"]
    end

    style explore fill:#E8F4FD,stroke:#4A90D9,color:#333
    style modify fill:#FDF2E8,stroke:#E67E22,color:#333
    style orchestrate fill:#F0E8FD,stroke:#7B68EE,color:#333
    style execute fill:#E8FDE8,stroke:#27AE60,color:#333
  • 探索类Read(读文件内容)、Glob(按模式匹配找文件,如 **/*.tsx)、Grep(搜索代码内容)
  • 修改类Write(创建/覆写文件)、Edit(精确编辑文件片段,只发 diff)
  • 编排类Task / 子代理(派分身并行工作)、TaskCreate(任务列表跟踪进度)
  • 执行类Bash(跑测试、装依赖、Git 等)、WebFetch / WebSearch(网络访问)、MCP(连接外部工具)

关键洞察在这里:Claude Code 的系统提示中有明确的工具选择规则。 比如,它被要求"读文件用 Read 而不是 cat"、"搜索用 Grep 而不是 grep 命令"、"编辑用 Edit 而不是 sed"。这些不是随意的偏好——专用工具比通用 Bash 命令更可靠、更可预测、也更方便你审查。

而且,模型会根据任务自主编排工具链。当你说"找到所有使用废弃 API 的地方并更新",它自然会触发这样的链:

flowchart LR
    A["Glob\n找候选文件"] --> B["Grep\n定位使用位置"]
    B --> C["Read\n理解上下文"]
    C --> D["Edit\n逐个替换"]
    D --> E["Bash\n跑测试验证"]

    style A fill:#E8F4FD,stroke:#4A90D9,color:#333
    style B fill:#E8F4FD,stroke:#4A90D9,color:#333
    style C fill:#E8F4FD,stroke:#4A90D9,color:#333
    style D fill:#FDF2E8,stroke:#E67E22,color:#333
    style E fill:#E8FDE8,stroke:#27AE60,color:#333

你不需要告诉它用哪个工具——它自己会选。

所以:用匹配工具能力的方式描述任务

知道队友会什么,你才能更好地给他派任务。

反例 ❌:

帮我手动检查这 20 个文件里有没有用 deprecated API

(这会让 Claude Code 一个个 Read,慢且低效)

正例 ✅:

找到项目中所有调用 oldApi.fetchData() 的地方,
替换为 newApi.getData(),并确保类型兼容

(这自然触发 Grep 批量搜索 → Edit 批量替换的高效路径)

再比如,如果你知道它有 WebSearch 工具,你可以这样:

使用 jose 库替换 jsonwebtoken 实现 JWT 验证。
如果你不确定 jose 的 API 用法,可以查阅其文档。

口诀:知道队友会什么,才能用好队友。


2.3 记忆系统 — 记忆宫殿

这是全文最重要的一节。如果你只记住一件事,就记住这个。

四层记忆体系

新队友的记忆不是铁板一块,它有层次。Claude Code 有一套精心设计的四层记忆体系:

graph TB
    subgraph L1["🏛️ 第一层:CLAUDE.md — 长期记忆"]
        direction LR
        C1["📖 项目根目录 CLAUDE.md"]
        C1D["会话启动时最先加载\n始终在上下文中,不会被压缩"]
    end

    subgraph L2["💬 第二层:对话上下文 — 工作记忆"]
        direction LR
        C2["🗣️ 当前会话交互"]
        C2D["你说的话 + AI 回复 + 工具输出\n会过期,会被自动压缩"]
    end

    subgraph L3["📐 第三层:.claude/rules/ — 模块化规则"]
        direction LR
        C3["📏 条件加载的规则文件"]
        C3D["处理 .tsx 时加载前端规范\n处理 .go 时加载 Go 规范"]
    end

    subgraph L4["📝 第四层:Auto-Memory — 自动记忆"]
        direction LR
        C4["🧠 AI 自己的学习笔记"]
        C4D["跨会话持久化\n权重低于前三层"]
    end

    L1 --- L2 --- L3 --- L4

    style L1 fill:#DCEEFB,stroke:#2980B9,stroke-width:3px,color:#333
    style L2 fill:#E8F8F5,stroke:#27AE60,stroke-width:2px,color:#333
    style L3 fill:#FEF9E7,stroke:#F1C40F,stroke-width:2px,color:#333
    style L4 fill:#FDEDEC,stroke:#E74C3C,stroke-width:1px,color:#333

优先级从上到下递减:CLAUDE.md 的指示权重最高,Auto-Memory 最低。越上层越可靠,越持久。

用公司来类比:

记忆层公司类比持久性可靠性你能控制吗
CLAUDE.md公司工程师手册★★★★★ 永不丢失★★★★★✅ 完全控制
对话上下文今天站会笔记★★☆☆☆ 会被压缩★★★★☆⚠️ 部分控制
.claude/rules/特定场景 Runbook★★★★☆ 按需加载★★★★☆✅ 完全控制
Auto-Memory员工个人笔记★★★★☆ 跨会话★★★☆☆❌ AI 自主

CLAUDE.md:你 ROI 最高的投入

在所有四层中,CLAUDE.md 是你能控制的、影响最大的一层。 它之所以重要,是因为三个特性:

  1. 首先加载 — 在 Claude Code 做任何事情之前,它就已经读了 CLAUDE.md
  2. 始终在场 — 不管上下文怎么压缩、怎么 compact,CLAUDE.md 永远在
  3. 全局影响 — 它影响 Claude Code 在这个项目中的所有行为

而且它支持分层——就像 CSS 的层叠规则,越具体的越优先:

graph TB
    subgraph scope["CLAUDE.md 分层加载机制"]
        direction TB
        G["🌍 ~/.claude/CLAUDE.md\n个人偏好(全局生效)\n例:偏好 Vim 键位、暗色主题"]
        P["📦 项目根目录/CLAUDE.md\n项目规范(团队共享)\n例:技术栈、架构原则、代码规范"]
        M["📂 src/api/CLAUDE.md\n模块规范(特定目录生效)\n例:API 设计规范、错误码定义"]
    end

    G -->|"被项目层覆盖"| P
    P -->|"被模块层覆盖"| M

    style G fill:#f0f0f0,stroke:#999,color:#333
    style P fill:#DCEEFB,stroke:#2980B9,color:#333
    style M fill:#D5F5E3,stroke:#27AE60,color:#333
    style scope fill:#fff,stroke:#ddd,color:#333

越具体的层级优先级越高:如果项目 CLAUDE.md 说"用 tabs 缩进",但 src/api/CLAUDE.md 说"用 2 spaces",那么在 src/api/ 目录下工作时,2 spaces 生效。

很多人把 CLAUDE.md 写成了流水账,或者压根没有。这就像招了个资深工程师却不给他看任何文档,让他自己猜你们的规范——他当然也能干活,但效率和质量会大打折扣。

一个真实的 CLAUDE.md 示例

# Project: E-Commerce Platform

## Tech Stack
- TypeScript + React 18 + Next.js 14 (App Router)
- Tailwind CSS (no CSS modules)
- Prisma ORM + PostgreSQL
- Vitest for unit tests, Playwright for E2E

## Architecture Principles
- Feature-based directory structure: src/features/{feature}/
- Each feature has: components/, hooks/, api/, types.ts, index.ts
- Shared code goes in src/shared/ (not src/utils/ or src/common/)
- Server Components by default; only use "use client" when needed

## Code Conventions
- Prefer named exports over default exports
- Use Zod for all runtime validation (API inputs, form data, env vars)
- Error handling: use Result<T, E> pattern, never throw in business logic
- Database queries only in src/features/*/api/ (never in components)

## Testing Requirements
- Every new feature needs unit tests (Vitest)
- API routes must have integration tests
- Run tests before any commit: `pnpm test`
- E2E tests for critical flows: `pnpm test:e2e`

## Git Conventions
- Conventional commits: feat/fix/refactor/docs/test
- Branch naming: feature/xxx, fix/xxx, refactor/xxx
- Squash merge to main

## Common Gotchas
- Prisma needs `npx prisma generate` after schema changes
- Next.js middleware runs on edge runtime (no Node.js APIs)
- TailwindCSS v4 uses CSS-based config, not tailwind.config.js

注意几个要点:

  1. 50-200 行是理想长度 — 精炼但全面,不要写成万字文档
  2. 定义原则,不定义细节 — "使用 Zod 做校验" ✅,"Zod schema 用这种格式写" ❌
  3. 包含"常见坑" — 这些是新人最容易踩的,也是 Claude Code 最容易犯的
  4. 可以被 Git 追踪 — 把它当作项目文档的一部分,团队共享

所以:写宪法,而非写代码

如果你今天只做一件事来提升 Claude Code 体验,就是给你的项目写一份 CLAUDE.md

这不是一次性工作。它应该随着项目演进持续更新——就像一份活的工程师手册。

当你发现 Claude Code 反复犯同一个错误,不要每次在对话里纠正它。把正确的做法写进 CLAUDE.md,一劳永逸。

反例 ❌:

> 记住,我们项目用 pnpm 不用 npm
> (下次新会话又得说一遍)

正例 ✅:

# CLAUDE.md
## Package Manager
- Use pnpm exclusively (never npm or yarn)
- Lock file: pnpm-lock.yaml

口诀:写好入职文档,新人自然好用。


2.4 子代理架构 — 分身术

它能分身

你的新队友有一项特殊能力:分身术

当面临复杂任务时,Claude Code 可以派生出多个子代理(Sub-agents),每个子代理有独立的上下文窗口,互不干扰,并行工作。

目前有几种类型的子代理:

  • Explore 代理 — 只读,专门用来快速探索代码库。不能修改文件,只做调查
  • Plan 代理 — 设计方案。像架构师一样分析问题,输出结构化的实施计划
  • 通用 Task 代理 — 能使用全部工具,执行具体任务

一个典型的场景:你报告了一个 bug,Claude Code 不确定根因在哪。它可以同时派出三个 Explore 代理:

sequenceDiagram
    participant U as 👤 用户
    participant M as 🤖 主代理
    participant S1 as 🔍 子代理 1
    participant S2 as 🔍 子代理 2
    participant S3 as 🔍 子代理 3

    U->>M: "订单金额计算有 bug"

    par 三路并行调查
        M->>S1: 调查数据库查询
        Note right of S1: 独立上下文窗口<br/>读取 SQL、分析查询逻辑
    and
        M->>S2: 检查 API 数据转换
        Note right of S2: 独立上下文窗口<br/>追踪数据流转过程
    and
        M->>S3: 检查前端状态管理
        Note right of S3: 独立上下文窗口<br/>排查 race condition
    end

    S1-->>M: "数据库查询正常 ✅"
    S2-->>M: "发现:货币转换丢失精度 ❌"
    S3-->>M: "前端状态正常 ✅"

    M->>U: "根因定位:API 层货币转换使用了<br/>浮点数运算导致精度丢失,建议改用 Decimal"

三个调查同时进行,最后主代理汇总结论,定位到问题所在。这比串行调查快了三倍。

每个子代理有自己的上下文窗口,这意味着主代理的上下文不会被大量调查结果污染。子代理完成后,只把结论汇报回来——就像团队开完调查后,在站会上各自汇报一句结论,而不是念自己的全部调查笔记。

所以:设计可并行化的任务

了解了分身术,你就可以主动设计适合并行处理的任务。

反例 ❌:

先查一下 userService 有没有问题,
然后再查 orderService,
最后查 paymentService

(这强制了串行,一个一个来)

正例 ✅:

调查以下三个服务中哪个导致了订单金额计算错误:
1. userService 中的折扣计算
2. orderService 中的价格汇总
3. paymentService 中的货币转换
分别检查后给出结论。

(Claude Code 可能会并行派出子代理调查)

不过要注意,不是所有任务都适合并行。如果步骤之间有依赖关系(后一步依赖前一步的结果),强行并行反而会出问题。

口诀:分而治之,并行调查。


2.5 上下文窗口管理 — 桌面大小问题

桌面就这么大

现在想象你队友的工作桌面。

这张桌面的面积是固定的——所有正在处理的信息都得放在上面:读取的文件内容、你们的对话记录、工具调用的输出、系统提示、CLAUDE.md……

这就是上下文窗口(Context Window)

当桌面快满了,Claude Code 会自动做一件事:把最早的对话和工具输出压缩成摘要,推到桌面边缘。核心信息保留,但细节丢失了。

graph LR
    subgraph before["😰 上下文快满了"]
        direction TB
        B1["📖 CLAUDE.md"]
        B2["⚙️ 系统提示"]
        B3["💬 早期对话(细节)"]
        B4["📄 读取的文件内容"]
        B5["💬 中期对话(细节)"]
        B6["🔧 工具输出(大量)"]
        B7["💬 最近对话"]
    end

    before -- "/compact" --> after

    subgraph after["😊 压缩后腾出空间"]
        direction TB
        A1["📖 CLAUDE.md ← 不变"]
        A2["⚙️ 系统提示 ← 不变"]
        A3["📝 历史摘要(压缩)"]
        A4["💬 最近对话"]
        A5["🆓 空闲空间(可继续工作)"]
    end

    style before fill:#FFF5F5,stroke:#E74C3C,color:#333
    style after fill:#F0FFF0,stroke:#27AE60,color:#333
    style B1 fill:#DCEEFB,stroke:#2980B9,color:#333
    style A1 fill:#DCEEFB,stroke:#2980B9,color:#333
    style A5 fill:#E8FDE8,stroke:#27AE60,color:#333

你也可以主动管理桌面:

  • /compact — 手动压缩。把对话细节压缩成摘要,腾出空间。就像把散落的笔记整理成一张提纲
  • /clear — 彻底清空。只保留 CLAUDE.md 和系统提示,其他全部丢弃。就像收拾好桌面开始全新工作

这里有一个关键细节:CLAUDE.md 永远不会被压缩或清除。 不管你 compact 还是 clear 多少次,CLAUDE.md 始终在场。这就是为什么它是记忆系统中最可靠的一层。

上下文窗口管理不当的后果很明显:

  1. 信息丢失 — 早期对话被压缩后,Claude Code 可能"忘记"之前讨论过的设计决策
  2. 性能下降 — 上下文塞得越满,模型的注意力越分散,输出质量下降
  3. 成本增加 — 更长的上下文意味着更多的 token 消耗

所以:保持"上下文卫生"

就像保持桌面整洁一样,上下文窗口需要主动维护。

原则一:一个对话处理一个逻辑任务

不要在同一个对话里又改 bug 又加功能又重构——这会把上下文搅成一锅粥。完成一个任务后,开新对话。

原则二:阶段间主动 /compact

如果一个任务确实需要多个阶段(比如先调查再实施),在调查完成、开始实施前,用 /compact 压缩调查阶段的细节,保留结论。

原则三:选择性读文件

不要让 Claude Code 读取整个大文件"了解一下"。先用 Glob + Grep 定位关键部分,再只读必要的片段。

反例 ❌:

读一下 src/ 目录下所有的文件,了解一下项目结构

(这会把上下文塞满文件内容,几个大文件就占了大半桌面)

正例 ✅:

项目使用 Next.js App Router 架构。
请找到与用户认证相关的路由和中间件文件,理解当前的认证流程。

(Claude Code 会用 Glob + Grep 精准定位,只读必要的文件)

原则四:关键信息放 CLAUDE.md

任何你不希望 Claude Code "忘记"的信息——项目规范、架构决策、常见陷阱——都应该放进 CLAUDE.md,而不是靠对话上下文记住。

口诀:保持桌面整洁,重要的东西钉在墙上(CLAUDE.md)。


2.6 权限模型 — 安全带

有风险的事会举手确认

你的新队友虽然能力强,但不是横冲直撞的莽夫。

Claude Code 内置了一套分级权限模型。工具按风险级别分类:

graph LR
    subgraph low["🟢 低风险 — 自动放行"]
        L1["Read"]
        L2["Glob"]
        L3["Grep"]
    end

    subgraph mid["🟡 中风险 — 可配置"]
        M1["Edit"]
        M2["Write"]
        M3["Bash(已知命令)"]
    end

    subgraph high["🔴 高风险 — 必须确认"]
        H1["rm -rf"]
        H2["git push --force"]
        H3["Bash(未知命令)"]
    end

    style low fill:#E8F5E9,stroke:#43A047,color:#333
    style mid fill:#FFF8E1,stroke:#F9A825,color:#333
    style high fill:#FFEBEE,stroke:#E53935,color:#333

当 Claude Code 要做有风险的事情时,它会暂停循环,举手确认:

Claude Code 想要执行: rm -rf build/
是否允许?[y/n]

你可以在 settings.json 中配置信任级别:

  • 默认模式 — 大部分修改操作需要确认
  • 信任项目 — 放宽常见操作(如 Edit、运行测试),但高危操作仍需确认
  • Yolo 模式 — 几乎不需要确认(适合实验性项目,不建议用于生产代码

系统提示中写得很明确:Claude Code 的行为准则是优先安全——它永远不会主动提交包含 .env 的文件、不会未经确认 force push、不会删除看起来像用户工作的分支。即使你授权了"推送代码",它也只认为这次授权有效,下次还会再问。

所以:信任但验证

对于成熟项目:在 settings 中放宽常见操作的权限——每次 Edit 都要确认会打断 Agent Loop 的流畅性,让你的队友干活缩手缩脚。

对于敏感操作:保留审批。数据库操作、部署脚本、Git push 等,永远值得多看一眼。

实用配置建议

// .claude/settings.json
{
  "permissions": {
    "allow": [
      "Edit",
      "Write",
      "Bash(pnpm test)",
      "Bash(pnpm lint)",
      "Bash(pnpm build)"
    ]
  }
}

允许编辑文件和运行测试 / lint / 构建这类安全的命令,但其他 Bash 操作仍需确认。

口诀:配好信任级别,常规放行,敏感必审。


2.7 规划模式 — 先谋后动

让队友先戴上"架构师帽"

有时候你不想让队友直接动手改代码。你想先听听他的方案。

规划模式(Plan Mode) 就是这个"架构师帽"。用 Shift+Tab 即可切换。

进入规划模式后,Claude Code 的行为发生根本变化:

flowchart LR
    subgraph plan["🎩 规划模式(Shift+Tab)"]
        direction TB
        P1["✅ Read — 读文件"]
        P2["✅ Glob — 找文件"]
        P3["✅ Grep — 搜内容"]
        P4["✅ 分析 + 设计方案"]
        P5["❌ Edit / Write"]
        P6["❌ Bash"]
    end

    User["👤 用户"] -- "Shift+Tab\n进入规划" --> plan
    plan -- "输出方案" --> Review{"👤 审批方案"}
    Review -- "✅ 同意" --> Exec["⚡ Agent Loop 执行"]
    Review -- "❌ 调整" --> plan

    style plan fill:#FFF8E1,stroke:#F9A825,color:#333
    style P5 fill:#FFEBEE,stroke:#E53935,color:#333
    style P6 fill:#FFEBEE,stroke:#E53935,color:#333
    style Exec fill:#E8F5E9,stroke:#43A047,color:#333

它变成了一个纯粹的分析者和规划者——只看不动手

这特别适合两类场景:

场景一:大规模重构

"我想把项目从 Redux 迁移到 Zustand"——这种涉及几十个文件的变更,你绝对不想让它直接开干。先进规划模式,让它分析依赖关系、列出所有需要改动的地方、给出迁移步骤和风险评估。你审批方案后,再让它执行。

场景二:不确定的问题

"应用启动越来越慢,帮我分析原因"——你不确定问题在哪,让 Claude Code 先以只读方式调查,给出分析报告,然后你根据报告决定下一步。

规划模式的输出通常是结构化的:

## 迁移方案

### 影响范围
- 12 个文件需要修改
- 3 个 store 需要重写
- 所有 useSelector 调用需要替换

### 执行步骤
1. 安装 zustand,移除 redux 相关依赖
2. 将 Redux store 逐个转换为 Zustand store
3. 替换组件中的 useSelector/useDispatch
4. 更新测试
5. 运行全量测试验证

### 风险点
- middleware 逻辑需要手动重写(不能自动转换)
- 异步 action 的处理方式有差异

你审批这个方案后,Claude Code 就会按步骤执行,遇到问题还会回来汇报。

所以:超过 3 个文件的变更,先谋后动

这是一条简单有效的经验法则:

  • 改 1-3 个文件 → 直接描述意图,让 Agent Loop 跑
  • 改 3+ 个文件 → 先进规划模式,审批方案再执行
  • 架构级变更 → 必须规划模式,甚至可以要求多轮规划

反例 ❌:

把所有的 class 组件重构成函数组件
(直接执行,可能改一半出问题,中间状态很难恢复)

正例 ✅:

[规划模式]
分析项目中所有的 class 组件,评估重构为函数组件的影响范围和风险,
给出分批重构的方案。

口诀:架构师帽先戴上,方案敲定再开工。


2.8 Hooks 系统 & MCP 集成 — 自动化与扩展

Hooks:自动化质量门禁

你可以为 Claude Code 的工具调用设置自动触发的脚本——就像 Git hooks,但更细粒度。

// .claude/settings.json
{
  "hooks": {
    "afterEdit": ["npx prettier --write $FILE"],
    "beforeBash": ["echo '正在执行: $COMMAND'"],
    "afterWrite": ["npx eslint --fix $FILE"]
  }
}

每次 Claude Code 用 Edit 工具修改文件后,自动跑 Prettier 格式化。每次 Write 创建新文件后,自动跑 ESLint 修复。

Hooks 的价值在于一劳永逸。你不需要每次告诉 Claude Code "改完记得格式化"——配好 Hook,它自动就做了。

MCP:给队友开更多权限

MCP(Model Context Protocol) 是一个标准化协议,让 Claude Code 连接外部工具和服务。通过 MCP,你的新队友不再局限于本地文件操作,而是能触达完整的工作流:

  • 连接 Jira / Linear — 直接读取和更新任务状态
  • 连接 Slack — 发消息、查讨论
  • 连接 数据库 — 查询数据辅助调试
  • 连接 Figma — 读取设计稿信息
  • 连接自定义内部工具 — 任何你能写 API 的东西

比如,你可以告诉 Claude Code:

看一下 JIRA-1234 的需求描述,然后实现它

它会通过 MCP 读取 Jira 任务,理解需求,然后在本地实现代码。

最佳实践

  1. 配置 Hooks 实现自动化质量门禁 — 格式化、Lint、类型检查,让它们自动在 Claude Code 操作后运行
  2. 通过 MCP 扩展 AI 的工具链 — 把你日常工作流中的工具都接进来,减少手动切换

口诀:Hooks 设了就忘,MCP 越多越强。


2.9 系统提示 — 隐形之手

110+ 条内置直觉

你的新队友受过优秀的工程教育。

Claude Code 的系统提示中有 110 多条精心设计的行为规则,覆盖方方面面:

安全规则

  • 永远不提交 .envcredentials.json 等敏感文件
  • 破坏性 Git 操作(force push、reset --hard)必须确认
  • 不猜测或生成 URL,除非明确是编程辅助

工具偏好

  • 读文件用 Read,不用 cat
  • 搜索用 Grep,不用 grep 命令
  • 编辑用 Edit,不用 sed
  • 这些规则确保操作可预测、可审查

代码风格

  • 修改前先读代码("不要改你没读过的代码")
  • 优先编辑已有文件,避免创建不必要的新文件
  • 避免过度工程化——只做要求的事情,不画蛇添足
  • 不要在没改的代码上加注释、类型注解或 docstring

Git 操作规范

  • 优先创建新 commit,不 amend 已有的
  • 用具体文件名 add,不用 git add -A
  • 提交前要看 diff 和 log
  • 绝对不 skip hooks(--no-verify

这些规则你无法修改——它们是系统级别的。但好消息是:CLAUDE.md 可以扩展甚至覆盖部分行为。

比如系统提示说"不要主动提交",但你可以在 CLAUDE.md 里写:

## Workflow
- After completing a change, always commit with a descriptive message

Claude Code 会遵守你在 CLAUDE.md 里的指示,即使它和系统提示的默认行为不同。

但有些规则你不应该尝试覆盖——比如安全相关的规则。强行让 Claude Code 提交 .env 文件或 force push 到 main,它会拒绝或至少强烈警告。这些是安全底线。

所以:顺势而为,不要逆流

理解了系统提示的存在,你就能解释很多"奇怪"的行为:

  • "为什么它总是先读文件再改?" — 因为系统提示要求"修改前先读"
  • "为什么它不用 sed 而用 Edit?" — 因为系统提示规定了工具偏好
  • "为什么它创建 commit 不用 --amend?" — 因为系统提示说"优先新 commit"

这些不是 bug,是特性。它们让 Claude Code 的行为更安全、更可预测。

反例 ❌:

用 sed 命令替换文件中的所有 oldFunction 为 newFunction

(你在要求它逆着系统提示的偏好工作,它可能还是会用 Edit)

正例 ✅:

把项目中所有的 oldFunction 调用替换为 newFunction

(让它自己选择最佳工具——它会用 Grep 找到所有位置,然后用 Edit 逐个替换)

口诀:借力不对抗,理解默认值。


2.10 透视实例 — 一次请求的完整生命周期

前面九节讲的都是"原理"。现在,我们把所有原理串成一条线——用一个真实例子,逐帧回放 Claude Code 处理一次请求时,到底发生了什么。

包括:发给大模型的数据结构长什么样、每一轮循环做了什么决策、你的 CLAUDE.md 如何影响行为。

场景设定

你在一个 Next.js 电商项目里,输入了这条消息:

用户列表页的搜索功能有 bug:输入中文后搜索结果为空。请修复。

项目根目录有一份 CLAUDE.md:

# E-Commerce Platform
## Tech Stack
- TypeScript + Next.js 14 (App Router)
- Prisma ORM + PostgreSQL
## Code Conventions
- Use Zod for runtime validation
- Error handling: use Result<T, E> pattern
## Testing
- Run `pnpm test` before finishing

下面是 Claude Code 背后真实发生的事情。


第 0 步:组装第一次 API 请求

你按下回车的那一刻,Claude Code 客户端并不是直接把你这句话扔给模型。它先组装一个完整的请求体。简化后大致长这样:

// 发送给 Claude API 的第一次请求
{
  "model": "claude-sonnet-4-20250514",
  "max_tokens": 16000,
  "system": [
    {
      // 🔵 系统提示(2.9 节讲的"隐形之手",110+ 条规则)
      "type": "text",
      "text": "You are Claude Code, Anthropic's official CLI...\n
        - Do NOT use Bash to run commands when a dedicated tool exists\n
        - Read files with Read, not cat\n
        - Edit files with Edit, not sed\n
        - In general, do not propose changes to code you haven't read\n
        - Avoid over-engineering...\n
        ..."
    },
    {
      // 🟢 CLAUDE.md(2.3 节讲的"宪法",始终注入系统提示)
      "type": "text",
      "text": "<claude-md>\n# E-Commerce Platform\n## Tech Stack\n
        - TypeScript + Next.js 14 (App Router)\n
        - Prisma ORM + PostgreSQL\n
        ## Code Conventions\n- Use Zod for runtime validation\n
        ## Testing\n- Run `pnpm test` before finishing\n
        </claude-md>"
    }
  ],
  // 🔧 工具定义(2.2 节讲的"工具箱",告诉模型它有哪些能力)
  "tools": [
    {
      "name": "Read",
      "description": "Reads a file from the local filesystem...",
      "input_schema": {
        "type": "object",
        "properties": {
          "file_path": { "type": "string" },
          "offset": { "type": "number" },
          "limit": { "type": "number" }
        },
        "required": ["file_path"]
      }
    },
    {
      "name": "Glob",
      "description": "Fast file pattern matching...",
      "input_schema": { "..." : "..." }
    },
    {
      "name": "Grep",
      "description": "Search tool built on ripgrep...",
      "input_schema": { "..." : "..." }
    },
    {
      "name": "Edit",
      "description": "Performs exact string replacements in files...",
      "input_schema": { "..." : "..." }
    },
    {
      "name": "Bash",
      "description": "Executes a bash command...",
      "input_schema": { "..." : "..." }
    },
    {
      "name": "Task",
      "description": "Launch a new agent to handle complex tasks...",
      "input_schema": { "..." : "..." }
    }
    // ... 共 12+ 种工具
  ],
  // 💬 对话消息(2.5 节讲的"上下文窗口",此时只有用户这一条)
  "messages": [
    {
      "role": "user",
      "content": "用户列表页的搜索功能有 bug:输入中文后搜索结果为空。请修复。"
    }
  ]
}
graph TB
    subgraph req["📦 第一次 API 请求的组成"]
        direction TB
        SP["⚙️ system prompt\n系统提示 110+ 条规则"]
        CM["📖 CLAUDE.md\n项目宪法(注入 system)"]
        TL["🔧 tools\n12+ 工具定义(JSON Schema)"]
        MS["💬 messages\n用户消息(目前只有 1 条)"]
    end

    style SP fill:#E8EAF6,stroke:#3F51B5,color:#333
    style CM fill:#DCEEFB,stroke:#2980B9,color:#333
    style TL fill:#FFF3E0,stroke:#FB8C00,color:#333
    style MS fill:#E8F5E9,stroke:#43A047,color:#333

注意三个关键点:

  1. CLAUDE.md 在 system 层级,和系统提示平级。这就是为什么它"始终在场"——它不是对话消息,不会被压缩
  2. 工具以 JSON Schema 定义。模型看到这些定义后,就"知道"自己能做什么。这是 2.2 节说的"工具箱"
  3. messages 此刻只有用户的一条话。后续每轮循环都会往这里追加,这就是 2.5 节说的"上下文窗口越来越满"

第 1 轮:模型决定先探索(Agent Loop 启动)

Claude API 返回响应。模型没有直接开始改代码——它决定先了解情况(2.1 节说的"先看现有代码"):

// Claude API 的第一次响应
{
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "我来调查这个中文搜索的 bug。先定位搜索相关的代码。"
    },
    {
      // 模型选择了 Grep 工具(不是 Bash + grep 命令!遵守系统提示的工具偏好)
      "type": "tool_use",
      "id": "tool_01",
      "name": "Grep",
      "input": {
        "pattern": "search|filter|query",
        "glob": "**/user*",
        "output_mode": "files_with_matches"
      }
    },
    {
      // 并行调用!同时用 Glob 找相关文件(2.2 节:模型自主编排工具链)
      "type": "tool_use",
      "id": "tool_02",
      "name": "Glob",
      "input": {
        "pattern": "src/**/search*.{ts,tsx}"
      }
    }
  ]
}

注意:一次响应中包含了两个并行的工具调用。模型判断这两个搜索互不依赖,所以同时发出。这不是偶然——系统提示明确要求"如果多个工具调用没有依赖关系,并行发出"。

Claude Code 客户端执行这两个工具,把结果追加到 messages 中:

// 客户端追加工具结果到 messages
{
  "role": "user",  // 工具结果以 user 角色返回
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "tool_01",
      "content": "src/features/users/hooks/useUserSearch.ts\nsrc/features/users/components/UserList.tsx"
    },
    {
      "type": "tool_result",
      "tool_use_id": "tool_02",
      "content": "src/features/users/components/SearchBar.tsx"
    }
  ]
}

此时 messages 数组有 3 条消息:用户原始请求 → 模型的工具调用 → 工具执行结果。上下文窗口开始填充。


第 2 轮:精准读取关键文件

客户端把更新后的 messages 再次发送给 Claude API(这就是 Agent Loop 的"循环"——每一轮都是一次完整的 API 调用)。

模型看到搜索结果,决定读取最可疑的文件:

// 第二次 API 响应
{
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "找到了 3 个相关文件。先看搜索 hook 的实现。"
    },
    {
      "type": "tool_use",
      "id": "tool_03",
      "name": "Read",
      "input": {
        "file_path": "/project/src/features/users/hooks/useUserSearch.ts"
      }
    }
  ]
}

客户端执行 Read,返回文件内容(假设是这样的代码):

{
  "type": "tool_result",
  "tool_use_id": "tool_03",
  "content": "     1→import { useState, useMemo } from 'react'\n
     2→\n
     3→export function useUserSearch(users: User[]) {\n
     4→  const [query, setQuery] = useState('')\n
     5→\n
     6→  const filtered = useMemo(() => {\n
     7→    if (!query) return users\n
     8→    const q = query.toLowerCase()\n
     9→    return users.filter(u =>\n
    10→      u.name.toLowerCase().includes(q) ||\n
    11→      u.email.toLowerCase().includes(q)\n
    12→    )\n
    13→  }, [query, users])\n
    14→\n
    15→  return { query, setQuery, filtered }\n
    16→}"
}

messages 数组已有 5 条消息。 文件内容全部进入上下文窗口。这就是为什么"选择性读文件"很重要——每读一个大文件,桌面空间就少一块。


第 3 轮:定位 Bug 并修复

模型分析了代码,发现了问题——toLowerCase() 对中文无效(中文没有大小写概念,但问题在于某些环境下 toLowerCase() 可能改变 Unicode 字符)。但更关键的是,真实 bug 可能在于搜索是前端过滤,而数据源中 u.name 的中文编码有问题。

模型决定进一步确认:

// 第三次 API 响应 — 继续调查
{
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "搜索逻辑看起来基本正确。但 toLowerCase() 对中文搜索没有意义,
               而且可能受 locale 影响。让我检查数据获取端,
               看是否有编码或 normalize 的问题。"
    },
    {
      "type": "tool_use",
      "id": "tool_04",
      "name": "Grep",
      "input": {
        "pattern": "fetchUsers|getUsers|findMany.*user",
        "glob": "src/features/users/api/**",
        "output_mode": "content",
        "-A": 5
      }
    }
  ]
}

Grep 返回了 API 层的代码,模型发现问题:

{
  "type": "tool_result",
  "tool_use_id": "tool_04",
  "content": "src/features/users/api/getUsers.ts:
     8→export async function getUsers(query?: string) {
     9→  const where = query
    10→    ? { name: { contains: query, mode: 'insensitive' } }
    11→    : {}
    12→  return prisma.user.findMany({ where })
    13→}"
}

现在模型看清了全貌:搜索有两条路径——前端过滤(useUserSearch)和后端查询(getUsers)。前端的 includes 对中文实际上是有效的,问题大概率在后端这边——Prisma 的 contains 配合 mode: 'insensitive' 在 PostgreSQL 上对中文支持有问题(PostgreSQL 的 ILIKE 对非 ASCII 字符的行为取决于 locale 配置)。


第 4 轮:执行修复

模型确认了根因,现在开始修复。注意它如何遵守 CLAUDE.md 的规范:

// 第四次 API 响应 — 执行修复
{
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "找到根因了。问题在后端:Prisma 的 `contains` + `insensitive` 模式
               在 PostgreSQL 上对中文不可靠。\n\n
               修复方案:改用 Prisma 的原生查询进行 Unicode 安全的模糊搜索,
               同时修复前端搜索使用 normalize 来确保一致性。"
    },
    {
      "type": "tool_use",
      "id": "tool_05",
      "name": "Edit",  // 系统提示要求用 Edit 而非 sed
      "input": {
        "file_path": "/project/src/features/users/api/getUsers.ts",
        "old_string": "  const where = query\n    ? { name: { contains: query, mode: 'insensitive' } }\n    : {}",
        "new_string": "  const where = query\n    ? {\n        OR: [\n          { name: { contains: query } },\n          { name: { contains: query.normalize('NFC') } },\n          { email: { contains: query } },\n        ],\n      }\n    : {}"
      }
    },
    {
      "type": "tool_use",
      "id": "tool_06",
      "name": "Edit",  // 并行修复前端
      "input": {
        "file_path": "/project/src/features/users/hooks/useUserSearch.ts",
        "old_string": "    const q = query.toLowerCase()\n    return users.filter(u =>\n      u.name.toLowerCase().includes(q) ||\n      u.email.toLowerCase().includes(q)\n    )",
        "new_string": "    const q = query.normalize('NFC')\n    return users.filter(u =>\n      u.name.normalize('NFC').includes(q) ||\n      u.email.normalize('NFC').includes(q)\n    )"
      }
    }
  ]
}

这里模型做了两个关键决策:

  1. 用 Edit 而不是 Write — 系统提示偏好精确编辑而非覆写整个文件
  2. 两个 Edit 并行发出 — 两次编辑互不依赖,所以同时执行

第 5 轮:自动验证(遵守 CLAUDE.md)

修复完成后,模型没有停下来向你汇报——因为 CLAUDE.md 写了 Run pnpm test before finishing。这条规则被注入了 system 层级,模型会严格遵守:

// 第五次 API 响应 — 运行测试
{
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "两个文件已修复。按照项目规范,先跑一下测试。"
    },
    {
      "type": "tool_use",
      "id": "tool_07",
      "name": "Bash",
      "input": {
        "command": "cd /project && pnpm test --filter='**/users/**'",
        "description": "Run user module tests",
        "timeout": 30000
      }
    }
  ]
}

假设测试通过了:

{
  "type": "tool_result",
  "tool_use_id": "tool_07",
  "content": "✓ useUserSearch - filters by Chinese characters (3ms)\n
              ✓ useUserSearch - filters by email (2ms)\n
              ✓ getUsers - returns filtered results (15ms)\n
              Tests: 3 passed, 3 total"
}

第 6 轮:汇报结果(循环结束)

测试通过,Agent Loop 终于结束。模型生成最终回复:

// 第六次 API 响应 — 最终回复(无工具调用 = 循环结束)
{
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "已修复中文搜索 bug。\n\n
               **根因**:两个问题叠加\n
               1. 后端 Prisma 的 `insensitive` 模式对中文不可靠,改为直接 `contains` 匹配\n
               2. 前端的 `toLowerCase()` 对中文无意义,改为 `normalize('NFC')` 确保 Unicode 一致性\n\n
               **改动文件**:\n
               - `src/features/users/api/getUsers.ts` — 修复后端查询\n
               - `src/features/users/hooks/useUserSearch.ts` — 修复前端过滤\n\n
               所有相关测试已通过 ✅"
    }
  ]
}

没有 tool_use 块 = Agent Loop 终止。 这是循环结束的标志——模型认为任务完成了,不再需要调用任何工具。


全景回顾:一次请求背后的完整数据流

sequenceDiagram
    participant U as 👤 你
    participant CC as 🖥️ Claude Code 客户端
    participant API as ☁️ Claude API

    Note over CC: 组装请求:system prompt<br/>+ CLAUDE.md + tools + messages

    U->>CC: "中文搜索 bug,请修复"

    rect rgb(240, 245, 255)
    Note over CC,API: 🔄 第 1 轮 — 探索
    CC->>API: messages: [user_msg]
    API-->>CC: Grep + Glob(并行)
    Note right of CC: 执行工具,追加结果到 messages
    end

    rect rgb(240, 245, 255)
    Note over CC,API: 🔄 第 2 轮 — 深入调查
    CC->>API: messages: [user_msg, asst_1, tool_results_1]
    API-->>CC: Read(useUserSearch.ts)
    Note right of CC: 执行工具,追加结果到 messages
    end

    rect rgb(240, 245, 255)
    Note over CC,API: 🔄 第 3 轮 — 追查根因
    CC->>API: messages: [...之前所有, asst_2, tool_results_2]
    API-->>CC: Grep(API 层代码)
    Note right of CC: 执行工具,追加结果到 messages
    end

    rect rgb(255, 248, 240)
    Note over CC,API: ✏️ 第 4 轮 — 修复代码
    CC->>API: messages: [...之前所有, asst_3, tool_results_3]
    API-->>CC: Edit × 2(并行)
    Note right of CC: ⚠️ 可能触发权限确认
    end

    rect rgb(240, 255, 240)
    Note over CC,API: 🧪 第 5 轮 — 运行测试(遵守 CLAUDE.md)
    CC->>API: messages: [...之前所有, asst_4, tool_results_4]
    API-->>CC: Bash("pnpm test")
    end

    rect rgb(245, 240, 255)
    Note over CC,API: ✅ 第 6 轮 — 汇报结果(无工具调用 = 循环结束)
    CC->>API: messages: [...之前所有, asst_5, tool_results_5]
    API-->>CC: 纯文本回复(无 tool_use)
    end

    CC->>U: 展示修复结果 + 改动摘要

从这个例子中看到的所有原理

回顾一下这个例子中体现的全部机制:

原理在例子中的体现
Agent Loop6 轮 API 调用自主循环,从探索到修复到验证,用户只说了一句话
工具系统模型自主选择 Grep→Read→Edit→Bash 的工具链;用 Edit 而非 sed(系统提示偏好)
并行工具调用第 1 轮 Grep+Glob 并行,第 4 轮两个 Edit 并行
CLAUDE.md注入 system 层级;pnpm test 规则让模型在修复后自动跑测试
系统提示"修改前先读代码" → 模型先 Read 再 Edit;"用 Edit 不用 sed" → 遵守工具偏好
上下文窗口messages 每轮追加,从 1 条增长到 11 条;文件内容全部进入上下文
权限模型Edit 操作可能触发用户确认;Bash 执行测试命令需要权限放行
意图式描述用户说"修复中文搜索 bug",没有指定步骤,模型自主完成全部决策

关键 takeaway:你看到的 Claude Code 界面上的每一行输出,背后都是一次完整的 API 往返。那个看起来"在思考"的光标闪烁,就是客户端在等待 API 响应、执行工具、把结果追加到 messages、再次发送……这就是 Agent Loop 的心跳。


第三章:范式总结 — 文档驱动开发

把前面所有机制和实践汇聚在一起,我们得到了一个统一的工作范式。

我叫它文档驱动开发(Document-Driven Development,DDD)

旧模式 vs 新模式

旧模式:人写代码,AI 辅助片段。

你是司机,AI 是导航 GPS。你决定方向盘怎么打,AI 只是建议"前方 200 米左转"。写代码的主体还是你,AI 提供自动补全、代码建议、解答问题。

新模式:人定义"做什么",AI 实现"怎么做"。

你是工程经理,AI 是执行工程师。你定义目标、约束、标准和验收条件。AI 自主探索代码库、制定方案、编写代码、运行测试、迭代修复。

这不是偷懒或推卸责任。恰恰相反——定义好"做什么"比亲手"怎么做"更难。它要求你有清晰的架构思维、完善的规范体系、精准的需求描述能力。

角色转变

"使用 AI 的编码者""指挥 AI 的工程经理"

工程经理不会亲手写每一行代码,但他确保:

  • 团队有清晰的规范(CLAUDE.md)
  • 任务被清晰定义(意图式描述)
  • 方案在执行前被审批(规划模式)
  • 执行过程有质量保障(Hooks + 权限模型)
  • 产出被验证(测试 + 审查)

完整 DDD 工作流

flowchart TB
    S1["📖 Step 1\n编写 CLAUDE.md"]
    S2["🎯 Step 2\n意图式描述任务"]
    S3{"📐 需要改 3+ 文件?"}
    S3Y["🎩 Step 3\n进入规划模式\n审批方案"]
    S4["⚡ Step 4\n让 Agent Loop 自主执行"]
    S5{"✅ 结果满意?"}
    S5N["💬 Step 5\n意图式反馈迭代"]
    S6["🧹 Step 6\n/compact 或新对话\n更新 CLAUDE.md"]

    S1 --> S2
    S2 --> S3
    S3 -- "是" --> S3Y
    S3 -- "否" --> S4
    S3Y --> S4
    S4 --> S5
    S5 -- "否" --> S5N
    S5N --> S4
    S5 -- "是" --> S6
    S6 -. "下一个任务" .-> S2

    style S1 fill:#DCEEFB,stroke:#2980B9,color:#333
    style S2 fill:#E8F4FD,stroke:#4A90D9,color:#333
    style S3 fill:#FEF9E7,stroke:#F1C40F,color:#333
    style S3Y fill:#FFF8E1,stroke:#F9A825,color:#333
    style S4 fill:#E8F5E9,stroke:#43A047,color:#333
    style S5 fill:#FEF9E7,stroke:#F1C40F,color:#333
    style S5N fill:#FDE8E8,stroke:#E74C3C,color:#333
    style S6 fill:#F3E8FD,stroke:#8E44AD,color:#333

Step 1:编写优秀的 CLAUDE.md

项目开始的第一件事。定义技术栈、架构原则、代码规范、测试要求、常见陷阱。这是你 ROI 最高的时间投入。

Step 2:用意图式描述定义任务

不要说"打开文件 A,在第 X 行加 Y"。说"实现 Z 功能,确保满足 W 约束"。

Step 3:复杂任务先进规划模式

超过 3 个文件的变更,按 Shift+Tab 进入规划模式。审批方案后再让 Claude Code 动手。

Step 4:让 Agent Loop 自主执行

方案审批后,放手让它跑。它会自己读文件、改代码、跑测试、修 bug。不要中途打断——除非你发现方向性错误。

Step 5:审查结果、反馈迭代

Agent Loop 完成后,审查变更。如果有问题,用意图式描述反馈("这里的错误处理不符合我们的规范,请按 CLAUDE.md 中的 Result<T, E> 模式修改"),而不是手动指定修改。

Step 6:任务间管理上下文

一个任务完成后,/compact 或开新对话。保持上下文窗口干净。把本次工作中发现的重要模式更新到 CLAUDE.md。


第四章:速查表

10 对"机制→实践"的快速参考:

机制核心洞察最佳实践一句话口诀
Agent Loop它会自主迭代意图式描述说目的地,不说路线
工具系统它有专业工具箱匹配工具描述任务知道队友会什么
CLAUDE.md它先读手册写宪法而非写代码写好入职文档
子代理它能分身设计并行任务分而治之
上下文窗口桌面有限上下文卫生保持桌面整洁
权限模型风险操作会确认信任但验证配好信任级别
规划模式可以只看不动手先谋后动架构师帽先戴上
Hooks支持自动化自动化质量门禁设了就忘
MCP能用外部工具扩展工具链给它开权限
系统提示有内置直觉顺势而为借力不对抗

快速行动清单

  • 给项目写一份 CLAUDE.md(今天就做)
  • 下次需求描述从"打开文件改第 X 行"改为"实现 Y 功能"
  • 尝试一次规划模式(Shift+Tab
  • 配置一个 Hook(比如 Edit 后自动格式化)
  • 完成一个任务后试试 /compact

第五章:回到那两个程序员

现在回头看开篇的故事,你应该能解释一切了。

程序员 A 的问题不是 prompt 写得差,而是他的心智模型错了。他把 Claude Code 当成一个需要逐步指令的"遥控车",结果:

  • 短路了 Agent Loop — 每条消息都在告诉它下一步做什么,剥夺了它自主迭代的能力
  • 没有 CLAUDE.md — 每次新会话都要重新交代项目规范
  • 没用规划模式 — 直接让它改跨多个文件的代码,没有方案审批就开工
  • 上下文被污染 — 来回纠错的对话塞满了上下文,降低了后续输出的质量

程序员 B 做对了每一件事:

  • 意图式描述 → 激活了完整的 Agent Loop
  • 引用了 CLAUDE.md → 规范一开始就到位
  • 不啰嗦 → 上下文保持干净
  • 信任 Agent Loop → 给出目标后放手让它跑

差距不是 10% 的 prompt 优化,是 10 倍的范式升级


最后一句话

最好的 prompt 根本不是 prompt——而是一份写得好的 CLAUDE.md、一个清晰的意图、和让 Agent Loop 自己跑起来的智慧。

现在就去给你的项目写一份 CLAUDE.md 吧。

这一个动作,比任何 prompt 技巧合集都更能改变你的 Claude Code 体验。