从文档债到文档驱动:AI时代软件开发的Spec-First工程实践
2026/5/1 9:34:05 网站建设 项目流程

1. 项目概述:从“文档债”到“文档驱动”的工程实践

如果你和我一样,经历过一个项目从零到一,再到功能膨胀、团队扩张,最后被“文档债”压得喘不过气,那你一定能理解那种痛苦。代码库在迭代,但文档要么是几年前的“历史遗迹”,要么散落在各个角落的README-v2-final-revised.md里,没人知道哪个是“真相”。更糟的是,当你想引入 AI 助手(比如 Claude Code、Cursor)来提升开发效率时,会发现它们和你一样迷茫——没有准确、实时、结构化的上下文,AI 给出的代码建议往往南辕北辙,修复错误代码比从头写更费劲。

这正是doc-first-dev这个项目要解决的核心问题。它不是一个新奇的文档工具,而是一套可安装的Agent Skills(技能)和配套的工作流模板,目标是把“文档先行”从一个美好的口号,变成团队和 AI Agent 都能下意识遵循的工程习惯。它的核心理念非常直接:每个功能模块只有一份“活”的规格说明书(Spec),它代表“现在应该是什么样子”;所有的设计决策和变更理由,则按时间顺序记录在独立的决策日志里。这样一来,无论是新人 onboarding、老手回顾,还是 AI Agent 介入开发,都能基于唯一、准确的“现状”文档开展工作,极大降低认知偏差和沟通成本。

这套技能包主要包含三个核心技能:spec-first用于单个模块的全生命周期开发;spec-multi用于协调跨多个服务或项目的变更;whylog-record则在任务完成后,自动或手动记录“我们为什么这么选”的决策过程。它们共同构成了一个闭环,确保“做什么”(Spec)和“为什么做”(决策日志)既分离又关联。

我花了些时间深入研究并将其应用到自己的几个项目中,发现它确实能改变团队与文档、以及与 AI 协作的“肌肉记忆”。下面,我就结合自己的实操经验,为你彻底拆解这套方法论的设计精髓、落地步骤以及那些只有踩过坑才知道的注意事项。

2. 核心设计哲学:为什么传统的文档方法会失败?

在深入使用doc-first-dev的技能之前,我们必须先理解它背后针对的“顽疾”。传统的文档管理,无论是完全缺失,还是过度管理,通常都会陷入以下几个陷阱,而doc-first-dev的每一条设计原则,都是对这些陷阱的精准反击。

2.1 模块目录化:对抗文档的“膨胀死亡”

常见陷阱:很多项目喜欢把所有模块的说明都塞进一个巨大的SPEC.mdDESIGN.md里。初期看起来整洁,但随着模块增加,这个文件会迅速膨胀到几千行。任何微小的改动都可能引发巨大的合并冲突,搜索一个特定功能变得异常困难。最终,没人敢动这个文件,它变成了一个过时且无法维护的“纪念碑”。

doc-first-dev的解法:强制采用模块化的文档结构。每个业务或技术模块,在docs/plans/<module-name>/目录下拥有自己独立的 spec 文件(例如user-auth-spec.md)。一个顶层的PROJECT.md文件仅作为索引,列出所有模块及其简要描述和路径。

your-project/ └── docs/ ├── plans/ │ ├── PROJECT.md # 索引:仅包含模块名、简介、链接 │ ├── user-auth/ │ │ └── user-auth-spec.md # 独立、完整的认证模块 spec │ ├── order-service/ │ │ └── order-spec.md │ └── payment/ │ └── payment-spec.md └── decisions/ └── log.md

实操心得:这种结构带来的最大好处是“关注点分离”和“独立演化”。前端团队可以放心更新frontend-components-spec.md而不用担心影响后端的 API 文档。当某个模块被废弃时,直接删除整个docs/plans/old-module/目录即可,干净利落,不会留下僵尸文本污染其他内容。对于 AI Agent 来说,当它处理一个与“用户认证”相关的需求时,它能被精确地引导到user-auth-spec.md这个文件,获取最相关、最干净的上下文,而不是在一锅粥的大文档里费力搜寻。

2.2 单一活文档:终结版本混乱

