文档的边界——当 Spec 不够用时
1. 文档的边界——当 Spec 不够用时
📌 本文是「AI 时代的编码新范式」系列的第 6 篇。全系列共 9 篇,基于 43 篇行业文献、学术论文与一线实践报告,探讨 Spec-Driven Development 如何在 AI Agent 时代从边缘实践变为工程的基础设施。每篇可独立阅读。前五篇讲了 spec 为什么重要、怎么写、怎么用。本篇讲一个你可能不想听到的事实:spec 也会失效。失效不是因为你写错了,是因为 spec 有它的系统性边界——学术界已经把四条边界摸清楚了。
你的团队写了一份 spec。
不是敷衍的三行字——是按第 5 篇的五要素认认真真写的。
目标清楚,约束明确,验收标准可测试,边界条件覆盖到位。
你把它交给 Agent,Agent 读完,开始写代码。
然后 Agent 调用了一个不存在的 API。
不是拼写错误。
Agent 确信这个 API 存在——它甚至给出了参数类型和返回值结构。
但你在代码库里搜了一遍,没有。
文档里也没有。
Agent 从训练数据里「记住」了一个看起来合理但实际不存在的接口签名,然后围绕这个幻觉构建了整个功能。
你检查了 spec——spec 里没写「只能使用以下 API」。
你检查了 CLAUDE.md——里面只有技术栈和通用约束。
Agent 没有违反任何一条 spec 条款。
它只是不知道当前代码库里到底有哪些接口。
这不是你的 spec 写得不够好。
这是一个 spec 本身解决不了的问题。
1.1. 第一个边界:Agent 是「上下文盲人」
Spec Kit Agents 论文给这个问题起了个名字:context blindness。
论文的描述很精确:「Agent 的中间产物可以在内部逻辑自洽的同时,与仓库的实际状态不兼容。」
什么意思?
Agent 写出来的 spec、plan、task breakdown,单看每一步都合理——逻辑通顺,设计清晰。
但它引用的 API 不存在,它提到的文件路径是编的,它假设的依赖关系在当前版本里已经变了。
Agent 不是在偷懒,也不是在乱猜——它在用它训练数据里的「一般情况」填补当前仓库的「具体情况」,而两者之间的差距它自己看不出来。
这篇论文做了一件有用的事:它不只是诊断问题,还给了解法。
研究团队在 GitHub Spec Kit 的四阶段流程(Specify → Plan → Tasks → Implement)中,每个阶段都加了一层 context-grounding hooks——让 Agent 在生成产物之前,先做一轮只读探查:检索相关文件、确认依赖版本、检查现有 API、扫描代码风格惯例。
生成产物之后,再加一层 validation hooks——用项目实际环境验证 Agent 的中间产物,跑测试、跑 linter,看它有没有引用不存在的东西。
实验覆盖了 5 个仓库、32 个功能、128 次运行。
结果:加了 grounding hooks 之后,Agent 产出质量提升了 0.15 分(1-5 分制),同时保持了 99.7% 到 100% 的仓库级测试兼容性。
提升幅度看起来不大——但论文指出,真正的好处不是平均分跳了多少,而是减少了多步工作流中上下文错误的累积放大。
一个不存在的 API 在第一步被引入,如果到第四步才发现,Agent 需要回溯整个链条。
grounding hooks 把这个发现在第一步就截住了。
结论很直接:spec 本身不够。
你还需要一套 grounding 机制,让 Agent 在每次生成之前先回答一个问题——「这个仓库里到底有什么」。
spec 告诉 Agent 该做什么,grounding 告诉 Agent 在什么环境下做。
1.2. 第二个边界:Spec 会跟代码「静默漂移」
Spec Growth Engine 论文识别出了第二个系统性问题。
它有两个名字,第一个叫 context explosion——Agent 需要同时理解整个仓库,上下文窗口越塞越满,输出质量随之下降。
论文引用了一组数据:一个强模型在长上下文编程基准上,当窗口从 32K 增长到 256K token 时,表现从 29% 暴跌到 3%。
但更危险的是第二个名字:silent spec-code drift。
论文对它的描述几乎是文学性的:「代码在演化,规范没有跟上。分歧变得不可见,直到修复成本已经很高。」
这不是新问题——论文引用了 1990 年代软件架构研究的「architectural erosion」概念。
但 AI 时代赋予了它一个新的危险维度:当一个 Agent 每分钟生成几百行代码,而 spec 停留在上个月的版本,损害积累的速度远远超过传统开发。
论文说了一段让人后背发凉的话:「这种失败模式尤其阴险,因为它始终不可见。Linter 不会标记它。CI 不会标记它。系统带着漂移发布出去。」
就像一架带着裂缝起飞的飞机——没有人知道,直到它出事。
你在第 4 篇里读过 Agent 的外部记忆系统——进度文件、功能清单、git log。
这些文件解决了 Agent「跨会话失忆」的问题。
但它们解决不了漂移——因为漂移不是「忘记」,是「记错了」。
Agent 读了上个月的 spec,spec 说 API 返回三个字段,但代码上周改成了四个。
Agent 基于过时的 spec 生成了代码,代码跑得通——因为 Agent 还顺便修了调用方。
但那个第四个字段携带的安全校验逻辑,被 Agent 当成冗余删掉了。
没有人发现,因为测试没覆盖到,CI 没报错,spec 没更新。
Spec Growth Engine 的解法是把漂移检测变成合并阻断条件——不是「建议你更新 spec」,是 spec 和代码不一致时,PR 不能合并。
drift gate。
硬门禁。
跟 linting 报错一样不可绕过。
论文把这个机制叫「code-coupled」——spec 和代码在同一个 commit 里演化,改代码必须同时改 spec,否则你过不了门禁。
这意味着 spec 的维护方式必须改变。
它不再是「有空了更新一下文档」的软约束,而是和测试一样的 CI 硬门禁。
1.3. 第三个边界:安全不是 Agent 的默认行为
Constitutional SDD 论文开篇就点出了一个让人不安的事实:LLM 优先保证功能正确性,不优先保证安全性。
当你对 Agent 说「创建一个用户注册端点」,它给你一个能跑的实现——但那个实现可能用字符串拼接构造 SQL 查询,因为训练数据里大量代码就是这么写的。
「能跑」和「安全」之间隔着的距离,Agent 不会自动填补。
论文做了一个对照实验。
研究团队用银行微服务应用作为测试场景——客户管理、账户操作、交易处理,覆盖 10 个 CWE/MITRE Top 25 关键漏洞。
一组 Agent 无约束生成代码,另一组 Agent 在 spec 层嵌入了不可协商的安全约束——他们管这叫「Constitution」,一份版本化、机器可读的安全约束文档,映射到具体的 CWE 编号,每条约束标记了强制等级(MUST / SHOULD / MAY)。
结果:有宪法约束的 Agent 产出的代码,安全缺陷比无约束组减少了 73%。
同时保持了开发速度——论文特别指出「while maintaining developer velocity」,安全约束没有拖慢交付。
这个数字背后有一个更深的判断:安全不是 Agent 能「理解」的东西——它是必须被显式编程进 spec 的东西。
你不能指望 Agent 在写代码时「顺便考虑安全」,就像你不能指望一个建筑工人「顺便」计算承重——那是图纸上的事,不是施工现场的临场判断。
Constitutional SDD 的核心贡献是把安全约束从「review 阶段检查」前移到了「spec 阶段写入」——by construction,不是 by inspection。
第 1 篇那个注册页面案例,回头看,本质就是一个安全问题被 spec 层遗漏的例子。
「密码需要唯一。该密码已被用户 r***88 使用。」——Agent 没有做错任何事,它只是没有被约束。
如果把「错误提示不附带任何关联账户信息」「密码使用 bcrypt 存储」写进 spec 的安全约束层——就像 Constitutional SDD 建议的那样——这个 bug 在生成阶段就不会出现。
1.4. 第四个边界:工具不等于流程
Agile V 论文做了一个重要的区分。
它把 GSD、BMAD、SpecKit 这类工具归类为 productivity tooling——生产力工具。
它们优化的是「Agent 写代码的效率」:怎么拆任务、怎么管上下文窗口、怎么编排多个 Agent。
但论文明确指出,它们不是 process frameworks——流程框架。
它们不解决三个问题:独立验证(构建和测试共享上下文时如何保证测试独立性)、需求到测试的可追溯性(每条需求是否都有对应测试覆盖)、人工治理节点(什么时候必须停下来等人审批)。
论文用一句话划了线:「GSD is a build accelerator, Agile V is an engineering process.」
GSD 是构建加速器,Agile V 是工程流程。
这个区分为什么重要?
因为很多团队在用 SDD 工具时有一个隐含假设:只要 Agent 按 spec 流程走,产出就是可靠的。
但 Agile V 指出,spec 流程解决的是「Agent 理解了你要什么」——它不解决「Agent 做的东西对不对」。
后者需要独立验证:测试不能由写代码的同一个 Agent 生成(因为它们共享上下文,会共享盲区),需求到测试必须有可追溯的映射(否则你不知道哪些需求没被覆盖),关键决策必须有人工审批门禁(因为有些判断 Agent 做不了)。
Agile V 自己的实验数据来自一个 Hardware-in-the-Loop 系统:约 500 行代码、8 个需求、54 个测试。
每个开发周期只需要 6 次人工介入,估计成本相比 COCOMO II 基线降低 10 到 50 倍。
论文坦诚地声明这些结果来自一个边界清晰的有限项目,推广到更大或更模糊的系统还需要独立验证。
但它的核心论点不需要推广就能成立:工具让你跑得更快,流程保证你跑对方向。
你可以用最快的 Agent 和最好的 spec,但如果没有独立验证和治理节点,你只是在更快地积累未经检验的代码。
1.5. 四层配套:Spec 不是终点
把四篇论文的发现叠在一起,你会看到一张清晰的问题地图,以及一张同样清晰的解法地图。
Spec 解决的是「Agent 理解你要什么」。
但在它之上,还有四层问题需要配套机制:
Grounding 层——让 Agent 在生成之前先确认当前环境。
Spec Kit Agents 论文的 context-grounding hooks 做的就是这件事:读代码库、检查 API、验证依赖。
没有这一层,Agent 就是用训练数据的平均值填补当前仓库的具体情况——幻觉由此产生。
Drift 检测层——让 spec 和代码的分歧变得可见。
Spec Growth Engine 的 drift gate 做的就是这件事:spec 和代码不一致时阻断合并。
没有这一层,漂移是沉默的——CI 不报错,linter 不标记,系统带着裂缝起飞。
安全约束层——让安全原则成为不可协商的 spec 条款。
Constitutional SDD 的 Constitution 做的就是这件事:CWE 映射、强制等级、从原则到代码位置的全链路追溯。
没有这一层,安全靠 Agent「临场判断」——而 Agent 的默认行为是功能优先,不是安全优先。
治理流程层——让验证独立于生成,让关键决策有人工门禁。
Agile V 的 Infinity Loop 做的就是这件事:独立测试生成、需求-测试可追溯、人工审批节点。
没有这一层,你跑得越快,未经检验的代码积累得越多。
这四层不是让你放弃 spec——恰恰相反,它们都是 spec 的延伸。
Grounding 是让 spec 在正确环境中执行的前提,drift 检测是 spec 作为 living document 的硬约束,安全约束层是 spec 内容的必要组成部分,治理流程是 spec 交付质量的保障机制。
spec 是这四层的地基,但地基不等于整栋楼。
1.6. 知道边界,才能正确使用
SDD 不是银弹。
这句话听起来像否定,其实是肯定。
银弹不需要你知道它的边界——它对所有问题都有效。
SDD 需要你知道它的边界,因为它的有效性是有条件的:有 grounding 机制时有效,没有时会幻觉;有 drift 检测时有效,没有时会腐烂;有安全约束层时有效,没有时会暴露漏洞;有治理流程时有效,没有时会积累未经检验的代码。
这些边界不是 SDD 的设计缺陷——它们是所有工程方法的共同特征。
测试驱动开发有它的边界(测试不能覆盖未预期的交互),代码审查有它的边界(审查者会有盲区),微服务有它的边界(分布式系统的复杂性)。
知道边界不是放弃理由,是使用前提。
你在第 5 篇学会了写 spec——目标、约束、边界、验收标准、技术上下文。
这一篇告诉你 spec 写完之后还需要什么——grounding hooks、drift gate、security constitution、governance process。
前五篇是「怎么让 spec 起作用」,这一篇是「spec 起作用之后,什么会让它再次失效」。
下一篇,我们离开 spec 本身,进入一个更大的问题:当 Agent 让代码产出速度暴增,但 review、测试、部署的速度没跟上时,瓶颈会转移到哪里——以及流程该怎么重新设计来接住这个速度。
1.7. 参考文献
- Spec Kit Agents: Context-Grounded Agentic Workflows. (2026). arXiv:2604.05278. Context blindness in large repositories; context-grounding hooks across Specify/Plan/Tasks/Implement stages; 128 runs, 32 features, 5 repositories; +0.15 quality improvement, 99.7-100% test compatibility.
- The Spec Growth Engine: Spec-Anchored, Code-Coupled, Drift-Enforced Architecture. (2026). arXiv:2606.27045. Context explosion and silent spec-code drift as two structural failure modes; Spine context assembler; drift gate as blocking merge condition; “A linter does not flag it. CI does not flag it.”
- Constitutional Spec-Driven Development: Enforcing Security by Construction. (2026). arXiv:2602.02584. Security principles embedded in spec layer as non-negotiable Constitution; CWE/MITRE Top 25 mappings; 73% security defect reduction vs. unconstrained AI generation; banking microservices case study.
- Agile V: A Compliance-Ready Framework for AI-Augmented Engineering. (2026). arXiv:2602.20684. Productivity tooling vs. process frameworks; GSD/BMAD/SpecKit as build accelerators, not engineering processes; independent verification, requirement-test traceability, human governance gates; ~500 LOC case study, 6 prompts per cycle.