#6 文档的边界——当 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 本身解决不了的问题。
第一个边界: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 在什么环境下做。

第二个边界: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 硬门禁。

第三个边界:安全不是 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 在生成阶段就不会出现。

第四个边界:工具不等于流程
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,但如果没有独立验证和治理节点,你只是在更快地积累未经检验的代码。

四层配套: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 是这四层的地基,但地基不等于整栋楼。

知道边界,才能正确使用
SDD 不是银弹。这句话听起来像否定,其实是肯定。
银弹不需要你知道它的边界——它对所有问题都有效。SDD 需要你知道它的边界,因为它的有效性是有条件的:有 grounding 机制时有效,没有时会幻觉;有 drift 检测时有效,没有时会腐烂;有安全约束层时有效,没有时会暴露漏洞;有治理流程时有效,没有时会积累未经检验的代码。
这些边界不是 SDD 的设计缺陷——它们是所有工程方法的共同特征。测试驱动开发有它的边界(测试不能覆盖未预期的交互),代码审查有它的边界(审查者会有盲区),微服务有它的边界(分布式系统的复杂性)。知道边界不是放弃理由,是使用前提。
你在第 5 篇学会了写 spec——目标、约束、边界、验收标准、技术上下文。这一篇告诉你 spec 写完之后还需要什么——grounding hooks、drift gate、security constitution、governance process。前五篇是「怎么让 spec 起作用」,这一篇是「spec 起作用之后,什么会让它再次失效」。
下一篇,我们离开 spec 本身,进入一个更大的问题:当 Agent 让代码产出速度暴增,但 review、测试、部署的速度没跟上时,瓶颈会转移到哪里——以及流程该怎么重新设计来接住这个速度。
参考文献
-
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.