Skip to main content
← All posts
作者:Sagasu

#007-反思与边界 :文档驱动不是银弹

副标题:什么时候应该用,什么时候不应该用

写到第七篇,我们的博客已经从一个简单的 .md 想法,演变成了一个拥有多作者系统、极致 SEO 和高性能的 v0.8 版本。

回头看这段旅程,文档驱动开发(Document-Driven Development)仿佛一把无坚不摧的利剑,帮我们斩断了需求蔓延的荆棘,劈开了 AI 幻觉的迷雾。

但是,作为一名负责任的技术写作者,我必须在这里按下一个暂停键。

文档驱动开发不是银弹。 它不是万能药,如果你在所有场景下都盲目使用它,它甚至可能变成你的毒药。

在这篇文章里,我们要把这把"利剑"放下,甚至还要用放大镜去检查上面的裂纹。我们要聊聊它的代价、边界,以及那些可能让你掉进坑里的陷阱。

一只卡皮巴拉正对着一面镜子深深凝视,镜子里的倒影显得深思熟虑,背景是一半光明一半阴影的房间,象征着自我反思

凡事皆有代价

在软件工程里,从来没有"免费的午餐",只有 Trade-off(权衡)。文档驱动开发也不例外,它向你索取的代价主要有三点:

  1. 时间成本:显而易见,写文档需要时间。在这个博客项目中,我粗略统计了一下,大约 20% 的时间花在写文档上,80% 的时间花在写代码和调试上。如果没有文档,我直接上手写,会不会更快?对于 v0.1 版本,绝对会。

  2. 认知成本:你需要强迫自己先思考、再动手。这对于习惯了"边做边想"(Vibe-coding)的开发者来说,是一种痛苦的思维逆行。就像是强迫一个习惯了自由奔跑的人去走正步。

  3. 维护成本:这是最隐蔽的代价。文档不是写完就结束了,它是有生命的。每次代码变了,文档必须跟着变。这种"同步纪律"一旦松懈,文档就会变成谎言。

一只卡皮巴拉站在一个巨大的天平前,左边盘子放着厚厚的文档,右边盘子放着金币和时间沙漏,卡皮巴拉正在仔细权衡利弊

何时不应该用文档驱动?

既然有代价,那就一定有"不划算"的时候。如果你处于以下几种场景,请毫不犹豫地抛弃文档驱动,直接动手写代码:

1. 探索性原型 (Prototyping)
假设你有一个疯狂的想法:"我想做一个基于声音控制的俄罗斯方块"。你根本不知道这在技术上行不行得通,也不知道好不好玩。这时候,去写什么 spec.md 简直是浪费生命。你应该直接打开编辑器,写代码,试错,如果不行为立马删掉重来。

2. 一次性脚本
老板让你把数据库里所有用户的名字改成大写。这是一个只运行一次、运行完就扔的脚本。你不需要为它写一份 intent.md 来阐述"为什么我们要把名字大写"。

3. 极度熟悉的领域
如果你已经做过 10 个类似的博客系统,闭着眼睛都能背出数据库表结构。那么,你脑子里的"心智模型"已经足够清晰,不需要再外化为文档。或许保留一个简单的 intent.md 提醒自己别走偏就够了。

一只卡皮巴拉面前摆着一张皱巴巴的餐巾纸,上面用铅笔潦草地画着草图,背景是混乱但充满活力的工作室,象征着快速原型的随意性

警惕:过度工程化的陷阱

即使在你决定使用文档驱动的时候,也很容易用力过猛。我见过有人把文档驱动变成了"文档折磨"。

陷阱一:文档粒度过细
这是新手最容易犯的错误。他们试图为每一个 React 组件、每一个工具函数都写一份 spec.md。
反例:为 Button.tsx 写一份 500 字的规范文档。
正解:文档应该是模块级的(如"作者系统"),而不是函数级的。细节留给代码注释。

陷阱二:流程过于僵化
"文档没写完,不许写代码!" —— 这就把我们带回了古老的瀑布开发模式。文档驱动应该是迭代的。v0.1 的文档可能只有几行字,随着对问题理解的加深,v0.8 的文档才变得丰满。
博客项目实践:回顾我们的 v0.1,那时候的 plan.md 简陋得可怜,但完全够用。

陷阱三:忽视人的因素
如果你的团队成员极度反感写文档,强推这套方法论只会导致对抗。文档驱动的本质是促进沟通,而不是制造流程。

一只卡皮巴拉被淹没在堆积如山的纸张文件中,只露出一双求救的眼睛,周围漂浮着各种复杂的流程图符号,象征过度工程化

文档驱动的局限性

除了上述的人为陷阱,这套方法论本身也有它触达不到的边界:

1. 无法完全消除歧义
自然语言天生是模糊的。你在 spec.md 里写"界面要简洁大方",AI 理解的"简洁"和你理解的"简洁"可能差了十万八千里。对于这种审美类、体验类的需求,文档很难精准传达。

