我用 2 个 Skill 解决AI开发如何记录文档的问题

我用 AI 写了三个月代码,然后我再也看不懂自己写的东西了

一个熟悉的故事

去年我开始大量用 Claude Code 辅助开发。速度确实快------一个下午能出一个以前要两天的功能。但渐渐地我发现了一个问题:三个月前写的东西,我自己都看不懂了。

不是代码写得差。代码本身还好。是因为没有文档------或者说,有文档,但文档跟代码对不上。

列表接口的 spec 里写的是"支持按状态筛选",但代码里加了七八个筛选条件,没有一个更新过文档。数据库表里多了三个字段,接口规范里完全没有提及。当我想加一个新功能的时候,我不知道该相信 spec 还是相信代码。

这是 AI 时代催生的一种新型技术债。AI 写代码太快了,文档永远跟不上。


两个真正的问题

我把这个现象归结为两个独立但相关的问题。

第一个问题:文档腐化。

传统项目里文档腐化已经够烦了。AI 时代更严重,因为生产速度被放大了好几倍,但维护文档的习惯没有跟上。更糟的是,很多人(包括我自己)会在某个需求开始前写一份 spec,然后在开发过程中随着需求变化多次修改,最后项目里存着三四个版本的"spec-v2-final.md",没有人知道哪个是最新的。

第二个问题:AI 的"立刻行动"倾向。

这个更隐蔽。AI coding 工具有一个天然的行为模式:理解需求 → 立刻写代码。它不会主动说"我先把方案写出来你确认一下",而是直接开干。这在需求清晰的时候很好,但在需求模糊、或者理解有偏差的时候,改错方向的代码比没有代码更难处理------因为你得先把错的删掉,再重新来过。


我做了一个工具

过去几个月我一直在想怎么解决这两个问题,最后做了一套叫 doc-first-dev 的东西:一组可以安装到 Claude Code 的 Agent Skills,把"文档先行"这套工作流强制固化下来。

核心是两个命令:

  • /spec-first:管理从需求到交付的完整开发周期。每次有新需求或变更,先写/更新文档,确认通过再开发,开发完再跑验收。
  • /whylog-record:在任务结束后把这次的决策背景记录下来------考虑过哪些方案,为什么选现在这个,有什么取舍。

两个命令一起用,才能回答开发中最重要的两个问题:现在的代码是什么样的 (spec)和为什么是这个样子(决策日志)。


三个我觉得值得说的设计决策

1. 确认门:分析和动手之间的强制停顿

/spec-first 的工作流里,有一个我最看重的机制:在 AI 开始写代码之前,必须经过一次用户确认

AI 会先分析需求,读代码,把影响到的接口、数据库结构、代码位置整理成文档,然后展示"改之前是什么样,改之后会是什么样"的对比。只有我点击"确认通过,开始开发",它才会动代码。

这个设计看起来简单,但背后的逻辑很重要:确认门把"理解"和"执行"强制解耦了

在没有这个机制的时候,AI 经常在我话还没说完时就开始写代码了。有时候方向对,有时候不对。不对的时候,我得花时间解释"不是这个意思",然后等它重写。有了确认门之后,我们先把"方向"对齐,再谈"执行"。返工少了很多。

如果在确认环节我觉得方向不对,可以补充说明,AI 会重新分析;如果需求本身变了,也可以在这里调整范围。改文档比改代码便宜。

2. Spec 和决策日志分开存

另一个我思考了很久的问题是:文档里该放什么,不该放什么

我见过很多项目的 spec 越写越臃肿,里面夹杂着"2023年10月我们讨论过方案A,最终选了方案B,因为..."这类历史记录。这些内容对新人有价值,但每次随机读取 spec 时都要跳过它们。

doc-first-dev 的做法是把两类信息分开存:

  • docs/plans/<模块>/ 里的 spec 只回答"现在是什么样"------当前的接口规范、数据库设计、代码结构。就地更新,永远只有一份,历史版本交给 git 管理。
  • docs/decisions/log.md 只回答"为什么是这个样子"------方案选择、取舍背景、考虑过但放弃的替代方案。顺序追加,不覆盖。