常见陷阱:我们常看到api-spec-v1.md,api-spec-v2-draft.md,api-spec-v2-final.md,api-spec-latest.md并存。哪个是当前线上运行的?哪个是正在开发的?这种混乱使得无论是人还是 AI,都需要花费额外的心智去判断“真相”,错误率极高。

doc-first-dev的解法:一个模块,一份 Spec,永远代表当前线上或主分支应有的状态。任何变更,无论是新增功能、修改接口还是修复 Bug,都直接在这份唯一的文件上修改、提交。历史版本由 Git 来完美管理。你需要查看历史时,用git log docs/plans/user-auth/user-auth-spec.md即可。

理念剖析:这强迫团队形成一种纪律——更新代码和更新文档是同一个原子操作。如果你修改了登录接口的响应格式,那么必须在同一个 Pull Request 里更新user-auth-spec.md。这样,Spec 文件就和代码库一样,成为“源代码”的一部分。AI Agent 在分析时,读取到的永远是最新的、权威的现状描述,从根本上避免了基于过时信息进行开发的风险。

注意:“当前状态”指的是在特性分支上开发时,Spec 描述的是该特性完成后的预期状态。因此,在特性分支合并前,其 Spec 可能与其他分支的 Spec 存在临时的不一致,这需要通过 Code Review 来确保合并时的最终一致性。这比维护多份“未来”文档要简单得多。

2.3 Spec与决策分治:让文档各司其职

常见陷阱:在 Spec 文件里夹杂大量的设计讨论,比如“我们曾考虑过 OAuth 2.0 但因为复杂度放弃了,最终选择了 JWT”。这些内容对于理解“现状”是噪音,但对于理解“决策背景”又至关重要。混在一起的结果是,Spec 变得冗长难读,而真正重要的决策逻辑却随着时间流逝被遗忘。

doc-first-dev的解法:严格区分“是什么”(Spec)和“为什么”(Decision Log)。

  • docs/plans/:存放描述现状的 Spec,格式要求清晰、简洁、结构化。读写模式是随机访问(根据模块名快速定位)。
  • docs/decisions/log.md:存放决策日志,按时间顺序追加,记录每次重要选择的原因、考虑的备选方案以及最终拍板的理由。读写模式是顺序追加(像日记一样,只增不改)。

操作示例:user-auth-spec.md中,你只写:

## 认证方式 - 主要方式:基于 JWT 的 Bearer Token。 - Token 有效期:访问令牌 15 分钟,刷新令牌 7 天。

而在docs/decisions/log.md中,你会追加一条记录:

## 2024-05-27: 选择 JWT 而非 OAuth 2.0 作为主要认证方案 **上下文:** 设计用户认证模块。 **备选方案:** 1. OAuth 2.0:行业标准,第三方集成友好,但客户端/服务器端实现较复杂,对我们初期简单的内部系统而言过重。 2. Session-Cookie:传统,有状态,不利于横向扩展。 3. JWT:无状态,易于扩展,适合 RESTful API。但需妥善处理令牌注销问题。 **决策:** 采用 JWT。理由:我们初期是纯 API 服务,无第三方登录需求,且需要无状态扩展。令牌注销问题可通过短有效期访问令牌和将刷新令牌加入服务器端黑名单(小型)来解决,复杂度可控。 **记录人:** @yourname

经验之谈:这个分治策略在项目复盘、新人培训和技术债务评估时价值连城。当有人问“为什么我们不用 OAuth?”时,直接指向决策日志即可。AI Agent 在执行whylog-record技能时,会自动按照这个格式帮你归档决策,让“记录为什么”变得毫不费力。

2.4 确认门:把人放在决策回路上,而非事后救火

常见陷阱:AI Agent 能力强大,有时在理解需求后,会急于展示其能力,直接开始生成代码。如果它对需求的理解存在细微偏差,或者需求本身模糊,那么生成的代码可能就是“精致的错误”,后期修改成本反而更高。

doc-first-dev的解法:spec-firstspec-multi的工作流中,明确设置了确认门(Confirmation Gate)。具体来说,在 Phase A(分析阶段)结束时,AI Agent 会生成一份更新后的 Spec 草案,并停止行动,等待开发者(你)的明确确认。

