用 spec-driven development 打破 doom-prompting 循环
Source: Dev.to
将软件工程纪律引入 AI 辅助编码
每个使用 AI 编码工具的开发者都经历过这样的循环:你发出提示,AI 生成代码,出现一点问题,你再次提示,AI 在修复第一个问题的同时又弄坏了别的东西,你再次提示。一个小时后,你陷得比开始时更深,陷入了现在被称为 doomprompting 的循环。
这就是 vibe coding 的暗面——Andrej Karpathy 用来形容完全屈从于 AI 生成代码而不真正理解它的术语。Karpathy 本人指出,这种方式对“随手的周末项目”来说“还算不错”。但对任何更重要的项目,这种方法往往会崩溃。
我一直在使用 spec‑kit,GitHub 的规范驱动开发工具包,它改变了我对 AI 辅助编码的思考方式。核心洞见很简单:在规范中捕获问题的成本远低于在代码中捕获问题的成本。
将左移原则应用于 AI 编码
左移测试的理念是:在开发的早期捕获缺陷比在后期捕获更便宜。每个调试过生产问题的人都直观地明白:在需求阶段发现问题几乎不花钱,在代码审查阶段发现需要一些返工,而在生产环境中发现则代价更高。
Spec‑kit 将这一原则应用到 AI 辅助开发中,但把左移进一步推进。不是通过测试代码来捕获问题,而是通过审查规范来捕获问题。四阶段工作流将这一点明确出来:Specify → Plan → Tasks → Implement。每个阶段都有一个门槛,必须在继续之前进行审查。
这让接受过正规软件工程教育的人感到熟悉。大学项目中,我们常常在写第一行代码之前花数周时间制定规范和架构。当时这种纪律看似繁琐,但真正进入编码阶段时,过程异常顺畅。Spec‑kit 将同样的严谨性带入了 AI 辅助开发。
spec‑kit 实际提供的功能
该工具包与具体的 AI 代理无关,可配合 Claude Code、GitHub Copilot、Cursor 以及其他 AI 编码工具使用。其核心是一组斜杠命令,引导你完成结构化的阶段:
/specify– 强制你阐述要构建的内容。/plan– 生成研究和技术方向。/tasks– 将计划拆解为离散的实现步骤。/implement– 执行这些任务。
每个阶段都会生成 Markdown 文件,既充当文档,又充当 AI 的上下文。规范、计划和任务列表会跨会话持久化,充当记忆,使 AI 与你的意图保持一致。
Spec‑kit 还引入了一个“constitution”(或称“principles”)文件,用来为项目设定横切规则:测试方法、编码标准、架构约束等。这些非功能性需求适用于 AI 生成的所有内容。
工作流如何改变日常工作
使用 spec‑kit 时,我的工作流与典型的 AI 编码循环不同。我会花时间审查并编辑规范和任务列表,然后让 AI 完整实现功能。我把 AI 看作是我委派工作的开发者,而不是配对编程的伙伴。我像审查人类团队成员的 Pull Request 那样审查 AI 生成的代码。
这种心智模型很重要。配对编程时,你会盯着每一次按键;而委派时,你审查的是结果是否符合规范。后者在 AI 能够自主实现大块功能时更具可扩展性。
plan 阶段已成为最有价值的环节。AI 会对技术方向进行研究,我常常从中学到新东西。更重要的是,我能提前捕获误解。一次项目中,计划阶段揭示 AI 误以为 IBM Cloud 的无服务器服务部署在 VPC 中——如果等到后期才发现,这个错误的代价会更高。
我不再审查每一行代码改动,而是:
- 仔细审查规范。
- 让实现阶段在自动接受模式下运行。
- 进行冒烟测试。
- 审查完整的变更集。
如果出现问题,我会重新走完整个流程(plan → tasks → implementation),而不是直接跳到代码修复。这样可以保持规范的准确性,并与实际构建的内容保持一致。
开销问题
Spec‑kit 确实会带来额外开销。对于简单任务,这种开销可能不值得。
但对于更大的功能特性,投入会得到回报。规范迫使我认真思考需求。架构问题会在计划审查阶段浮现,而不是在投入代码后才暴露。我也因此避免了 doom‑prompting 循环,因为思考中的歧义会在规范阶段得到解决,而不是通过反复试错的提示来解决。
使用 spec‑kit 时 token 使用量会增加——因为在写代码之前要生成规范、计划和任务列表。但这些 token 通常会通过避免无止境的提示消耗而“自我抵消”。
基于提示的流程 vs. 编码管道
spec‑kit 设计中有一点让我感到惊讶。我的直觉是把大部分工作流实现为传统编程语言中的显式控制流。相反,spec‑kit 将流程封装在详细的提示中,只配合极少的脚本。
这在前沿模型上表现良好。提示用自然语言描述各阶段,AI 能可靠地遵循。带有门槛的模板化方法提供了确定性的结果,而不需要像 LangGraph 那样的编码编排节点。
我猜在非前沿模型上,这种做法的可靠性会下降,因为它们缺乏完成复杂多阶段指令所需的指令遵循能力。
除模型本身外,每个 AI 助手可用的工具也很关键。计划阶段受益于网页搜索、代码库搜索以及其他研究能力。Claude Code 默认内置这些功能,包括深度搜索以进行彻底研究。其他助手可能缺少部分功能,我在计划质量上看到的差异主要来源于研究工具的限制。
在执行流程前配置 MCP 工具也能提升结果。例如,我会为 Terraform 模块注册表搜索和云提供商文档查找配置工具,从而帮助 AI 生成更有依据的计划。
为基础设施即代码(IaC)进行适配
刚开始使用 spec‑kit 时,我以为它可以直接套用到基础设施即代码(IaC)上。随着实践的深入,我意识到 IaC 有其特有的特性,需要不同的处理方式:
- Terraform 等工具的声明式特性。
- 必须将云无关的需求与特定提供商的实现分离。
- 与应用代码不同的安全性和成本治理关注点。
- 需要针对实际云提供商 API 和模块注册表进行验证。
为了解决这些问题,我创建了 iac‑spec‑kit 并开源。它在 spec‑kit 工作流的基础上加入了 IaC 专用的约定和验证步骤,使该方法在 Terraform、CloudFormation 等工具上同样实用。