#003-文档驱动项目-写出第一份最小可行文档(MVD)
——不求完美,但求有用
系列导读:这是《老项目如何引入文档驱动》系列的第 3 篇。前两篇我们聊了为什么需要文档驱动,以及如何用 AI 理解代码。现在,真正的挑战来了——如何把理解转化为文档?更重要的是,第一份文档该写什么?
小张的困境:文档写到一半就放弃了
小张是我们团队的一名工程师。
上周,他用 AI 分析完支付回调的代码,信心满满地决定:“我要把这些整理成文档!”
结果呢?
他花了整整 3 个晚上,写了 20 页,还没写完一半。
每写一段,他都要纠结:
“这个方法要不要详细说明?”
“这个配置项要不要记录?”
“这段历史演进要不要写?”
第四天,他崩溃了。
他放弃了。
这就是很多人写文档时遇到的困境:想写得完美,结果一点都写不出来。
你可能会说:“那就简单写写不就行了?”
但问题是:简单到什么程度?写什么?不写什么?
这就是这篇文章要解决的问题。
我们不追求完美的文档,而是追求“刚好够用”的文档。
这就是 MVD(Minimum Viable Documentation,最小可行文档)。
一、什么是 MVD?为什么要从“最小”开始?
MVD 的定义

MVD 不是缩水的文档,而是只包含核心信息的文档。
它回答三个最关键的问题:
-
是什么(What):这段代码是干什么的?核心流程是什么?
-
为什么(Why):为什么这样设计?关键决策是什么?
-
怎么用(How - 关键部分):遇到问题怎么办?有什么坑要注意?
不回答的问题:
-
每个方法的详细实现
-
所有的配置项说明
-
完整的历史演进
-
详尽的数据库设计
这些都很重要,但不是第一优先级。
为什么要从“最小”开始?
1. 降低启动成本
写一份完美的文档需要 20-40 小时。你很难一次性投入这么多时间。
但写一份 MVD 只需要 4-6 小时。这个投入是可接受的。
2. 快速验证价值
MVD 写完就能用,你能立即看到效果:
-
新人能不能通过这份文档理解代码?
-
自己 3 个月后回来能不能快速上手?
如果答案是“能”,你就成功了。
如果答案是“不能”,你只浪费了 6 小时,而不是 40 小时。
3. 避免完美主义陷阱
很多人写文档失败,不是因为能力不够,而是因为追求完美。
MVD 的理念是:先有,再好,最后才完美。
第一份文档不需要完美,只需要有用。
对独立开发者来说,MVD 更重要
如果你是独立开发者,同时维护多个项目,MVD 对你的价值更大:
你可能今天在客户 A 的项目,下周切换到客户 B 的项目。
如果没有 MVD:
回来时要花 1-2 天“回忆”当时的设计。
如果有 MVD:
5-10 分钟就能进入状态。
防止知识遗忘:
3 个月后,连自己的代码都看不懂?有了 MVD,关键决策和设计思路都记录在案,随时可以回忆起来。
这就是 MVD 的价值。
二、MVD 框架:老项目该写什么?

