第 26 章:场景七:文档生成
如果你问十个开发者"工作中最讨厌什么",至少八个会回答"写文档"。写文档痛苦,维护文档更痛苦——代码改了三版,文档还停留在第一版。但文档缺失的代价是真实的:新人入职要花两周才能跑通项目,API 调用全靠口口相传,架构决策只存在于老员工的脑子里。
本章介绍如何用 Claude Code 系统性地解决文档问题——不是让它帮你"写"文档,而是让它从代码中生成文档。生成的内容直接来源于代码本身,天然与代码保持同步。
本章前置知识:第五篇的前六章(第 20-25 章)各自独立,你可以按需跳读。本章假设你已经掌握了基础对话(第 5 章)和代码编辑(第 6 章)的基本操作。
场景描述
你接手了一个中型后端项目——一个基于 Express.js 的 RESTful API 服务,大约有 30 个 API 端点。项目已经运行了两年,积累了相当多的业务逻辑。但文档状况令人绝望:
- README:只有一行
npm start,连项目是做什么的都没写清楚 - API 文档:不存在。前端同事对接 API 全靠翻源码和口头询问
- 架构说明:零。当初为什么选 PostgreSQL 而不是 MySQL、为什么用 Redis 做缓存层——这些决策只有当初做决定的那个人知道,而他已经离职了
- 代码注释:导出函数几乎没有 JSDoc,参数类型全靠猜
老板给你的任务:两天内补全项目文档,让新来的同事能在一小时内跑通项目并理解架构。
听起来不可能?用传统方式(手动阅读代码 → 整理 → 撰写 → 排版)确实不可能。但用 Claude Code,这个任务变得可行。以下是完整的四步方案。
Step 1: API 文档自动生成
API 文档是最紧迫的需求——前端同事每天都在等你给出接口说明。Claude Code 最擅长的就是"读代码然后总结",这正是 API 文档生成的完美场景。
1.1 第一步:生成 Markdown 格式的 API 文档
首先,让 Claude Code 分析所有路由文件并生成结构化的 API 文档:
帮我分析 src/api/ 目录下的所有路由,生成一份完整的 API 文档。要求:
1. 按模块分组(用户模块、订单模块、商品模块等)
2. 每个端点列出:HTTP 方法、路径、请求参数(Query/Body/Params)、返回值结构、状态码
3. 每个端点给出一个 curl 请求示例和一个 JSON 响应示例
4. 标注哪些端点需要认证(需要 token),哪些是公开的
5. 输出为 Markdown 格式,保存到 docs/api.mdClaude Code 收到这个任务后,会执行以下操作:
- 搜索路由文件:使用 Glob 工具扫描
src/api/下的所有文件 - 逐个读取路由文件:读取每个路由定义文件,提取路由注册代码
- 追踪中间件和控制器:顺着路由定义找到对应的 controller 函数,分析请求处理和响应逻辑
- 提取参数信息:从
req.params、req.query、req.body中推断参数类型 - 提取认证信息:从
authMiddleware等中间件中判断哪些路由需要认证 - 生成文档:按你要求的格式组织所有信息
生成结果示例:
## 用户模块 (User)
### POST /api/users/register
注册新用户。
- **认证**:不需要
- **请求体 (JSON)**:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| username | string | 是 | 用户名,3-20 个字符 |
| email | string | 是 | 邮箱地址 |
| password | string | 是 | 密码,至少 8 位 |
- **成功响应 (201)**:
```json
{
"code": 0,
"data": {
"id": 42,
"username": "zhangsan",
"email": "zhangsan@example.com",
"createdAt": "2025-06-15T08:30:00Z"
}
}
```
- **curl 示例**:
```bash
curl -X POST http://localhost:3000/api/users/register \
-H "Content-Type: application/json" \
-d '{"username":"zhangsan","email":"zhangsan@example.com","password":"mypassword123"}'
```对于 30 个端点,Claude Code 通常能在几分钟内完成全部文档生成。相比手动整理(可能需要一整天),效率提升是数量级的。
1.2 第二步:生成 OpenAPI/Swagger 格式
前端同事看到 Markdown 文档后很高兴,但提出一个问题:"能不能给一个 Swagger 格式的?我们想在 Apifox 里直接导入,还能自动生成请求代码。"这个需求对 Claude Code 来说零额外成本——只需要指定输出格式:
很好,现在帮我把同一份 API 文档用 OpenAPI 3.0 格式(Swagger)重新生成一次,保存到 docs/openapi.yaml。
要求:
- 使用 OpenAPI 3.0.3 规范
- 包含 servers 配置(开发、测试、生产三个环境)
- 为每个端点添加 tags 用于 Swagger UI 分组
- 定义可复用的 components/schemas(User、Order、Product 等数据模型)
- 为需要认证的端点添加 security 配置(Bearer Auth)Claude Code 会重新读取路由文件(从上下文中已经有了之前的分析),按照 OpenAPI 规范组织输出:
openapi: 3.0.3
info:
title: Shop API
version: 1.0.0
description: 电商平台后端 API 文档
servers:
- url: http://localhost:3000
description: 本地开发环境
- url: https://test-api.example.com
description: 测试环境
- url: https://api.example.com
description: 生产环境
components:
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
schemas:
User:
type: object
properties:
id:
type: integer
username:
type: string
email:
type: string
format: email
createdAt:
type: string
format: date-time
paths:
/api/users/register:
post:
tags:
- User
summary: 注册新用户
security: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [username, email, password]
properties:
username:
type: string
minLength: 3
maxLength: 20
email:
type: string
format: email
password:
type: string
minLength: 8
responses:
'201':
description: 注册成功
content:
application/json:
schema:
type: object
properties:
code:
type: integer
example: 0
data:
$ref: '#/components/schemas/User'这就是 Claude Code 在文档生成上的核心优势:同一套分析结果,适配不同的输出格式。你不需要重新描述 API,只需要说"用另一种格式输出"。
1.3 技巧:适配项目的文档风格
每个团队的文档习惯不同。如果你已经有了一些文档,可以让 Claude Code 模仿现有风格:
参考 docs/ 目录下已有的文档格式和风格,生成 API 文档时保持一致的标题层级、表格样式和代码块语言标注。如果你还没有文档,可以先让 Claude Code 建议一种格式:
我们这个项目是一个内部微服务,文档会放在内部 Wiki 上。建议一个适合的 API 文档格式,并按照这个格式生成文档。Claude Code 会根据你的使用场景建议最适合的格式,而不是千篇一律地套模板。
Step 2: 架构决策记录(ADR)
API 文档解决了"怎么用"的问题,但还有一个更棘手的问题:"为什么"。为什么选 PostgreSQL 而不是 MySQL?为什么 Redis 只做缓存不持久化?为什么支付模块用消息队列而不是直接调用?
这些问题不会出现在代码里——它们只存在于当初做决策的人脑子里。而当那个人离职后,就变成了"幽灵知识"(tribal knowledge)。架构决策记录(Architecture Decision Records,ADR)就是用来解决这个问题的。
2.1 从 Git 历史中挖掘架构决策
Claude Code 可以帮你从 Git 历史中挖掘架构决策的线索:
帮我回顾项目的 git log(最近 200 条提交),梳理项目的主要架构决策。重点关注:
1. 引入新技术栈的提交(比如引入 Redis、PostgreSQL、消息队列)
2. 大规模重构的提交(目录结构调整、模块拆分)
3. 配置文件的大幅变更(.env.example、数据库配置变更)
4. 合并大功能分支的 PR 描述
帮我生成一份架构决策记录(ADR)文档,每条包含:
- 决策标题
- 做出决策的时间(根据 git 提交时间推断)
- 决策背景(为什么需要做这个决策)
- 决策内容(选了什么方案)
- 后果(这个决策对项目的影响)Claude Code 会读取 git log 并进行分析:
git log --oneline -200 → 发现关键提交
↓
分析提交信息中的关键词("add Redis"、"migrate to PostgreSQL"、"refactor")
↓
深入读取关键提交的 diff → 推断决策内容
↓
生成 ADR 文档2.2 人机协作:补充 Claude 无法知道的信息
Claude Code 能从 git 历史中推断出做了什么决策,但它无法知道当时为什么选择了 A 而不是 B——因为这个信息通常不在代码里。
这时候就需要人机协作:Claude 生成框架,你补充业务理解。
Claude 生成的 ADR 草稿:
---
## ADR-003:选择 PostgreSQL 作为主数据库
- **日期**:2024-03-15
- **状态**:已采纳
- **决策**:使用 PostgreSQL 替代原本的 SQLite
待补充:选择 PostgreSQL 的具体原因。你的补充指令:
补充我现在的理解到 ADR-003:当时选择 PostgreSQL 是因为:
1. 需要支持 JSONB 字段存储灵活的商品属性
2. 需要全文搜索功能(pg_trgm)
3. 团队对 PostgreSQL 更熟悉,SQLite 在并发写场景下出现锁竞争问题
另外 ADR-001(选择 Redis 做缓存)请补充:当时评估过 Memcached,但 Redis 的数据结构更丰富,方便后续做排行榜功能Claude Code 会将你的补充内容组织成正式的 ADR 文档:
## ADR-003:选择 PostgreSQL 作为主数据库
- **日期**:2024-03-15
- **状态**:已采纳
- **作者**:张三(基于 git 历史推断),李四(补充)
### 背景
项目初期使用 SQLite 作为开发数据库,但随着业务增长,遇到了以下问题:
- 商品 SKU 属性差异大,需要灵活的字段存储
- 需要支持商品搜索的模糊匹配
- SQLite 在并发写入场景下出现锁竞争,影响订单创建性能
### 决策
将主数据库从 SQLite 迁移至 PostgreSQL 14。
### 考虑的替代方案
| 方案 | 优点 | 缺点 | 结论 |
|------|------|------|------|
| MySQL 8.0 | 团队有运维经验 | JSON 支持不如 PostgreSQL;全文搜索需额外配置 | 不采用 |
| PostgreSQL | JSONB 原生支持;pg_trgm 全文搜索;并发控制更好 | 运维经验较少;迁移成本 | **采用** |
| 继续用 SQLite | 无需迁移 | 无法解决并发和功能需求 | 不采用 |
### 后果
- **正面**:JSONB 字段解决了商品属性的灵活存储;全文搜索性能满足需求;并发写入不再出现锁竞争
- **负面**:团队需要学习 PostgreSQL 运维;历史数据迁移花费了 3 个工作日
- **风险**:PostgreSQL 的 vacuum 机制需要定期维护这就是 Claude Code 在 ADR 场景中的正确用法:它负责还原历史、整理格式、生成框架;你负责补充决策背后的业务原因和上下文。两者结合,才能产出真正有价值的架构文档。
2.3 持续维护 ADR
ADR 不是一次性的文档。每次重大架构变更时,都应该新增一条 ADR。你可以把这件事也交给 Claude Code:
我刚才把支付模块从 REST API 改成了 gRPC。帮我生成一条新的 ADR,记录这个架构决策。变更涉及的文件在 git diff 里可以看到。Step 3: README 与项目文档
有了 API 文档和 ADR 之后,接下来补充项目最核心的入口文档——README。一个优秀的 README 应该让新人在几分钟内了解项目全貌并成功运行。
3.1 生成完整的 README
帮我重新写 README。当前 README 只有一句 "npm start",太简陋了。新的 README 应该包含以下内容:
1. 项目简介(一段话概括项目做什么、解决什么问题)
2. 技术栈(前后端技术、数据库、中间件)
3. 快速开始(从 clone 到跑起来的最少步骤,要求每一步都可执行)
4. 目录结构(顶层目录和各模块的职责说明)
5. 环境变量说明(从 .env.example 读取并生成说明)
6. 常用命令(dev / build / test / lint 等)
7. 贡献指南(分支规范、commit 规范、PR 流程)
8. 联系方式
先读取 .env.example、package.json、目录结构,然后生成 README。保存到 README.md。Claude Code 的生成过程:
读取 package.json → 提取项目名、依赖、scripts
读取 .env.example → 提取所有环境变量
读取目录结构 → 理解项目组织方式
读取 CLAUDE.md(如果存在)→ 获取项目上下文
读取 Git 配置 → 了解分支和贡献信息
↓
组织生成 README.md生成的 README 示例对比:
之前:
# shop-api
npm start之后:
# Shop API
基于 Express.js 的电商平台后端 API 服务,提供用户管理、商品管理、订单处理、支付集成等核心功能。
## 技术栈
- **运行时**:Node.js 18+
- **框架**:Express.js 4.x
- **数据库**:PostgreSQL 14 + Redis 7
- **ORM**:Prisma
- **认证**:JWT + bcrypt
- **消息队列**:RabbitMQ(支付回调)
- **日志**:Winston + Morgan
## 快速开始
### 前置要求
- Node.js >= 18.0.0
- PostgreSQL >= 14
- Redis >= 7
- pnpm >= 8
### 安装与运行
```bash
# 1. 克隆项目
git clone git@github.com:team/shop-api.git
cd shop-api
# 2. 安装依赖
pnpm install
# 3. 配置环境变量
cp .env.example .env
# 编辑 .env,填入你的数据库连接信息
# 4. 初始化数据库
pnpm db:migrate
pnpm db:seed # 可选,填充测试数据
# 5. 启动开发服务器
pnpm dev
# 服务运行在 http://localhost:3000
# API 文档:http://localhost:3000/api-docs目录结构
shop-api/
├── src/
│ ├── api/ # 路由定义(按业务模块组织)
│ ├── controllers/ # 请求处理逻辑
│ ├── services/ # 业务逻辑层
│ ├── models/ # 数据模型(Prisma Schema)
│ ├── middleware/ # Express 中间件
│ ├── utils/ # 工具函数
│ └── app.js # 应用入口
├── prisma/ # Prisma 迁移文件
├── tests/ # 测试文件
├── docs/ # 项目文档(API 文档、ADR)
└── scripts/ # 辅助脚本常用命令
| 命令 | 说明 |
|---|---|
pnpm dev | 启动开发服务器(热重载) |
pnpm build | 构建生产版本 |
pnpm start | 启动生产服务器 |
pnpm test | 运行测试 |
pnpm lint | 代码规范检查 |
pnpm db:migrate | 执行数据库迁移 |
pnpm db:studio | 打开 Prisma Studio |
(其余部分略,实际生成的 README 会更完整)
**对比**:从两个词到一份完整的项目说明书。新人按照快速开始指南,通常能在 10 分钟内跑通项目——这就是文档的直接价值。
### 3.2 生成新人 Onboarding 指南
README 解决了"跑起来"的问题,但新人还有一个需求:"第一天我应该做什么?"刚才的 README 写得很好。现在帮我给新人写一份 onboarding 指南,保存到 docs/ONBOARDING.md。
内容包括:
- 第一天:环境准备、运行项目、了解基本命令
- 第一周:阅读关键文档、了解业务流程、跑通测试
- 第一月:独立完成一个小需求、参与 Code Review
- 常用工具和链接(Jira、Confluence、监控面板、日志平台)
- 团队联系人(各模块负责人,先留空让团队自己填)
要求语气友好,面向刚毕业的校招生也能看懂。
Claude Code 会基于它已经读取的项目信息(目录结构、技术栈、常用命令)生成一份友好的 Onboarding 文档,新同事的第一天不再是"不知道干什么只能发呆"。
### 3.3 为每个模块生成 README
大型项目中,每个子模块也值得有自己的 README。这可以批量完成:src/ 目录下有以下模块:api/、controllers/、services/、models/、middleware/、utils/。
帮我给每个模块生成一个简短的 README.md,放在对应目录下。每个 README 包含:
- 模块职责说明
- 主要文件列表和用途
- 模块间的依赖关系
Claude Code 会逐个读取各目录的文件,为每个模块生成专属的 README。这样当一个开发者进入任意目录时,都能快速理解这个模块的职责和结构。
## Step 4: 代码注释补充
文档的最后一块拼图是**代码注释**。外部文档(API 文档、README)说明"怎么用",但代码注释说明"怎么实现"——当其他开发者需要修改代码时,注释是他们的地图。
### 4.1 分两步走:先列出,再执行
让 Claude Code 直接修改所有文件是危险的——你可能不想让它动某些文件,或者想先看看它会加什么注释。推荐的安全做法是**分两步走**:
**第一步:列出需要补充注释的函数**。扫描 src/ 目录下所有 .js 文件中缺少 JSDoc 注释的导出函数,给我列一个清单,标注:
- 文件路径
- 函数名
- 参数列表(从函数签名提取)
- 当前是否有注释
不要修改任何文件,只列出清单。
Claude Code 的输出示例:需要补充注释的导出函数清单:
src/services/userService.js
- createUser(username, email, password) → 无注释
- getUserById(id) → 无注释
- updateUser(id, data) → 无注释
src/services/orderService.js
- createOrder(userId, items) → 无注释
- calculateTotal(items) → 无注释
- validateOrder(order) → 有部分注释但不完整
src/utils/formatDate.js
- formatDate(date, format) → 无注释
- parseDate(str) → 无注释
...共 47 个函数需要补充注释
**第二步:确认清单后,批量补充**。确认清单没问题。帮我对清单中的每个函数补充 JSDoc 注释,要求:
- 描述函数的功能(一句话)
- @param 标注每个参数的类型和说明
- @returns 标注返回值的类型和说明
- @throws 标注可能抛出的异常
- 如果函数逻辑复杂,在注释中给出一个 @example
对于已有部分注释的函数,只补充缺失的部分,不要改动已有的注释内容。
Claude Code 会逐个打开文件,使用 Edit 工具精确地在函数上方插入 JSDoc 注释:
```javascript
// 之前
function createUser(username, email, password) {
if (!username || username.length < 3) {
throw new ValidationError('用户名至少需要 3 个字符');
}
const hashedPassword = await bcrypt.hash(password, 10);
return db.user.create({
data: { username, email, password: hashedPassword }
});
}
// 之后
/**
* 创建新用户,对密码进行 bcrypt 哈希后存入数据库。
*
* @param {string} username - 用户名,至少 3 个字符
* @param {string} email - 用户邮箱,会验证格式
* @param {string} password - 明文密码,存储前进行 bcrypt 哈希
* @returns {Promise<User>} 创建成功的用户对象
* @throws {ValidationError} 当用户名、邮箱或密码不符合要求时抛出
* @example
* const user = await createUser('zhangsan', 'zhangsan@example.com', 'securePass123');
* console.log(user.id); // 42
*/
function createUser(username, email, password) {
// ...
}4.2 谨慎对待注释生成
Claude Code 生成的注释基于代码逻辑推断,大部分时候是准确的,但也可能出现偏差——特别是当函数名和实际行为不一致时。比如一个名叫 validateOrder 的函数,实际还做了金额计算,Claude 可能只根据函数名推断它只做校验。
因此,生成的注释需要 Review。好在这个 Review 比完全手写注释快得多——你只需要检查"它说的对不对",而不是"该说什么"。检查的要点:
- 函数描述是否准确:对照代码逻辑确认
- 参数类型是否正确:特别是 JavaScript 这类弱类型语言
- 异常情况是否遗漏:特别是一些隐式抛出的异常
- 示例代码是否可运行:如果有
@example,确保代码是正确的
26.5 复盘与技巧总结
回顾本章四步的文档生成流程:
API 文档生成 → 解决了"怎么用",前端同事不再翻源码
架构决策记录 → 解决了"为什么",防止幽灵知识
项目文档 → 解决了"怎么上手",新人一小时跑通项目
代码注释 → 解决了"怎么实现",降低维护成本这个四步流程覆盖了项目文档的四个核心维度,从外部接口到内部实现,从当前状态到历史决策。
文档生成的核心技巧
1. 指定输出格式比指定内容更重要。 你不需要解释 API 长什么样(Claude 会自己读代码),但你必须说清楚输出格式(Markdown、OpenAPI、JSDoc)。Claude Code 理解格式的能力很强,只要格式明确,输出质量就稳定。
2. 先要清单,再执行修改。 在代码注释这种涉及大量文件修改的场景中,一定分两步走。先让 Claude 列出"要改什么",你确认后再让它执行。这不只是安全考虑,也是一次人工审核的机会——有些函数你可能觉得不需要注释,可以在清单阶段排除。
3. 人机协作:AI 负责还原"做了什么",你负责补充"为什么"。 在 ADR 生成中,Claude 能从 git 历史推断出决策内容,但决策背后的业务考量需要你来补充。这是一个经典的分工模式:AI 承担信息整理的工作,你把精力花在只有你知道的信息上。
4. 维护比生成更重要。 文档最大的敌人不是缺失,而是过时。生成文档只是第一步,关键是要有维护机制。一个实用的策略:每次功能变更完成后,追加一句"同步更新相关文档"。比如:
功能已完成。请同步更新 docs/api.md 中涉及 POST /api/orders 的部分,请求体新增了 discountCode 字段。这样文档就能和代码保持同步,不会出现"文档写的和代码做的是两回事"的尴尬局面。
5. 模仿现有风格,保持一致性。 如果项目已有部分文档,让 Claude Code 模仿现有样式——标题层级、表格风格、代码块语言标注。一致的文档风格能大幅降低阅读成本。
常见问题与对策
| 问题 | 对策 |
|---|---|
| Claude 生成的文档有事实错误 | 这是最需要警惕的问题。对于函数行为、参数类型的描述,一定要抽样核对代码。不要因为"看起来合理"就全盘接受 |
| 大型项目一次生成太多,质量下降 | 分模块生成。先做用户模块的 API 文档,再做订单模块。上下文窗口有限,任务越聚焦,质量越高 |
| 生成的注释风格不统一 | 可以在指令中给出一个注释模板:"所有 JSDoc 请参考 src/utils/formatDate.js 中已有的注释风格" |
| Claude 遗漏了一些端点 | 重新检查。可以说"src/api/order.js 中还有 POST /api/orders/:id/refund 端点没有包含在文档中,请补充" |
| git 历史太长,分析不完整 | 指定时间范围,比如"只分析 2024 年之后的提交",或者分段分析,"先分析 2024 年的,再分析 2025 年的" |
文档生成后的维护策略
生成文档只是开始。为了让文档持续保持价值,建议建立以下机制:
- 把文档检查纳入 PR 流程:CLAUIDE.md 中加入一条规范——"涉及 API 变更的 PR,必须同步更新 docs/api.md"
- 让 Claude Code 在功能开发完成后自动提醒:养成习惯,每次功能开发完成时追加一句"请检查并更新相关文档"
- 定期审计:每季度跑一次"扫描代码与文档的一致性",让 Claude Code 对比 API 文档和实际路由,找出不一致的地方
- 文档版本管理:文档和代码放在同一个 repo 中(而不是外部 Wiki),这样文档就能跟着代码一起在 PR 中被 Review,一起被版本管理
本章小结
本章介绍了用 Claude Code 系统化补充项目文档的四步法。核心要点:
- API 文档:让 Claude 读取路由代码,直接生成 Markdown 或 OpenAPI 格式的文档。关键是指定输出格式,同一套分析结果可以适配不同格式。
- 架构决策记录(ADR):让 Claude 回顾 git 历史挖掘架构决策,你补充业务背景。人机协作是这个环节的核心模式。
- README 与项目文档:从零生成完整的 README、Onboarding 指南、模块 README。一个指令,一份完整文档。
- 代码注释:采用"先列出清单,确认后再执行"的安全模式,避免大规模无监督修改。
- 文档维护比生成更重要:建立"代码变更 → 同步更新文档"的工作习惯。
文档不是一次性的工程,而是项目持续健康的保障。Claude Code 的价值不在于"帮你写字",而在于把写文档的成本降到接近于零——当文档成本足够低时,"没时间写文档"就不再是一个合理的借口。
下一章将介绍 CI/CD 场景——如何将 Claude Code 接入持续集成流水线,实现自动化 PR Review 和 Issue 分类。