Spec 也会骗人:AI Coding 为什么一进真实仓库就翻车
最近读到一篇论文《Spec Kit Agents: Context-Grounded Agentic Workflows》,讨论的是 AI Coding Agent 在真实仓库中为什么会出现“上下文失明”:它能写 Spec、Plan 和 Tasks,但这些中间产物仍然可能引用不存在的 API、错误理解仓库结构,或者违反已有架构约定。论文地址:https://arxiv.org/abs/2604.05278
这篇文章不是逐段翻译论文,而是借它讨论一个更现实的问题:AI Coding 真正进入工程化之后,难点不只是生成代码,而是让需求、方案、任务、代码和验证都能被真实仓库校准。
过去一年,AI Coding 的讨论里,一个很明显的变化是:大家不再满足于让 AI 直接改代码了。
一开始,我们更多是在说补全、解释、局部修改。后来,Coding Agent 开始进入真实仓库,可以读文件、改多个模块、跑测试、提交 PR。再往后,很多人开始意识到,直接让 Agent 写代码太容易失控,于是,“先明确规格,再推进实现”的工作流,在 AI Coding 语境下重新变得重要。
这个思想本身并不新。软件工程里一直有需求文档、技术方案、任务拆解和评审流程。变化在于,AI Coding 让这些中间产物有了新的作用:它们不只是给人看的协作文档,也开始成为约束 Agent 理解、规划和执行的控制面。
先写需求,再写方案,再拆任务,最后再实现。听起来很合理。
这确实比一句“帮我实现这个功能”要稳定得多。Spec 把原本藏在对话里的需求、约束、设计取舍和任务拆解变成了显性的中间产物。对人来说,这些文档可以审阅;对 Agent 来说,这些文档可以作为后续执行的依据。
但这里有一个容易被忽略的问题:Spec 本身也可能是错的。
它可能引用了不存在的 API,规划了不存在的文件路径,假设了仓库里并不存在的模块边界,也可能设计出一套看起来完整、实际不符合当前项目架构的方案。
显性化不等于真实,结构化也不等于正确。
这时候,Spec 没有解决幻觉,只是把幻觉变得更有条理了。
一、AI Coding 的很多失败,不是写错代码,而是读错仓库#
我们在真实仓库里用 AI Coding,很容易遇到一种情况。
你让 Agent 实现一个功能,它会先分析一通,然后给出一个挺完整的方案:要改哪个组件、加哪个 service、补哪个接口、在哪个目录下新增测试。
第一眼看上去很专业。
但你细看会发现,路径不对,项目里根本没有这个 service;它提到的 hooks 已经废弃;它假设的接口参数和真实类型不一致;它新增的测试命令在这个仓库里跑不了;它用的组件规范也不是当前项目这一套。
更具体一点,在一个长期演进的 Web 仓库里,这种问题会非常常见。
比如项目早期有一套旧的权限组件,后来迁移到新的权限体系,但旧目录还没有删干净。Agent grep 到旧代码后,以为那就是当前主路径,于是在方案里继续沿用旧组件。再比如仓库里同时存在历史页面、实验页面和线上主页面,Agent 找到了相似实现,却没有判断哪个实现仍然有效。它也可能看到一个过期的 README,就按里面的命令设计测试流程,最后发现当前项目早已换了构建方式。
这些问题表面上是“代码写错了”,本质上是“仓库读错了”。
更麻烦的是,如果这些错误出现在最终代码里,我们还能通过编译、测试、review 发现。但如果这些错误出现在 Spec、Plan、Tasks 里,它们会变成后续所有步骤的输入。
也就是说,错误会被流程放大。
一个错误的需求理解,会生成一个错误的技术方案;一个错误的技术方案,会拆出一组看似合理但方向不对的任务;一组错误任务再进入实现阶段,就会让 Agent 在错误路径上越走越远。
所以,真实工程里的 AI Coding 难点,不只是“模型会不会写代码”,而是它有没有真正读懂当前仓库。
这里的“读懂”不是把 README 扫一遍,也不是 grep 到几个关键词,而是知道:
这个项目现在的模块边界是什么;同类功能过去是怎么实现的;哪些接口是真实存在的,哪些已经被废弃;哪些测试命令能代表这次修改的正确性;哪些目录只是历史遗留,哪些才是当前主路径;哪些代码风格是团队约定,哪些只是偶然写法。
没有这些,Agent 写得越快,返工也可能越快。
二、Spec-Driven Development 有价值,但它不是终点#
Spec-Driven Development 的价值,是把一次模糊的开发请求拆成多个可检查的阶段。
不是直接写代码,而是先明确要做什么,再说明怎么做,再拆出任务,最后实现。
这套思路对 AI Coding 特别重要。因为 Agent 很擅长顺着当前上下文往下生成,但不擅长自己停下来问:这个需求是否完整?这个方案是否符合仓库事实?这个任务顺序是否真的能执行?这个实现是否还在最初的目标范围内?
Spec、Plan、Tasks 这些中间产物,本质上是在给 Agent 加刹车。
它让开发过程从“自由生成”变成“阶段推进”。每个阶段都有一个产物,每个产物都可以被人或工具检查。相比一次性 prompt,这已经是工程化进步。
但问题在于,仅仅把流程拆开还不够。
如果 Spec 是在没有充分读取仓库的情况下生成的,它可能会把模型的通用经验误当成当前项目事实。
如果 Plan 没有校验真实路径和依赖,它可能会设计出一个项目里落不了地的方案。
如果 Tasks 没有验证测试方式和执行顺序,它可能会把任务拆得很漂亮,但每一步都不可执行。
所以,Spec 不是天然可靠的。Spec 也需要被验证。
这也是《Spec Kit Agents: Context-Grounded Agentic Workflows》这篇论文最有意思的地方。它没有简单说“让 Agent 先写 Spec 就好了”,而是进一步指出:在真实大型仓库里,Agent 往往会出现上下文失明,导致虚构 API、违反架构约定和生成不兼容的方案。
换句话说,Spec 工作流解决的是“过程失控”,但没有自动解决“事实失真”。
论文里的实验也说明了这一点。作者在 32 个 feature、5 个真实仓库上做了 128 次运行,比较普通 Spec 工作流和加入仓库探测、阶段验证后的工作流。结果并不是那种夸张的“质变”,但方向很明确:加入这些机制后,综合质量分从 3.51 提升到 3.66,同时保持了接近 100% 的仓库级测试兼容性;在 SWE-bench Lite 上,Pass@1 也提升到了 58.2%。
这个结果真正有价值的地方,不是分数涨了多少,而是它验证了一个工程直觉:Agent 的中间产物不能只看起来合理,还要能被真实仓库验证。
三、真正关键的是:每个阶段都要回到真实仓库确认一次#
这篇论文的做法,可以简单理解成一句话:
不要相信 Agent 自己说它理解了仓库,要让它在每个阶段都拿仓库证据说话。
它基于 Spec Kit 的流程,把开发任务拆成 Specify、Plan、Tasks、Implement 几个阶段。但在每个阶段前后,它加了两类机制。
第一类是阶段前的只读探测。
在生成 Spec、Plan、Tasks 或代码之前,系统会先去真实仓库里查证。它会看相关文件、目录结构、依赖配置、历史实现、测试命令、相似模块和项目约定。这个过程不是为了让 Agent 多读一点材料,而是为了避免它把想象中的项目结构当成真实项目结构。
第二类是阶段后的验证。
当 Agent 生成 Spec、Plan 或 Tasks 之后,系统不会立刻进入下一步,而是检查这个产物和仓库是否匹配。比如方案里提到的文件是否存在,依赖是否真实安装,任务里是否包含必要的验证步骤,实现后能否通过项目级测试。
这两个动作看起来朴素,但非常关键。
因为它把 AI Coding 从“生成一个看起来合理的方案”,推进到了“生成一个能被当前仓库承认的方案”。
这才是工程化的关键差异。
在真实研发系统里,我们不能只问 Agent 输出是否流畅,也不能只看它有没有把文档写完整。我们要问的是:这些中间产物有没有被真实环境校准过?它们能不能经得起路径、依赖、测试、架构和历史实现的检查?
如果不能,那么这份 Spec 再完整,也只是新的文档债。
四、这篇论文给我们的启发,不是多 Agent,而是阶段性验证#
这篇论文里有 PM Agent、Developer Agent,也有 workflow orchestrator。但我觉得它真正有价值的地方,不是“又用了多 Agent”。
多 Agent 很容易被包装成一个热闹的概念:一个负责产品,一个负责开发,一个负责测试,一个负责审查。听起来像模拟一个小团队。
但在真实工程里,角色分工并不会天然带来可靠性。多个 Agent 如果共享同一套错误上下文,只会更快地产生一组互相配合的错误产物。
这篇论文更值得关注的是它的边界设计:在每个阶段的入口和出口做检查。
这和真实研发流程其实很像。
需求评审不是为了写一份更漂亮的需求文档,而是为了确认需求是否完整、边界是否清楚、约束是否真实。
技术评审不是为了让方案看起来专业,而是为了确认方案能否落进当前系统。
任务拆解不是为了把列表写得更细,而是为了确认执行顺序、依赖关系和验收方式。
代码 review 和测试也不是流程装饰,而是为了确认实现没有偏离目标,并且没有破坏已有系统。
AI Coding 的工程化,也要回到这些基本问题。
不是让 Agent 更自由,而是让 Agent 的每一步都能被检查、被纠偏、被追溯。
五、这也解释了为什么很多 AI Coding Demo 到真实项目里会变形#
很多 AI Coding Demo 看起来非常惊艳,是因为上下文是干净的。
需求明确,文件少,依赖简单,测试路径清楚,历史包袱有限。Agent 只要沿着题目给出的上下文推进,就能产出很好的结果。
但真实仓库不是这样。
真实仓库里有历史遗留,有重复实现,有迁移中的模块,有没删干净的旧接口,有临时方案变成长期方案的代码,有 README 里已经过期的说明,有团队口口相传但没有写进文档的约定。
这时候,Agent 面对的不是一道编程题,而是一个长期演化的系统。
它需要先判断哪些信息可信,哪些文件相关,哪些路径是主路径,哪些实现是历史包袱,哪些测试可以代表正确性。只有完成这些判断,后面的编码才有意义。
所以,未来 AI Coding 的竞争,不会只是谁的模型补全更强,也不会只是谁的 Agent 工具更多。真正重要的是:
它能不能恢复真实仓库的上下文;
能不能把需求、方案、任务和实现绑定到仓库事实上;
能不能在每个阶段发现偏差,而不是等代码写完再返工;
能不能把一次开发任务变成可审阅、可验证、可复现的工程过程。
这也是为什么我觉得 Spec 工作流本身还不够。Spec 只是把过程显性化,验证才让过程可靠。
六、从 AI Coding 到 Agentic Engineering,核心是 Representation 和 Harness#
如果把这件事放到更大的软件工程演化里看,它其实对应两个关键词:Representation 和 Harness。
Spec、Plan、Tasks 是 Representation。它们把需求理解、技术方案和执行路径表示出来,让原本隐藏在模型思考里的东西变成可见产物。
Discovery hook、Validation hook、测试、lint、路径检查、依赖检查,是 Harness。它们负责把这些中间产物放回真实环境里验证,确认它们不是模型自己编出来的一套逻辑。
过去我们谈 AI Coding,经常把重点放在“生成”上。模型能不能写更多代码,Agent 能不能一次改更多文件,工具能不能自动完成更多操作。
但真实研发系统最怕的不是 Agent 写得不够多,而是它写得很快,却没人知道它从哪里开始偏了。
所以,AI 研发自动化真正要解决的问题,不是把人从流程中彻底拿掉,而是把流程中那些原本靠人隐性判断的环节显性化、结构化、可验证化。
需求为什么这样理解?
方案为什么这样设计?
任务为什么这样排序?
实现为什么改这些文件?
验证为什么能证明这次修改是对的?
这些问题回答不清楚,Agent 就还没有真正进入工程系统。
七、结语:从生成代码,到打通需求、方案、任务、代码和验证#
AI Coding 发展到现在,已经不缺“会写代码”的能力了。真正稀缺的是把 AI 写代码放进真实研发系统里的能力。
Spec-Driven Development 是一个重要方向,因为它让 Agent 不再只是边想边写,而是开始围绕需求、方案、任务和实现推进。
但 Spec 本身不是答案。
如果 Spec 没有读懂真实仓库,它也会骗人。
如果 Plan 没有校验真实依赖,它也会制造返工。
如果 Tasks 没有绑定验证方式,它也只是更漂亮的待办列表。
如果实现没有经过项目级检查,它也只是一次看起来完成的生成。
AI Coding 真正进入工程化,不是从“没有 Spec”到“有 Spec”,而是从“生成产物”到“验证产物”。
更进一步说,它也不是只要把代码写出来,而是要把需求、方案、任务、代码和验证连成一个闭环。
需求要能被澄清,方案要能被仓库事实校准,任务要能被执行路径约束,代码要能被测试和 review 检查,验证结果还要能反过来修正前面的理解。
这才是 AI Coding 从演示走向生产系统的关键。
未来优秀的 Coding Agent,不只是更会写代码,而是更会在真实仓库里确认自己写的每一步是否成立。
「企业研发 AI 自动化」是我持续记录 AI 进入真实研发流程后的实践系列。
它关注的不只是 AI Coding 工具本身,而是从需求输入、任务表示、Agent 执行到自动化验证的完整链路:AI 如何在真实工程系统里稳定运行,并逐渐形成可复用的研发自动化能力。
欢迎关注和交流~
《企业研发 AI 自动化》是我持续记录 AI 进入真实研发流程后的实践系列。
它关注的不只是 AI Coding 工具本身,而是从需求输入、任务表示、Agent 执行到自动化验证的完整链路:AI 如何在真实工程系统里稳定运行,并逐渐形成可复用的研发自动化能力。
欢迎关注和交流~