【AI Native开发-00】代码生成变快之后,为什么交付反而更难了?
这是“AI Native 开发”系列的第 0 篇。本系列讨论一个具体问题:当 AI 成为软件生产过程中的重要执行者,我们如何用 SDD 开发、验证并交付传统软件产品。
30 秒看懂这篇
一个越来越常见的场景:AI 用 20 分钟生成了 800 行代码,团队却需要两天确认它到底改了什么、有没有权限漏洞、测试是不是真的有效。
生成加速了,交付却没有同比加速。瓶颈只是从键盘移到了评审、验证和返工。
这篇文章回答三个问题:
- AI Native、AI-enabled 和 AI Coding 到底有什么区别?
- 为什么“代码 + 测试通过”仍不等于可靠交付?
- 怎样让流程强度匹配风险,而不是把所有变更都拖进重流程?
flowchart TB
A["一句模糊需求"] --> B["AI 快速生成大量代码"]
B --> C{"审查与验证跟得上吗?"}
C -- "跟不上" --> D["评审排队 · 缺陷逃逸 · 反复返工"]
C -- "跟得上" --> E["意图 + 代码 + 测试 + 证据"]
D --> F["SDD:把决策与验证前移"]
F --> E适合谁读: 技术负责人、架构师、测试负责人,以及正在把 AI 引入研发流程的团队。时间有限可先读本文结论与附录清单,再按第 01–02 篇理解问题与全流程,后续按需深入。
案例说明:本系列用真实 Astro 静态博客说明本地 CMS、Markdown、Git 与构建,用假想全栈服务说明 API、鉴权、幂等和接口测试。没有执行记录的接口与测试结果均为教学示意。
真正的变化:交付单元被重写
“AI Native”经常被理解成给产品加一个聊天框,或者让 Copilot 帮忙补全代码。这两个方向都有价值,但本文讨论的是第三种含义:产品本身仍然是博客、CRM、商城或管理后台,软件的生产方式却已经围绕 AI 重新组织。
AI Native 开发真正改变的,不是代码由谁敲出来,而是一次变更必须携带什么,才能被称为“完成”。
传统开发常以代码提交或 Pull Request 作为交付单元。AI Native 开发则要求把意图、约束和证据一起交付:
flowchart TB
I["业务意图"] --> S["Spec:行为契约"]
S --> P["Plan:变更边界"]
P --> C["代码 + 测试"]
C --> V["Verify:验证证据"]这条链不是为了多填五份文档。它要让别人能够回答:为什么改、允许改什么、实际改了什么、凭什么认为改对了。 只有代码,回答不了这四个问题。
术语约定
不同团队对这些词的用法差异很大,先固定本系列的定义,避免后文歧义。
| 术语 | 本系列定义 | 常见误用 |
|---|---|---|
| AI-enabled 产品 | 产品对用户暴露了 AI 能力 | 与 AI Native 混用 |
| AI Coding | AI 辅助人类完成编码动作 | 等同于 AI Native 开发 |
| AI Native 开发 | 软件生产流程围绕 AI 执行者重新组织 | 等同于“用了 Copilot” |
| SDD | Spec 先行、可追踪、可验证的开发方法 | 等同于写文档 |
| Spec | 描述系统应有行为的可测试契约 | 等同于需求文档 |
| Plan | 基于当前代码库的受约束执行方案 | 等同于任务拆分 |
| Gate(闸门) | 阶段间的准入准出判定点 | 等同于审批流 |
| Verify | 用可复现证据证明行为正确 | 等同于跑一遍测试 |
| 证据 | 可复现、可审计、与 REQ 关联的验证结果 | 等同于截图 |
其中最需要强调的是 Spec 与一般需求描述的区别:一般需求描述解释“我们想要什么”,本系列所说的 Spec 进一步固定“系统在什么条件下必须表现出什么行为”。需求文档同样可以写得可测试;这里强调的是可判定、可追踪,而不是给文档形式划分高下。
AI Native、AI-enabled 和 AI Coding 不是一回事
可以把三个概念拆开:
| 概念 | AI 在哪里 | 例子 | 核心变化 |
|---|---|---|---|
| AI-enabled 产品 | 产品功能中的一个环节 | 智能写作、发票识别 | 原有产品增加 AI 能力 |
| AI Coding | 开发者的辅助工具 | 代码补全、生成组件 | 同一套开发流程写得更快 |
| AI Native 开发 | 软件生产流程的执行者 | AI 分析、规划、编码、测试 | 重新定义人和工具的分工 |
这三者可以同时存在,但不能混为一谈。一个产品可以是 AI-enabled,却仍然用传统方式开发;一个团队也可以使用 AI Coding,却仍然没有建立 AI Native 的生产流程。
本系列的范围是:**用 AI Native 的生产方式,结合 SDD,开发和测试传统软件产品。**这不是 AI Native 的全部含义,但它是一个可以被实践、观察和复盘的切入点。
一个判别工具:把 AI 拿掉会怎样
可以用一个思想实验观察 AI 在产品与流程中的位置:把 AI 完全移除,什么会改变?
AI-enabled 产品 → 智能摘要等用户功能失效
AI Coding → 开发流程基本不变,编码效率下降
AI Native 开发 → 围绕 AI 设计的分工、工具授权与执行规模需要重排这个检验法有个反直觉的推论:AI Coding 用得再重,也不会自动演进成 AI Native 开发。 关键不在调用次数,而在流程结构是否围绕 AI 重新设计。
注意,Spec、Plan 和 Verify 对人类开发同样有价值。因此 SDD 不是 AI Native 的专属产物,也不是它的充分条件;本系列关注的是,它为什么特别适合约束 AI 的高频执行。
判断自己属于哪一类,可以问:过去三个月,有没有为了让 AI 更好地执行,而修改过流程、目录结构、文档规范或测试策略?如果没有,通常还停留在 AI Coding 阶段。
为什么速度提升会自己撞墙
可以用一个简化模型观察变更成本:
总成本 = 生成成本 + 审查成本 + 返工成本AI Coding 主要降低生成成本。如果生成速度提升、变更数量随之增加,而评审和验证能力不变,队列就可能向审查端转移。未被拦住的缺陷还会增加后续返工。
审查吞吐并非绝对不能扩充,但它受合格评审者数量、领域上下文和沟通成本约束,通常不像生成代码那样容易瞬时扩容。团队的真实体感可能是:需求交付快了,但评审排队变长,Code Review 更容易变成橡皮章。
因此 AI Native 开发的一个核心命题是:
如何让审查与验证能力跟上生成速度。
SDD 提供了一种答案:让人优先审查“意图、风险与证据”,同时保留对关键实现和高风险 Diff 的审查。它不是用 40 行 Spec 替代 600 行代码评审,而是帮助评审者更快找到真正需要人判断的部分。
一个具体变化:从“写代码”到“管理变化”
假设需求是:
给博客后台增加删除文章功能。
如果直接交给 AI,它很可能立即做出一套看起来合理的实现:增加删除按钮、调用删除接口、刷新列表、补一个成功用例。
但真正需要决定的问题还没有出现:
- 普通用户能不能删?
- 已发布文章能不能删?
- 删除是物理删除还是归档?
- 删除失败时页面状态怎么保留?
- 重复点击会不会发出两次请求?
- 内容是数据库记录,还是 Git 管理的文件?
传统开发者也会遇到这些问题,但通常依靠个人经验、会议和口头沟通解决。AI Native 开发要求把它们变成 AI 可以消费、测试可以引用的显式产物:
角色:管理员可以删除未公开文章;普通用户和访客不能删除
状态:已公开文章不能直接删除
权限:服务端必须校验管理员身份
交互:删除前必须二次确认,取消不发请求
失败:删除失败时保留列表状态并给出重试提示
非目标:本次不做回收站、恢复、批量删除和审计日志这里发生的变化不是“AI 取代了开发者”,而是开发者的主要工作从实现细节转向定义变化的边界,并判断变化是否正确。
AI Native 开发的四个角色
在这套模式里,人的职责不是消失,而是上移:
人:定义目标、业务规则、风险边界和最终责任
AI:研究代码库、提出方案、执行实现、生成测试
Spec:把“正确行为”固定成可讨论的契约
Verify:把“我觉得没问题”转换成可复现证据AI 最擅长的是在已有约束下快速执行;它不应该在没有授权时替你决定产品规则。人的价值也不只是最后点一下“批准”,而是:
- 判断哪些决策必须由业务方明确;
- 判断哪些风险不能交给自动化流程;
- 判断测试是否真的证明了用户行为;
- 在失败时决定应该修改 Spec、Plan、代码还是测试。
责任矩阵:谁决定,谁执行,谁负责
角色描述容易流于抽象,用矩阵表达更清楚。下表的 D 表示决定(Decide)、E 表示执行(Execute)、A 表示最终负责(Accountable):
| 活动 | 业务方 | 开发者 | AI | 说明 |
|---|---|---|---|---|
| 定义业务规则 | D / A | 协助澄清 | 提问,不决定 | AI 只能暴露歧义 |
| 编写 Spec | 审阅确认 | D / A | E(起草) | AI 可起草,人必须确认 |
| 技术方案选型 | — | D / A | E(提方案) | AI 提供选项与依据 |
| 研究代码库 | — | 审阅 | E | AI 的强项 |
| 编写实现代码 | — | A | E | 人不必逐行写,但要负责 |
| 生成测试用例 | — | A | E | 覆盖度由人判定 |
| 判断测试是否充分 | — | D / A | 建议 | 不可委托 |
| 失败归因分层 | 参与(规则层) | D / A | 提供线索 | 不可委托 |
| 发布决策 | D / A | 提供证据 | — | 不可委托 |
有三行的 D 永远不应该落在 AI 上:判断测试是否充分、失败归因分层、发布决策。 原因一致 —— 这三件事都需要承担后果的能力,而 AI 不承担后果。把它们交出去,等于让一个不为结果负责的执行者决定风险边界。
自主性成熟度:L0 到 L4
“让 AI 做多少”不是二选一,而是一条光谱。团队可以按下表自评当前位置:
| 级别 | 模式 | AI 的权限 | 人的介入点 | 适用场景 |
|---|---|---|---|---|
| L0 | 手工 | 无 | 全程 | 极高风险变更 |
| L1 | 补全式 | 建议片段 | 每行接受或拒绝 | 探索性编码 |
| L2 | 任务式 | 在批准范围内改文件 | 事前批 Plan,事后审 Diff | 大多数功能开发 |
| L3 | 闸门式 | 自主完成 Spec 到 Verify | 各 Gate 判定 + 证据审查 | 规则清晰的成熟模块 |
| L4 | 事后审计 | 自主交付并合并 | 抽样审计 + 监控告警 | 低风险、高覆盖率区域 |
几点实践观察:
- 对刚开始引入 AI 的团队,L2 通常是更稳妥的起点。 AI 承担执行,人保留方案与结果判断;是否继续升级,应由本团队的风险与证据能力决定。
- 缺少积累时跳级,是常见的失控风险。 没有 L2 阶段积累的 Spec 规范与自动化覆盖,直接尝试 L3 可能退化成“AI 自由发挥 + 人事后救火”。
- 级别是按模块而非按团队设定的。 同一个项目里,文案与样式可以跑 L4,支付与权限应当停在 L2 甚至 L1。用一个统一级别覆盖全仓库,必然要么过度笨重要么过度冒险。
- 升级的前置条件是证据能力,不是信心。 判断能否从 L2 升到 L3,标准是“该模块的自动化测试能否在无人观察时拦住回归”,而不是“最近 AI 表现不错”。
三种典型反模式
在实际推行中,失败的形态比成功更有规律:
反模式一:Spec 剧场。 团队要求每个变更都提交 Spec,但 Spec 是在代码写完后补的。产物齐全,决策却从未前移。识别信号是 Spec 的提交时间晚于实现代码。
反模式二:闸门橡皮章。 每个 Gate 都有人点通过,但没人真的判断准出条件。识别信号是拒绝率长期为零 —— 一个从不拦住任何东西的闸门不是闸门。
反模式三:全量重流程。 把改错别字也套进四阶段,团队被流程压垮后整体放弃。识别信号是开发者开始私下绕过流程直接提交。
这三种反模式的共同根源是把 SDD 当成合规要求,而不是降低审查成本的工具。一旦流程的收益不再大于它的开销,被绕过只是时间问题。
为什么必须有 SDD
AI 会把模糊的意图迅速变成具体代码,而具体代码会制造一种危险的确定感:系统已经有页面、接口和测试,看起来就像完成了。
SDD(Spec-Driven Development)提供的是一条可追踪的链路:
用户问题
↓
Spec:系统应该做什么
↓
Plan:当前项目准备怎么做
↓
Implement:按计划修改什么
↓
Verify:用什么证据证明正确它的价值不是让文档变多,而是让每个决策有来源:
REQ-003 已公开文章不能直接删除
→ Plan-02 服务端状态校验
→ TEST-003 删除已公开文章返回 409
→ Verify-003 接口测试和人工验收通过不是流程越重越好:让风险决定强度
AI Native 不等于所有任务都要写几十页 Spec。改一个错别字和修改支付权限,显然不该走同一条流程。真正成熟的团队,是让流程强度与变更风险匹配:
flowchart TB
A["一次变更"] --> B{"可逆性 · 影响面<br/>数据敏感性 · 检测延迟"}
B -->|"均为低风险"| L["文案、样式等"]
B -->|"普通业务变更"| M["单模块功能"]
B -->|"任一维度高风险"| H["权限、资金、迁移等"]
L --> L1["明确目标 + 快速验证"]
M --> M1["轻量 Spec + Plan + 自动化测试"]
H --> H1["完整契约 + 人工审查 + Verify"]风险分级的判定依据
“低风险”不能凭感觉。建议用四个可观察维度评估,任一维度命中高位,就将整体流程升级:
| 维度 | 低 | 中 | 高 |
|---|---|---|---|
| 可逆性 | 改回来即可 | 需要数据修补 | 不可逆(删除、发资金) |
| 影响面 | 单页面 | 单模块 | 跨模块或对外接口 |
| 数据敏感性 | 无持久化 | 业务数据 | 权限、身份、资金 |
| 检测延迟 | 立即可见 | 当天可见 | 数月后才暴露(如权限泄漏) |
第四个维度最容易被忽略:错误暴露得越晚,前置流程越值得投入。 一个样式错位当天就会被发现,一个越权漏洞可能潜伏半年,两者不该走同一条流程。
本系列的边界与不适用场景
一份负责的方法论应该说明自己在哪里不成立。
本系列不覆盖:
- AI 产品本身的开发(模型训练、评测集、Prompt 工程作为产品功能)
- 纯研究性或探索性项目,需求在探索中才成形
- 一次性脚本与数据分析任务
- 团队规模为 1 且生命周期小于数周的项目
SDD 在以下情况会产生净负收益:
- 需求变化快于 Spec 的维护速度(此时 Spec 会持续过期,反而误导)
- 领域规则尚未被任何人理解清楚(应先做 Spike 或原型,而不是先写 Spec)
- 缺少自动化测试基础设施,Verify 无法产生证据(需先补基建)
一个诚实的前提: 本系列的方法建立在“业务规则可以被明确表达”这一假设上。存在一类问题的正确行为本身就模糊(推荐排序是否合理、文案是否得体),这类需求无法靠 Spec 消除歧义,只能靠评测集与人工判断。把它们硬塞进 SDD,会得到一份看起来严谨但毫无约束力的 Spec。
结语:先改变一次交付,而不是先改造整个团队
如果只把 AI 当作更快的代码补全器,瓶颈迟早会从“写不完”变成“审不完”。
代码是实现,Spec 是意图,测试是证据;可靠交付必须把三者连起来。
不必从一场流程革命开始。选一个正在开发的中等功能,在下次提交时多回答四个问题:为什么改、允许改什么、实际改了什么、凭什么认为改对了。 这四个答案,就是 AI Native 开发最小、也最可验证的起点。
附录 A:团队现状自评表
逐条回答,记录“是 / 否 / 部分”。否的条目就是下一步的改进入口。
交付单元
[ ] 一次变更能否找到对应的业务意图记录
[ ] 一次变更能否找到验证证据,而不只是“测试跑过了”
[ ] 三个月后能否回答“这条规则当初为什么这样定”
决策前移
[ ] Spec 是否在实现之前产生
[ ] 业务规则的空白是否被显式列出,而不是被默认填充
[ ] AI 是否有权在歧义未解决时拒绝继续
审查可持续性
[ ] 审查对象是意图与证据,还是大段 diff
[ ] Code Review 的实际拦截率是否大于零
[ ] 审查是否已成为交付瓶颈
风险匹配
[ ] 是否区分了低风险与高风险变更的流程强度
[ ] 高风险清单(权限、删除、资金、迁移)是否明确
[ ] 不同模块是否允许不同的 AI 自主级别
证据能力
[ ] 关键路径是否有自动化测试
[ ] 测试断言的是用户可观察行为,还是内部实现
[ ] 验证过程能否被他人复现一个参考解读:如果“证据能力”整组都是否,那么当前不该急于推行 SDD,而应先补测试基建 —— 没有证据产出能力的 Verify 阶段只会变成签字环节。
附录 B:最小交付单元清单
可以直接作为 Pull Request 模板使用:
## 业务意图
本次变更解决谁的什么问题(一到两句)
## Spec
链接:specs/<feature>/spec.md
关键规则:REQ-001 ... REQ-00N
## Plan
链接:specs/<feature>/plan.md
影响文件范围:
风险与回滚方式:
## 实现
变更文件清单(应与 Plan 一致,不一致需说明)
未在 Plan 中的改动及理由:
## 验证证据
需求追踪矩阵:REQ → 用例 → 自动化 → 结论
执行命令与环境:
未覆盖项与人工验收说明:
已知限制:这份清单的作用不是增加填写负担,而是让缺失变得显眼。当“验证证据”一栏只能写“本地测试通过”时,问题已经暴露了。
下一篇不再抽象讨论 SDD,而是看一次具体的失败:AI 如何在没有得到授权的情况下,把一个合理的产品猜测直接做成生产代码。
