AI 编程工作流怎么落地
五个阶段、一份能照抄的任务卡模板,和三种千万别用它的场景
📅 更新于 2026-09-13
0030 秒速览:三句话,然后按你的处境直接跳
读完这一篇,你能做三件事:给 AI 派活时写出一份它不会理解错的说明书;用四道硬度不同的"闸门"确认它真的做完了;并且认出哪三类任务你根本不该走这套流程。
① 它不让你更快地写代码,它让你不用回头重写——省下的时间是返工时间;② 整套流程只有一件事在起作用:把"做完了没有"变成一条能跑的命令(AI 自己说得再好都不算证据);③ 判断要不要用它,不看任务大小,看两个量:改动碰几个文件,和改坏了能不能撤回——一句话能说清、又能随便撤的,直接做。
按你现在的处境,直接看这一节
| 你现在的状态 | 直接看 | 为什么先看它 |
|---|---|---|
| 刚开始用 AI 写代码,不知道怎么开口 | 03.1 任务卡模板 | 照抄一份模板就能立刻改变输出质量 |
| AI 写的代码"看着对但一跑就错" | 05 验证阶段 | 问题通常不在模型,在于没有闸门 |
| 改了一晚上,越改越乱 | 05.8 调试死循环 | 这不是继续调的时机,是退回规划的信号 |
| 想让 AI 一次改 20 个文件 | 01.5 什么时候别用它 | 这是最容易翻车的一种派活方式 |
| 重复让它做同一件事,已经烦了 | 06 沉淀阶段 | 把重复劳动变成一句话触发 |
| 团队里每个人用 AI 的姿势都不一样 | 03.6 项目记忆该放什么 | 项目级约定要落成文件,不是靠口头传 |
| 只想先跑通一次,别讲方法论 | 08 完整例子 | 从任务卡到验收的完整链路,可照抄 |
| 想知道什么任务配什么强度的流程 | 10 任务 × 闸门对照表 | 一张表决定这次要不要开计划模式 |
一条可执行的上手路径(今天就能跑完)
比如给你手上项目里的一个页面加个筛选条件。不要拿最重要的事当试验田——第一次走完整流程一定会漏步骤,代价要可控。
照抄 03.1 的五格模板。写完先把"验证"那一格填上——填不出来,说明这个任务你还没想清楚,别急着往下走。
在 Claude Code 里按 Shift+Tab 直到状态栏出现 ⏸ plan mode on,或者用 claude --permission-mode plan 直接以计划模式启动(见 03.4)。
关键句是"跑完把命令和输出原文贴出来"。它说"已完成"你要当没听见(见 05)。
只加一条规则,别写论文。这一步的收益要下一周才看得见(见 06)。
读完你应该能
01它到底是什么:三个常见的错想,先破掉
一句话定义:AI 编程工作流就是你和 AI 代理(AI agent——能自己读文件、改文件、敲命令的 AI 程序)协作时,从接到任务到交付代码所遵循的一套固定顺序。它不是某个软件,装了就有;它是你这一侧的做事顺序。
它是"做法"而不是"对象",所以它没有版本号、没有安装命令。同一个 Claude Code,配合这套顺序能产出可以合并的代码;不配合,就产出一堆需要你重写的东西。
01.1 错想一:它是"让 AI 自己跑"的自动化
恰恰相反。这套流程里最花时间的几件事全是你在做:写清楚要什么、判断它给的方案对不对、决定什么算做完。AI 承担的是中间那段——读代码、写代码、跑命令。
分工说得再清楚一点:你负责定义意图和验收标准,AI 负责写码和自检。它不是"把活全丢出去",而是"把脑子留在自己这里,把手交出去"。
01.2 错想二:它是提示词技巧,多写几个字就完了
提示词技巧管的是这一次怎么问;工作流管的是一轮一轮怎么推进。你可以每句话都问得很漂亮,但如果不检查产出、不设验证、不沉淀经验,下一轮照样从零开始。
更准的区分:提示词是单次动作,工作流是带检查点的循环。检查点才是重点——它保证错误不会一路滑到线上。
01.3 错想三:它只适合大项目、只适合某种工具
流程是跨工具的。下面这些工具都能承载同一套五阶段,差别只在"操作方式"(按哪个键进计划模式、规则文件叫什么名字),不在于"要不要按流程来":
| 工具 | 形态 | 它的项目记忆文件叫什么 | 别把它当什么用 |
|---|---|---|---|
| Claude Code | 终端里的 AI 代理 | CLAUDE.md(每次会话自动读,官方建议目标 200 行以内) | 当文档仓库用——它只该装"AI 猜不出来的约定" |
| Codex CLI | 终端里的 AI 代理 | AGENTS.md(全局 ~/.codex/AGENTS.md + 项目根逐层合并,合并上限默认 32 KiB) | 当"越全越好"的说明书——它会被大小上限截断 |
| Cursor | 编辑器里的代理 | .cursor/rules 目录下的规则文件 | 当唯一真相源——规则分散在多处会互相冲突 |
| GitHub Copilot | 编辑器内联补全 + 代理 | 仓库里的自定义指令文件 | 当"代你思考的人"——补全场景它只看得到眼前几十行 |
反过来说也成立:流程对了,工具差一点你也能干活;流程不对,换最贵的模型也救不回来。模型是容易换的那部分,顺序是你自己的。
01.4 它的五个阶段(官方写的是四个)
Anthropic 的官方文档把推荐工作流写成四个阶段:Explore(先摸清现状)→ Plan(订计划)→ Implement(实现)→ Commit(提交)。其他来源的名字和颗粒度不同,但骨架一致。本文把它整理成五个,因为"验证"在官方四阶段里是隐含的,而它恰好是新手最容易跳过的一步,值得单独拎出来当一段:
| 阶段 | 这一段的唯一产出 | 产出该长什么样 | 跳过它会怎样 |
|---|---|---|---|
| 规划 | 一份任务说明 | 五格任务卡:做什么 / 不做什么 / 约束 / 验证 / 完成标准 | AI 自己去猜"完成"是什么,猜错就是白干 |
| 执行 | 一批小改动 | 每个小步都能单独跑、单独回退 | 一次给你一千行,你审不动也不看懂 |
| 验证(也叫验证门——一个"过不了就不许往下走"的硬信号) | 一份通过的证据 | 测试输出、类型检查输出、风格检查输出的原文 | 你会把"它说完成了"当成"真的完成了" |
| 沉淀 | 一条新规则 | 写进项目记忆文件的一两行,下次自动生效 | 同样的错下周再犯一次,重复付费 |
01.5 什么时候别用它:三种场景,直接做反而更好
这是本篇最该被认真读的一段。工作流有成本——写任务卡、等计划、跑验证,每一步都要花你的注意力。当成本明显大于返工风险时,用它就是自找麻烦。
| 别用的场景 | 为什么 | 更好的做法 |
|---|---|---|
| 改动一句话就能说完,而且改错了随便撤 | 比如改个变量名、加一行日志、修个错别字 | 直接让它做。官方文档给的判据是:如果你能用一句话描述这个 diff,就跳过计划 |
| 你还不知道自己要什么 | 工作流的前提是"你能说清目标"。说不清的时候,流程会把你卡在第一格,然后你开始糊弄那一格 | 先用对话探路——随便聊、让它给两三个方案、看哪个顺眼,定下来之后再走流程 |
| 目标本身就是"先跑通看看"的探索 | 原型阶段的价值在于快,不在于省心,而且回退成本接近零 | 放开手让它写,把探索结论记下来;等要把它变成正式代码时再补任务卡 |
第一种:任务不可逆,但你没开计划模式。数据库迁移、删除线上数据、改鉴权逻辑——这类动作一旦执行,回退成本极高。风险越高,计划这道闸越不能省,跟任务大小无关。
第二种:你用了流程,但验证那一格填的是"我看看"。没有可运行的命令就没有闸门,你能做的只剩"逐行读 AI 写的代码"——这是最贵、也最不可靠的一种验证(05 会讲为什么)。
01.6 一张表看清它和近邻做法的差别
| 做法 | 它的核心动作 | 和本文这套的差别 | 什么时候这个差别不重要 |
|---|---|---|---|
| 氛围编程(vibe coding) | 凭感觉不断提要求,看着结果像样就收 | 它没有"完成标准"和"验证闸门"这两样东西,质量靠运气 | 你在做一次性原型、或者写个自己用的小脚本 |
| 提示词工程 | 把单次提问写得更精确 | 它优化"这一次的输入",本文优化"整轮的推进顺序" | 你的任务只用一轮对话就能结束 |
| 测试驱动开发(TDD) | 先写会失败的测试,再写代码让它通过 | 它是本文验证阶段的一种实现方式,不是替代品:它管"代码对不对",不管"你要的是不是这个" | 差别一直在——TDD 和本文是叠加关系,不是二选一 |
| 结对编程 | 两个人并肩写,一人写一人盯 | 本文把"盯的人"留给你、把"写的人"换成 AI;AI 不会在你走神时自己停下来 | 任务里有人情判断、需要现场协商的时候 |
| 代码评审(code review) | 合并前由别人看一遍改动 | 它是本文验证阶段的最后一道;前几道(测试、类型、风格)都过不了,就不该走到它 | 改动极小、且已有自动化检查兜底 |
01.7 没有它的时候,你实际在经历什么
很多人以为自己缺的是"更强的模型",其实缺的是检查点。下面的对比不是修辞,是两种流程产生的两种工作量分布:
直接让 AI 写 → 它输出一大段
→ 运行时报错 → 让它改 → 冒出新的问题
→ 来回十几轮 → 最终代码一团糟,看不懂也拆不开
先写清"完成标准" → 让它出计划 → 你审 → 批准后分步做
→ 每步跑验证 → 出错只退一小步
→ 最后你验收的是证据,不是它的承诺
# 一条消息就想让 AI 输出完整功能
帮我做一个用户登录系统
# 结果:AI 忘了密码加密、没做输入校验、把数据库连接硬编码进去了——你拿到手才发现要重写。
# 1. 先定义"完成"的标准
任务:用户登录系统
约束:JWT 认证、bcrypt 密码哈希、限流
验证:跑测试套件通过
# 2. 让 AI 出计划 → 审核 → 分步实现
# 结果:AI 每一步都知道"完成"是什么,你只在关键节点把关。
在一个没有自动化测试的代码库上重度依赖 AI 代理,是这套做法里风险最高的组合。测试是整套流程唯一客观的信号源——没有它,AI 无法自证,你也无法验收,双方都只能猜。如果你正打算把 AI 大规模引入一个测试几乎为零的老项目,先补测试,这是性价比最高的一步准备工作。
02动手前必须先有的东西:一条命令,两个文件
这套流程需要三个前置条件。缺任何一个,后面每一节都会卡住。好消息是三个都很小,半小时内能补齐。
02.1 前置一:一条"能告诉你对不对"的命令
你需要至少一条命令,跑完给你一个明确的通过或不通过。它是什么不重要,常见的是这几种:
# 跑测试套件(Node.js 项目的常见写法,具体看 package.json 里的 scripts)
npm test
# 类型检查:只检查、不生成文件
npx tsc --noEmit
# 代码风格检查
npm run lint
# 跑单个测试文件(改哪里测哪里,比每次全跑快得多)
npm test -- src/orders/order.test.js
为什么这条命令如此关键:它是整套流程里唯一一个"不需要谁相信谁"的信号。AI 说完成了,你可以不信;命令的退出码是 0 还是非 0,你没法争辩。
02.2 前置二:项目记忆文件
这是 AI 每次开工自动读的一份说明,装着"它猜不出来、但必须知道"的项目约定。不同工具认的文件名不同,跨工具的通用约定是 AGENTS.md(见 agents.md);Claude Code 则读 CLAUDE.md。
这里有个坑要提前知道:Claude Code 读的是 CLAUDE.md,不是 AGENTS.md。如果你的仓库已经有 AGENTS.md 给别的代理用,官方给的做法是让 CLAUDE.md 把它导进来,两边共用同一份内容,避免复制两份:
# CLAUDE.md 里写一行,把 AGENTS.md 的内容导进来
@AGENTS.md
# 或者在 macOS / Linux 上直接建软链接(symlink),让两个名字指向同一个文件
ln -s AGENTS.md CLAUDE.md
Claude Code 也提供了生成器:跑 /init 会让你先审一份它分析代码库后写出来的草稿,而不是直接覆盖你已有的文件。文件写好后跑 /context 可以确认它真的被读进去了。
02.3 前置三:一个能回退的干净起点
开工前把当前状态提交一次,让"回到原点"永远是一条命令的事。AI 改坏了你不需要跟它争论,直接回退再换说法。
# 开工前:把当前状态存成一个还原点
git add -A && git commit -m "开工前的检查点"
# 想先看 AI 改了哪些地方、改了多少
git diff --stat
git diff
# 改坏了,丢掉未提交的改动,回到还原点
git checkout -- .
git reset --hard HEAD
git reset --hard 会永久丢掉未提交的改动
它会把你没提交的工作直接抹掉,找不回来。执行前先跑 git status 看清楚有什么会丢。如果你想让多个 AI 任务同时开工又不互相踩,可以用 git worktree(工作树):同一个仓库的多个独立检出目录,各有自己的分支和文件,互不干扰。
# 工作树:为并行任务开一个独立目录,各自一个分支
git worktree add ../myproject-feature-a -b feature-a
# 用完清理
git worktree remove ../myproject-feature-a
02.4 准备度自检:三格都能打勾再往下看
| 检查项 | 合格的样子 | 不合格就先做这个 |
|---|---|---|
| 有一条验证命令 | 你说得出具体命令,而且它现在是绿的 | 先补一个最小的测试,让它在修改前就是通过的 |
| 有项目记忆文件 | 文件存在、内容短、AI 确实读到了 | 跑一次工具的初始化命令(如 Claude Code 的 /init),然后删掉一半 |
| 有可回退的起点 | 工作区干净,或者至少你知道哪些改动已提交 | 先提交一次,别在脏工作区上让 AI 大改 |
03规划:怎么把话交代清楚,让 AI 不用猜
这一节解决新手最痛的问题:话该怎么说。规则只有一条——把"做什么、不做什么、怎么证明做完了"写成 AI 不需要猜的形式。
03.1 任务卡模板:五格,照抄
下面这份模板可以直接复制,把方括号里的内容换掉。它按五格组织,每一格都对应一种 AI 容易猜错的东西:
任务:[一句话说清要做什么。不要用"更好""优化"这类形容词]
背景:
- 技术栈:[框架 / 语言 / 数据库]
- 相关文件:[关键文件路径,说明它们是干什么的]
- 现状:[现在是怎么工作的,你要改成什么样]
要做的:
1. [具体动作一]
2. [具体动作二]
3. [具体动作三]
不要做的:
- 不要 [最容易顺手做但你不想它做的事,比如改数据库结构]
- 不要引入新的依赖
验证方式:
- 运行 [确切的命令]
- 确认 [具体的行为]
完成标准:
- [哪些条件全部满足才算完]
五格各自防的是哪一种猜错,值得分开看一眼:
| 格子 | 要写什么 | 不写它会怎样 | 写好的判据 |
|---|---|---|---|
| 任务 | 一句话,说清"改成什么样" | AI 自己挑一个方向,大概率不是你要的 | 里面没有形容词。出现"更好""优化""完善"就是没写清 |
| 背景 | 技术栈、相关文件路径、当前行为 | 它会去猜项目结构,然后改错文件 | 你把关键文件的路径和用途都点了名 |
| 要做的 | 编号的具体动作 | 它会顺手扩大范围,做你没要的功能 | 每条都能对应一个小到能单独验证的改动 |
| 不要做的 | 明确的禁止项 | 最典型的翻车:它"顺手"帮你改了数据库结构 | 至少有一条,且是你真的在意的边界 |
| 验证 + 完成标准 | 具体命令 + 具体行为 | 你会拿到"应该可以了"这种答复 | 命令能跑,条件能一条条打勾 |
对照着看,差别很直观:
❌ "做个更好的搜索"
✅ "在产品列表页添加按价格排序的筛选器,默认升序,改完跑 npm test 全部通过"
其中四格还可以再短一点——它们本来就是一行标签加一句具体内容,所以你甚至只写这四行就发出去(下面这四条是本文 03.2 那个订单通知任务的原文):
边界:不要修改现有的订单数据库结构,不要引入新的邮件服务提供商
验证:运行 npm test 且全部通过,并确认邮件发送函数被正确调用
约束:复用现有的 EmailService(src/services/email.js),不新建邮件客户端
完成标准:所有测试通过、lint 干净、发送失败有重试
03.2 五格分别怎么写:一个真实任务
假设你要给一个现有的 Node.js 电商项目加"订单邮件通知"。五格填出来是这样(下面这份原样粘给 AI 就能用):
任务:为现有的电商订单系统添加邮件通知功能
背景:
- 项目用 Node.js + Express + PostgreSQL
- 订单创建后需要发邮件通知用户
- 已有 EmailService 类(见 src/services/email.js)
要做的:
1. 在订单创建流程中调用邮件通知
2. 邮件模板:订单确认(用户名、订单号、总额)
3. 失败时重试 2 次
不要做的:
- 不要修改现有的订单数据库结构
- 不要引入新的邮件服务提供商
验证方式:
- 运行测试套件 npm test
- 确认邮件发送函数被正确调用
完成标准:
- 所有测试通过
- 错误处理覆盖发送失败场景
逐格看它为什么这么写:
"订单创建成功后,调用已有的邮件服务给下单用户发一封确认邮件(含用户名、订单号、总额)。"一句话说完,没有"更好的""更完善的"。
"不要修改数据库结构;不要引入新的邮件服务商;不要动 /api/login。"这一格投入产出比最高,写一行能省掉一次全量返工。
"npm test 必须全绿,且新增至少一条断言:订单创建后邮件发送函数被调用了一次。"注意后半句——它在防"只测了不报错"。
"复用现有的 src/utils/format.js 做金额格式化,不要引入 date-fns。"这格的判据是:你能说出至少一个"必须用现有实现"的地方。
"测试通过 + 风格检查干净 + diff 小到能一次看完 + 发送失败有重试。"最后一格往往就是你的验收动作清单。
03.3 为什么"先写完成标准"比"先写代码"重要
因为没有完成标准的任务,AI 的产出永远是"差不多"。它会给你一个能跑但漏了错误处理、或者实现了你没要的功能的版本,而你没有依据说它不对。
一个可用的检查法:把"验证"那一格单独拿出来读。如果你不能用它判断一个陌生人的代码是否合格,说明它还不够具体。"测试通过"不如"npm test 全绿,且新测试断言邮件函数被调用"。
顺序上还有个反常识的地方:先写验证,再写要做的。因为"怎么证明做完了"往往比"要做几件事"更能暴露你其实没想清楚——如果连怎么验证都写不出来,这个任务大概还不该开工。
03.4 计划模式(Plan Mode)到底怎么用
计划模式是 AI 编程工具的一种只读状态:AI 只能读文件、向你提问、写一份计划,不能改任何代码,直到你批准。它的全部价值就是"在你同意方向之前,一行代码都不会被写"。
Claude Code 里的确切操作(照抄官方文档):
# 方式一:进入会话后按 Shift+Tab,直到状态栏显示这行字
⏸ plan mode on
# 方式二:启动时就以计划模式开始
claude --permission-mode plan
# 想直接改它的计划:按 Ctrl+G 把计划在编辑器里打开,改完再批准
Ctrl+G
计划模式下值得用的两句提示词(取自官方文档的示例,可直接粘):
读 src/auth 目录,搞清楚我们现在的会话和登录是怎么处理的。
顺便看一下环境变量里的密钥是怎么管理的。
我想加 Google OAuth。哪些文件需要改?会话流程会变成什么样?给我一份计划。
批准计划之后,用一句话把"实现 + 验证"绑在一起:
按你的计划实现 OAuth 流程。给回调处理函数写测试,跑测试套件,修掉所有失败项。
| 情况 | 要不要开计划模式 | 为什么 |
|---|---|---|
| 能用一句话描述这个改动 | 不开 | 官方判据原话:能一句话说清 diff,就跳过计划。开它纯属加开销 |
| 改动会碰 3 个以上文件 | 开 | 你已经没法在脑子里预演全部改动了,需要一份书面计划当靶子 |
| 方向不确定,有几个方案在犹豫 | 开 | 这是计划模式最值钱的场景——试错很便宜,正好比对方案 |
| 改动不可逆(数据库迁移、删数据) | 开,而且必须逐字读计划 | 回退成本极高。这是唯一"必须逐字读"的情形 |
| 你对这段代码完全不熟 | 开 | 计划本身就能告诉你这段代码长什么样 |
开了计划模式,然后不看计划就点批准。那等于多花一次往返,什么都没换来。计划模式存在的唯一理由就是让你在批准前读一遍——所以批准前问自己一句:"如果它现在按这份计划写,我知道哪些文件会被改吗?"答不上就别批准。
03.5 比任务卡更重的一种做法:先写规格
任务卡是"一个任务一张",规格(spec,一份一页纸的说明文档)是"一次改动一张"。规格驱动开发(Spec-Driven Development,SDD)的核心主张是:先把要什么写成一页纸,再让 AI 从这一页派生计划和代码;代码是产物,规格才是那个真正该被维护的东西。
什么时候值得升到规格?判据是这件事会不会跨越多个会话或多人。一张任务卡在单次会话里够用;一旦要隔天接着做、或者别人接手,口头共识就会掉——这时写成一页纸。
规格里该有什么(一页纸够,不要写成详细设计):
# 规格模板:一页纸,写成文件放进仓库
## 用户故事
作为 [谁],我希望 [做什么],以便 [得到什么]。
## 验收标准
- [ ] [一条一条能打勾的行为,不要写"性能好"这类形容词]
## 边界情况
- 输入为空怎么办
- 权限不足怎么办
- 重复提交怎么办
## 明确排除的范围
- 这次不做:多语言邮件模板
- 这次不做:短信通知
## 未解决的疑问
- [ ] [写下来还没定的事,而不是装作定下来了]
写完之后有一件高价值的事,只有 AI 做得又快又好:让它先找缺口。这句提示词建议直接抄:
读这份 spec。它有哪些模糊的地方?哪些验收标准没法客观判断?
哪些边界情况没覆盖?把疑问列出来,先不要写代码。
它的价值在于:规格里的一个模糊点,就是实现阶段的一次返工。把疑问在上游暴露出来,比在下游改代码便宜得多。
| 直接下任务 | 先写规格 | 怎么选 | |
|---|---|---|---|
| 产出物 | 一段对话 | 一个写进仓库的文件 | 对话会丢,文件不会 |
| 适合的规模 | 单个会话能做完 | 跨会话、跨人 | 问自己"隔三天还接得上吗" |
| 额外成本 | 几乎为零 | 15–30 分钟 | 省下的是返工时间,不是写码时间 |
| 要维护的东西 | 没有 | 规格本身会过时,得跟着改 | 如果你不打算维护它,就别建它 |
03.6 项目记忆该放什么:一份真实的规则文件
项目记忆文件装的是"AI 读代码猜不出来的约定"。官方文档给的正反清单很实用,照它取舍:
| 该放进去 | 不该放进去 | 判断法 |
|---|---|---|
| 它猜不到的构建 / 测试命令 | 它读代码就能知道的事 | "删掉这行会导致它做错吗?"不会就删 |
| 和语言默认风格不同的代码约定 | 语言本身的通用规范 | 通用规范它已经知道了 |
| 测试怎么跑、用哪个测试框架 | 详细的 API 文档(给链接就行) | 频繁变的信息不要抄进来 |
| 分支命名、提交信息这类仓库礼仪 | 整篇教程式的解释 | 它是操作手册,不是教材 |
| 项目特有的架构决策 | 逐文件的代码库导览 | 文件一多必然过时 |
| 必须的环境变量、容易踩的环境坑 | "写干净的代码"这类没有信息量的规则 | 没有信息量的规则会被连同真规则一起忽略 |
一份能直接用的小样例(官方文档给的形态,换成你自己的内容):
# CLAUDE.md
# 代码风格
- 用 ES modules(import/export)语法,不用 CommonJS(require)
- 导入尽量解构:import { foo } from 'bar'
# 工作流
- 做完一批代码改动后一定要跑类型检查
- 平时优先跑单个测试文件,不要每次跑整个测试套件(太慢)
# 已知陷阱
- 金额一律走 src/utils/format.js 的 formatMoney,不要自己写 toFixed
- 不要直接改 prisma/schema.prisma 后忘记跑迁移
官方文档明确说:臃肿的 CLAUDE.md 会让 AI 忽略你真正的指令,并建议目标在 200 行以内。如果你发现"明明写了规则它还是不听",第一反应不该是"再加粗一次",而是去删——删掉那些它自己能读出来的内容,剩下真正约束行为的几行。顺手跑一次 /doctor,它会指出哪些内容是可以从代码库里推出来的、可以删。
04执行:怎么让 AI 动手,而且每一步都收得住
计划过了,进入写代码。这一节只解决一件事:让每次改动小到你能一眼看懂、坏了能一步退回。
04.1 为什么一次不要超过 200 行
因为瓶颈是你的审阅能力,不是 AI 的输出能力。AI 一次给你一千行,你只有三个选择:全信、全不信、或者花三小时逐行读——前两个不对,第三个不划算。
把它拆小的另一个好处是:你能理解它写的代码。这一点常被忽略——如果你不理解自己仓库里的代码,下一个 bug 会由你付账。
一个可执行的拆法:按"能单独验证"切,不按"文件"切。一次改动如果能单独跑一次测试并看到结果,它就是一个合适的颗粒度。200 行是经验值,真正的判据是"我能不能一次把它看完"。
04.2 猴子模式 vs 教练模式
这两种模式的区别不在工具,在你给指令的精确度:
给一句模糊指令,让它自己决定怎么做。
它会写一大片你审不过来的东西,
然后你花几小时审查和修复。
给非常精确的指令,明确限制它只做一件事。
它输出一小段精确改动,
你马上就能验证。
❌ "帮我重构这个模块"
✅ "在 UserService.ts 第 45-60 行添加 email 字段校验,用已有的 validator 库"
| 猴子模式 | 教练模式 | 切换的判据 | |
|---|---|---|---|
| 你的指令 | "重构这个模块" | "第 45-60 行,加 email 校验,用现有 validator" | 指令里有没有具体位置和具体工具 |
| 它的产出规模 | 上百行起步 | 几十行以内 | 你能不能一次看完 |
| 你的验证成本 | 小时级 | 分钟级 | 验证时间超过写码时间,就说明切错了 |
| 什么时候可以用猴子模式 | 探索阶段、你不在乎这段代码留不留 | 只要产出要进主干,就切教练模式 | |
04.3 上下文分三层,别一次全倒给它
"上下文"(context)就是 AI 这一次能看到的全部信息。并不是越多越好——塞太多无关内容,它会开始抓错重点。按三层组织最省事:
| 层 | 装什么 | 存活多久 | 放错层会怎样 |
|---|---|---|---|
| 项目记忆文件 | 技术栈、代码约定、架构决策、已知陷阱 | 每次会话自动加载 | 放太多 → 关键规则被淹没(这就是它必须短的原因) |
| 任务说明(任务卡 / 规格) | 这次要做什么、不做什么、怎么验收 | 这一个任务 | 放太泛 → AI 帮你做邻接功能 |
| 即时信息 | 报错原文、相关代码片段、你刚发现的现象 | 这一次对话 | 放得太少 → 它只能瞎猜你在说哪个 bug |
04.4 指定读哪些文件,比让它自己找效果好
现代 AI 代理都能自己翻文件系统,但翻的顺序和范围直接决定输出质量。一个反直觉但有效的做法是:你主动点名文件,并且说出为什么读它。
我点名几个文件,说明一下为什么要读:
- src/models/order.js —— 它定义了订单的数据模型,你要在这个结构上工作
- src/routes/order.js —— 这是你要扩展的路由实现
- tests/order.test.js —— 新测试要加在这里,先看现有测试怎么写的
读完这三个文件再动手,不要先去看仓库里其他部分。
最后一句很重要:加一句范围限制,否则它会出于"负责任"把整个仓库都翻一遍,既慢又容易跑偏。
04.5 让 AI 自己跑验证,一次都别省
这是执行阶段最值钱的一个习惯:不要只说"帮我实现这个功能"。把验证绑在同一句话里:
实现这个功能,然后运行 npm test,让所有测试通过。
如果失败,读错误日志、修复、再跑,直到全绿。
最后把命令和输出原文贴给我。
官方文档的表述是:给 AI 一个它能自己跑的检查,是"你在旁边盯着"和"你可以离开"之间的区别。它自己能闭环,你就不用守在那儿。
还有一句要加上——要求它给证据,而不是下结论:
不要告诉我"已完成"。给我三样东西:
1. 你运行的完整命令
2. 命令的输出原文(不要摘要)
3. git diff --stat 的结果
04.6 多个任务同时开工时怎么不乱
想同时推两件事的时候,别在同一份工作区里交叉进行——两个任务的文件改动会互相污染,你会分不清哪行是谁改的。三种开法,按隔离程度递增:
| 开法 | 怎么开 | 隔离了什么 | 什么时候用 |
|---|---|---|---|
| 一个任务一个会话 | 做完一个就清空上下文、开新会话 | 对话上下文 | 任务的先后顺序无所谓时 |
| 工作树 | git worktree add ../项目-任务A -b 任务A | 文件也隔离了,各在各的目录 | 两个任务要同时改代码 |
| 子代理 | 让代理派一个独立上下文的分身去做调查 | 把大量翻文件的噪音隔离在主会话之外 | 需要先调研一大片代码、又不想脏了主会话 |
把不相关的任务混在同一个会话里,会让 AI 的上下文被污染,输出质量明显下滑。做完一个任务就清空上下文再开下一个——这不是洁癖,是在保住前面所有工作的质量。
05验证:怎么确认它没在骗你
这一节是整篇文章的重心。跳过规划你会白干一次;跳过验证,你会把白干过的东西发到线上。
05.1 为什么"它说完成了"不能算证据
因为语言模型输出的是一段"看起来最像答案"的文字,不是对现实世界的检查结果。它无法区分"这个测试通过了"和"这个测试应该会通过"——除非你真的让它去跑。
更麻烦的是,它的语气不会随把握程度变化:猜错的时候和猜对的时候一样自信。于是你会遇到这种局面——它产生错误改动的速度,比你能发现错误的速度还快。这不是模型不行,是你装了一台没有刹车的加速器。
永远说"把测试输出给我看"。它自己说完成,当作没听见;测试输出是这台机器上唯一值得信的信号。
05.2 四层验证:从最便宜到最贵
不要一上来就人工逐行读代码——那是最贵的一层,应该留到最后。按这个顺序往上走,多数问题会在前两层被拦住:
| 层 | 它回答什么 | 具体怎么做 | 为什么放在这个位置 |
|---|---|---|---|
| 一、自动化测试 | 原来能用的功能,现在还能用吗 | 跑测试套件,看退出码 | 最便宜、最客观,一次跑完所有历史结论 |
| 二、类型检查 | 数据结构的用法对不对 | npx tsc --noEmit 这类命令 | 同样便宜,能抓到测试没覆盖的整类错误 |
| 三、风格检查(lint) | 有没有明显写错、写歪的地方 | npm run lint | 便宜,且能拦住一类低级错误滑到评审环节 |
| 四、人工审阅 | 它要的是不是你要的东西 | 读 diff,只看改动,不重读整个文件 | 最贵,只在前三层都过了之后才值得做 |
前三层的具体命令形态:
# 第一层:测试。让 AI 跑,失败就让它读日志修,循环到全绿
npm test
# 如果失败:AI 读取错误日志并修复,重复直到所有测试通过
# 第二层:类型检查(TypeScript 项目)
npx tsc --noEmit
# 第三层:风格检查
npm run lint
# 第四层之前先看范围:只改了该改的地方吗?
git diff --stat
第四层人工审阅有个省力的技巧:只看 git diff,不要重读整个文件。你要回答的问题只有三个:它改了该改的地方吗?有没有夹带你没要的改动?边界情况处理了吗?
05.3 前三层都绿了还是有 bug:说明闸门漏了
这不是"验证没用",而是你的闸门没有覆盖到那条路径。两种补法,按优先级:
把出问题的那条路径写成测试,看着它变红,再让 AI 修到变绿。这样这个 bug 永远只能犯一次——这才叫"闸门加强"。
测试能防"代码不对",防不住"做的是另一件事"。后者要回到 03,在任务卡或规格里把验收标准写具体。
05.4 错误信息该怎么喂回去
这是新手最容易做错的一步。"它不工作了"对 AI 等于零信息,它只能猜,猜错你就更生气,然后进入死循环。
"这个页面有个 bug"
"它不工作了"
"还是不对"
症状:点提交按钮后页面白屏
报错原文:TypeError: Cannot read property 'id' of undefined
位置:src/utils/validate.js 第 12 行
期望行为:应该提示"邮箱格式不正确"并留在当前页
一个可以直接粘的排查句式:
这个页面点击提交按钮后报错:TypeError: Cannot read property 'id' of undefined(来自 src/utils/validate.js 第 12 行)。
期望行为:邮箱格式不对时应该提示错误并留在当前页。
请先排查根本原因,不要先加 try/catch 掩盖它。修完跑相关测试确认。
注意最后两句话:"先找根本原因"和"用测试确认"。少了它们,AI 最常见的反应是加一层错误捕获把报错藏起来——报错消失了,bug 还在。
05.5 调试 AI 代码的四种手法
| 手法 | 你要说的一句话 | 为什么有效 |
|---|---|---|
| 最小可复现 | "我把问题隔离到这几行了,你在这一小段里找原因" | 把整个项目塞过去,相关信号会被大量无关代码淹掉 |
| 逐行走一遍 | "逐行解释这个函数,每一步告诉我 X 的值是多少" | 让它的推理过程露出来,错的那一步就自己显形了 |
| 把错误原文喂回去 | "报错是:…… 位置在……" | 精确的错误信息是它定位问题最直接的线索 |
| 换一个立场审查 | "审查这段代码,找出你刚才漏掉的 bug 和边界情况" | 从"作者"换成"审查者",它会主动找茬而不是辩护 |
四句话都可以直接抄:
把整个项目塞过去之前,先帮我把问题隔离成最小的一段。
逐行解释这个函数的执行过程,每一步告诉我 X 的值。
报错原文是:[贴完整报错]。请从这个报错出发定位,不要猜。
现在换个身份:你是审查者。审查你刚才写的这段代码,找出 bug、边界情况和你自己的假设。
重要功能合并前,用一个新会话(或者第二个代理)来审阅第一个会话的产出。原因很实在:写代码的那个有确认偏差,会倾向于认为自己写对了;新会话没有这份感情投入,会真的挑刺。这就是"让另一个 AI 帮你 review"的全部意思。
05.6 重构为什么是最危险的一种改动
重构(refactoring——改变代码的内部结构,但不改变它的外部行为)是这套流程里最容易悄悄出事的一类任务:AI 会在"整理"的过程中顺手改掉一个行为,而测试没覆盖到那里,于是这个改动一路滑到线上。
一个可以直接照抄的四步做法:
# 1. 让 AI 先理解现有代码
解释 src/services/payment.js 的整体结构和数据流
# 2. 在 Plan Mode 下提出重构计划
把支付服务拆分为 3 个函数,提取错误处理,保持行为不变
# 3. 用测试做安全网
跑现有测试确保全部通过 → 重构 → 再跑测试
# 4. 逐文件验证
每改一个文件就确认一次,不一次性改所有文件
先让测试通过,再重构。如果没有测试,先写测试。没有测试的重构就像没有安全网的杂技——你可以做,但摔下来会很疼。
05.7 计划里最该看的不是步骤,是"风险"那一段
把 03.2 那份订单通知任务卡发给 AI,它读完文件后通常会回这么一份计划。注意最后那一条——那才是你真正要看的东西:
# AI 的计划(你审核这一步)
1. 在 src/orders/orderService.js 中添加 notifyUser 函数
2. 在 src/controllers/orderController.js 的 createOrder 中调用
3. 在 tests/order.test.js 中添加邮件发送的测试用例
风险:
- 修改了 orderController 的返回值格式,需要确认前端兼容
为什么风险那一段比三步计划更有价值:步骤只说明它打算动哪些文件,风险才说明它意识到哪里可能改坏。上面这条风险指向一个真实问题——接口返回值格式变了,调用它的前端页面会跟着坏,而项目里的测试很可能覆盖不到前端。看到这类提示,你的动作不是批准,而是先回答它:
关于返回值格式:请不要改现有的返回结构,只把邮件通知加在副作用里。
前端不在这个仓库里,改了格式我这边没法验证。
反过来,如果它给的计划里只有"1. 实现 2. 测试 3. 完成"这种空壳,没有任何具体文件名和风险,那说明它没真的读代码——退回计划模式,让它先读文件再出计划。
05.8 陷入"修了又坏"的死循环时怎么办
先认出一个信号:同一个报错反复出现、或者每修一处就冒出新的一处,而且已经超过两三轮。这时候继续调不是坚持,是沉没成本在推着你走。
AI:"修好了" → 测试失败 →"再改" → 又失败 → 再改 ……
每一轮都在改代码,没有人回头看方向是不是错的。
1. 停止当前代理
2. 问自己:方向对吗?方法本身有问题吗?
3. 回到规划阶段,重新审视需求定义
4. 方向确认后再重新开始
判断该退到哪一层,有一张简单的对照:
| 现象 | 退回哪一层 | 为什么 |
|---|---|---|
| 测试失败,但方向看着没错 | 退回执行 | 计划没问题,是代码没写对——继续修是合理的 |
| 同一类错误反复出现,修不完 | 退回规划 | 方法本身有问题,继续修只会越修越乱 |
| 修的过程中发现需求本身就不对 | 退回规划(改任务卡) | 这不是代码问题,验收标准要重写 |
| 你开始看不懂 AI 在改什么了 | 退回执行,缩小颗粒度 | 改动已经超出你能审阅的范围,先拆小 |
# 错误做法:反复让 AI 改
AI: "修复了" → 测试失败 → "再改" → 又失败 → 死循环
# 正确做法:停下来,回到规划阶段
1. 停止当前 agent
2. 问自己:方向对吗?方法本身有问题吗?
3. 回到规划阶段,重新审视需求定义
4. 修正方向后再重新开始
06沉淀:怎么让下一次不用从头解释
这是被跳过最多的一个阶段。多数人的循环是:提需求 → 写代码 → 测试 → 收工 → 下一个任务。缺的那一步是:把这次的教训变成下次自动生效的规则。结果是每次从零开始,同一个坑反复踩。
06.1 为什么这一步的收益最晚才看得见
因为它是唯一有复利的一步。任务本身只完成一次,而规则会在此后每一次会话里生效。第一天你可能觉得"写这一行有什么用",第三周你会发现 AI 第一次就把约定做对了——因为你已经不用再解释。
反过来说,如果你发现自己每天都在重复同一句纠正("不要用 toFixed,走 formatMoney"),那说明这就是一条该写进项目记忆的规则,而不是一句每天都要重说的话。
06.2 沉淀有三种强度,从轻到重
| 强度 | 什么时候用 | 怎么做 | 成本 |
|---|---|---|---|
| 加一条规则 | 犯了一次的错,说一句就能防住 | 往项目记忆文件加一行 | 1 分钟 |
| 加一条验证 | 同一类错误犯了两次以上 | 补一个测试用例,或加一条风格检查规则 | 10 分钟起 |
| 封成一个技能 | 这件事你已经反复让它做了三四次 | 把整套步骤写成可复用的技能文件 | 半小时起,但之后一句话触发 |
判断该用哪一种,问自己:"这件事会再发生吗?大概多久一次?"只发生一次的就别花半小时去封装,写一行规则就够了。
06.3 规则文件更新样例:照着这个格式写
每次任务完成后往里面追加的,就是几行"这个项目里的做法"。示例(一个邮件通知功能收尾时加的三行):
# 在 CLAUDE.md 中新增规则
## 邮件通知
- 使用已有的 EmailService,不要新建邮件客户端
- 发送失败时重试 2 次(指数退避)
- 测试必须验证邮件函数被调用过一次,不能只测"不报错"
再换一个场景,认证端点收尾时的规则:
# CLAUDE.md 新增规则
## 认证端点
- 必须使用 bcrypt 哈希密码,禁止明文存储
- 必须有输入校验(用项目里已有的 express-validator)
- 注册成功必须调用 EmailService 发送欢迎邮件
注意这些规则有三个共同特征,值得模仿:短(一行一条)、具体(点名文件和库)、可检查(能判断有没有违反)。(CLAUDE.md 是 Claude Code 认的文件名;别的工具认 AGENTS.md,见 02.2。)
06.4 第三种强度:把重复流程封成一句话
当你发现自己反复让 AI 做同一套动作("跑测试、修到全绿、把输出给我"),就该把它封成一个技能(skill)——一份写好的操作说明,放在工具约定的目录里,下次用一句话触发。
Claude Code 里技能落盘的形状是这样的:
# 技能目录:一个技能一个文件夹,里面一份 SKILL.md
.claude/skills/fix-tests/SKILL.md
# 建好之后,会话里用斜杠加名字触发
/fix-tests
# 旧的 .claude/commands/xxx.md 写法仍然有效,两者等价
.claude/commands/deploy.md
技能和项目记忆的分界线:偶尔才用到的整套流程适合做成技能(按需加载,不占每次会话的位置);每次都要遵守的约定适合放进项目记忆文件(每次自动加载)。官方文档给的一句判据很好用:当项目记忆文件里的某一段已经长成"一套流程"而不是"一条事实"时,把它挪去当技能。
06.5 收尾检查清单:五步,两分钟
这次哪里出了问题?是需求理解错了、代码写错了,还是环境配置不对?先分清是流程问题还是代码问题——前者改任务卡,后者加测试。
把对应的规则写进去。写之前先搜一遍有没有重复规则——重复规则会让文件膨胀,然后所有规则一起失效。
如果某类错误反复出现,说明靠"提醒"防不住,得靠"检查"防。补测试用例或风格检查规则,比再写一条规则更可靠。
这件事如果还会再来,把整套流程封成技能。判据是"你已经做过三次以上"。
不要把不相关的任务混在同一个会话里。开新会话;已经落进文件的部分可以放心忘掉。
06.6 复利效应到底长什么样
不用算公式,看这只飞轮就够——它把前面所有阶段串成了一个环:
任务完成 → 记录失败模式 → 更新项目记忆 → 创建/优化技能 → 下次任务更快更准
↑ |
└────────────────────────────────────────────────────────────────────┘
具体到你手上的变化:第一个任务你可能要写一份很长的任务卡来解释项目约定;第十个任务时,那部分内容已经在记忆文件里了,你的任务卡只需要写"这次要做什么"。省下来的是重复解释的时间。
还有一个更隐蔽的收益:你自己的判断力也在复利。你会在几周内摸清"哪类任务它一做就对、哪类任务它总要跑偏",然后自然地把流程强度调到合适的位置——这正是 10 那张表的用法。
07七个最常见的坑(附改法)
下面七个坑按"出现频率"排序,不是按"严重程度"。每一段的前半是这个坑长什么样,后半是可以直接照做的改法。
坑 1:跳过规划直接写码
现象:"帮我做个 XX"这种模糊指令,得到的是一堆需要返工的代码。改法:发出指令前,先花 5 分钟填 03.1 的五格任务卡。填不出"验证"那一格就别发——那是没想清楚的信号。
坑 2:信任 AI 的"done"声明
现象:它说完成了,你直接合并——没有验证门,等于把错误直接放进主干。改法:把"跑完把命令和输出原文贴给我"变成每次必带的一句。看输出,不看结论。
坑 3:一次给太多任务
现象:"帮我重构整个后端"——产出混乱、改动巨大,你审不动也不敢不回退。改法:拆到"能单独验证"的颗粒度。10 的对照表里验证层写"测试"的那种任务,就是合格的颗粒度参照。
坑 4:不提供错误上下文
现象:"它不工作了"——AI 只能猜,猜错你更急,两轮之后你就开始怀疑模型能力。改法:用 05.4 的四件套——症状 + 报错原文 + 位置 + 期望行为。四样缺一样,它的猜测空间就大一圈。
坑 5:一个会话做多件事
现象:前半段在改订单模块、后半段在改登录——两边的改动互相干扰,AI 开始把 A 任务的约定用到 B 任务上。改法:一个任务一个会话,做完就开新的。04.6 给了三种隔离开法。
坑 6:不沉淀,每次从零开始
现象:同一句纠正你说了一个月,AI 每次都犯。改法:说出第二次的时候就该写进文件了。06 给了三种沉淀强度。
坑 7:在测试为零的代码库上重度依赖 AI
现象:没有测试,AI 无法自证,你也无法验收,最终只能逐行读代码。这是七个坑里唯一一个"会伤到别人"的。改法:先给要改的那一小块补上测试,再让 AI 进场。不需要整个项目都有覆盖——从你这次要动的地方开始补就有效。
七个坑速查:现象 → 一条改法
| 坑 | 你会看到的现象 | 一条改法 | 修在哪一层 |
|---|---|---|---|
| 跳过规划 | 拿到的代码要重写 | 发指令前填五格任务卡 | 规划 |
| 信任 done | 线上出问题,回查发现没人验证 | 要求贴命令和输出原文 | 验证 |
| 任务太大 | diff 几百行,审不动 | 拆到能单独验证 | 执行 |
| 没给错误上下文 | 反复两轮还在猜 | 症状 + 报错原文 + 位置 + 期望 | 验证 |
| 一会话多任务 | 输出开始张冠李戴 | 一个任务一个会话 | 执行 |
| 不沉淀 | 同一句纠正说了一个月 | 第二次就把规则写进文件 | 沉淀 |
| 无测试还重度依赖 | 只能逐行人工读 | 先补这次要动的那块的测试 | 前置 |
08完整例子:给一个商城加注册邮件通知
上面所有原则,在这一节跑一遍完整链路:一个真实的 Node.js + Express 项目,要加一个"用户注册后发欢迎邮件"的接口。每一段提示词都可以改改就用。
第 0 步:开工前(2 分钟)
确认验证命令现在是绿的,并留一个还原点:
git add -A && git commit -m "feature: 注册邮件通知 开工前检查点"
npm test # 确认现在是全绿的——不绿就先别开工
第 1 步:规划(5 分钟)——第一句话就是任务卡
在计划模式下输入(注意五格齐全、且带"不要做的"):
为现有的电商系统添加用户注册邮件通知端点。
需求:
- POST /api/register 接收 username, email, password
- 使用 bcrypt 哈希密码
- 调用已有的 EmailService.sendWelcomeEmail()
- 返回 201 + { userId, email }
- 密码最低 8 位,含特殊字符
不要做的:
- 不要修改数据库 schema
- 不要引入新的依赖
- 不要修改现有的 /api/login 端点
验证:npm test 且所有测试通过
它会先读文件、再给一份计划。计划大概长这样,你要审的就是那三行和一个"风险":
# AI 的计划(你审核这一步)
1. 在 src/routes/auth.js 中创建注册端点
2. 在 tests/auth.test.js 中添加测试用例
3. 运行 npm test 验证
风险:
- 新增端点会共用 validate 中间件,需要确认它不会被改动影响 /api/login
看到一个具体的风险提示,通常说明它真的读了代码;如果计划只有"1. 实现 2. 测试 3. 完成"这种空壳,退回去让它先读文件。
第 2 步:执行(15 分钟)——分三步,每步都能单独验证
批准计划后,明确要求分步、一步一步来:
按计划分步做,每做完一步停下来告诉我改了什么。
步骤 1:在 src/routes/auth.js 中创建注册端点
步骤 2:在 tests/auth.test.js 中添加测试用例
步骤 3:运行 npm test 验证
底层要遵守的纪律(04):单次改动别超过 200 行;上下文只给相关文件;每步跑一次验证。
第 3 步:验证(5 分钟)——它自己发现了一个失败
它跑测试,发现密码校验那一步有问题(只校验了长度、漏了特殊字符),读报错、修复、重跑,最后全绿。这一步的价值恰恰在于失败是它自己撞上的——如果它没跑测试,这个漏掉的校验就会直接进你的 diff。
✓ 3 tests passing
✓ lint clean
✓ tsc --noEmit passes
你要的那句话在这里:"把命令和输出原文贴出来"。上面那三行是它的证据,不是它的结论。
第 4 步:人工审阅(3 分钟)——只看 diff
git diff --stat
git diff src/routes/auth.js
只回答三个问题:只改了该改的文件吗?有没有夹带 /api/login 的改动?密码校验和错误返回符合预期吗?
第 5 步:沉淀(2 分钟)
# CLAUDE.md 新增规则
## 认证端点
- 必须使用 bcrypt 哈希密码,禁止明文存储
- 必须有输入校验(用已有的 express-validator)
- 注册成功必须调用 EmailService 发送欢迎邮件
注意这条规则是怎么长出来的:失败模式(漏了特殊字符校验)→ 一条规则(必须有输入校验)→ 下次自动生效。这就是整个循环的复利来源。
整条链路的时间账
| 阶段 | 花的时间 | 这一段买到了什么 | 省掉的话会怎样 |
|---|---|---|---|
| 开工前检查点 | 2 分钟 | 随时能一步回退 | 改坏了要手工挑回来 |
| 规划(任务卡 + 计划) | 5 分钟 | 它不会去改数据库 schema | 最典型的一次全量返工 |
| 执行(分三步) | 15 分钟 | 每步都能单独看、单独退 | 拿到一大坨看不懂的 diff |
| 验证(跑测试 + 看输出) | 5 分钟 | 密码校验漏了一个条件被提前发现 | 这个 bug 留到线上 |
| 人工审阅 diff | 3 分钟 | 确认没夹带无关改动 | 合并了一个"顺手"的重构 |
| 沉淀 | 2 分钟 | 下个端点不用再解释这三条 | 同一句话下个月还要再说一遍 |
不要把它当成"总用时 32 分钟"的承诺——真实任务会卡壳、会返工,时间不会是这么整齐的加法。它真正想说明的是:这段时间里有一大半花在"防止返工"上,而返工一次的代价通常是小时级。你买的不是速度,是确定性。
09排错:四种卡住的情况,怎么解
下面四种是实际用起来最常撞上的。它们的共同点是:看起来都像"AI 不行",实际都不是。
情况一:它说完成了,但我觉得不对
先别重读代码。按顺序问三句,通常第二句就能定位:
如果它没有真的运行,或者贴出来的是摘要——这就是问题本身,先让它跑。
对不上的那一条,就是它理解错的地方,比你自己翻 diff 快得多。
git diff --stat 给我看。"改动范围一旦超出你的预期,问题就不是"对不对",而是"它做了别的事"。
情况二:它一直在同一处绕圈
这属于 05.8 的死循环。这里补一条具体操作:把"停止"当成一个正规动作,而不是失败。停下来的做法是三件事——停止代理、把当前 git diff 存成一份补丁文件(万一里面有值得留的片段)、然后用一个新会话重述任务。
为什么换会话有效:旧会话里积了一堆错误尝试和错误结论,它们会持续影响它的判断。新会话只拿着"任务卡 + 现在代码的真实状态",比在污染过的上下文里继续纠缠干净得多。
情况三:测试一直是红的,但它说已经修好了
这几乎总是三件事之一:
| 真实原因 | 怎么确认 | 怎么解 |
|---|---|---|
| 它跑的不是你以为的那条命令 | 让它贴出完整命令行(不是"测试通过"四个字) | 把确切命令写进任务卡的"验证方式"那一格 |
| 它跑了,但只跑了相关的那一个测试文件 | 看输出里的用例数量,和全量对不上 | 明确要求"跑全套,不是单文件" |
| 它改的是测试,不是代码 | git diff tests/ 看断言有没有被放宽 | 这就是"改测试让它变绿",一旦发现必须回退,并把"不许修改现有断言"写进不要做的 |
把断言删掉、把期望值改小、给测试加 skip——都能让红色变绿,但那是把报警器拆了,不是把火灭了。养成习惯:每次验收都单独看一眼测试文件的 diff。
情况四:环境问题它搞不定,反复重试
表现是"同样的报错、不同的尝试、每次都不对"。典型的环境类问题有:依赖没装、运行时版本不对、端口被占、环境变量没配。这类问题你比它强——因为你手上有它没有的信息(比如你十分钟前刚在别的终端占用了那个端口)。
处理方式:把这类东西从"让它自己摸索"改成"写进项目记忆"。比如:
# CLAUDE.md 里加一节,专治环境类反复重试
## 开发环境
- 本机 Node 版本:见 .nvmrc,开工前先 nvm use
- 测试需要本地 Postgres,启动命令:docker compose up -d db
- 3000 端口常被占用,开发服务固定用 3001
# 以及一条给它的行为指令
- 遇到"端口占用""模块找不到"这类环境报错,不要反复重试,
直接把命令和报错贴给我,由我来处理环境。
四种情况的速查
| 你看到的 | 别做 | 先做这个 | 根治 |
|---|---|---|---|
| 它说完成但你不信 | 自己重读全部代码 | 要命令 + 输出原文 | 把验证命令写进任务卡 |
| 同一处绕圈 | 继续让它改 | 停下来,换新会话 | 退回规划重审需求 |
| 测试红但它说好了 | 相信它的描述 | 看完整命令和用例数 | 单独审测试文件的 diff |
| 环境问题反复重试 | 让它继续摸索 | 你来处理环境 | 把环境信息写进项目记忆 |
10到底什么任务用什么闸:一张决策表
这套流程最常见的误用是对什么都上全套——那会让你觉得它慢、麻烦、不值得。正确的用法是按风险配闸门。这张表是本篇最该存下来的一份东西。
按任务类型配闸门
| 任务类型 | 计划模式 | 验证层 | 沉淀 | 人工审阅重点 |
|---|---|---|---|---|
| 改文案 / 变量名 / 加日志 | 不用 | 无 | 不用 | 不需要 |
| 单个函数的小修小改 | 不用 | 跑相关的那一个测试文件 | 遇到坑才记 | 只看这一处 diff |
| 新功能(涉及 1–2 个文件) | 建议开 | 测试 + 类型检查 | 有新约定就记 | 边界情况处理了没有 |
| 新功能(涉及 3 个以上文件) | 必须开 | 测试 + 类型 + 风格 + 人工 | 记规则 | 有没有夹带无关改动 |
| Bug 修复 | 看情况 | 先写一条会失败的测试,再修到绿 | 把这个 bug 写成测试 | 是不是只修了症状没修根因 |
| 重构 | 必须开 | 改前先全绿,改后再全绿 | 记规则 | 行为有没有被悄悄改掉 |
| 数据库迁移 / 删除数据 / 改鉴权 | 必须开,且逐字读计划 | 能做的全上 + 人工逐行 | 必须记 | 回退方案是什么 |
| 一次性原型 / 探索 | 不用 | 无 | 记结论,不记规则 | 不需要——但别合并 |
按你自己的处境选路线
| 你的状态 | 先练什么 | 预计多久上手 | 最容易卡在哪 |
|---|---|---|---|
| 刚开始用 AI 写代码 | 先把"任务卡五格"练成习惯 | 几天 | 忍不住想直接说"帮我写个 XX" |
| 已经会用,但质量不稳 | 加验证层:每次都要命令和输出 | 一周内见效 | 嫌麻烦,中途放弃要证据 |
| 已经稳定,但重复劳动多 | 沉淀:项目记忆 + 技能 | 两到三周见效 | 把记忆文件写成文档仓库,越写越长 |
| 要带团队用 | 先把"验证命令"和"记忆文件"变成仓库里的公共约定 | 按团队规模 | 每个人的 AI 用法不一致,规则各写各的 |
如果这张表你只记得住一行,记这个:改动会碰 3 个以上文件,或者改坏了很难撤回——就开计划模式,并且要求它给命令和输出原文。其他所有格子都是这两条的细化。
11一页纸:下次开工照着念
这一节是给你贴在手边用的,不是给你读的。它把全文压成四组可打勾的条目。
整份清单:四组,十六格
# 开工前(每 2 分钟)
[ ] 我有一条能跑、而且现在是绿的验证命令
[ ] 工作区已提交,能一步回退
[ ] 这次的任务能用一句不含形容词的话说清
[ ] 如果涉及 3 个以上文件或不可逆操作 → 我准备开计划模式
# 发指令时(照着填五格)
[ ] 任务:一句话,没有"更好/优化/完善"
[ ] 背景:技术栈 + 点名相关文件(并说明为什么读它们)
[ ] 要做的:编号,每步都能单独验证
[ ] 不要做的:至少一条真在意的边界
[ ] 验证 + 完成标准:确切命令 + 确切行为
# 验收时(不顺就回退,不要硬调)
[ ] 它贴了完整命令和输出原文(不是"已完成")
[ ] 我看的是 git diff,不是重读整个文件
[ ] 我单独看了测试文件的 diff(断言有没有被放宽)
[ ] 出错的那条路径 → 我补了一条会失败的测试
# 收尾时(2 分钟,收益在下一周)
[ ] 这次犯的错 → 写成一条项目记忆规则(一行,具体,可检查)
[ ] 反复出现的错 → 补测试或风格检查规则,别只写提醒
[ ] 做过三次以上的流程 → 考虑封成技能
[ ] 清空上下文,再开下一个任务
红线(违反这几条,上面所有努力都会打折)
| 红线 | 为什么是红线 | 替代动作 |
|---|---|---|
| 用"它说完成了"代替验证 | 它无法区分"通过了"和"应该会通过" | 要命令 + 输出原文 |
| 让它改测试来变绿 | 拆报警器不等于灭火 | 回退测试改动,从代码侧修 |
| 在没有测试的代码上大改 | 没有客观信号,双方都在猜 | 先补这次要动的那块的测试 |
| 让记忆文件无限增长 | 太长会让关键规则被忽略 | 删到 200 行以内,长的流程挪去技能 |
| 在同一个会话里混做不相关的任务 | 上下文污染,输出质量下滑 | 一个任务一个会话 |
12术语对照表
这些词会在你读工具文档、和同事讨论时反复出现。第三列是它为什么重要、什么时候用、以及最容易把它当成什么——只看前两列是不够的。
| 术语 | 定义 | 为什么重要 / 何时用 · 别当什么用 |
|---|---|---|
| AI 编程代理(agent) | 能自己读文件、改文件、运行命令来完成编程任务的 AI 程序,不只是聊天窗口里给建议 | 为什么重要:它"能动文件"正是这套流程必须加验证闸门的原因——它会真的改坏东西。别当什么用:不是更聪明的补全工具,它的行为是一串动作,要看过程也要看结果。 |
| 计划模式(Plan Mode) | 工具的只读状态:AI 只能读文件和写计划,不能改代码,直到你批准 | 何时用:涉及 3 个以上文件,或改动不可逆时。别当什么用:不是所有任务都要开——一句话能说清 diff 的改动,开了只是多一次往返。 |
| 任务卡 | 一份五格的短说明:做什么 / 不做什么 / 约束 / 验证 / 完成标准 | 为什么重要:它是本文成本最低、见效最快的一件东西,五格缺哪格就补哪类返工。别当什么用:不是设计文档,一屏以内;写长了反而没人看。 |
| 规格(spec) | 一份一页纸的说明文档,写清用户故事、验收标准、边界情况和排除的范围 | 何时用:改动跨会话、跨人时——口头共识会丢,文件不会。别当什么用:不是详细设计,不要把实现细节写进去;它回答"要什么",不回答"怎么写"。 |
| 规格驱动开发(SDD) | 先写规格,再让 AI 从规格派生出计划和代码;代码是产物,规格是源头 | 为什么重要:它把"唯一真相源"从代码挪到了人写得清的文档上,评审和验收都有共同依据。别当什么用:不是"先写文档再写代码"的瀑布流程——规格是活的,发现不对就改。 |
| 验证门(verification gate) | AI 的产出被接受之前必须通过的自动化检查:测试、类型检查、风格检查 | 为什么重要:它是这套流程里唯一不依赖"相信谁"的信号,是防错误进主干的最后一道。别当什么用:不是"AI 说好了就行"——没有退出码的检查不算检查。 |
| 项目记忆文件 | AI 每次会话开始自动读的一份短说明,装项目约定、构建命令、已知陷阱(Claude Code 里叫 CLAUDE.md,跨工具约定是 AGENTS.md) | 何时用:任何时候,只要你在重复解释同一件事。别当什么用:不是文档仓库——官方建议控制在 200 行以内,太长会让关键规则被忽略。 |
| 技能(skill) | 一份可复用的操作说明文件,把反复执行的整套流程封装成一句话触发 | 何时用:你已经反复做同一套动作三次以上。别当什么用:不是替代思考——它加速的是确定性的流程,不是判断。 |
| 上下文(context) | AI 这一次能看到的全部信息:项目记忆 + 任务说明 + 你当场给的材料 | 为什么重要:它的质量直接决定输出质量——给什么比给多少重要。别当什么用:不是越多越好;无关内容会稀释信号,让它抓错重点。 |
| 上下文工程 | 主动设计"给 AI 看什么、按什么顺序看、说清为什么看"的做法 | 何时用:任务一大就见效——点名文件并说明用途,比把整个仓库塞过去好得多。别当什么用:不是把仓库打包上传,那是把信号埋进噪音。 |
| 子代理(subagent) | 在独立上下文里运行的代理,有自己的工具权限 | 何时用:调研、大范围翻文件这类"会产生很多噪音"的活。别当什么用:不是"更快的主代理",它是用来隔离噪音的工作间。 |
| 氛围编程(vibe coding) | 凭感觉不断提要求、看着结果像样就收的做法 | 何时用:一次性原型、自己不打算维护的小脚本。别当什么用:不要用在要进主干的代码上——它没有完成标准和验证闸门,质量靠运气。 |
13常见问题
下面这些问题都是"读者真会问的",不是用来凑章节的。答案尽量给判断依据,而不是给立场。
/doctor,它会指出哪些内容是可以从代码库里推出来的、该删。npm test。写文档的验证是"事实核对 + 找人读一遍能不能懂";做设计的验证是"给人看、看他们会不会用错"。关键不是照搬命令,是每类工作都要找到那个不依赖"相信谁"的信号。99一句话总结
AI 编程工作流的本质是把"做完了没有"变成一条能跑的命令:你先说清要什么(规划),让它小步地做(执行),然后看证据而不是看它的承诺(验证),最后把这次的教训写成下次自动生效的规则(沉淀)。它不让你写得更快,它让你不用重写——而判断该不该用它,只看两个量:改动碰几个文件,改坏了能不能撤回。
如果只能带走一件事:下次它说"完成了"的时候,回一句"把命令和输出原文贴给我"。这一句话的收益,比这篇文章里其他所有内容加起来都大。
98参考来源与证据边界
这是一篇"做法型"文章,所以它的事实成分主要是工具的确切行为(按哪个键、文件叫什么名字、有没有大小限制)。下面这些是我逐一取回原文核对过的,没有一条是凭记忆写的。
一手来源(逐条取原文核对)
- Claude Code 官方最佳实践(code.claude.com/docs/en/best-practices)——四阶段工作流的官方表述(Explore → Plan → Implement → Commit)、进入计划模式的确切操作(按
Shift+Tab到状态栏显示⏸ plan mode on,或claude --permission-mode plan)、Ctrl+G打开计划编辑、以及"能一句话描述 diff 就跳过计划"这条判据。本文 03.4 里的提示词示例取自这一页。 - Claude Code 官方记忆文档(code.claude.com/docs/en/memory)——
CLAUDE.md每个会话加载、目标 200 行以内、/init与/context的用途、@AGENTS.md导入写法与ln -s软链接做法,以及一句关键澄清:Claude Code 读的是CLAUDE.md,不是AGENTS.md。02 与 03.6 的取舍清单同样来自这里。 - Claude Code 技能文档(code.claude.com/docs/en/slash-commands)——技能的落盘形状(
.claude/skills/<名字>/SKILL.md)、用/名字触发、以及"旧的.claude/commands/xxx.md写法仍然有效、两者等价"。 - Codex CLI 的 AGENTS.md 官方文档(developers.openai.com/codex/guides/agents-md)——发现顺序(全局
~/.codex/AGENTS.md,项目从根目录往下走、遇到第一个就停)、逐层合并、AGENTS.override.md的优先级、以及默认 32 KiB 的合并上限。 - AGENTS.md 跨工具约定(agents.md)——把
AGENTS.md作为通用文件名的那份约定,是"不同工具认不同文件名"这一节的依据。 - Codex CLI 官方仓库 README(github.com/openai/codex)——它的定位是"在你自己电脑上本地运行的编程代理",以及安装方式(
curl -fsSL https://chatgpt.com/codex/install.sh | sh、npm install -g @openai/codex、brew install --cask codex)。 - OpenCode README(github.com/anomalyco/opencode)——"开源的 AI 编程代理"定位,与本文 01.3"流程跨工具"的论述一致。
- Pi Coding Agent README(pi.dev)——一句值得注意的对照:Pi 刻意不做子代理与计划模式,把"要不要这套流程"完全交给你通过扩展自己装。这说明本文这套流程是一种做法,不是一个工具的必备功能。
行业实践类来源(用于交叉印证做法,不作为工具行为的事实依据)
- Addy Osmani — My LLM Coding Workflow Going Into 2026(medium.com/@addyosmani)——"把项目拆成迭代步骤、一次实现一个""每次任务后问自己哪里出了问题,把新规则加到项目记忆或技能里"。
- Andrew Crookston — AI Coding Field Guide(andrewcrookston.com)——Scope → Plan → Execute → Verify → Wrap-up 五步分法、"不要把不相关的事混在同一个会话"、反馈循环表(测试失败退回执行、死循环退回规划)。
- Mehul Jain — AI Coding Agents Implementation Guide(jainmehul.com)——"验证门是核心"、以及"没有测试的代码库上重度依赖代理是风险最高的组合"这一判断。
- Jyme News — Prompt Engineering for Coding Tasks(jyme.io)——"显式说明为什么要读这个文件,比把整个仓库塞给 AI 效果好得多",本文 04.4 的写法依据。
- Levelop — Spec-Driven Development 指南(levelop.dev)——SDD 的五步循环与"spec 是唯一真相源"的表述。
- DeepLearning.AI — The AI Engineering Skills Map(deeplearning.ai)——"最有价值的不是模型本身,而是工作流"这一判断的出处。
本文自己做的核对
- 工具行为逐条取原文:本文所有"按哪个键""文件叫什么名字""有没有大小限制""命令怎么写"都来自上面列出的官方页面原文,没有一条来自转述或记忆。凡是官方页面里没有的,本文一律不写具体键位。
- 旧版做法的修正:旧版说 Claude Code 的 Plan Mode 是"按
Shift+Tab两次"。本次核对官方文档,当前表述是按到状态栏出现⏸ plan mode on为止,并且多给了claude --permission-mode plan这条启动参数。所以本文改成"按到状态栏显示为止",不再写"两次"。 - 旧版一处前提的修正:旧版把
CLAUDE.md / AGENTS.md当作同一回事。核对官方记忆文档后确认:Claude Code 只读CLAUDE.md,仓库里的AGENTS.md需要导入或软链接才会被读到。这一点对"规则写了却不生效"的读者很关键,所以 02 单独讲了。
证据边界与时效
- 模型与界面在变。本文标了
learn:shelf-life=evolving:流程骨架(说清要什么 → 小步做 → 看证据 → 沉淀)不会过时,但具体键位、文件名、大小限制会随版本变化。看到与你的界面不符的地方,以你所用工具的官方文档为准。 - 没有做的事。我没有实际安装并跑完上面每一个工具;没有验证各家工具在具体版本上的界面细节;旧版里引用的一些具体数字(如"3x 速度提升""80% 首次通过率""10x 调试时间减少")我无法在任何一手来源中找到对应出处,因此本次没有保留——这类数字如果不能指出原始研究,就不该出现在教程里当事实用。
- 一处口径提醒。"3 个文件以上就该开计划模式"是官方文档给的经验判据,不是硬阈值。真正的判据是那两个量:改动范围和可逆性;文件数只是范围的一个方便代理指标。
最后一句:这篇文章是做法,不是规范。你的项目、你的团队约定、你手上的验证手段,都比这里的任何一条更该被优先遵守。