对于老项目,我总结了一个三层优先级框架。
第一层:核心流程(必须写)
这是 MVD 的基础。
回答一个问题:这段代码的主流程是什么?
用支付回调举例:
核心流程包含这 7 个步骤:
-
接收回调(来自支付网关)
-
验证签名(防止伪造)
-
查询订单(获取当前状态)
-
锁订单(防止重复处理)
-
更新状态(根据回调结果)
-
释放锁
-
返回响应
就这么简单。
时间投入:30 分钟
第二层:关键决策(重点写)
这是 MVD 的灵魂。
回答一个问题:为什么这样设计?
继续用支付回调举例:
2 年前的生产事故:支付宝回调失败重试,导致用户被扣了两次钱。所以加了分布式锁(Redis 实现),确保同一个订单只能被处理一次。
为什么用同步调用而不是异步?
早期用的异步,但发现用户支付后要等 5-10 秒才能看到结果,体验很差。权衡后改成同步,虽然响应时间长了,但用户体验好了。
但它们极其重要,因为它们解释了代码的“合理性”。
时间投入:1-2 小时
第三层:关键细节(选择性写)
这是 MVD 的补充。
不是所有细节都要写,只写容易出错或不符合直觉的部分。
继续用支付回调举例:
幂等性处理:
-
锁的过期时间是 30 秒,足够处理一次回调
-
如果处理超过 30 秒,锁会自动释放,可能导致重复处理
-
所以处理逻辑必须在 30 秒内完成
状态转换规则:
-
PAYING → PAID(正常)
-
PAYING → FAILED(失败)
-
PAYING → CREATED(不允许)
不要尝试回滚到 CREATED,会导致状态混乱。
时间投入:1-2 小时
三、实战:写出你的第一份 MVD

