Skip to content

文档先行——需求分析是编码的前提

为什么需要文档先行

对于大型项目来说,文档先行不是"最佳实践",而是保命措施。Growth 产品矩阵有 57 个 .NET 项目、横跨五种语言、仓库中有 19 份需求分析文档。在这样的体量下,跳过文档直接编码几乎必然后悔。

有三个硬理由让你必须在编码之前写文档。

理由一:验证方案的正确性

这是最直接的理由:只有方案对了,才值得编码。

需求分析文档不是写完了就完的。它需要被审查、被质疑、被验证。让团队中的其他人(或者 AI)阅读你的文档,判断业务流程是否完整、架构设计是否合理、修改清单是否有遗漏。发现错误只需要改几行文字,而不是改几千行代码。

方案一旦确认,编码阶段就不会有三心二意的反复——你已经有了一份经过验证的设计蓝图。

理由二:大模型记忆有限,减少 Token 消耗

这一点很容易被忽略,但在实践中价值非常大。

AI 的上下文窗口是有限的。当你让 Agent 修改一个三个月前开发的功能模块,它不知道这个模块当初是怎么设计的——它要么靠训练数据中的记忆猜,要么重新读一遍整个模块的代码。两个方式都不理想:猜会错,重读浪费 token。

但如果你有一份需求分析文档,情况完全不同。Agent 只需要读这篇文档,就能快速恢复对模块的理解——包括业务背景、架构设计、接口定义、数据流向。文档是对模块上下文的高密度压缩,比直接读几十个代码文件便宜得多,也准确得多。

这个优势在频繁修改的模块上尤其明显。如果你的工作中经常需要反复改动某个核心模块,每次改动前读一遍文档而非读一遍代码,长期下来的 token 节省非常可观。

理由三:团队协作

大型项目的生命周期远超过一个人的参与周期。Growth 产品线的代码我写了 200 万行,但如果有新人加入,或者半年后的我自己回来接手一个模块,我不可能记得当初为什么这么设计。

文档就是给未来的人(包括未来的你)留下的设计笔记,回答三个问题:

  • 这个模块当初为什么要这么设计?
  • 这个接口的参数为什么是这三个?
  • 这个架构决策是在什么约束下做出的?

没有文档,新人的"为什么"只能靠猜或者翻 git blame。

理由四:Bug 或方案错误的追溯依据

编码完成后发现 Bug,或者上线后出了故障,第一件事不是改代码——是翻当初的设计文档,确认问题是出在方案层面还是实现层面。

  • 如果是方案问题:需求分析时遗漏了一条边界条件 → 修正文档后重新编码
  • 如果是实现问题:编码偏离了设计方案 → 按文档修正代码

没有文档,Bug 复盘只能靠人脑回忆"当时怎么设计的",效率低且不可靠。文档就是方案的"源代码"——Bug 出现在代码里,原因很可能在方案中。

我的需求分析文档系统

在 Growth 产品线中,我建立了一套完整的需求分析文档体系,并将其封装为一个 Skill(create-proposal),每次新需求自动按模板生成。

文件命名规范

MMDD-HHMMSS-具体需求名字.md

示例:

  • 0408-143052-新增插件创建接口.md
  • 0408-091230-修复工作流执行异常.md
  • 0409-161500-优化批量查询性能.md

时间戳精确到秒,这是这套命名体系的核心——按时间排序自动就是需求的时间线,追溯历史改了什么一清二楚。

PowerShell 生成命令:

powershell
$timestamp = Get-Date -Format "MMdd-HHmmss"
$filename = "$timestamp-具体需求名字.md"

文档存储路径

D:\DEV\CODE\Automator\Components\Documents\需求分析记录\

存放在项目仓库内部的 Documents 目录下,AI 可以直接读取。以下是实际项目中的文档目录:

需求分析文档目录

每个文件代表一次独立的需求分析,按时间线排列,追溯起来非常直观。

文档结构规范

每份需求分析文档遵循固定的五段式结构:

markdown
# [需求标题]

> **创建时间**: YYYY-MM-DD HH:MM:SS  
> **需求描述**: 一句话描述需求  
> **涉及模块**: CLI/CodeRunner/LLM/Plugin/Workflow  
> **涉及层级**: Interfaces/Implementations/Engine/Persistence

---

## 一、需求分析

### 1.1 业务背景
描述业务场景和背景

### 1.2 核心问题
需要解决的核心问题

### 1.3 预期结果
完成后的效果

---

## 二、业务流程分析

### 2.1 业务流程图
用文本图描述业务流程

### 2.2 关键步骤说明
| 步骤 | 操作 | 说明 |
|------|------|------|

---

## 三、架构设计

### 3.1 模块依赖关系
模块间的依赖关系图

