Claude Code 是如何写代码的 — 从提示词到可运行代码的完整旅程

拆解 Claude Code 的工具循环、代码理解机制、验证闭环和持久化体系——它不是更强的 Copilot,而是一个在终端里运行的自主编程 Agent。

20 分钟阅读
Claude Code 是如何写代码的 — 从提示词到可运行代码的完整旅程

如果你用过 GitHub Copilot,你可能觉得 AI 写代码就是「你敲几个字,它帮你补全下一行」。这个模型放在 Claude Code 身上,完全不对。

Claude Code 不是补全工具。它是一个在终端里运行的 自主编程 Agent——能读懂整个项目、做工程决策、写代码、跑测试、修 bug,然后从头再来一遍,直到通过。

这篇文章从工程视角拆解它的工作原理。不讲营销话术,讲它实际在做什么。

一、它跟 Copilot 根本不是一回事

Copilot 的工作方式:你写注释,它猜下一行。它看的是你当前文件的上下文窗口(通常几百到几千行),然后给你一个补全建议。它的核心能力是 模式匹配

Claude Code 的工作方式:你告诉它「我要一个用户认证系统」,它自己去读你的项目结构、看懂你的框架、决定文件放在哪、写代码、写测试、跑测试、看报错、修 bug、再跑。它的核心能力是 工具使用 + 迭代推理

区别一句话:Copilot 帮你写一行,Claude Code 帮你做一个功能。

这个区别的根因在于架构。Claude Code 有一个「工具循环」(Tool-Use Loop),这是它跟所有代码补全工具的本质分界线。

二、工具循环:读 → 想 → 做 → 看,再来一遍

Claude Code 的每一次「思考-行动」是一个循环,大概 2-8 秒。一个中等复杂度的功能(比如加一个 API 端点 + 测试),通常走 5-15 个循环。

循环的四个阶段:

📖 READ(读取) 🧠 THINK(推理)
┌──────────┐ ┌──────────┐
│ Grep │──────────▶│ 分解任务 │
│ Glob │ 找到相关 │ 选择工具 │
│ Read │ 代码文件 │ 生成参数 │
└──────────┘ └────┬─────┘
▲ │
│ 上下文注入 │ 执行指令
│ ▼
┌──────────┐ ┌──────────┐
│ AGENTS │◀──────────│ Write │
│ .md │ 结果反馈 │ Edit │
│ Skills │ │ Bash │
│ Memory │ │ Git │
└──────────┘ └──────────┘
💾 CONTEXT ⚡ ACT(执行)

◀──── 迭代循环 ────
(发现问题 → 修复 → 再验证)

具体拆开来看:

1. READ — 读取阶段。 Agent 不会一上来就写代码。它先用 Grep 搜关键词、Glob 找文件名模式、Read 打开具体文件。这一步的目标是建立「项目地图」——框架是什么、目录怎么组织、相关代码在哪。你给它一个模糊描述,它自己找到 auth 中间件、user model、路由文件。

2. THINK — 推理阶段。 读完代码后,它在内部做几件事:理解用户意图 → 分解成子任务 → 选择正确的工具 → 生成精确的参数。复杂任务会先输出一份计划让你确认,简单任务直接执行。

3. ACT — 执行阶段。 真正动手。Edit 工具做精确的文本替换(不改无关代码),Write 创建新文件,Bash 跑命令。每个操作都有明确的输入输出,可追踪。

4. OBSERVE — 观察阶段。 执行完不是结束。它会读回结果——测试过了吗?lint 报错了吗?类型检查对吗?如果不对,回到 READ 阶段重新理解,再来一遍。这个「验证→纠错→再验证」的闭环,是它能写对代码的核心原因。

三、它怎么「读懂」你的项目

很多人以为 Claude Code 是一次性把整个项目「吞进去」。不是的。它的上下文窗口虽然大(200K tokens),但它不会无脑全读。它用一套分层策略来理解代码库:

第一层:项目级上下文(每次会话自动加载)
CLAUDE.md / AGENTS.md → 项目地图、编码规范、关键约定
.gitignore → 知道哪些文件不该碰

第二层:按需搜索(需要时才加载)
Grep 关键词 → 找到相关代码的精确位置
Glob 文件名模式 → 发现目录结构和文件组织
Read 具体文件 → 理解实现细节

第三层:工具链感知(从配置文件推断)
package.json → 依赖、脚本、框架
tsconfig.json → TypeScript 配置
pyproject.toml → Python 项目结构

这个策略的精妙之处:它不猜,它读。你不需要事先告诉它「我的项目用 pnpm 不是 npm」,它会自己看 package.json 里的 packageManager 字段和 lock 文件。