流程示意:

  1. 你输入:/spec-first 为用户个人资料增加一个“头像裁剪”功能,支持矩形和圆形裁剪,并生成不同尺寸的缩略图。
  2. AI 进入 Phase A:分析现有user-profile-spec.md,理解需求,起草新的 Spec 变更(如新增avatar_processing字段,描述裁剪选项和输出格式)。
  3. AI 输出:“Phase A 完成。我已更新docs/plans/user-profile/user-profile-spec.md草案。主要变更为:……。请确认此 Spec 变更是否符合预期。确认后我将进入开发阶段(Phase B)。
  4. 需要仔细阅读这份草案,确认理解无误。你可以说“确认”,或者说“等等,我还需要支持自定义裁剪比例”,AI 会基于你的反馈重新回到分析阶段。

为什么这至关重要?这个强制暂停的机制,确保了人类开发者始终是需求的最终仲裁者和设计审查者。它把 AI 定位为“高效的执行者”,而非“自主的决策者”。这避免了在错误方向上浪费大量时间,也让你在代码编写前就对系统变更有了清晰的蓝图。在我自己的使用中,这个“确认门”拦截了至少30%的潜在需求理解偏差,其价值远超那一次额外的点击确认。

3. 三大核心技能深度解析与实操指南

理解了设计哲学,我们来看这三个技能具体怎么用。它们不是三个独立的工具,而是一个协同工作的体系。

3.1spec-first:单模块开发的自动驾驶仪

这是最常用、最基础的技能。它处理的是单个模块(如“用户认证”、“订单处理”、“支付回调”)内的需求变更或功能新增。

典型工作流拆解:

当你触发/spec-first <需求描述>后,它会遵循一个严谨的状态机流程:

  1. Step 0:文档匹配与初始化

    • 检查索引:首先检查docs/plans/PROJECT.md是否存在。如果不存在,会运行init.md逻辑,引导你创建一个基本的模块索引文件。
    • 模块选择器:AI 会分析你的需求,然后扫描PROJECT.md,尝试将需求匹配到已有的模块。它会给你一个列表让你选择(例如:“1. user-auth, 2. payment, 3. (Other/新建)”)。
    • 选择“新建”:如果你选择新建,AI 会引导你在docs/plans/下创建新的模块目录和 Spec 文件。我强烈建议你直接使用项目assets/目录下的tech-spec-blank.md模板,它已经预设好了结构(概述、接口、数据模型、业务流程、非功能需求等),能帮你保持文档规范。
  2. Phase A:分析与 Spec 更新

    • AI 会读取对应模块的现有 Spec,结合你的新需求,进行影响分析。
    • 然后,它会生成一份Spec 变更草案。这个草案会明确标出新增、修改、删除的部分。
    • 关键动作:确认门。草案生成后,流程暂停,等待你的确认。这是你纠正 AI 理解、补充细节的最后也是最佳时机。
  3. Phase B:开发与实现

    • 一旦你确认了 Spec,AI 就进入了“开发模式”。它会基于确认后的 Spec 来生成或修改代码。
    • 一个隐藏的依赖:构建命令。在 Phase B.4(构建验证)阶段,AI 需要运行项目的构建命令(如npm run build,go build,mvn compile)来验证代码是否可编译。这个命令从哪里来?它来自于你项目根目录的CLAUDE.md文件中的一个特定片段。这是初期 setup 的一个关键点,后面会详细说。
  4. Phase C:验收与交付

    • 代码写完后,AI 会尝试启动服务(命令同样来自CLAUDE.md)并进行一些基础的验收测试(比如调用新接口)。
    • 最后,进入 Phase D,进行一致性检查(确保代码和 Spec 对齐),并生成一个简单的交付简报。

实操配置要点:要让spec-first顺畅工作,项目需要一点前置配置,主要是CLAUDE.md文件。你需要将spec-first/assets/claude-md-snippet.md中的内容合并到你项目的CLAUDE.md中,并填写关键信息。

<!-- 这是你项目 CLAUDE.md 中需要包含的部分(根据 snippet 模板调整) --> ## 构建与开发 - **项目构建命令:** `npm run build` # 用于 Phase B.4 构建验证 - **本地开发启动命令:** `npm run dev` # 用于 Phase C.1 服务启动与验收 - **测试命令:** `npm test` ## 认证与环境(如果适用) - **API 密钥/令牌位置:** 位于 `~/.config/myapp/token` - **服务访问地址:** `http://localhost:3000` - **数据库连接字符串:** `postgresql://localhost:5432/mydb` (仅示例,敏感信息勿直接写死,可用环境变量占位符)