### 3.2 数据流向图
数据在模块内部的流向

### 3.3 接口设计
接口名称、层级、职责、方法列表

---

## 四、修改清单

按模块层级列出所有新增和修改的文件:

| 层级 | 操作 | 文件路径 | 目的 |
|------|------|----------|------|
| Interfaces | 新增 | I{Xxx}Service.cs | 定义对外契约 |
| Implementations | 新增 | {Xxx}Service.cs | 实现业务逻辑 |
| Engine | 新增 | {Xxx}Engine.cs | 核心引擎 |
| Persistence | 新增 | Entity/{Xxx}Entity.cs | 数据实体 |

---

## 五、编码实施

### 自底向上实现顺序
1. Persistence/Entity → 数据库实体定义
2. Persistence → 数据访问层
3. Engine → 核心引擎逻辑
4. Implementations → 接口实现
5. Interfaces → 对外接口定义
6. {ModuleName}Module.cs → DI容器注册

### 验证步骤
1. 编译检查
2. 单元测试
3. 集成测试
4. 异常场景测试

完整的 Skill 自动化

这套流程被封装为 create-proposal Skill(通过 /create-proposal 命令触发),AI 自动完成:

  1. 生成时间戳文件名
  2. 按模板填充文档结构
  3. 写入 需求分析记录 目录
  4. 后续编码按自底向上顺序执行

检查表:需求分析文档质量

  • [ ] 文件名是否包含精确到秒的时间戳?
  • [ ] 是否回答了"不改会有什么后果"?
  • [ ] 业务流程是否覆盖了正常流程 + 异常流程?
  • [ ] 架构设计是否标注了模块间的依赖关系?
  • [ ] 修改清单是否覆盖了所有受影响的层级?
  • [ ] 修改清单中的每个文件是否标注了操作类型(新增/修改/删除)?
  • [ ] 是否有一个明确的验收标准?
  • [ ] 文档是否已经过至少一次审查?

实践反思:为什么没有用 OpenSpec

你可能听说过 OpenSpec——一个开源的 spec-driven development 框架,由 GitHub 母公司推动,核心理念跟"文档先行"很像:写 spec、对齐需求、再编码。

我们在项目中试用过一段时间。结果是没有用下去,原因很简单:太复杂了,团队不划算。

OpenSpec 定义了一套完整的工作流:proposal → tasks → design → validate,每个环节有固定的文件结构和 CLI 指令。对于一个人维护的项目来说,这套流程的维护成本超过了它带来的收益——你需要记指令、维护 spec 文件树、处理 validate 报错。

这也解释了为什么目前使用 OpenSpec 的团队并不多。工具本身的设计理念是对的(先写 spec 再编码),但执行成本偏高。

我们的选择更简单:需求分析文档 + AI 提交日志。

  • 需求分析文档(MMDD-HHMMSS 命名)覆盖了 OpenSpec 的 proposal + design 环节
  • AI 生成的 git commit 日志覆盖了 task tracking 和变更追溯
  • 一个 /create-proposal Skill 替代了 OpenSpec 的整套 CLI
  • 不需要额外的 spec 文件树,文档就在仓库的 Documents/需求分析记录

��终效果一样:先写方案、确认方案、再编码、变更可追溯。 但维护成本低了一个数量级。

当然,这套做法适合的是小团队或个人开发者的场景。我之前在蚂蚁金服时,面对的完全是另一种局面:工程体量巨大、微服务架构、团队分散在不同城市,每个小团队可能有自己的编码规范和设计风格。那种环境下,不可能让每个小团队各自定义一套文档体系——必须由内部研发平台提供统一的工具链和规范约束。这属于企业内部工程平台建设的范畴,跟本书讨论的 AI 编码工具使用方法不是同一个话题,不展开。

但有一点值得在这里点出来,跟我推崇 Qoder Quest 模式但不完全信任它的原因有关:Quest 模式是一个"黑盒"。

你给它一个需求描述,它自己拆任务、编码、测试、交付,中间过程你是看不见的。问题在于——架构师对项目的宏观掌控力在 Quest 模式下被削弱了。你没办法像编辑器模式那样,每改一个文件就看 diff、中间随时纠偏。Quest 跑完了你才看到结果,这时候发现方向偏了,成本已经发生了。

所以 Quest 模式的有效性高度依赖文档先行:文档越精确,Quest 的黑盒风险越低。 而架构师必须做的,就是对照文档和 Quest 产出的代码进行 review,而不是因为 Quest 是"自动的"就放弃审查。编辑器模式是"开盒"的,每一步你都能介入;Quest 是"黑盒"的,你必须用文档来框定它的边界。两者不是替代关系,而是不同自主程度下的不同控制策略。

