# [Project] 10. 我的 vibe coding 最佳实践: 一句话到代码


了解我的人都知道，我一直专注于怎么让 AI 去更好地维护需求、开发功能。这套流程，是最近这一轮实践里沉淀出来的最佳实践。

这两年我用 AI 写了不少东西，从一行脚本到整套系统。踩过的坑多了之后，我总结出一条自己真正信得过的路子：**别让 AI 直接写代码，先让它把需求"翻译"成一份几万字的设计文档，人读完、盲审通过，再动代码**。听着绕，实际上快得多。

先交代一下"vibe code"这个词：就是近年来流行的、用自然语言跟 AI 对话来写代码的做法——你给一句需求，AI 帮你把代码写出来。这套流程本质上是 vibe code 的一种，只不过比"一句话换一千行代码"多走了几步，让 AI 先理解、再动手。下面不熟悉 vibe coding 的读者，把这当成"让 AI 写代码"就行。

这篇文章就把这套流程完整拆开讲。我不会教你怎么像念咒语一样拼 prompt——那是术。我讲的是为什么一句话需求直接甩给 AI 总是崩、为什么非要绕一大圈先写文档、每一步人该怎么和 AI 交互。唯一讲"术"的是最后写代码那一节的模型选型——那是个例外，因为它直接决定成败，我放到后面单独说。

