导语
用 AI 写代码最典型的失败模式不是「写不出来」,而是第一天跑通、第二周返工。本文拆解这一现象的根因,并给出可复制的工程动作。读完你会知道:为什么聊天窗口天然诱导人跳过设计、三份文档分别该写什么、以及 AI 改坏代码时怎么按工作区与暂存区两层分别回退。
一、现象,第一天跑通,第二周返工
一位开发者在对话框里输入一句需求(做一个浏览器插件,提取网页正文、调用 AI 翻译、导出 Markdown),AI 生成了几千行代码,当天装进 Chrome 就能运行,demo 页面的翻译结果看起来正常。
第二周开始出现问题:
| 现象 | 直接原因 |
|---|---|
| 提取正文在不同网站翻车 | 导航栏被当成正文、广告混入、分页只抓到第一页 |
| 修了 A 坏了 B | 缺少回归验证基线 |
| 新会话后 AI 不记得之前的决策 | 上下文未持久化 |
| 一次「优化」改挂整体逻辑,且上一个可运行版本未提交 | 缺少小步提交 |
真正致命的是最后一条。前三条只是效率低,最后一条意味着没有回退能力。
二、根因,不是模型能力,是上下文丢失
把问题归因为「AI 不够聪明」会导向错误解法(换模型、加提示词)。真实的因果链是这样的:
- 聊天窗口的反馈是即时的,敲一句话三十秒出代码
- 即时反馈制造了一种错觉,认为「想清楚」这一步可以省略,反正改起来也快
- 于是设计决策只存在于会话里,没有被固化
- 会话一关,上下文清零,AI 只能基于残缺信息猜测
- 猜测产生幻觉,幻觉导致返工
第 3 步是整个链条的断点。盖房子不画图纸,工人手快不是好事,墙砌得越快,发现卧室没留门时越绝望。
从后端视角看,这和「接手一份没有设计文档的遗留代码」是同一类问题。换个工程师来改,一样会崩。AI 只是把周期从半年压缩到了两周。
三、成本结构变了,稀缺的东西也变了
以前写代码成本高,设计粗一点的代价还能承受。现在写代码的边际成本趋近于零,稀缺的变成了「一份清晰、可执行、可验证的意图」。
举一个具体的例子。「一键提取文章核心内容」这句话,敲下来十秒。要落成可执行规范,必须回答:什么算核心内容?导航菜单算不算?评论区呢?分页文章怎么处理?
这些问题不回答,AI 只能猜。答案写进文档,它每一轮都读得到。
当写代码的成本趋近于零,最贵的就不再是代码,是一句说得清楚的「我要什么」。
会话一关上下文清零,但文件还在。这就是文档在 AI 时代的新角色,它不是交付物,是上下文存档。
四、解法一,三份文档,按需来
放在项目根目录,核心三份。
proposal.md
管「要做什么、为什么做、边界在哪」,核心动作是把需求抠到最小可行单元。
## 要做什么
在英文博客页面一键完成,
提取正文 → 调 AI 翻译成中文 → Markdown 渲染 → 一键复制
## 不做什么
- 不做收藏夹、历史记录
- 不做账号系统
- 不做中英以外的语种
- 不做整页翻译,只翻正文
「不做什么」这栏用来拦 AI,也拦自己。没有这栏,AI 会主动补充登录、云同步、深色模式等未被要求的功能。
design.md
管「怎么实现、技术架构和选型」,技术难点要逐条摊开写。
## 技术难点
1. 正文提取,网页结构千奇百怪,先调研 Readability 类方案
2. AI 接入,统一走 OpenAI 兼容格式,deepseek、qwen 只改配置
3. Markdown 渲染,用 npm 的 marked
4. 输出格式要适配微信公众号(标题、引用、代码块样式)
「AI 模型可配置」这条写下来之后,选型就确定了:不绑定任何一家,全部按 OpenAI 接口格式对接,换模型只改 baseURL 和 key。这类决策在对话中随口确定,三个会话后必然遗失。
task.md
管「先干什么后干什么、哪些能并行」。
落地方式
三条指令固定带一句「先读根目录的 proposal.md 和 design.md,再动手」。
判断文档是否有价值的标准不是写得好不好,而是新会话读一遍能不能把人和 AI 拉回同一页。按这个标准,应付检查式的设计文档价值为零。
五、解法二,小步提交,回退分三层
文档解决「想清楚」,但 AI 生成代码仍会幻觉。配套铁律是:跑通一个可验收的版本,立刻提交。
改动出问题分三种情况:
# 情况 1,改了文件,还没 git add,直接丢弃工作区修改
git restore .
# 情况 2,已经 git add 进暂存区,但还没 commit
# 先把改动移出暂存区,再丢弃
git restore --staged .
git restore .
# 情况 3,已经 commit 了,硬回退到上一个提交
git reset --hard HEAD^
情况 2 最容易踩。 git restore . 只作用于工作区,暂存区里那份坏代码不受影响,AI 后续还会基于它继续修改。工作区和暂存区是两层,需要逐层外退。
$ git status
On branch main
Changes not staged for commit:
modified: src/extractor.js
$ git restore .
$ git status
On branch main
nothing to commit, working tree clean
注意:git reset --hard HEAD^ 会丢弃当前提交之后的全部改动,执行前先 git status 确认。
六、验证方法
新开一个会话,不做任何额外解释,只发一句「先读 proposal.md 和 design.md,然后继续昨天的任务」。
- 动作符合预期 → 文档写到位
- 反问「这个项目是做什么的」 → proposal.md 不达标,回去补「不做什么」那栏
七、局限(尚未解决的部分)
- 文档腐化。代码改了文档没改,AI 会拿过期文档当依据,比没有文档更危险。目前只能在每次合并前人工扫一遍。
- 颗粒度无标准。写粗了 AI 照样猜,写细了写文档的时间超过写代码。目前凭项目规模判断,没有量化判据。
- 适用边界。一次性脚本、两小时写完就扔的任务,引入三份文档是纯负担。适用于跨多个会话、有明确技术难点、需要长期迭代的项目。
总结
| 关键判断 | 内容 |
|---|---|
| 根因 | 上下文未持久化,而非模型能力不足 |
| 核心动作一 | proposal / design / task 三份文档固化意图 |
| 核心动作二 | 跑通即提交,按工作区、暂存区、提交三层分别回退 |
| 角色转变 | 从写代码的人,变成给每天失忆的执行者做意图管理的人 |
今天可以做的一件事:在当前 AI 项目根目录建一个 proposal.md,只写「要做什么」和「不做什么」两栏,然后新开会话验证。
素材来源与出处
| 来源 | 标题 | 链接 | 发布时间 |
|---|---|---|---|
| 掘金 | 被 Vibe Coding 反噬之后,我老老实实地回去写文档了 | juejin.cn/post/769503… | 2026-10-11 14:08 |
| InfoQ中国 | 利用 AI 代码智能体优化软件架构的五种方法 | www.infoq.cn/article/soR… | 2026-10-11 10:04 |