引申开来,这两种模式在适用场景上有清晰的划分:

维度Quest 模式Agent/IDE 模式
适合场景新建工程、新产品、一次性原型复杂项目、遗留系统、已有代码库
代码风险没有存量代码可破坏改错了可能影响现有功能
介入方式定义目标 → 审查结果全程实时纠偏
试错成本低(大不了 reject 重来)高(需要理解已有架构才能改对)
对架构的理解要求低(从零开始设计)高(必须理解现有代码才能改对)

核心逻辑:存量代码越多,越需要透明度。 Quest 模式在新项目上效率极高,因为你不需要担心"改错了什么"——本来就没有东西可破坏。但在遗留系统上,每一步改动的副作用都可能是灾难性的,你需要 Agent 模式的"玻璃盒"来确保每步都可控。Quest 的半透明度和风险是匹配的——新项目风险低,半透明就够了;遗留项目风险高,需要全透明。

为什么很多人说"AI 写的代码无法维护"

如果你经常刷技术社区,一定见过这些抱怨:

"AI 生成的代码根本没法维护,越改越乱。" "用 AI 写了三个月,代码重复率到了 90%,整个项目废了。" "AI 根本不懂项目架构,每次都在自由发挥。"

这些抱怨是真的吗?是真的。但问题不在 AI 本身,而在使用方式——这些几乎全部是 Quest 模式(或类似的自主模式)长期使用后的必然结果。

三个根因

1. 上下文窗口有限,AI 每次都当新项目写

Quest 模式下,AI 的每一次任务都是一次独立的 LLM 调用。它不记得上一次改了什么,更不记得整个代码库里已经有哪些工具函数、哪些通用组件。结果就是:同一个功能,两个 Quest 会话各自写了一套实现,逻辑大同小异,代码却完全不同。

这不是 AI 笨,是上下文窗口放不下整个代码库。Agent/IDE 模式你可以随时让 AI "先看看这个文件""参考一下那个模块",通过人工引导弥补上下文的不足。Quest 模式没有这个机制。

2. 无法方便地指定目录和框架

Quest 模式没有目录树。你没法告诉 AI "用 CLI/Engine/ 下面的那个工具类"或"参考 Workflow.Node/ 里的模式"。AI 不知道项目里已经有什么框架、什么工具函数,它只能凭训练数据的记忆去猜——猜对了是运气,猜错了就是"又写了一套轮子"。

相比之下,Agent/IDE 模式有完整的目录树支持。你可以精确地让 AI 阅读特定文件、参考特定模块,甚至指定"这次的修改范围只在这个目录下"。路径引导是控制 AI 输出质量的核心手段。

3. 长期使用就是"自由风格"开发,代码持续腐化

Quest 模式下没有架构师的角色。没有人在每次修改时检查"这个函数是否应该复用已有的工具类""这个模式是否符合项目规范"。每一次 Quest 都在按自己的"自由风格"生成代码——今天用 A 模式,明天用 B 模式,后天混着用。

我有一个朋友长期使用 Trae 的 SOLO 模式(跟 Qoder Quest 模式同类),最后被迫做了一次全量重构。重构时发现代码重复率高达 90%——同一个工具函数的功能,在代码库里被不同的 Quest 会话以不同的参数签名、不同的实现路径写了五六遍。每一次修改正确的代码,却因为互相不知道彼此的存在,导致了灾难性的重复。

这不是猜测,研究已经证实

2026 年,中山大学与阿里巴巴联合发布了 SWE-CI 评测,首次系统评估了 AI 的长期代码维护能力。结论触目惊心:

  • 在长期代码维护任务中,大多数 AI 大模型在超过 75% 的任务中会破坏原本正常的代码功能
  • 只有 Claude Opus 保持了 50% 以上的"零退化率"(修改后不破坏原有功能的比例),绝大多数模型的零退化率低于 25%
  • 研究团队直言:"写代码"和"维护代码"是两种截然不同的能力

独立代码审查工具 CodeRabbit 的分析也印证了这一点:AI 编写的代码出现问题的概率是人工代码的 1.7 倍

可靠性工程公司 Entelligence AI 的统计更直接:企业 44% 的 AI Token 消耗用于修复 AI 自己生成的 Bug

为什么 IDE 模式能避免

回到文档先行和 IDE 模式,你会发现这三个问题被系统地规避了:

Quest 模式的问题IDE 模式的解决方案
每次当新项目写 → 重复代码路径引导 + 文档阅读,AI 知道项目已有结构
无法指定目录 → 无法复用框架目录树精确指定"参考/修改范围"
自由风格 → 代码腐化人实时介入纠偏 + Rule 约束编码风格