这个分法的好处在于:spec 保持精简,可以快速读完;决策日志保留完整上下文,在需要回溯历史的时候去查。两者的读写模式根本不同------spec 是随机读写,决策日志是顺序追加------分开存才能让各自保持最适合自己的形态。

代码里我们已经很自然地把变量命名(what)和注释(why)分开。文档里做同样的分离,其实是一件很自然的事。

3. 三角一致性:接口 ↔ 数据库 ↔ 代码,三角对齐

最后一个设计是在 spec 更新完成后的自动检查。

我发现一类高频错误是:数据库加了一个字段,接口规范里没有更新,然后代码里用了这个字段,但调用方不知道可以传这个参数。或者反过来,接口文档里写了某个查询条件,但数据库里没有对应的索引,代码里也没有处理。

doc-first-dev 在每次分析完之后会做三角校验:接口规范中的字段、数据库设计中的字段、代码地图中的方法签名,三者必须对齐。发现不一致时会立刻暴露,并且问你"以代码为准还是以 spec 为准",让你来做决定。

这个机制解决的不是什么高深问题,就是那种"我以为我都改完了但其实漏了一处"的低级错误。但这类错误在 AI 开发中特别容易出现,因为 AI 改代码的范围有时候超出你的预期,而你没有一个系统地检查全貌的方法。


一次典型的使用过程是什么样的

举个具体的例子。假设我要给一个列表接口加"按作者筛选"的功能:

bash 复制代码
/spec-first 给文章列表接口加一个按作者筛选的参数,支持模糊匹配

接下来:

  1. AI 读当前的 spec,找到相关接口和数据库表,分析影响范围。
  2. 它把需要修改的内容整理出来:接口规范加 author 参数、数据库查询逻辑说明、受影响的 Mapper 方法。展示改前改后的对比。
  3. 我检查一遍,觉得没问题,点"确认通过,开始开发"。
  4. AI 开始改代码------Mapper、Service、Controller,按顺序来。
  5. 改完构建一遍,然后自动进入验收:实际调用 POST /article/listauthor=张三,检查返回结果里所有文章都包含"张三"。
  6. 验收通过,输出简报:改了哪些文件,验收结果是什么。

整个过程我只需要在确认门那里介入一次。其余的它自己处理。


适合谁用,不适合谁用

说实话,这套工具不是适合所有场景的。

适合:

  • 你在维护一个要持续迭代的项目,而不是一次性脚本
  • 你(或你的团队)用 AI 写了大量代码,但文档状态已经一团糟
  • 你希望 AI 的每次修改都有迹可循,可以回溯

不太适合:

  • 纯探索性的原型,你只是想快速验证一个想法
  • 完全不在意文档的快速实验
  • 项目生命周期很短,文档的投资回报不合算

我自己的用法是:新项目的早期探索阶段先不用,等方向确定了、开始认真迭代了,再引入这套工作流。


安装

如果你想试试:

bash 复制代码
npx skills add zzusp/doc-first-dev

安装完之后,在你的项目里运行 /spec-first 加上一句需求描述,它会自动检测是否需要初始化,然后走流程。

项目地址:github.com/zzusp/doc-f...


写这个工具的出发点很简单:我不想三个月后看不懂自己写的代码。目前用下来,文档腐化的问题确实好了很多。如果你有类似的困扰,可以试试。有什么问题或者想法,欢迎在评论区聊。

相关推荐
user20585561518133 小时前
Codex App 安装与模型接入实战:GPT、DeepSeek
claude
newbe365241 天前
对接 Reasonix 1.x 跑通 DeepSeek V4:ACP 模型选择器接入实战
gpt·claude·chatglm (智谱)
保持清醒的坐标系2 天前
3份配置喂给7个AI编程助手,直接抄
claude
卡卡罗特AI2 天前
有了 DESIGN.md 后,大家也能写出高颜值的网站了!
ai编程·vibecoding
newbe365242 天前
如何使用 Upptime 免费搭建自己的状态站点
gpt·claude·chatglm (智谱)
kunge20132 天前
1. OpenSpec 命令执行过程与 Claude Code 提示词详解
vibecoding
沉默王二2 天前
老板:“请说出一个录用你的理由。”我脱口而出:“每个月 AI 支出都超过我的生活费了!”老板愣了一下,随即哈哈大笑:“好吧,你被录用了。”
人工智能·ai编程·claude