这套流程的直接可用版本，是 goody-hao 推荐的 AI skill，放在 [pi-desktop 的 skills 目录](https://github.com/GOODDAYDAY/pi-desktop/tree/main/src/plugins/system/goody-hao/skills)。先说明：这段只是给出可落地的成品，你只想读方法论的话，完全可以跳过它，不影响后面任何理解。解释一下三个名字：AI skill 是"能直接喂给 AI 工具、让 AI 自动按流程干活"的打包指令；goody-hao 是维护这套 skill 的一个 AI 助手；pi-desktop 是托管它的一个桌面工具项目。目录里的 `write-design-doc` 就是本文的方法论本体，`arch-to-code` 是它延伸到"架构文档 → 完整代码"的配套流程。把目录下的文件放进你本地 AI 工具约定的 skills 目录（各家 AI 工具路径不同，按它的说明放即可）就能触发。下面讲的是这套 skill 背后完整的设计思路。

开头先给一张全流程图，后面每一段都贴着它讲。图里的每个词（标题、简述、盲审）都会在正文里展开解释，现在只需要先有个整体印象。

<img src="/images/mermaid/vibe-zh-1.svg" alt="diagram" style="max-width:100%;">

**图 1 — 全流程：一句话需求到代码，中间的每一级都是人-AI 对齐的检查点**

你可能会问：中间隔了三万字，这也叫 vibe code？叫。vibe code 的本质不是"少写字、快出活"，而是人用自然语言驱动 AI 干活。我这条路子是把该花的对齐时间前置了——前期慢，后期不再返工。这个账下面算给你看。

## 一句话需求直接写代码，为什么总是崩

先还原最常见的翻车现场。你给 AI 一句"帮我写个工单系统"，它哗啦啦吐出一千行代码，页面有了、数据库表建了、接口调通了。你打开一看——不是你要的东西。缺了状态流转，多了个没人要的通知，字段命名和你团队习惯完全不符。然后你开始"改 prompt 循环"：这里不对，改一下；那里也不对，再改一下。改到第十轮，AI 开始把前面改好的地方改坏。你火气上来了，它开始道歉，然后给你重写一版，把第一版能用的功能也弄丢了。

这是最典型的 vibe code 死亡螺旋，几乎每个人都经历过。问题出在哪儿？

不是 AI 笨。是**你给的输入太薄，而 AI 的产出太厚**。一句话到一千行代码，中间隔着成千上万个你没有说出口的决策：状态怎么流转、谁有权限、数据存哪、异常怎么办、UI 长什么样。你脑子里的"工单系统"是一个完整的、充满默认值的图景，而你说出口的只有五个字。AI 只能猜，猜错是必然，猜对是运气。

<img src="/images/mermaid/vibe-zh-2.svg" alt="diagram" style="max-width:100%;">

**图 2 — 一句话到代码：信息被压扁，再被猜开。差异在这条链上必然产生**

这里有个关键认知：**你和 AI 的理解差（diff）是躲不掉的**。不管 prompt 写得多么好、上下文塞得多么满，只要存在"压缩-猜测"这一步，diff 就存在。所以问题的关键不是"怎么消灭 diff"，而是**让 diff 在一个便宜的地方暴露出来**。

代码是最贵的地方。等代码写完了你才发现理解偏了，意味着推倒重写、返工、测试重跑。改代码层的 diff，一次要花几小时到几天。而文本层便宜得多——文档里一段话理解偏了，改几个字就回来，成本是秒级。

<img src="/images/mermaid/vibe-zh-3.svg" alt="diagram" style="max-width:100%;">

**图 3 — diff 在文本层暴露 vs 在代码层爆发，成本差两个数量级**

所以我的结论是：vibe code 要玩得转，得先学会"不写代码"。把该对齐的东西，全部前置到文本层解决。

## vibe code 的成败在于理解对齐

把话说透一点：AI 写代码的本质，不是"执行指令"，而是"理解需求，然后自己把需求翻译成代码"。翻译的前提是理解，理解必然走样——因为你的意图是一团没有完全显性化的图景，AI 只能从你有限的表达里重建它。

这听起来像哲学，但它有一条非常实用的推论，我管它叫 **diff 定律**：

> 你脑子里的方案和 AI 重建出来的方案之间的差异，必然存在，且只会迟到，不会缺席。你要做的，是在它便宜的时候抓住它，而不是等它变成昂贵的 bug。

怎么抓？让 AI 在**每一个层级**都向你复述一次它的理解，你逐层对比、修正。这就是"一句话需求 → 标题 → 简述 → 完整文档"这条链的全部意义——它不是仪式感，而是一排**对齐检查点**，每一级都逼 AI 把当前理解摊开给你看，你则负责在每一级都认真检查，发现偏了立刻纠。

<img src="/images/mermaid/vibe-zh-4.svg" alt="diagram" style="max-width:100%;">

**图 4 — 逐步扩展的本质：每一级都是一次"AI 复述 → 人核对 → 人扩展"的循环**

图里"修正+扩展"的意思是每个循环里人要做的两件事：**修正**是把 AI 这级输出里理解偏的部分纠过来，**扩展**是在它基础上补充你没有说过的新想法——两个动作同一次做，AI 带着修正和补充继续往下展开。它对应的是你写文档时最常干的活：既在改 AI 说错的，又在加你自己刚想到的。

这里有个反直觉但很重要的点：**每一级的 diff 都要查，但它们防的不是同一种错**。早期的 diff 查的是方向——一句话和标题层面的理解差，修正了 AI 可能还会再偏一点，但它用一次三十秒的代价，挡住了"整个方向搞错"这种灾难。晚期的 diff 查的是细节——到了万字文档层面，AI 已经把每个决策显性化，你的每一次修正都落在实处、不会再漂，但代价也贵了。所以两头的检查都不能省：早的便宜，挡大错；晚的精确，兜细节。前面欠的对齐债，后面要用十倍利息还。

## 流程全景：六步，每一步都是检查点

整条链子串起来是这样：一句话需求 → 标题 → 简述 → 万字级完整文档 → 盲审 → 代码。下面每步的产出物和检查点列一张图，后面逐节拆。

<img src="/images/mermaid/vibe-zh-5.svg" alt="diagram" style="max-width:100%;">

**图 5 — 六步全景：前五步在文本层完成对齐，代码层只剩翻译**

你看出来了吗，前五步的产出物全部是"人读的东西"，只有最后一步是"机器跑的东西"。设计阶段完成时，整个方案已经不需要再"想"了——所有决策都在文档里，写代码只是照着翻译。这正好呼应一句话：**设计文档是给人读的论证，不是给系统填的字段**。

为什么必须逐步扩展，而不是一口气让 AI 写三万字？三个原因。（提前说明：这里讲的是"为什么不要一口气写"，不是说每一步都机械地走；具体到实践，起标题、写简述这些产出形式可以按项目合并跳过，见 4.1 和 9.3——但那是在方向已经确认的前提下。）

1. **避免自作主张铺细节**：一口气让 AI 写长文档，它会在你还没定方向的地方自作主张铺一堆细节，然后那些细节会变成后面推倒重来的成本。逐步扩展保证了每一步都建立在上一步你确认过的地基上。
2. **训练对 diff 的敏感度**：你从一句话开始，每一级都认真比对，慢慢地你会练出一种手感——哪里 AI 理解偏了、哪里它在滑过去、哪里它在替你拍板。这种手感，是一口气写长文永远练不出来的。
3. **迁就人的阅读速度**：人的阅读速度和消化速度是有限的。一口气拿到三万字，你大概率读不完，或者读完就忘了前面——你根本没有足够的脑力在每一个决策上都和 AI 对齐。但一截一截地给，每给一截你都有时间读透、想清楚、再确认，这本身就构成了"你慢慢梳理需求"的过程。文档写到第几节，你对需求的认知就清晰到第几层；这一步一步走完，需求也就被你想透了。**这不是 AI 在帮你，是你借 AI 的产出，把自己的需求一点点想明白。**

## 把"解决什么问题"钉死

很多人上来就写文档，但前三步被当成废话跳过了。其实最值钱的对齐就发生在这三步——因为这时候文档还是空的，你还没被"已有的文字"带偏，你的意图最干净。

### 一句话需求：起点是意图，不是指令

开工第一句话，别写"帮我写一个 XX 系统"这种指令式的话。先想清楚：你**为什么**要这个东西？它解决什么问题？给谁用？

这不是故弄玄虚。因为 AI 从"为什么"能推出的东西，远比从"做什么"多。"做一个工单系统"和"让客服不用在 Excel 里记工单"是两句话，后者让 AI 自己就能补出大量合理的设计决策，前者让 AI 只能瞎猜。

我一般会多说三样：背景（现在是怎么做的、痛在哪）、目标（做完之后什么样算成了）、边界（哪些明确不做）。这三样加起来，通常也就百来个字。举个例子，我最近一个需求是这样开的头：

> 团队现在用 Excel 记工单，客服每人一份，合并全靠手工，经常漏单。（背景）我想做一个内部工单系统：客服能建单、流转状态、跟进备注，主管能看统计。（目标）第一版不做权限体系，全员可见；不做消息通知，先人工通知。（边界）

这段只有一百多个字，但它已经把"为什么做、做什么、第一版做到哪为止"三件事全交代了。AI 基于它能推出：要有工单对象和状态字段、要有列表和详情页、要有备注时间线、要有简单的统计视图。它推出来的这些默认决策，就是你接下来要逐条核对的对象。

不过以上说的是理想形态，实际操作里我会更随意一点。我一般会先跟 AI 聊一下这个功能本身——让它先装载一些相关领域的上下文（就是把背景、类似项目、相关约定讲给它听），然后再聊我自己的想法，聊到彼此都明白为止。到这时候往往不用再按部就班走那三步，直接从一句话进到"起标题"就行了。这条链上的每一步是检查点，但具体在哪几步多停、哪几步跳过，按项目灵活来，别被流程绑死——保住的只是"每一级都对齐"这个精神。注意区分：可以跳过的是"起标题、写简述"这些产出步骤的先后和取舍，但**每一级产出之后的"认真核对"这个动作，永远不能跳**——那是这条链的命根子（后面 9.3 会再强调）。

说清楚"跳过产出形式"到底是什么意思，免得误导：它不是说你不核对、直接冲去写文档，而是说"标题、简述"这两级**可以合并甚至略去独立的产出物**——比如你跟 AI 聊着聊着，方向已经确认了，就直接让它开始逐节写文档，不再单独产出"标题"和"简述"两个中间文件。但即便合并了，你依然要对着 AI 每节产出的内容认真核对、看出 diff 就纠。跳的是"多一级中间文件"，不是"核对这个动作"。

### 标题：逼 AI 复述你的意图

第一步做完，让 AI 根据你这点描述，**先起个标题**。

标题是一句话的概括，它天然逼着 AI 把"它理解的你要的东西"压缩成一个判断。你一看标题就知道它理解偏没偏——偏了，立刻纠，成本为零；没偏，说明方向对了，可以放心往下走。

顺带一提，标题还能看出另一件事：**AI 有没有关注到你关注的重点**。你的需求里最在意的那一点，它有没有在标题里体现出来？比如你要的是"不丢单、流转不错"，它给个"工单协作平台"这种四平八稳的标题，就说明它没抓住你真正的心头好——这个偏，和"理解偏了"一样值得当场纠。

这一步千万别嫌小。它是第一个真正的对齐点，而且因为它小，你几乎不会偷懒跳过核对。这个"每一级都认真看"的习惯，就是从这里养起来的。

实际操作时，我拿到标题会做一件事：把标题在心里翻译回需求，看两头对得上对不上。AI 给我的标题如果是"内部工单协作平台"，我预期它理解成了"协作平台"，重点在多人协作；如果我要的其实是"工单记录与跟进"，那这俩就不是一回事——我要当场纠，而不是将就着往下走。

### 简述：提炼核心机制

标题确认后，让 AI 写一段简述——用几百字说清楚这个系统最核心的机制是什么。

这一步的价值在于：**它逼你回答"这个系统的心脏是哪一块"**。很多需求你嘴上说要，但你从没认真想过它真正的核心机制是什么。AI 写简述时如果抓错重点，你一眼就能看出来，然后你被迫去回答"那核心到底该是什么"——这个被迫想清楚的过程，本身就在消灭你最贵的那类 diff：**你连自己要什么都还没想清楚**。

还是工单那个例子。AI 写的简述如果重点放在"统计报表多好看"，而你要的核心其实是"状态流转不出错、不丢单"，那这就是一个方向性 diff——它想往左走，你想往右走。在这一步纠，一句话的事；等文档写完再纠，整个文档推倒。

<img src="/images/mermaid/vibe-zh-6.svg" alt="diagram" style="max-width:100%;">

**图 6 — 前三步：每级产出都很小，但每个都是消灭方向性 diff 的关口**

### 每步都要看 diff：不放过任何一步的含糊

这三步的共同纪律只有一条：**AI 每产出一级，你都要认真看，看出 diff 就纠，别往下走**。看着像废话，但 90% 的人栽就栽在这儿——标题不对，想着"先往下写，后面再说"，结果整个文档建在歪地基上，最后全返工。

这不是效率低，这是省时间。前面纠偏一次三十秒，后面返工一次三小时。

## 三万字完整文档——靠长度逼出具体

前三步把方向钉死了，接下来是重头戏：让 AI 把整个方案展开成一份完整的、能直接照着写代码的设计文档。

说句实话，前面折腾的起标题、写简述，都只是开胃菜。这套流程真正的核心，就是这一步产出的这份贼长的设计文档——它是前面所有对齐的载体，也是后面写代码的唯一依据。前面那么多步，说到底只是**防止上梁不正下梁歪**：方向不先钉死，这份核心文档写得再长也是错的。方向对了，这份长文档才有意义。

### 长不是目的，具体才是

为什么一定要三万字这个量级？因为**只有这么长，AI 才没有空间含糊**。

AI 的懒惰和人类很像：给定个短篇幅，它会把每个决策都写得模棱两可，因为"再具体的部分留给读者脑补"在短文档里不算错。但当篇幅被拉长到万字级，每个话题都必须展开讲透，模糊就没有藏身之处了——它必须把状态机画出来、把每个字段定义清楚、把失败路径写全。**长度不是目标，长度是手段：用篇幅逼出具体。**

这个过程对人也一样残忍，同样公平。AI 在长文档里暴露的所有含糊，都是你脑子里那些"我以为我懂了、其实没想清楚"的地方。你逐段读的时候被迫补齐它们——这正是文档阶段最大的价值：**它把你脑子里的浆糊，变成文档里一段段实打实的决策**。

### 块状化散文：长文怎么做到可读可扫

三万字长文最容易翻车的地方是读不下去。AI 默认的输出是"短词提纲 + 扁平章节"——全是碎片 bullet，读起来像 PPT，信息密度极低，人撑不过前五千字就放弃核对了。放弃核对，就回到"AI 自己写自己看"的老路，diff 又全部漏掉。

我的做法是让 AI 按**块状化散文**写：每个自然段是一个完整的论证块，用列表外壳隔开边界，但块内是完整的句子、完整的论证，不是碎片短语。标题给地图，段落给踩点——读者可以扫读，但扫到哪都能抓住完整的信息。你现在在读的这篇文章，正文就是这种写法。

再加一条：**章节标题按内容本身命名**（"为什么必须逐步扩展"，而不是"第 3 节"）。读者凭标题就知道这节讲什么，想去哪看去哪看。

我给的典型指令是这样：

> 请把这套方案写成一份完整的设计文档，按主题分节，每节围绕一个决策展开。每节尽量拆出小节，宁可拆细别全堆一节。正文用完整句子写论证，不要用碎片短词列点；每个关键概念都要定义清楚，别让我脑补。

这几句话背后全是血泪：碎片 bullet 会让你读不下去，扁平章节会让重点淹没，不要求"定义清楚"它就会默认你能脑补。

### 逐节扩展中的 diff 收敛

三万字的文档，别让 AI 一次吐完。让它**逐节展开**，一节一个话题，每节写完你读一遍、纠一遍 diff，再进下一节。

这和前三步是同一个节奏，只是规模放大了：前三步是"句子级对齐"，这里是"章节级对齐"。逐节扩展还有一个额外的好处——AI 每节是在"你已经确认过"的上文基础上写的，它偏的幅度会越来越小。开头几节你可能纠很多，越往后越顺，这就是 diff 收敛。

<img src="/images/mermaid/vibe-zh-7.svg" alt="diagram" style="max-width:100%;">

**图 7 — 逐节扩展：每节都是"AI 起草 → 人核对 → diff 清零"的循环，越往后越顺**

逐节核对时我最常纠的四类 diff，列出来供你对号入座：

- **理解偏**：这节讲的和你要的不是一回事——直接改，让 AI 重写这节。
- **自作主张**：AI 替你拍板了一个你没提过的决策——先问自己"这个决策对不对"，对就收下，不对就纠。
- **含糊滑过**：这节读到一半发现它在绕，没说清楚——退回让它展开讲透。
- **越界**：这节悄悄把边界外的功能也写进来了——砍掉，回到边界内。

### 写到什么程度，就可以开始写代码

这是个经常被问的问题。我的判断标准很朴素：**当文档里没有任何一句话还需要你脑补细节时，就可以开始写代码了**。

具体可操作的说法：你通读一遍，如果每个决策都能在文档里找到明确的定义——状态有哪些、数据长什么样、异常怎么办、哪个方案为什么被选——不需要自己心里再补东西，那文档就够了。如果读着读着发现自己心里在补"这里应该还有……"而文档没写，说明还没写完，继续。

另一个实用信号：你发现自己开始"觉得 AI 写得啰嗦"了。啰嗦说明它把细节铺得太满，而这些细节你都认可——这恰恰是好消息，说明 diff 已经基本清零，剩下的都是你已经确认过的东西。

## 盲审——质量门禁

文档写完了，你自己读着挺通顺。这时候最危险——因为你脑子里自带上下文，你觉得"这段显然是在说 X"，但一个没参与过的人可能完全看不懂。**你没法替读者读你的文档**。这一步，就是请一个"没见过世面"的读者来帮你发现所有你以为说清了、其实没有的地方。

### 什么是盲审

盲审就是：找一个**完全没参与过这个项目**的人（或一个全新的 AI 会话），只喂给他当前这版文档，让他从零开始读，看能不能读懂、能不能找到他想要的信息。

核心就四个字：**零上下文**。任何背景、任何对话历史、任何"你之前跟我说过"都不给。因为读者拿到你文档时就是这样——他只有文档，没有你。

实操上，所谓"起一个全新的 AI 会话"，就是在你用的 AI 工具里开一个全新的对话（新的聊天窗口、不继承当前对话），然后把当前这版文档整份粘进去，再附上你要问的那一个问题——就这些，别的什么都不给。（文档太长、一条消息粘不下的情况，6.3 里有具体处理办法。）开完这个会话，不要再回到当前这个写文档的对话里继续问它，那样它就有上下文了，就不再是"零上下文读者"。

### 为什么必须盲审

因为写的人永远高估自己写清楚了。心理学上这叫"知识的诅咒"：你一旦知道了一件事，就想象不到不知道它的人有多难理解。你自己写的文档，你读的时候会自动补齐所有跳跃，但读者不会。

我吃过这个亏。有份文档我自认为逻辑严密，盲审时让 AI 扮演"从没听过这个项目的读者"逐段读，结果它报了七八个"这段我看不懂它在说什么""这仨概念是不是同一个东西"的疑问。每一个都是我理所当然地跳过去、读者却会卡住的地方。

### 具体怎么做

盲审分两条线，并行跑。

**问题线**：

1. 先预测 5 到 8 个"一个新读者想用这篇文档时最可能问的问题"——比如"这个状态到底怎么流转的？""失败的时候怎么办？""为什么不用现成的 XX？"。
2. 对每个问题，起一个全新的 AI 会话（不是当前会话！），只喂它文档 + 这一个问题，问它："这个问题的答案，在文档哪一段能找到？还是根本找不到？"
3. 实际操作上，"只喂文档 + 一个问题"就是把整份文档粘进新会话的第一条消息，紧跟那个问题。文档太长粘不下的话，分段粘进同一条消息（继续输入，别开新消息让它"收到"），或者先让它"已收到完整文档，请回答……"——关键是这个会话除了文档和你这个问题，没有任何别的背景。喂完就问，问完就结束，不要顺着它追问，更不要带任何历史。

**横扫线**：

1. 再起一个全新的 AI 会话，让它把整篇文档扫一遍，专门报告三件事——哪里模糊不清、哪里假设读者已经知道某个知识、哪里前后矛盾。
2. 这条线我常用的指令是："你是一个从未看过这份文档的读者。通读全文，只回答三个问题：①哪些地方读起来模糊、让人卡住？②它默认读者已经知道什么？③不同章节之间有没有互相矛盾的地方？逐条列出，给出位置。"——读者照抄即可。

这里我想单独强调一点，也是盲审最重要的作用之一：**内部纠错，把文档自己内部的矛盾揪出来**。长文档是分好几节写出来的，写第 6 节的时候，第 2 节说了什么，作者早就忘了——于是极容易出现"这节说状态 A，那节说状态 B""这里说返回 null，那里说抛异常"这种前后打架。你自己读发现不了，因为你读的时候带着"我知道是这么回事"的滤镜；但零上下文读者没有这个滤镜，他一眼就看出两节对不上。盲审抓的就是这个——它不止查读者读不读得懂，还查这份文档自己站不站得住。

两条线撞见同一个缺口是正常的，去重就行。然后把所有缺口汇总成清单，回文档逐条补，补完重新盲审，直到横扫报告为空、每个问题都能在文档里定位到答案。

<img src="/images/mermaid/vibe-zh-8.svg" alt="diagram" style="max-width:100%;">

**图 8 — 盲审是回环：暴露缺口就回文档补，补完重测，直到干净**

这里有个技术细节值得说：**每个问题都必须用全新的 AI 会话**，绝不能复用当前会话、也不能复用上一轮的会话。因为复用了，它就有了上下文，就不再是"零上下文读者"了——那盲审就变成自己考自己，比不测还坏，因为它制造了"我已经验证过了"的假象。

### 收敛判据

盲审什么时候算过？看两个可观察的事实：横扫那一路报告"没有模糊、没有假设、没有矛盾"，且问题那一路每个问题都能定位到文档里的回答段落。

注意，判据是"**能不能定位到**"，不是"AI 觉得答得对不对"。设计问题没有标准答案，能判的只有"文档里给没给依据"。这是个很清醒的边界：盲审不负责替你评价方案好坏，只负责告诉你"读者能不能读懂你的方案"。

盲审最多测三轮。三轮还清不干净，把剩下的缺口列出来，由你来决定是补还是接受——不要无限磨。

## 写代码——把文档翻译成实现

文档盲审通过，这时候才轮到写代码。写代码这一步相对就"简单"了——因为所有决策都在文档里，AI 要做的事情从"理解需求"变成了"照着翻译"，而翻译的出错率比理解低一个数量级。

### 有完整文档后，代码只是翻译

这一步我要强调的恰恰不是怎么写，而是**先别急**。很多人写到这一步就开始兴奋，把文档一删，直接开个新会话从零写——等于把前面辛苦对齐的 diff 全部扔掉，重新回到"一句话写代码"。

正确做法：把整份文档作为上下文喂给写代码的会话，让它照着一节一节实现。文档里已经写清楚了状态机、数据结构、接口、失败路径，AI 要做的只是把它们变成代码。你可以要求它"每个功能实现前，先指出来源是文档哪一节"——这样它想偷懒滑过去的时候，你能立刻发现。

我给代码会话的典型要求：

> 下面的文档是唯一的规格来源。按节实现，每实现一个功能，先告诉我它对应文档的哪一节。实现过程中如果发现文档没写清楚的地方，不要自作主张，列出来先问。

这个要求把"AI 自作主张"的冲动提前掐住了：它一旦开始补文档里没有的东西，要么它会主动报告，要么它在"指出来源"时露馅。

实际操作里我还试过一种更省心的做法：在 Claude Code 里**拉一个动态工作流**去实现，而不是靠单个会话一次翻译完。（Claude Code 是一个命令行 AI 编程工具；动态工作流是它的一种运行方式——把一个大任务拆成多步、按顺序自动跑完，每步有独立上下文。）动态工作流会把"照文档写代码"拆成一个长程任务——按文档的节拆成一步步，每一步有明确的输入输出、做完自检再进下一步，中途有上下文衔接和状态记录。实测下来，这种方式比单会话一次吐完靠谱得多：大工程的实现不会被一个会话的上下文上限压垮，每一节的完成度都能单独盯住，漏东西的概率低一个档次。如果你用的工具支持动态工作流，实现阶段优先走这条路。

### 模型经验：k3 完整，glm5.2 及以下会漏

这里有一条我用真金白银换来的经验，单独拎出来说。先交代两个模型代号，下文直接沿用：k3 是我日常用的高阶模型（能力排在第一梯队，相当于市面上最强的几家之一），glm5.2 是一个常见的中端模型，也够用了——下面说的是这两类模型在"文档转代码"这一步上的差异。你自己用什么模型，对号入座：能力属于第一梯队就是 k3 那档，属于中端就是 glm5.2 那档。

文档阶段对模型能力的要求其实不高——写文档、盲审，中等模型都能胜任。但**从文档翻译到代码这一步，对模型完整性的要求陡增**。我实测的结果：

- **k3（高阶模型）级别的模型，能把文档里定义的东西比较完整地实现出来**——状态全覆盖、失败路径都处理、字段都对齐。
- **glm5.2 及以下的模型，会漏——而且这个漏，跟你 prompt 怎么写没关系，咋写都漏**。不是它不听话，是它的"完整性能力"就是不够：文档里写了的某些分支、某些边界情况，它在实现时就是会丢掉一两个，而且它自己不知道。

<img src="/images/mermaid/vibe-zh-9.svg" alt="diagram" style="max-width:100%;">

**图 9 — 文档阶段和代码阶段对模型完整性的要求，不是一个量级**

这条经验的实操含义很直接：**如果文档很详细而你手头只有中等模型，代码实现这一环要么升级模型，要么做严格的逐条核对**——把文档里每个决策过一遍，对着代码打勾。别指望换个 prompt 让 glm5.2 变完整，它做不到，这不是 prompt 能救的。

### 为什么会漏：完整性的模型差异

为什么有的模型会漏？不是它"变笨"，而是**长上下文中保持完整性的能力**是一种独立的能力维度。这里的"长上下文"指的是 AI 一次能"装进脑子"的信息量——文档越长、决策越多，模型要在生成代码的过程中"记住所有约束并且都实现"就越难。高模型在这个维度上余量足，低模型在这个维度上会"溢出"——超出它的保持范围后，它开始悄悄丢掉一些它认为"不重要"的东西，而且它不会告诉你。

所以文档阶段的价值在这里又体现一次：**文档越详细、每条决策越显性，代码阶段模型"漏"的代价越小**——因为漏了什么，你能对着文档立刻发现。反过来，如果文档很薄，模型漏了你也发现不了，就变成上线后的 bug。

## 文档是活的：AI 会持续维护需求文档

这套流程跑完，文档交付了、代码写完了，事情是不是就到此为止了？我一开始也这么以为。但实际用下来，发现一个意料之外的收获：**这些文档不是死的，AI 会跟着项目一直更新它**。（顺带说明：前面一直叫它"设计文档"，从本节起叫它"需求文档"，指的是同一份文档——设计阶段它是设计方案，代码阶段之后它就成了这份需求的事实来源。）

高智能的 AI 在后续开发中，会自动把新的决策写回文档——加了个字段，它会在文档的数据结构节补上；改了个状态流转，它会去改状态机那一节。它做的甚至超出了"忠实记录"：当你在代码里提出一个改动时，如果发现和文档矛盾，它会先指出"这和文档第几节冲突"，提醒你决定是改代码还是改文档。这实际上已经做到了**维护需求文档**这件事——而这本来是项目里最容易荒废、最没人愿意干的活。

为什么能做到？因为文档写得足够详细、结构化足够好，AI 读得懂它、也维护得起它。一份三万字的文档，对 AI 来说不是负担，反而是一份它自己能读懂的"世界模型"——它知道需求长什么样，改起来心里有数。反过来，如果文档只有一千字、含糊不清，AI 维护起来无从下手，它自然也不会去碰。

这件事反过来又喂回流程本身：**文档之所以值得认真写，不只是为了写代码前对齐，更是为了写完之后成为项目唯一可信、且有人（AI）持续维护的需求源**。需求文档不腐化，代码和需求就不会越漂越远。

## 边界与常见问题

这套流程很好用，但它不是万能的。说说哪些情况不该用，以及最容易踩的坑。

### 这套流程什么时候不该用

- **体量太小的时候**：改个 bug、加个小功能、写个一次性脚本，不值得走全流程——文档比代码还长就是浪费。我的分界线大概是：能在一个会话里说完、半小时能写完的东西，别写文档；要跨几天、几十个文件、涉及状态的系统，必须走。
- **你自己都不确定需求的时候**：也别急着写文档。这流程的输入是"你至少要有一个大致的方向"，如果连方向都没有，先做原型、先聊，别用文档流程硬套。

### 三万字不是所有项目都该有

篇幅要跟着复杂度走。一个小工具的文档可能就几千字，一个完整系统的文档才需要到万字级。别为了凑篇幅而凑——**长度是逼出具体的手段，不是目标**。文档的合格标准永远是"每条决策都显性化了"，不是"到了某个字数"。所以标题里的"三万字"指的是一个量级——那种需要文档的项目，通常一展开就奔着万字去了；而不是说你非得数着写到三万才算完。

### 常见坑

- **跳过核对**：前面 4.1 说过，起标题、写简述这些产出形式可以按项目灵活跳过；但"每一级产出之后认真核对"这个动作，跳了就全盘皆输。很多人嫌标题、简述小，直接跳过去不核对，结果方向性 diff 在文档阶段才暴露，返工一片。
- **盲审走过场**：用当前会话"自己考自己"，或者让同一个会话既写又审。这比不测还糟——它给你"我验证过了"的假象。
- **急着写代码**：文档一好就兴奋，开了新会话从零写，把前面的 diff 清零成果全部扔掉。记住：代码阶段必须把文档作为上下文喂进去。
- **低模型硬撑代码阶段**：文档写得很细，代码阶段却用 glm5.2 硬扛，然后反复改 prompt 想让它不漏——它做不到。要么换模型，要么逐条核对，二选一。

## QA：读者最可能问的问题

**Q：这套流程得花多久？会不会比直接写代码还慢？**

分项目看。小项目确实不划算（前面说过，半小时能写完的别写文档）。但中型以上项目，前期写文档多花的时间，会在代码阶段全部省回来——因为不再返工。写一份能直接落地的完整文档，通常要投入一两天；但一次"理解错了全推倒"的返工，往往不止一两天。账是这个方向算的。

**Q：文档和代码会越写越漂移吗？**

如果代码阶段把文档作为上下文喂进去，漂移很小；如果开了新会话从零写，漂移很大。所以关键动作是：**代码会话必须带着文档**。文档是代码的规格书，代码阶段的一切疑问都应回到文档找答案。

**Q：AI 写文档会不会把我没说的东西都编出来？**

会，而且这是特性不是 bug。你漏掉的部分，AI 会补上默认决策——这正是你核对时最容易发现 diff 的地方。你逐段读的时候，看到的每一个"AI 自作主张"都是在提醒你"这里你自己还没想清楚"。改掉它，比让 AI 留空让你事后补，高效得多。

**Q：盲审一定要用 AI 吗？找个真人看行不行？**

真人更好，但贵且慢。我的做法是 AI 盲审为主（快、可重复、每轮零上下文），真人在关键文档上补一轮。AI 盲审的价值恰恰在于它可以无限次重跑，每次都是真正的"零上下文"，这是真人做不到的。

**Q：三万字是必须的吗？我没写过这么长的文档，写不出来怎么办？**

三万字是结果，不是要求。你先要求 AI"把每个话题展开讲透、不许含糊"，它写出来的自然就长。你不需要自己会写长文——你要做的是读它、纠它、逼它讲清楚。文档越长，往往说明讲得越具体，也就越接近"可以直接写代码"的状态。

**Q：这份文档写完之后是不是就固定了？后面需求变了怎么办？**

写代码过程中需求变了，改文档再改代码，顺序别反过来。文档是唯一可信的需求源，代码永远跟着文档走。改需求的第一步永远是改文档，这样代码和文档始终对得上，不会出现"代码里有、文档里没有"的幽灵功能。而且如第 8 节说的，高智能的 AI 会主动帮你维护这份文档，这个"先改文档再改代码"的纪律，它帮你执行。