现在,让我们一步步写出支付回调的 MVD。
第一步:准备材料(15 分钟)
在开始写之前,先收集信息:
1. AI 的分析结果
你在第二篇文章中已经让 AI 分析过代码了,把结果拿出来。
2. 代码验证笔记
你验证 AI 分析时记录的发现,比如:
-
AI 遗漏的“锁订单”步骤
-
实际的状态转换规则
-
发现的潜在 bug
3. 关键问题列表
问自己几个问题:
-
为什么这样设计?
-
有什么坑要注意?
-
新人最容易搞错什么?
把这些答案记下来。
第二步:搭建文档框架(10 分钟)
一个标准的 MVD 包含这些部分:
-
概述 - 一句话说清楚这是什么
-
核心流程 - 主流程,7-10 个步骤
-
关键决策 - 为什么这样设计?(2-3 个重要决策)
-
状态转换 - 列出所有状态和转换规则
-
注意事项 - 坑和容易出错的地方
-
常见问题 - FAQ,2-3 个
这就是 MVD 的标准框架。
第三步:填充内容(2-3 小时)
技巧 1:先写概述
用一句话说清楚这是什么:
支付回调处理模块负责接收支付网关(支付宝/微信)的异步通知,验证合法性后更新订单状态。
核心职责: 确保支付结果准确同步,防止重复处理。
技巧 2:核心流程用列表
不要写长段落,用列表展示关键步骤:
-
接收回调 - 解析请求参数,记录原始数据
-
验证签名 - 用支付网关的公钥验证,失败直接返回 400
-
查询订单 - 从数据库获取订单当前状态
-
锁订单(关键!) - 使用 Redis 分布式锁,过期时间 30 秒
-
更新订单状态 - PAYING → PAID(成功)或 FAILED(失败)
-
释放锁
-
返回成功响应 - 200 OK
每个步骤只需要一句话说明核心动作,不需要展开实现细节。
技巧 3:关键决策讲故事
不要只写“是什么”,讲清楚“为什么”:
为什么要锁订单?
2022 年 8 月,我们遇到一次严重的生产事故。支付宝的回调因为网络问题失败了,它按规则重试了。但我们的代码没有幂等性处理,同一个订单被处理了两次。
解决方案:
引入分布式锁,确保同一个订单在同一时刻只能被一个线程处理。锁的过期时间设为 30 秒,足够处理一次回调。如果超过 30 秒,说明出现异常,自动释放锁。
为什么用同步处理而不是消息队列?
早期设计时,我们用的是消息队列异步处理。但产品经理反馈:用户支付后要等 5-10 秒才能看到“支付成功”,体验很差,用户以为支付失败了,会重复支付。
权衡:
同步处理虽然响应时间长了(200ms → 500ms),但用户体验好了,投诉率下降了 60%。我们接受这个权衡。
技巧 4:状态转换用表格
状态机用表格比文字清晰:
状态转换规则:
| 当前状态 | 允许的下一状态 | 触发条件 |
|---|---|---|
| CREATED | PAYING | 用户点击支付 |
| PAYING | PAID | 支付成功回调 |
| PAYING | FAILED | 支付失败回调 |
| PAID | REFUNDING | 用户申请退款 |
| REFUNDING | REFUNDED | 退款成功 |
不允许的转换:
-
❌ PAYING → CREATED(不要回滚!)
-
❌ PAID → PAYING(已支付不能回到支付中)
-
❌ FAILED → PAID(失败不能直接变成功)
技巧 5:注意事项用警告符号
让重要的事情显眼:
⚠️ 锁的过期时间是 30 秒
如果处理逻辑超过 30 秒,锁会自动释放,可能导致重复处理。
所以: 处理逻辑必须在 30 秒内完成。如果有耗时操作,考虑异步化。
⚠️ 幂等性是硬性要求
支付网关可能重试多次,你的代码必须支持幂等性。
测试方法: 用同一个回调数据调用接口 3 次,检查订单状态。
⚠️ 不要在回调中做复杂业务
回调处理应该只做状态更新,不要做:
-
❌ 发送短信/邮件(放到消息队列)
-
❌ 更新用户积分(放到消息队列)
-
❌ 调用其他微服务(异步处理)
原因: 回调必须快速响应(< 1 秒),否则支付网关会重试。
第四步:自我检查(30 分钟)
写完后,不要急着发出去。先自己检查:
检查清单:
-
概述是否一句话说清楚了这是什么?
-
核心流程是否清晰?(让不熟悉的人能看懂)
-
关键决策是否解释了“为什么”?
-
状态转换是否完整?(没有遗漏)
-
注意事项是否标注了容易出错的地方?
-
整体长度是否控制在 2-3 页?(不要太长)
模拟测试:
找一个不熟悉这块代码的同事(或者想象 3 个月后的你),问他:
“看了这份文档,你能理解这段代码吗?”“如果让你改一个 bug,你知道从哪下手吗?”
如果答案是“能”,你就成功了。
最终成果:一份“刚好够用”的 MVD
按照上面的步骤,你最终会得到一份:
特征:
-
长度: 约 1.5-2 页
-
耗时: 约 4-6 小时
-
包含: 概述、核心流程、关键决策、状态转换、注意事项、常见问题
这份文档能做到:
✅ 新人能通过它快速理解核心流程(不需要看代码)✅ 出问题时能快速定位可能的原因✅ 3 个月后的自己能快速回忆起关键决策
这就是 MVD 的价值。
四、常见错误:第一次写文档容易踩的坑
错误 1:写得太详细
症状:
文档写了 20 页,包含每个方法的详细说明、所有配置项、完整的历史演进……
为什么错?
新人不需要这么多信息。太多信息反而让人不知道该看什么。
正确做法:
**只写核心的 20%。 **详细信息等需要时再补充。
错误 2:只写“是什么”,不写“为什么”
症状:
文档只有流程图和方法说明,没有解释设计决策。
为什么错?
看完文档,你知道代码“做了什么”,但不知道“为什么这样做”。
3 个月后,你还是会困惑:“为什么当时这样设计?”
正确做法:
把“为什么”放在和“是什么”同等重要的位置。
错误 3:追求完美
症状:
“这里要不要再详细一点?”“那个方法要不要也说明一下?”“状态机要不要画得更精确?”
结果:永远写不完。
为什么错?
完美是持续改进的结果,不是第一次就能达到的。
正确做法:
先完成,再完美。 第一版只要“够用”就行。
错误 4:文档脱离代码
症状:
写完后跑一遍代码,验证流程是否正确。
为什么错?
文档和代码不一致,导致误导。
正确做法:
写完后跑一遍代码,验证流程是否正确。
错误 5:没有读者视角
症状:
文档写得很技术化,只有自己能看懂。
为什么错?
文档的读者是“不熟悉这块代码的人”。 如果只有你自己能看懂,文档就失去了意义。
正确做法:
找一个不熟悉的同事看一遍,问他能不能看懂。
五、如何判断你的 MVD “够好”?