四、它不是「补全」,是「工程决策」

Claude Code 写代码跟 Copilot 最大的不同:Copilot 猜你想写什么,Claude Code 决定该怎么做。

你跟它说「加一个用户注册接口」。这不是一行补全,这是一次工程决策。它会:

1. 检查项目用的是 Express / Fastify / Koa?→ 读 package.json
2. 已有的 user model 长什么样?→ Grep "user" → Read model
3. 有没有现成的 validation 中间件?→ Grep "validate"
4. 路由注册的约定是什么?→ Read 路由文件
5. 写测试的风格是 Jest / Vitest?→ 读现有测试
6. 开始写代码 → 匹配已有风格
7. 跑测试 → 报错?→ 修复 → 再跑 → 通过

注意第 6 步的「匹配已有风格」。Claude Code 会观察你的命名习惯、缩进宽度、引号偏好、文件组织方式,然后模仿。你不会在 React 项目里突然看到 Vue 的写法。

五、验证闭环:写 → 测 → 修 → 再测

这是 Claude Code 跟所有「一次生成」类工具的根本区别。它不会写完就交差。

Write Code Run Tests
┌─────────┐ ┌─────────┐
│ 写代码 │─────────▶│ 跑测试 │
└─────────┘ └────┬────┘
▲ │
│ ┌──────────┴──────────┐
│ ▼ ▼
│ ┌─────────┐ ┌─────────┐
│ │ ✅ PASS │ │ ❌ FAIL │
│ │ 任务完成 │ │ 分析报错 │
│ └─────────┘ └────┬────┘
│ │
└──────────────────────────────┘
读报错 → 理解原因 → 修改代码

这个闭环不是跑一遍就停。它会反复迭代直到:所有测试通过 + lint 无报错 + 类型检查通过。一个中等复杂度的功能,典型数字:第一轮写代码 2 个循环,跑测试发现 3 个错误,修 bug 花了 4 个循环,最后的 lint 修复又花了 2 个循环。总共 8-10 个循环,3-5 分钟。

六、Skill 和 Memory:让 Agent 越用越聪明

Claude Code 不是每次都从零开始。它有两套持久化机制:

CLAUDE.md:项目级的「默认行为手册」。你在这里写「我们永远用 pnpm 不是 npm」、「commit message 必须符合 conventional commits」、「API 返回值统一用 { data, error } 格式」。每次会话自动加载,不用每次都解释。

Skill:可复用的专题工作流。比如「发版流程」、「接新 API 的安全审查」、「React 组件标准写法」。Skill 是按需加载的,只在相关任务触发,不占常驻 token。

层级 │ 内容 │ 加载方式
─────────────┼───────────────────────────┼──────────
CLAUDE.md │ 项目地图、编码规范、约定 │ 每次会话自动
Skill │ 专题流程、多步操作、模板 │ 按需触发
Memory │ 跨会话偏好、经验、教训 │ 自动注入
Hook │ 强制性规则(提交前 lint 等) │ 事件触发

这套体系的核心价值不是「让 AI 更聪明」,而是「让 AI 的行为可预测」。你知道它每次都会遵守 CLAUDE.md 的约定,会在提交前跑 hook,会在处理数据库迁移时加载对应的 skill。

七、它也有明显局限

坦诚说,Claude Code 不是银弹。以下是实际使用中反复出现的问题:

1. 长会话漂移。 连续工作 30 分钟以上,Agent 的行为会逐渐「漂移」——忘记最初的要求、重复读同一个文件、跳过 CLAUDE.md 里的约定。缓解手段:把大任务拆小、适时 /reset。

2. Skill 触发不稳定。 即使 description 写得很好,Skill 也不一定每次都能触发。Vercel 评测显示默认情况下 56% 的 Skill 没被调用。需要明确触发指令才能拉到 79%。

3. 大型重构易出错。 涉及 10+ 文件、跨模块的架构级重构,Claude Code 容易「只见树木不见森林」。这类任务仍然需要人类做架构决策。

4. 过度工程化。 如果你说「加一个简单的计数器」,它可能给你写一个带 Redux store、TypeScript 类型、单元测试、集成测试的完整方案。你需要学会精确地限制它的范围。

八、写在最后

Claude Code 代表的不是「更强的代码补全」,而是一个范式转换:从 「我写代码,AI 帮忙」「我定方向,AI 执行」。

理解它的工具循环、上下文分层、验证闭环和持久化机制,不是为了「用得更好」——而是为了知道什么时候该信它,什么时候该接手。