摘要:接手这个系列第二篇的时候,我其实犹豫了一段时间。第一篇把文档驱动的底座逻辑讲清楚了,很多朋友留言问:文档驱动到底怎么落在工程交付里?光有文档,代码还是得一行行写,那文档驱动的价值在哪? 这篇我直接从交付链路切入。AI 开……
接手这个系列第二篇的时候,我其实犹豫了一段时间。第一篇把文档驱动的底座逻辑讲清楚了,很多朋友留言问:文档驱动到底怎么落在工程交付里?光有文档,代码还是得一行行写,那文档驱动的价值在哪?

这篇我直接从交付链路切入。AI 开发走到今天这个阶段,单点用 AI 写代码已经不是新鲜事,真正拉开差距的是:你能不能把文档从"写给人看的说明书"变成"驱动整个交付流程运转的任督二脉"。工程流交付,核心不是流程本身,而是让每一环都有一份明确、可校验、能被 AI 理解和执行的文档资产。
- 为什么是"工程流"而不是"流程"——AI 交付的底层矛盾
先聊一个我反复遇到的现场。很多团队说自己在做 AI 开发,实际干的事情是:产品经理写一版需求,开发拿着需求去让大模型生成代码,模型生成一段,开发复制粘贴修一修,能跑就提交。这个模式前三周效率确实高,但真正的灾难出现在第三周之后。
AI 生成代码的速度远快于代码审查的速度,远快于需求澄清的速度,更远快于测试用例补全的速度。当模型产出的代码量超过团队能消化的上限,整个交付链路就失衡了。这个失衡跟传统软件开发中"需求蔓延"还不一样——需求蔓延是需求变多了,AI 场景下是
**
需求的理解路径变长了
**
。
传统开发里,需求到代码之间隔着一个程序员的理解和判断。程序员会去问、去想、去过滤,这个环节天然有一道"人肉稳定器"。AI 辅助开发时,如果你直接把需求丢给模型,模型会非常忠实地按字面理解去生成代码——注意,是忠实,不是正确。需求文档里一句模糊的"支持多租户",模型可能给你生成一套基于 URL 前缀的租户隔离方案,完全没考虑数据隔离和权限模型的差异,因为文档里就没写清楚。
所以我说,AI 交付的底层矛盾是:
**
意图传递的衰减率太高了
**
。传统开发里需求衰减主要体现在沟通偏差,AI 开发里需求衰减体现在文档到 Prompt 再到生成代码的全链路中。而工程流交付,本质上就是在这个衰减链路里一层层建立"防衰减栅栏"。
1.1 传统软件工程和 AI 驱动工程在交付上的本质差别
我做了个对比,方便大家直观感受差异:
维度
传统软件交付
AI 驱动软件交付
需求传递路径
需求文档 → 程序员理解 → 代码
需求文档 → Prompt → LLM → 代码
理解偏差来源
人的认知偏差、沟通损耗
文档歧义被模型"忠实放大"
变更成本
改代码 → 改测试 → 改文档
改文档 → 改 Prompt → 改生成代码
交付瓶颈
上游需求质量
文档颗粒度 + 验证机制
稳定器
程序员的工程判断
可执行的校验资产
看出差别了吗?传统交付里,文档是给人看的,程序员会做二次加工。AI 交付里,文档直接变成 Prompt 的原料,变成了模型的"默认假设来源"。文档里没有写清楚的东西,模型不会问,它会自己编一个最合理的假设填进去。
这就是为什么工程流交付里,文档驱动不仅仅是方法论层面的"写文档",而是对交付链路的一种重构。你不再是一个人肉解释需求再转成代码,而是把需求、设计、约束都固化到文档里,让 AI 在这些文档的约束下产出代码。
1.2 文档驱动不是"写文档",是把文档变成可执行资产
这个观点我在开篇提过,但这次我要把它讲得更透:在 AI 开发里,文档有两个截然不同的消费对象,一是人,二是模型(或者承载模型的上下文机制)。
写给人的文档,要求结构清楚、重点突出、有判断和取舍逻辑。写给模型的文档,要求无歧义、有边界、枚举明确、甚至要带正反例。一份文档如果只考虑人的阅读体验,丢给模型后产生的偏差会非常大。反过来,一份文档如果为了喂给模型写成了纯结构化清单,人看起来会非常痛苦,也无法形成有效的团队共识。
工程流交付里,文档必须同时服务于这两个消费对象。我的做法是:
**
文档分三层
**
。
第一层是给产品和人看的,叫意图层,描述业务背景、目标和范围边界。第二层是给设计和工程看的,叫逻辑层,包含数据模型、接口契约、状态流转和约束规则。第三层是给模型和测试看的,叫执行层,包含可运行的测试用例、Schema 定义、Mock 数据、验收断言。
很多团队只写了第一层,最多写到第二层,第三层基本没有。这就是为什么他们的 AI 辅助开发要么停留在"写点小函数可以用",要么写出了代码但测试一跑就崩。
工程流交付的骨架,就是把这三层文档做成一份连续的、互相引用的资产,让需求到设计到代码到测试,全程有据可循。
- 从需求到原型:用文档做第一轮"可运行验证"
工程流的第一步,是需求进入系统。这一步的产出物不是一份 PDF 或者 Word,而是可被后续链路消费的结构化需求文档。我自己在团队里推的标准是:需求文档里必须包含三样东西——用户故事、验收标准、边界规则。
缺少任何一个,需求文档就不允许进入技术设计阶段,更不允许直接进入 AI 生成阶段。
2.1 需求文档里最容易漏掉的"边界条件"
我先说个真实案例。有个业务方提了一个需求:"我们要做一个文档解析功能,上传 PDF 后自动提取里面的关键段落。"听起来很简单对吧?如果直接把这句话丢给大模型生成代码,模型大概率会生成一个调用 PDF 解析库、按段落切割、然后用 LLM 提取的流程。
但真实交付里,你立刻会遇到这些问题:
PDF 是扫描件还是文本型?扫描件要不要走 OCR?
页眉页脚、水印、表格内容算不算"关键段落"?
多栏排版的论文 PDF 怎么处理段落顺序?
加密 PDF 报什么错?错误信息给谁看?
单文件大小超过 50MB 还解析吗?
提取失败后是重试还是记录日志跳过?
这些任何一个不确定,AI 就会帮你做决定。而它做的决定不一定是你想要的。扫描版 PDF 被当成文本 PDF 处理,直接提取出一个空文档;多栏 PDF 的段落顺序完全混乱,提取结果逻辑断裂。
解决这个问题的方法很简单,但执行起来需要纪律:
**
需求文档里必须专设一个"边界与异常"章节
**
,把你能想到的异常输入、边界情况、不支持场景全部列出来。你不用在这一步想得百分之百全,但至少要穷举业务视角能想到的异常分支。
2.2 用 LLM 把 PRD 变成可执行测试用例
需求文档有了边界规则之后,下一步是让 AI 介入的时机。我常用的做法是:用一次上下文足够充分的 Prompt,要求 LLM 基于 PRD 生成可执行的测试用例清单。
注意,不要直接让 LLM 生成代码,先让它生成测试用例。理由是:
**
测试用例是需求文档和代码之间的翻译器,如果测试用例错了,生成代码必错。
**
具体操作是这样的:把需求文档中的功能描述、边界规则、验收标准都粘贴进上下文,然后给定一个模板,要求 LLM 输出测试用例清单。模板包含用例编号、前置条件、操作步骤、输入数据、预期结果、优先级。
举个例子,前面那个 PDF 解析需求,LLM 生成的测试用例里会有这么一条:
用例编号:TC-PDF-021
前置条件:上传一个 60MB 的文本型 PDF
操作步骤:调用解析接口,传入该文件
输入数据:60MB 文件
预期结果:接口返回明确的错误码(FILE_SIZE_EXCEEDED),提示信息为"文件大小不能超过 50MB"
优先级:P1
当你的测试用例列表里出现这类边界用例时,你的需求才算真正被"加深"了。而这些测试用例,后续可以直接作为验收测试的输入,也可以作为提示词的一部分约束代码生成。
这一步我实测下来,效率提升非常明显。以前人工写这些用例,一个模块要半天到一天。用 LLM 生成初版,人工只需要审核和补漏,时间缩短到一到两小时。而且 LLM 生成的边界用例经常能补上我们没想到的盲区。
- 契约先行:接口文档如何同时约束前后端和 AI Agent
需求层过完,进入设计层。工程流交付中,设计层的重中之重是接口契约。传统开发里,接口文档的作用是前后端协商;AI 开发里,接口文档还多了一个作用——
**
它是生成代码时的强约束
**
。
3.1 为什么 AI 写代码特别需要契约约束
大模型生成代码,本质上是概率推理。它没有"记忆",只有"上下文中的约束"。你在 Prompt 里描述"返回用户列表"和"返回 UserListDTO,字段包含 id、name、email、status,排序按 created_at 降序",生成结果的准确度是天壤之别。
我观察了很多团队用 AI 编码的姿势,最容易出的问题就是:接口契约藏在代码里,而 Prompt 里只有自然语言描述。结果模型生成的 API 字段名、类型、返回结构和真实约定对不上,跑起来报错一堆,还得人肉去改。
如果预先写好了 OpenAPI 规范的接口文档,情况就完全不同。我在项目里凡是涉及生成后端 Controller 或前端 API 调用层,一定会把接口定义文件直接作为 Prompt 的一部分。模型看到的是精确的路径、方法、请求参数、返回结构,它生成代码的自由度就被压缩到合理范围内。
3.2 实测:一份好的接口文档能让生成代码通过率翻倍
我说一个我自己项目里的横向对比数据。同一个模块,第一轮我只给模型自然语言的功能描述让它生成 Controller,结果接口层代码需要人工修正的地方大概七八处,包括路径不对、字段命名不一致、响应包装格式错误。第二轮我把 OpenAPI 契约文件贴进去,同样模块的 Controller 几乎不用改,一次跑通。
这个差距不是模型能力不同,而是
**
约束条件不同
**
。你给模型的上下文越精确,它做出精确反应的概率就越高。这就像你让一个新来的同事干活,只说"把用户信息保存一下",他大概率会来问你一堆细节;但如果你把数据库表结构、字段含义、那个项目里公用的响应包装类,以及历史代码风格示例都给他看,他基本能直接写出可用的代码。
接口契约文档本质上就是给 AI 的"资料包"。所以工程流里,我的习惯是先定义契约,再写实现。传统开发里可以先写代码后补接口文档,AI 驱动模式下这个顺序必须反过来。
契约文档的另一个重要应用场景是 AI Agent。如果你的系统里存在需要调用外部 API 的 Agent,接口契约文档可以直接转换成工具描述,交给模型做函数调用规划。LangChain4j 和 Spring AI 的生态里都有对应的工具定义方式,底层就是基于 OpenAPI 或者类似的 Schema。契约越规范,Agent 的工具调用成功率越高。
- 文档入库:把知识库、代码库和 AI 辅助工具串成一条线
文档在需求和设计阶段是给人看的,也是给模型看的,但还有一个场景容易被忽略:
**
AI 辅助工具(比如 AI 编程助手、Agent)在开发过程中的实时上下文。
**
这个场景下,文档不能只是躺在仓库里的文件,它需要被检索、被嵌入、被精准命中。
4.1 文档不是写完就完了,它是 Agent 的上下文
很多团队引入 AI 编程助手之后,发现效果远不如 demo 演示的惊艳,一个核心原因是:AI 编程助手不了解项目上下文。它知道通用语法,但不知道你的项目里 OrdersController 这个类沿用了哪个历史约定,不知道你们封装的返回结构叫 ApiResponse,不知道"状态为已删除"在数据库里是用 0 和 1 而不是布尔值。
但这恰恰是文档可以解决的。
工程流交付里,我不仅要求项目有文档,还要求这些文档能被 AI 工具直接消费。做法是:维护一个 AI 友好的文档目录,专门存放可以被检索和引用的文档片段。这些片段包括:
项目的技术架构说明(模块划分、关键依赖、运行方式)
核心业务对象和状态机的定义
接口规范摘要和易错点说明
已有的代码风格约定和命名规范
然后把它们做成可检索的索引,或者直接放进 AI 编程工具的规则文件里,让工具在生成代码时自动携带这些上下文。
4.2 一个典型的文档入库链路
这里我分享一个我们团队跑通的链路,技术栈不限制,思路通用。
第一步,文档标准化。所有项目文档统一用 Markdown 编写,放到 docs 目录,按领域划分文件。不要放 Word 或 PDF,因为这些格式没法被检索管道高效消费。
第二步,构建检索索引。对于小体量项目,最简单的做法是让 AI 编程工具直接读取 docs 目录下的文件。对于大项目,可以给文档建向量索引,或者用关键词索引就够用。关键点是:
**
文档里信息要有稳定的文件名和标题结构,这样检索的准确度才有保障。
**
第三步,把检索能力暴露给 AI 工具。在 AI 编程助手里配置规则:遇到"这个项目的响应包装是什么"这类问题时,先检索 docs/architecture 下的文件。这样模型在生成代码前,已经有你项目的领域知识在手。
我强烈建议各位在项目里实践这一步。它带来的改变不是单点提升某个函数的生成质量,而是让 AI 从"做一道题"进化到"在这个项目里做一道符合规范的题"。这个体验差异,用过的人都知道有多大。
- 交付流水线:文档变更如何触发代码生成和回归验证
说完了设计侧的驱动,工程流交付的下一个问题是:变更怎么管?
AI 开发节奏快,需求变更频繁。传统做法是提个变更单,开发改代码,测试回归。在 AI 驱动的工程流里,变更的第一落点应该是文档,而不是代码。谁先改了代码再回头改文档,流程就倒挂了。
5.1 把文档写进流水线的哪一环
我建议的流水线触发关系是:
需求变更 → 更新需求文档和验收标准
设计变更 → 更新接口契约和状态机描述
文档变更 → 触发 AI 生成或更新关联测试用例
测试用例变更 → 触发回归执行
回归通过 → 代码合并或发布
这个链路里,文档变更处在流水线的上游。一旦接口契约更新,下游测试用例的生成和回归验证就应该被触发,而不是等人手动去发现"接口改了测试该更新了"。
实际操作上,最简单的做法是在 CI 里配置一个文档变更检测。当 docs 目录下有文件变更,流水线就自动跑一个"文档影响分析"任务,识别变更涉及哪些模块,输出影响模块清单,再触发对应模块的测试套件。
这个机制在传统团队里可能要花大力气做,但在 AI 辅助下,用 LLM 分析文档 diff 可以快速做到。把变更前后的文档丢给 LLM,让它判断影响范围,输出结构化的影响清单,流水线根据清单去匹配测试套件。跑通之后,效率非常可观。
5.2 变更控制:文档 diff 和代码评审怎么联动
在 AI 辅助开发的节奏下,代码量会快速膨胀,传统的代码评审模式必然会被冲击。我的经验是:代码评审要降级,文档评审要升级。
怎么可能?逻辑是这样的。AI 生成的代码,如果 Prompt 是正确的、上下文是约束好的,代码本身的正确性是有保证的。这时候逐行去看代码反而效率低下。真正值得严格评审的是:需求文档有没有表达对?设计文档有没有覆盖边界?接口契约有没有定义清楚?
评审重点从代码审查转移到文档审查后,我发现 bug 的捕获率反而提高了。原因很简单:很多 bug 的根因根本不在代码层,而是需求理解不对或边界没有覆盖。代码层的 bug 有单元测试和集成测试兜底,但需求层的偏差只能靠文档评审兜底。
所以我的工程流里,代码合并的门禁是:相关文档更新完成、测试通过、文档评审通过。这个门禁看起来严格,其实执行起来比传统代码评审省力,因为 AI 生成的代码往往一致性很好,你只需要抽检关键逻辑,而不是逐行盯。
- 踩坑实录:LLM 生成代码的不确定性,真的可以靠文档压下去吗
最后这部分,我想诚实地聊聊这件事的边界。文档驱动再好,也有它压不住的东西。我在项目里踩过的坑不少,挑几个典型的说。
6.1 一个"文档很全但代码还是乱"的翻车案例
我们有个模块,文档写得非常详细,接口契约也规范,Prompt 里也加了上下文。但 AI 生成的代码,质量还是参差不齐。后来排查发现,问题出在一个很隐蔽的地方:
**
模型在生成跨模块调用逻辑时,丢失了项目级约束。
**
举个例子,项目的规范是所有数据库操作必须通过 repository 层,禁止业务代码里直接出现 SQL。但模型在生成一个复杂的业务分支时,不知道这个约定,直接在 Service 里写了一段 JPA 查询。代码能跑,测试也能过,但违反了项目架构约束。
为什么文档没拦住?因为那个约定在开发规范文档里,不在生成该模块代码时携带的上下文里。我们当时的 Prompt 带了接口契约、带了该模块的历史代码示例、带了相关数据模型定义,但没带那条架构规约。
这个教训很直接:
**
不是文档驱动没用,是文档的关联覆盖不完整。
**
你带进上下文的约束才是约束,没带进上下文的约束等于不存在。
6.2 用文档压不确定性的三条可行路径
踩过几次坑之后,我总结出三件事,可以显著降低 LLM 生成代码的不确定性。
第一条,把关键约束写进可校验的物理文件里。比如架构规约里说"禁止在 Service 层直接使用 JPA 查询",那就配一个静态检查规则或者架构测试,确保哪怕 AI 生成了违规代码,流水线也会拦截。文档描述是软的,校验代码是硬的,只有硬的约束能兜底。
第二条,建立"低层级组件库 + 高层级 AI 生成"的分层策略。通用的、稳定的底层功能,比如工具类、基础服务、通用组件,用规则化开发和人工审查,不允许 AI 自由发挥。AI 生成集中在业务装配层,用组件拼装业务的这部分,AI 擅长的正是这种模式。这个策略能让 AI 的不确定性被压缩在固定范围内,翻车概率大幅降低。
第三条,强制每个模块带上"代码示例"作为 Prompt 的一部分。LLM 对示例的模仿能力远强于对规范描述的理解能力。与其写十句话描述"响应包装必须是 ApiResponse 结构",不如给两段标准的 Controller 代码示例,让模型照着写。
从工程流交付的角度看,最终还是回到那句话:AI 开发里,文档质量的优先级高于代码数量。你能把需求转换为无歧义的文档资产,能把这些资产作为约束注入到 AI 生成的每一个环节,你的交付链路就立住了。至于 LLM 的不确定性,不需要靠幻想解决,靠的是给足上下文、上足校验、压足约束。实践下来的体会就是,文档驱动的核心目的不是让人少写代码,而是让每一行代码——无论是人写的还是 AI 写的——都有依据可追溯,有标准可衡量。
三、交付要点
- 同源 → 文档即单一事实源。
- 生成 → AI 依文档出代码测试。
- 变更 → 先改文档再改码。
文档驱动 AI 交付治”理解偏差”:需求、实现、验证同源于一份文档,变更先动文档,AI 据此生成,返工率显著下降。
本文整理自公开技术文章,正文未做实质性改写,仅供技术参考。正文主体与原文基本一致,版权归原作者所有;本站仅作技术学习与方案参考,如涉侵权请联系本站删除。





评论 0
还没有评论,来抢沙发吧。