写完 MVD 后,你可能会困惑:“这样够了吗?”
用这个简单的测试判断:
测试 1:3 分钟理解测试
找一个不熟悉这块代码的同事。
让他花 3 分钟看你的文档,然后问他:
“这段代码是干什么的?核心流程是什么?”
如果他能回答对 70-80%,你就成功了。
测试 2:快速定位测试
假设有个 bug:用户支付成功了,但订单状态还是“支付中”。
看了你的文档,能不能快速定位可能的问题点?
如果能,说明你的文档有实用价值。
测试 3:换位思考测试
假设你是一个刚加入团队的新人。
看了这份文档,你能回答这些问题吗?
-
这段代码的核心职责是什么?
-
为什么这样设计?(关键决策)
-
有什么坑要注意?(容易出错的地方)
如果你能用文档回答这 3 个问题,你就成功了。
额外的验证:
3 个月后,你自己回来看这份文档,能快速回忆起关键决策吗?
这是终极测试,但需要时间验证。
判断标准总结
一份“够好”的 MVD:
-
✅ 新人能通过它快速理解核心流程(不需要看代码)
-
✅ 出问题时能快速定位可能的原因
-
✅ 3 个月后的自己能快速回忆起关键决策
-
✅ 长度控制在 2-3 页(不超过 5 页)
-
✅ 投入时间在 4-6 小时(不超过 8 小时)
如果满足这 5 点,你的 MVD 就是成功的。
六、独立开发者的 MVD:更轻量的版本
如果你是独立开发者,同时维护多个项目,可以用更轻量的版本。
轻量 MVD 的三要素
1. 项目概览(2 分钟写完)
## 项目:客户 A 的支付系统
**核心功能:** 支付回调处理
**关键模块:**
- PaymentCallbackHandler(回调入口)
- PaymentStateMachine(状态管理)
**最后更新:** 2024-12-25(新增花呗分期)
2. 核心流程(5 分钟写完)
## 核心流程
接收回调 → 验证签名 → 锁订单 → 更新状态 → 释放锁
**关键点:**
- 用 Redis 锁防止重复处理
- 锁过期时间 30 秒
3. 关键决策日志(10 分钟写完)
## 决策日志
### 2024-12-25:为什么用同步处理?
用户体验优先。虽然响应慢了,但不用等 5-10 秒。
### 2022-08-15:为什么加锁?
生产事故,用户被重复扣款。加锁解决。
总耗时:约 15-20 分钟
适用场景:
-
个人项目,主要读者是 3 个月后的自己
-
时间有限,无法花 4-6 小时写完整 MVD
-
项目规模小(< 5000 行代码)
七、第一份文档最难,但它是基础
坦白说:第一份文档是最难写的。
因为你不知道该写多详细,不知道该聚焦什么,不知道该省略什么。
我第一次写 MVD 时,也是反复纠结。
写了删,删了写,花了整整 10 小时才写出一份 3 页的文档。
但第一份写完后,后面就越来越容易了。
因为你有了模板,有了参考,知道什么重要什么不重要。
第二份文档只花了 5 小时。
第三份文档只花了 3 小时。
现在,我写一份 MVD 只需要 2-3 小时。
所以,不要追求完美。
先写出第一份,哪怕不完美,哪怕有遗漏,哪怕有错误。
写完了,你就成功了一半。
下一篇,我们会聊:如何让这份文档“活”起来,而不是写完就束之高阁。
文档不是一次性的作品,而是持续演化的知识库。
如何维护?如何更新?如何让它不过时?
这些都在下一篇。
现在就开始吧:
找一个你最熟悉的模块,用 4-6 小时,写出你的第一份 MVD。
不要纠结细节,不要追求完美,先完成再完善。
记住:第一份文档不需要完美,只需要有用。