没有这个配置,AI 在需要构建或运行项目时会“不知所措”,导致流程中断。

3.2spec-multi:跨服务协同的交通指挥

当你的需求涉及前端、后端、数据服务等多个独立代码库或模块时,spec-first就力有不逮了。这时需要spec-multi登场。它像一个项目经理,负责协调跨边界的工作。

核心机制解析:

  1. 服务注册表(SERVICE.md):这是spec-multi的“地图”。它位于docs/plans/SERVICES.md(在 monorepo 的根目录或 workspace 的docs/plans/下)。里面记录了所有参与协同服务的元信息。

    # 服务注册表 | 服务名 | 代码路径 | 本地端口 | 描述 | 依赖服务 | |--------|----------|----------|------|----------| | frontend | ./frontend | 3000 | 用户界面 | backend | | backend | ./backend | 8080 | 核心API服务 |># 在你的项目根目录下执行 npx skills add zzusp/doc-first-dev

    这条命令会启动一个交互式 CLI。它会检测你系统里安装了哪些 Agent(如 Claude Code),然后询问你是否要为每个 Agent 安装这些技能。通常直接回车确认即可。

    手动安装(备选):如果你用的工具不在 CLI 自动检测列表,或者你想全局安装,可以手动复制文件。以 Claude Code 为例(macOS/Linux):

    # 克隆仓库 git clone https://github.com/zzusp/doc-first-dev.git # 复制技能到 Claude Code 的全局技能目录 cp -r doc-first-dev/skills/* ~/.claude/skills/

    安装成功后,在你的 AI 开发工具中,输入/应该能看到spec-first等命令提示。

    4.2 项目初始化与目录结构搭建

    假设我的新项目叫user-platform-backend

    1. 创建基础目录:

      mkdir -p docs/plans docs/decisions

      即使目录为空,也要先创建好。这是技能的约定。

    2. 初始化CLAUDE.md文件:在项目根目录创建CLAUDE.md,并将spec-first技能包里的assets/claude-md-snippet.md内容复制进去,然后根据你的项目实际情况修改。

      # user-platform-backend - 开发上下文 ## 项目概述 这是一个用户管理平台的后端 API 服务,基于 Node.js + Express + PostgreSQL 构建。 ## 构建与开发 - **安装依赖:** `npm install` - **项目构建命令:** `npm run build` (对应 `package.json` 中的 `build` 脚本) - **本地开发启动命令:** `npm run dev` (对应 `package.json` 中的 `dev` 脚本,使用 nodemon) - **测试命令:** `npm test` ## 服务与认证 - **服务访问地址:** `http://localhost:3000` - **数据库:** PostgreSQL,连接字符串通过环境变量 `DATABASE_URL` 配置。 - **认证:** 使用 JWT,密钥通过环境变量 `JWT_SECRET` 配置。 ## 代码风格与约定 - 使用 ES6+ 语法。 - 路由定义在 `src/routes/` 目录。 - 控制器逻辑在 `src/controllers/` 目录。 - 数据模型在 `src/models/` 目录。

      关键点:构建命令启动命令必须准确,这是 AI 能自动化验证和测试的基石。

    4.3 首次使用:创建一个用户认证模块

    现在,我们来触发第一个spec-first流程,创建最核心的认证模块。

    1. 在 AI 聊天框中输入:

      /spec-first 初始化用户认证模块。需要支持用户邮箱和密码注册、登录(返回JWT令牌)、以及令牌刷新接口。
    2. 跟随 AI 引导:

      • Step 0:AI 会发现没有PROJECT.md,它会主动运行初始化,生成一个简单的docs/plans/PROJECT.md索引文件,内容可能如下:
        # 项目模块索引 | 模块名 | 路径 | 简介 | |--------|------|------| | (暂无模块) | | |
      • 模块选择:AI 会提示“未找到匹配的现有模块,是否新建?”选择“新建”。
      • 命名与创建:AI 会建议模块名,比如user-auth。确认后,它会在docs/plans/user-auth/下创建user-auth-spec.md文件。这里有个技巧:你可以引导 AI 使用模板。在它询问时,你可以说:“请使用tech-spec-blank.md模板的结构来创建。” 这样生成的 Spec 会非常规范。
    3. Phase A - 分析与确认:AI 会基于你的需求,生成一份详细的 Spec 草案。内容会包括:

      • 概述:认证模块的目标和范围。
      • 接口定义:POST /api/auth/register,POST /api/auth/login,POST /api/auth/refresh的详细请求/响应格式、状态码。
      • 数据模型:User表的字段设计(id, email, password_hash, refresh_token等)。
      • 业务流程:注册、登录、刷新的步骤和校验逻辑。
      • 非功能需求:密码加密(bcrypt)、JWT 配置(有效期、密钥)。此时,务必仔细审阅这份草案!这是“确认门”。检查接口设计是否合理,字段是否齐全,安全考虑是否到位。你可以提出修改意见,例如:“登录接口的响应里,除了 access_token 和 refresh_token,还需要加上 token 的类型(Bearer)和过期时间。” AI 会据此更新草案,直到你确认。
    4. Phase B & C - 开发与验收:确认 Spec 后,AI 会开始“自动驾驶”:

      • 创建src/routes/auth.jssrc/controllers/authController.js
      • 创建src/models/User.js(可能使用 Sequelize 或 Prisma 等 ORM)。
      • 安装必要的 npm 包(bcryptjs,jsonwebtoken)。
      • 更新app.js或主路由文件,挂载认证路由。
      • 关键一步:在 Phase B.4,AI 会尝试运行npm run build。如果你的package.json里还没有build脚本,这一步会失败。因此,务必提前在package.json中配置好。对于 Node.js 项目,一个简单的构建脚本可以是"build": "echo 'No build step required for Node.js'或者"build": "npm run lint"(如果你有 lint 检查)。
      • 在 Phase C.1,AI 会尝试运行npm run dev来启动服务,并可能调用刚创建的注册接口进行验收测试。
    5. Phase D - 交付:完成后,AI 会给出一个简报,说明创建了哪些文件,修改了哪些配置,并提醒你检查决策日志。

    6. 触发决策记录:此时,你可以主动说:“记录本次决策到日志。” 或者等待 AI 提示。whylog-record技能会被触发,引导你记录为什么选择 JWT、为什么密码加密用 bcrypt 等决策。

    至此,一个完整的、文档先行的模块开发流程就走通了。你会发现,docs/plans/user-auth/user-auth-spec.md已经是一份非常完善、与代码完全同步的权威文档。PROJECT.md也被自动更新,加入了user-auth模块的条目。

    4.4 后续迭代:为认证模块添加“密码重置”功能

    现在模块已经存在,后续迭代会更加流畅。

    1. 输入:/spec-first 为用户认证模块添加密码重置功能。需要包含“发送重置邮件”和“通过令牌重置密码”两个接口。
    2. AI 在 Step 0 会通过PROJECT.md自动匹配到user-auth模块。
    3. 它直接读取现有的user-auth-spec.md,进入 Phase A,分析现有接口和模型,并起草新增功能的 Spec 变更(例如新增POST /api/auth/forgot-passwordPOST /api/auth/reset-password)。
    4. 你确认变更后,AI 会进入开发阶段,在已有的authController.js和路由文件中添加新逻辑,并可能需要更新User模型,添加reset_password_tokenreset_token_expires字段。
    5. 整个过程中,Spec 文件始终是唯一的真相来源,决策日志也追加了关于邮件服务选型(如 Nodemailer)和令牌过期策略的决策。

    5. 常见问题、避坑指南与进阶技巧

    在实际使用中,我遇到了一些典型问题,也总结出一些让流程更顺滑的技巧。

    5.1 问题排查速查表

    问题现象可能原因解决方案
    触发/spec-first无反应或报错1. 技能未正确安装。
    2. 当前 AI 工具不支持或未启用 Skills 功能。
    1. 运行npx skills list检查是否安装。使用npx skills add zzusp/doc-first-dev重装。
    2. 确认你使用的是 Claude Code、Cursor(Agent模式)等支持 Skills 的工具,并检查其设置。
    AI 提示“未找到构建命令”或构建失败1. 项目CLAUDE.md中未配置构建命令
    2.package.json中对应的脚本不存在或本身有错误。
    1. 检查并完善CLAUDE.md中的## 构建与开发部分。
    2. 确保npm run build等命令在本地可以独立运行成功。对于无需构建的脚本语言(如 Python、PHP),可以配置为"build": "echo 'Skipping build for Python project'"或运行 lint/格式化命令。
    AI 无法启动服务进行验收(Phase C失败)1.CLAUDE.md本地开发启动命令配置错误。
    2. 端口冲突或依赖服务(如数据库)未启动。
    3. 新代码本身存在启动错误。
    1. 核对启动命令,确保是npm run dev而非npm start(生产模式)。
    2. 确保数据库等基础设施已就绪。可以在CLAUDE.md中添加启动前置条件说明。
    3. 检查 AI 生成的代码,看是否有语法错误或逻辑问题导致服务崩溃。
    spec-multi找不到服务或依赖混乱1.docs/plans/SERVICES.md文件不存在或格式错误。
    2. 服务间的依赖关系声明有循环或错误。
    1. 首次使用/spec-multi时,AI 会引导创建SERVICES.md。务必按模板填写清楚每个服务的路径、端口和依赖。
    2. 仔细检查依赖关系图,确保其为一个有向无环图(DAG)。例如,frontend依赖backendbackend不能反过来依赖frontend
    决策日志log.md变得冗长难读决策日志是顺序追加的,缺乏分类。定期(如每月)对log.md进行归档。可以手动将旧的条目移动到log-2024-04.md,并在当前log.md开头添加链接。doc-first-dev的设计也支持在条目超过一定数量(如150条)后自动轮转,但需要确认具体技能的配置。

    5.2 进阶技巧与最佳实践

    1. Spec 文件的标准化模板:虽然技能提供了基础模板,但你可以为团队定制更详细的 Spec 模板。例如,强制要求每个接口必须包含成功响应示例错误响应示例边界条件性能要求。把这套模板放在团队的知识库,让 AI 在创建新 Spec 时引用,能极大提升文档质量。

    2. 利用CLAUDE.md提供更丰富的上下文:CLAUDE.md不仅是命令清单,更是项目的“AI 助手说明书”。除了构建命令,你还可以加上:

      • 架构图链接:- 系统架构图:参见 docs/architecture.png
      • 核心业务规则:- 重要:用户状态流转规则为:未激活 -> 已激活 -> 已禁用,不可逆。
      • 代码生成偏好:- 生成控制器代码时,请使用 async/await 风格,错误处理统一使用next(error)传递给全局错误中间件。这些信息能帮助 AI 生成更符合你项目惯例的代码。
    3. Monorepo 下的使用策略:如果你使用 monorepo(如 pnpm workspace, Turborepo),建议在每个子包(package)的根目录下独立维护docs/plans/CLAUDE.md。这样,当处理某个特定包的需求时,spec-first的上下文就限定在该包内,不会误操作其他包。spec-multi则可以用于协调跨包的变更。

    4. 与现有文档流程结合:如果你团队已有 PR 模板、代码审查清单,可以将“Spec 是否已更新”、“决策是否已记录”作为强制检查项加入。这样就把doc-first-dev的理念固化到了研发流程中。

    5. 处理模糊或探索性需求:有时需求非常模糊(如“优化用户体验”)。不要直接使用/spec-first。可以先和 AI 进行自由讨论,明确具体要改什么(例如:“优化登录页面的加载速度”)。将明确后的、具体的需求描述再交给spec-first处理。记住,AI 需要明确、可执行的指令。

    这套doc-first-dev方法论和工具链,其价值并非在于替代人类的思考和设计,而是通过一种轻量、可落地的约束,将良好的工程实践(文档即代码、决策可追溯、变更前确认)变成团队和 AI 协作的默认行为。它减少了沟通中的歧义,降低了返工的成本,让项目知识得以持续、有机地生长。开始可能会觉得多了一些步骤,但习惯之后,你会发现它带来的清晰度和长期可维护性,远超过那一点初始的时间投入。尤其是在 AI 辅助开发日益普及的今天,一份准确、实时的“活文档”,是让 AI 从“聪明的代码生成器”升级为“可靠的开发伙伴”的关键桥梁。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询