一个简单判断标准:如果你不确定 AI 对项目的理解程度,就不要让它自主执行。 先切到 IDE 模式,引导 AI 阅读关键文件和文档,确认理解正确后再让它动手。

实战示例:三种技术如何协同

上面讲了这么多理论,来看三个真实案例,分别展示上下文提供Skill 约束参考框架对比三种技术在实际中是怎么用的。

示例一:上下文提供——需求分析文档驱动 LLM 节点改造

场景:需要为工作流引擎的 LLM 节点增加流式输出支持。

做法:先写一份需求分析文档,精确描述要做什么:

文件 Documents/需求分析记录/0603-163407-工作流节点流式输出基础设施.md

文档结构:需求分析 → 业务流程 → 架构设计 → 修改清单 → 编码实施

文档中包含了完整的架构设计——事件总线模式、接口定义、模块依赖关系、甚至数据库表结构和写入策略:

INodeStreamBus ──→ NodeStreamBusImpl ──→ IWorkflowNodeStreamListener
(执行器注入)      (收集+分发+持久化)      (业务层实现)

效果:AI 不需要从零猜测设计。它直接拿到完整的架构方案,编码时只需要按文档逐条实现。每一个接口叫什么、放在哪个目录、依赖谁——文档全写清楚了,AI 不会跑偏。

这就是"文档是对模块上下文的高密度压缩"的实战体现。一份文档替代了 AI 对整个代码库的盲目扫描。

示例二:提示 Skill——Rule 约束节点执行器编写规范

场景:团队中所有工作流节点执行器必须保持统一的结构。

做法:编写一条 Rule,精确告诉 AI 怎么写节点执行器:

文件 .qoder/rules/node-executor-files.md

trigger:file_glob,作用于 **/Execution/*.cs 文件

这条 Rule 直接给出了代码必须遵循的模板:

csharp
// Rule 中定义的强制执行器模板
protected override async Task<Dictionary<string, object>> ExecuteNodeAsync(
    TConfig config,
    Dictionary<string, object> input,
    ILogger logger,
    CancellationToken ct)
{
    LogFormatHelper.EnterScope($"执行 {config.NodeId}", LoggerName);

    // 1️⃣ 必需字段校验 → 直接抛异常
    // 2️⃣ 可选字段降级 → Debug 日志
    // 3️⃣ 核心业务逻辑 → 不套 try-catch
    // 4️⃣ 输出结果

    LogFormatHelper.ExitScope("成功", LoggerName);
    return result;
}

同时还约束了:EnterScope/ExitScope 成对出现、所有日志传 LoggerName、不套 try-catch。

效果:不管是谁在什么时候让 AI 新建节点执行器,生成的代码结构永远一致。没有 Rule 的时候,同一个模块里的执行器可能三四种写法;有了 Rule,AI 不可能写出不符合规范的执行器代码。

示例三:参考框架对比——理解 deer-flow 的 Agent 设计,反哺 Growth 架构

场景:想了解业界其他 Agent 系统的架构设计,跟自己的系统做对比。

做法:让 AI 阅读外部参考项目 deer-flow(一个基于 LangGraph 的 AI Agent 系统)的架构文档,然后跟 Growth 产品线的设计做对比分析。

deer-flow 的核心架构:

Lead Agent(主 Agent,工厂+系统提示词)
  → Middlewares(10 个中间件组件)
    → SubAgent(子代理委派系统,内置+外部)
      → Tools(内置工具 + MCP 集成)
        → Sandbox(沙箱执行,本地 + 容器)

对比 Growth 的架构:

Agent 执行引擎(AIAgent 装饰器管道)
  → Workflow Engine(工作流编排,有向图)
    → Tool System(AITool/AIFunction)
      → Code Sandbox(Wasm + Hyperlight 多级沙箱)

发现

对比维度deer-flowGrowth
编排方式Middleware 链(顺序执行)Workflow 有向图(分支+并行+循环)
子代理SubAgent 委派系统Agent 分工(CodeReview/Browser/编码)
沙箱本地 + Docker 容器Wasm + Hyperlight 多级沙箱
工具集成内置工具 + MCPAIFunction + MCP
架构类型LangGraph Server + Python.NET 装饰器管道 + C#

效果:通过对比,你能清楚地知道自己的系统在哪方面更强(Growth 的工作流图模型更灵活),哪方面可以借鉴(deer-flow 的 Middleware 设计)。AI 帮你做这种跨项目的架构对比只需要几分钟,如果人工读两个项目的文档做对比,至少半天。


三个示例分别对应了三种技术:文档提供上下文、Rule 约束输出、参考框架对比。这三者是 IDE 模式下引导 AI 的核心手段——有了它们,AI 不再是"盲猜",而是基于精确上下文的有方向输出。