2. AI 的能力边界
目前的 AI 擅长逻辑推演和模式匹配,但在创造性和复杂业务理解上仍有局限。有时候你写了完美的文档,AI 生成的代码依然是一坨浆糊。这时候,你必须亲自介入。

3. 文档滞后
在修紧急 Bug 的时候(比如线上服务挂了),没有人会先去更新文档。这时候,"先文档后代码"的原则必须让位于"先救火"。事后补文档是常态,但这需要极强的自律。

一只卡皮巴拉困惑地看着一幅抽象派画作,画作代表着模糊的需求,卡皮巴拉手里拿着尺子试图去测量它,却无从下手

平衡之道:轻量级文档驱动

那么,我们该如何避开陷阱,用好这把利剑呢?答案在于平衡。

我建议根据项目的规模和阶段,采用分级策略:

  • L1(轻量级):只写一份 intent.md。

    • 适用:周末的小玩具项目、探索性原型、极度熟悉的任务。

    • 核心:只明确"为什么做"和"核心目标",剩下的交给直觉。

  • L2(标准级):intent.md + spec.md + plan.md。

    • 适用:像本系列这样的博客项目、大多数中小型应用。

    • 核心:想清楚要做什么、怎么做,但不纠结细节。

  • L3(重量级):完整文档库 + 自动化检查 + 严格的 Review。

    • 适用:团队协作的核心业务系统、开源库、金融医疗等高风险项目。

    • 核心:文档即法律,任何变更都必须有据可查。

一只卡皮巴拉正在走钢丝,左手拿着

这三个级别不是固定的。我们的博客项目在 v0.1 时是 L1/L2 混合体,到了 v0.8 就自然演化到了接近 L3 的状态。动态调整才是王道。

三只不同大小的卡皮巴拉站在一起,分别举着牌子写着 L1、L2、L3,展示不同级别的文档厚度,从一张纸到一本书

站在巨人的肩膀上

文档驱动开发并不是什么横空出世的新物种,它与许多经典的软件工程方法论有着千丝万缕的联系。

  • vs. 敏捷开发 (Agile):它们不是死对头。敏捷强调"工作的软件胜过详尽的文档",是指不要写那种没人看的死文档。文档驱动强调的是"活的文档"(Living Documentation)。我们的每一次迭代(v0.1 -> v0.2),其实就是一个 Sprint。

  • vs. TDD (测试驱动开发):它们简直是天作之合。文档定义了"我们要去哪里",测试定义了"我们有没有走偏"。你完全可以先写 spec.md,再让 AI 生成测试用例,最后生成代码。

  • vs. DDD (领域驱动设计):intent.md 其实就是通过通用语言(Ubiquitous Language)来定义限界上下文(Bounded Context)。

一只卡皮巴拉坐在中间,周围环绕着敏捷开发、TDD、DDD 等方法论的图标,图标之间有虚线连接,象征着融合与共生

博客项目的反思

最后,让我们回到这个博客项目本身。

做对了什么?
最让我欣慰的是可控性。从 v0.1 到 v0.8,虽然功能一直在加,代码一直在变,但我心里始终不慌。因为我知道每一步是基于什么意图,我也知道如果出问题了去哪里找原因。AI 在这个过程中,真正成为了我的"结对编程伙伴",而不是一个只会被动接受指令的打字机。

做错了什么?
早期的文档结构还是太随意了。在 v0.4 添加分类标签功能时,我发现 spec.md 里的逻辑开始打架。如果当时能早点拆分文档,可能会少走一些弯路。另外,我有几次偷懒没更新文档直接改了代码,导致后来让 AI 加新功能时,它基于旧文档生成的代码和现有代码冲突了。这都是血泪教训。

未来已来

我依然坚信,随着 AI 的进化,文档驱动开发会变得越来越重要。

未来的编程,可能不再是直接操作代码,而是操作意图和规范。AI 会从"代码补全工具"进化为"规范执行引擎"。也许有一天,我们只需要维护一份完美的 spec.md,剩下的都交给 AI 在云端实时编译生成。

但在那一天到来之前,我们要做的,就是学会恰如其分地使用文档。

一只卡皮巴拉站在悬崖边,手里拿着单筒望远镜眺望远方充满科幻色彩的未来城市,天空中飞过代表 AI 的光点

结语

写到这里,"道"理我们都讲完了。

我们从为什么要写文档,讲到了怎么写三份核心文档;从怎么用 AI 生成代码,讲到了如何管理文档的生命周期;从个人项目的实践,讲到了团队协作的规模化;最后我们又冷静下来,划清了它的边界。

现在,你手里已经握有了全套的地图和指南针。

但地图不是疆域,指南针不能代替你走路。是时候迈出第一步了。

下一篇,也就是本系列的最后一篇,我将为你提供一份30 天行动指南。

让我们把理论变成现实,从明天开始,用 .md 文件管理你的下一个项目。

一只卡皮巴拉站在十字路口,路标指向不同的方向,它坚定地迈向了通往