王永刚,英湃科技Inspire(原Thoughtworks)资深研发工程师,拥有多年企业级系统研发与大型团队交付经验,擅长复杂业务建模、系统设计与工程化实践,当前聚焦 AI 工程化与研发效能方向。
引言
基于 2025 年服务智能汽车、制造业、消费、医疗等多个行业的 AI 项目实践,我们曾试图分析 AI 介入后研发效能的本质变化,并提出了一个核心观察:AI 正在彻底重构研发的时间结构。随着 AI 不断压缩了原本编码这个长周期,研发的瓶颈发生了结构性位移,我们观察到原本作为衔接环节的前置“认知对齐”与后置“自测验证”,反而被意外拉长,演变成了新的矛盾。
这一变化的背后,潜藏着一个极易被忽视的问题。在传统模式下,长的编码期其实是人类开发者对需求的“二次打磨”过程。我们基于敏捷 3C 原则(Card、Conversation、Confirmation)与 Customer Focus(以客户价值为中心)价值导向,利用个体的主观能动性,通过与 BA(业务分析师,后文简称 BA) 保持高频沟通对齐,深度探索、理解和洞察业务的真实本质的需求,在编码开发的同时,同步完成业务隐性意图的纠偏。
然而,当 IDE 的战场从实现工具转向以 Agent 主导的对话界面,这层人的把控被弱化了。AI 缺乏识别模糊意图的能动性,若无确定性的上下文支撑,快速生成只会让初始的偏差不断放大,最终在验证阶段爆发为需要不断调整的效率黑洞。
摘自《Harness Engineering 橙皮书:AI 编程时代的工程方法论》: 模型对自己的第一个可行方案有天然偏好。它不是不会做得更好,是太容易满足于「看起来可以」。
为了填补这一认知真空,我们开始尝试将模糊的意图转化为可资产化的确定性输入。本文将聚焦于前置上下文工程,分享我们在 SDD(规范驱动开发)领域的实战反思;而关于如何提升后置环节的“验证信心”,我们也在同步进行一系列自动化探索,将在未来的文章中与大家另行讨论。
SDD 是一种面向 AI 时代的软件开发方式,核心是将需求理解、系统设计、代码实现与验证反馈等环节进行结构化表达,使 AI 能够在更清晰的工程上下文中参与到开发流程中。它并不是一个完全成熟或统一定义的标准,而是当前在 AI 辅助软件工程实践中逐步形成的一类方法探索。
SDD 的开始
在 2025 年,我们逐步的从 Vibe Coding 转向 SDD(Spec-Driven Development,后文简称 SDD),但这个过程并不顺利。随着 Cursor、Claude Code 等 AI 编程工具在团队的普及,我们一度以为:只要把需求写成 Spec,AI 就能自动生成高质量代码,从而彻底摆脱过去开发中的混乱与效率瓶颈,于是几乎没有犹豫就拥抱了 SDD,尝试用“需求卡 + Spec + AI 生成代码”的方式重构开发流程。
初期的效果确实令人兴奋:过去需要半天完成的接口开发,AI 几分钟即可生成,我们一度认为自己找到了拉齐开发经验差异、高效交付的秘密,可这种高效并没有持续太久。
直到这时我们才意识到:问题似乎并不在于 SDD 的使用方式,而在于我们是否真正理解了 Spec 在软件系统中的本质,它究竟是用来驱动代码生成的输入,还是用来承载系统认知的结构。更核心的是,我们后来发现,资产型 Spec 从来不是静态文档,而是一种系统治理的载体,它不是写出来的,而是打磨出来的,且具有极高的维护熵增风险。
SDD 里遇到的问题
图片来自网络
我们曾满心期许,一份 Spec 便能终结 Vibe Coding 时代的混乱与低效,化解团队协作中的沟通壁垒。但真正落地之后才发现,SDD 不仅没有根除这些老问题,反而在很多场景下,将原本隐藏较深的矛盾进一步放大。回头看,这些问题几乎都指向同一个核心那就是认知对齐,而 AI 的加入,并没有解决这个问题,反而在很多时候,成为了它的放大器。某种意义上,SDD 并不是让开发变简单了,而是把问题从“代码阶段”,前移到了“认知阶段”。
认知对齐了吗?
团队协作的核心,或许从来不是“谁来写代码”,而是“能否对同一份需求、同一种业务逻辑形成一致认知”。这句话听起来简单,但在实际落地中却异常困难,而这正是我们在 SDD 过程中首先遇到的阻力。
我们接手的很多系统,并不是全新的绿地项目,而是运行多年的复杂系统。核心业务规则从未被系统性记录:有些藏在历史代码或配置中,有些散落在 Bug 修复记录里,还有一些只存在于老员工的经验中。在人员流动频繁、业务变化较快的组织里,甚至连“当前业务到底是什么”,都很难被清晰描述。在这样的背景下,Spec 的撰写不可避免地变成了一种“信息拼图” 我们只能基于零散碎片去推测、补全和拼凑,很难形成真正一致的认知,偏差几乎是必然结果。
更关键的是,我们逐渐意识到一个非常容易被忽略的事实:代码并不等于业务真相。在遗留系统中,代码往往是被扭曲过的结果,其中混杂着历史妥协、临时补丁、紧急修复和人为操作的痕迹,它记录的是系统的现状,而不一定是“业务应该如何运作”。如果把这样的代码直接当作认知依据,那么从一开始,Spec 就已经建立在一个不稳定的基础之上。
AI 让错误更快发生
在没有 AI 的时代,开发拿到需求之后,很少能一步到位写出完全正确的实现,而是会在落地过程中持续遇到问题、修正对需求的理解。这个迭代校正的过程,本身就是一种被动的需求打磨、认知校准机制。
但引入 AI 之后,这个天然的校准过程被大幅压缩了。看到不少同事拿到需求后,没有和 BA(业务分析师)进行充分的来回确认,就基于当下的个人理解,直接将需求交给 AI 生成实现。简单场景尚且可控,但在复杂业务场景下,敏捷 3C 原则中,原本依靠人与人之间反复校对、逐步完成的认知对齐,渐渐被替换成了人与 AI 的一次性交互。
2025 年底,我们在讨论 AI 辅助研发时,我们也聊到一个话题:AI 是否会弱化大家对需求本身的深度思考?当时我并没有太深的感触。经过团队这一年 AI 辅助研发的落地实践,我慢慢发现:当开发者编写代码的成本大幅降低时,变更、修改代码的成本也随之变得更低。
从前,我们会尽全力先吃透、搞懂完整的需求,核心目的,是为了减少我们在代码上来来回回的修改,因为是人在写代码,这个成本是你需要去承接的。
而现在的问题在于:在我们描述的有限上下文里,AI 并不会主动质疑、反问需求本身的合理性与隐藏问题。它更倾向于扮演一名 “产出看起来合理结果” 的 To-Be 目标生成器,而非立足业务本身、结合真实世界的约束,反向推演可落地路径的架构思考者。
放眼行业前沿,无论是 Anthropic 的工程师团队,还是 OpenAI 公开的技术博客,在 Harness Engineering 的落地实践中,都发现了同一个规律:真正支撑系统持续演进的关键需求、底层决策逻辑,往往并不会完整留存于代码仓库当中,而是散落在 Google Docs 的文档推导、甚至 Slack 频道里那些转瞬即逝的聊天记录里。
而我们又何尝不是呢? 那些最核心的业务约束、复杂的边界判断,往往藏在会议室的白板上,拍照后存在手机的相册里,和产品的讨论沟通中,藏在开发者与 BA 之间那些没有记录的面对面沟通中,在深深的脑海里。甚至藏在某次为了应急而临时妥协的“潜规则”里。
在这种情况下,AI 不是在帮你理解需求,而是在放大你当前的理解。无论这个理解是否准确。即便现在的 AI 能通过 Agentic Search 去研究部分代码库现状,但由于它触达不到那些弥散在代码之外的“库外共识”,它的生成逻辑就成了无根之木。
结果就是,生成的代码在表面上完全符合需求描述,但在真实系统中却存在偏差,最终仍然需要花费不少时间去修正,甚至造成返工。今天就能 DC**(** Desk Check**)****,也因此成了一句常被挂在嘴边的调侃,但这个“搞定”,往往只是代码生成动作的终结,而不是问题真正被解决**。
这种变化还带来了一个微妙但关键的转变:自测的本质发生了变化。
过去,代码是一行一行写出来的,需求是在实现过程中逐步被吃透的,开发者对细节非常清楚,自测更多是在验证功能是否正确,而现在则更多的像是在检查 AI 做了什么。同时,现有 Spec 工具大多偏向开发者视角,BA (业务分析师)由于缺乏代码上下文,很难深度参与,Spec 逐渐演变为开发者的“单向表达”,进一步加剧了认知错位,也就是说当 BA 无法进入 Spec 语境时,Spec 就不再是人和人的对齐工具,而只是开发者的工具。在这种模式下,OPC(One Person Company)类的开发者感觉可能会觉得很自在。但在团队协作的模式下,Spec 由谁来写(BA?Dev?Agent?),为什么要写?写了之后给谁看?需求的载体是什么,就会遇到一些问题。
Spec 的投毒效应
另一个我们踩过的坑,是后来在团队内部被戏称为“给 AI 投毒”的问题,Spec 的质量直接决定了 AI 生成代码的成色,但在实际开发中,这一核心环节的问题却常常被忽视,最终引发了一系列连锁反应。
图片来自:Learnings from a No-Code Library: Keeping the Spec Driven Development Triangle in Sync
在 Spec 撰写的实际过程中,问题几乎不可避免:有人为了追求速度,对 Spec 打磨不够、遗漏关键信息;也有人在初版 Spec 中就存在业务认知偏差,却没有在后续迭代中及时修正。而在最初阶段,我们并没有对这些问题给予足够重视,总抱着“写错了,改代码就好”的侥幸心理,忽视了 Spec 作为 AI 生成代码的核心依据,其错误会被不断放大。
直到一次依赖卡开发的经历,让我们直观感受到了问题的严重性。当时我接手了一段前同事反复修改过的逻辑,表面上代码已经稳定,但推进过程中总觉得哪里不对劲,逻辑虽能运行却不符合业务直觉。深入追溯后才发现,问题根源并非当前代码实现,而是我的 AI 依赖了其他人最早的一版 Spec,最初的那份 Spec 它本身就存在关键业务理解偏差,后续所有修改都只是围绕这个偏差“修补”,而非从根源纠正,这种现象在依赖他人 WIP (Work in Progress) 的代码中也会有这样的问题。这种感受十分反直觉:我们不是在修复实现错误,而是在错误的认知基础上,不断叠加“正确”的代码。最终,我们选择回溯梳理业务规则,修正 Spec 后重新搭建实现路径,也正是这次经历,让我们深刻意识到:错误 Spec 一旦进入开发流程并被反复引用,就会从“局部偏差”变成系统性的隐性前提。
而这一问题的背后,还有一个更现实且普遍的痛点 Spec 的维护往往被忽视。
我和其他几个团队也交流过这个话题:需求变化之后,你们会回头修改 Spec 吗?
坦白讲,在迭代交付的压力下,大家往往会选择成本最低的路径:代码修改完成就视为交付,Spec 要么不同步更新,要么只是零散补充,甚至堆叠出一堆不同维度、逻辑混乱的内容。我们与其他团队交流后发现,这几乎是一种普遍现象,而这种对 Spec 维护的忽视,恰恰是“投毒效应”不断加剧的根源之一。项目上下文了解不深的开发者无法有效判断,会基于错误依据生成更多错误代码,甚至可以说,Spec 维护的缺失,比 Spec 本身写错更具破坏性。
问题或许不在 SDD
图片来自网络
被这些坑反复打磨了大半年,我们才终于静下心来复盘:究竟是 SDD 本身存在缺陷,还是我们的落地方式,从一开始就偏离了方向?
几番梳理之后,我们逐渐得出了一个有些反直觉的结论:
问题的根源,一部分来自传统敏捷模式的路径依赖,一部分来自在现实交付约束下对规范维护的持续让步,而未必在于 SDD 本身。
我们长久以来,一直沿用“需求卡驱动开发”的模式。User Story 的设计初衷,是为了适配批量开发场景、提升整体交付效率。但一个容易被忽略的事实是:**单张需求卡,从来都不等同于完整需求。**一份完整的业务真相,往往需要拼接所有需求卡、梳理历史变更,甚至逐行核对代码,才能勉强呈现。
需求卡本质上只是管理过程,对业务的局部表达,而不是全局认知。
而在转向 SDD 之后,我们几乎是无意识地把这套模式原封不动地迁移了过来,一张需求卡对应一份 Spec,使得 Spec 同样陷入零散化困境,无法沉淀为完整的业务资产。某种意义上,我们并没有在做 Spec-Driven Development,而是在做“Spec 版的需求卡开发”。
另一半问题,则来自更现实也更难规避的一点:在高频交付与不确定性变更的压力下,团队往往很难持续投入成本去维护 Spec 的一致性。
在实际工作中,突发 Bug、临时需求、紧急上线几乎是常态。在交付压力面前,很少有人会严格遵循 SDD 流程去完善 Spec、反复对齐认知。更常见的选择,是复用已有逻辑、弱化流程约束,先解决眼前问题,并将 Spec 更新延后处理。
这些看似高效的捷径,让 Spec 逐渐流于形式,开发重新滑回零散化状态,认知不断脱节,并与“需求卡模式”的惯性叠加,形成一个自我强化的循环。
某种程度上,SDD 并不是一个设计错误的模型,它的问题在于,它对团队提出了一个非常高的隐含前提:必须持续维护一致的系统认知,而这件事本身,是有较高的成本的,尤其是细粒度变化频繁的 Spec。
但当我们把“问题不在 SDD”这一点逐渐看清之后,一个更难的问题也随之浮现出来:
如果问题不在于工具和流程,那我们真正缺失的,到底是什么?
对问题的深入分析
但当我们逐渐接受“问题不在 SDD”之后,一个更具体的问题也随之浮现出来:如果不是流程出了问题,那我们在开发过程中,究竟缺失了什么?
回头看这些反复出现的现象,认知难以对齐、Spec 不断偏移、AI 放大理解偏差,它们表面上各不相同,但背后却指向同一个更底层的空白:我们始终没有一个稳定、清晰、可共享的“系统现状表达”。
我们习惯拆分需求、记录变更、描述目标,却很少真正去回答一个更基础的问题:当前系统到底是什么样?业务规则的真实边界在哪里?哪些是稳定存在的约束,哪些只是历史演化的结果?这些本该作为起点的内容,往往散落在代码、数据库、配置和人的经验之中,从未被系统性表达出来。
在这样的前提下,无论是需求卡、Spec,还是 AI 生成代码,本质上都是建立在一份并不完整的认知之上。我们以为自己在推进开发,实际上却是在一个模糊的“现状”之上不断叠加新的变化。
也正是在这个阶段,我们开始意识到:与其继续优化流程、打磨 Spec 的写法,或许更应该先回答一个更基础的问题,如果连“现在是什么”都说不清楚,我们如何能更好地引导 AI,更多的 Skill?精心维护的 Promot?或许都不是。我们也同步地发现,拥有更多项目背景的人在完成 Story 开发和 DC 的时候,效率及完成度会更高一些,在对他们进行观察之后,几乎都回到了一个逃避不开的话题,到位的需求理解。
那我们口中的“需求”,究竟指的是什么?
过去,我们习惯将需求理解为 To-Be,客户提出的目标、功能,或拆分后的 User Story。但这种理解,其实隐含了一个前提:我们已经清楚“当前系统是什么样”,只需要讨论“要做什么”。
而现实恰恰相反。
在大多数客户那里,业务的现状是复杂不清晰的,IT 系统也是“现状”不清晰的:它分散在代码、数据库、配置、历史需求以及业务人员的经验之中,没有任何一个单一载体可以完整表达。这意味着,在很多时候,我们甚至还没有搞清楚 As-Is,就已经开始讨论 To-Be。
这也解释了为什么,在 SDD 过程中,即使 Spec 写得再详细,AI 生成的代码依然可能偏离实际,因为整个推导的起点,本身就是模糊的。
基于这样的反思,我们也认识到真正的需求,或许并不是目标本身,而是从现状到目标之间那段被忽略的差距。
As-Is(现状) + To-Be(目标) + Gap(差异)
-
As-Is,是对当前系统与业务的真实还原,是一切的起点
-
To-Be,是在现状基础上的合理演进方向
-
Gap,才是开发真正需要解决的问题
在复杂系统中,最大的问题不是我们想做什么,而是我们根本说不清现在是什么。如果跳过 As-Is,直接定义 To-Be,AI 只是忠实地执行了这个不完整的输入。
但真正困难的,并不是定义 To-Be,而是还原 As-Is。
我们不得不通过翻代码、查配置、追溯历史、与业务人员反复确认,去拼凑出尽可能接近真实的系统状态。这个过程,我们做的,其实是一场业务考古。从零散信息中提取线索,通过不断对齐与验证,还原系统的真实运行逻辑。
而一旦 As-Is 能够被清晰表达,To-Be 的设计与 Gap 的识别,反而变得更加自然。
在下一篇文章中,我将结合大型制造业与电商履约等复杂项目实践,进一步展开我们在 SDD 落地过程中的治理方式,以及如何在真实工程场景中提升其可用性与稳定性。
英湃科技
Inspire
英湃科技(Inspire)是一家致力于将前沿 AI 技术与顶尖工程能力相融合,帮助企业实现数智转型的新一代科技服务商,源于 Thoughtworks 中国核心团队,2025年9月由高瓴资本收购,不仅拥有世界级的架构设计与敏捷交付底蕴,更具备深刻的行业洞察。英湃科技围绕企业核心价值链,聚焦研发、供应链、销售与服务等领域,重塑关键能力与组织模式,服务领域包括银行金融、消费电子、具身智能、智能汽车、制造业、医疗&制药、消费品&零售等各行各业130+家全球500强企业,业务中心遍布新加坡、香港、上海、北京、深圳、成都、西安、武汉。