T
traeai
登录
返回首页
Towards Data Science

从 vibe coding 到 spec-driven development

8.5Score
从 vibe coding 到 spec-driven development

TL;DR · AI 摘要

本文探讨了从 vibe coding 转向 spec-driven development 的必要性和实践方法,强调了后者在团队协作和项目管理中的优势。

核心要点

  • Vibe coding 适用于简单项目,但在大型项目中缺乏最佳实践和共享规范。
  • Spec-driven development 强调先进行架构决策和需求定义,再进行实现,有助于团队协作和项目管理。
  • Andrej Karpathy 提出 agentic engineering 概念,强调通过详细规范和人工监督来协调代理进行开发。

结构提纲

按章节快速跳转。

  1. 介绍从 vibe codingspec-driven development 的背景和动机。

  2. 比较两种开发模式的优缺点。

  3. 讨论 vibe coding 在大型项目中的问题。

  4. 介绍 spec-driven development 如何解决这些问题。

  5. 作者通过一个个人项目展示如何应用 spec-driven development。

思维导图

用一张图看清主题之间的关系。

查看大纲文本(无障碍 / 无 JS 友好)
  • From Vibe Coding to Spec-Driven Development
    • 引言
    • Vibe coding vs Spec-driven development
      • Vibe coding 的局限性
      • Spec-driven development 的优势
    • 实践案例

金句 / Highlights

值得收藏与分享的关键句。

  • 主要的问题是缺乏最佳实践和共享规范。例如,没有结构化的方法,团队很容易在同一个 DBT 管道中出现五种不同的 ML 模型训练方式。

    Vibe coding vs Spec-driven development

    ⬇︎ 下载 PNG𝕏 分享到 X
  • Spec-driven development (SDD) 更接近传统的工程实践。我们不是直接跳入实现,而是先自己进行深入思考:做出架构决策,定义需求,并将这些内容记录在存储库中的结构化 Markdown 规范中,与项目一起更新。

    Spec-driven development 的优势

    ⬇︎ 下载 PNG𝕏 分享到 X
  • 即使是提出“vibe coding”概念的 Andrej Karpathy 也在一年后承认,这个时代即将结束,我们将进入 agentic engineering 时代——通过详细规范和人工监督来协调代理进行开发。

    引言

    ⬇︎ 下载 PNG𝕏 分享到 X
#软件工程#AI#开发流程
打开原文

从氛围编码到规范驱动开发

我在之前的文章《从代码到洞察:数据分析师的软件工程最佳实践》中提到,工程技能和最佳实践对分析师和其他数据专业人士来说非常有用。

在人工智能时代,这一点更加明显,我们有更多机会构建自己的分析工具:从展示图表或不同场景的高级数据查看器,到可以根据输入参数预测结果的模拟器。我个人在日常工作中经常使用网络应用程序。

关于氛围编码有很多炒作,但似乎专业工程师已经开始超越它,更倾向于规范驱动开发。甚至“氛围编码”这一术语的创造者 Andrej Karpathy 也在 2025 年 2 月 承认,仅仅一年后,这个时代即将结束,我们正在进入代理工程的时代——在人类监督下根据详细规范协调代理。

_今天(一年后),通过 LLM 代理编程正逐渐成为专业人士的默认工作流程,只是增加了更多的监督和审查。目标是在利用代理的同时,不牺牲软件的质量。许多人试图为此找到一个更好的名称以区别于氛围编码,我个人目前最喜欢的是“代理工程”:

– “代理”是因为新的默认做法是你 99% 的时间不会直接编写代码,而是协调代理并进行监督。

– “工程”强调这是一门艺术与科学,需要专业知识。你可以学习并变得更好,它有自己的深度。_

在这篇文章中,我想在一个绿地项目中实践规范驱动开发,遵循 JetBrainsDeepLearning.AI 课程《规范驱动开发与编码代理》中的最佳实践。

这个项目有点个人化,但仍与数据相关。随着我准备九月份的半程马拉松,我正在努力平衡跑步和力量训练。市面上有那么多工具,每个工具都专注于旅程的不同部分,找到真正适合我的解决方案出乎意料地困难。因此,我决定一石二鸟:一边构建自己的网络应用,一边希望在这个过程中学到新东西。

准备好行动了吗?我也准备好了。但在我们开始实施之前,先花几分钟了解一下规范驱动开发背后的理论。

氛围编码 vs 规范驱动开发

我们很多人都已经体验过氛围编码:你写一个简短的提示(例如,“请在我的网络应用中添加一个 DAU 图表”),等待代理生成更改,本地运行并检查结果是否符合预期。

通常,结果并不符合预期。于是你回到同一个聊天窗口,要求代理调整图表,并不断迭代直到结果足够好。

这种方法对于简单的项目来说效果还算不错,但在多个开发者共同处理同一代码库时,扩展性较差。

主要的问题在于缺乏最佳实践和共享规范。例如,没有结构化的方法,团队很容易在同一个 DBT 管道中出现五种不同的机器学习模型训练方式。

另一个常见问题是,我们通常不会持久化与 AI 代理对话的结果或推理。因此,很容易忘记某些决策的原因。例如,代理可能会忘记你为什么以特定方式清理数据,下次更新时可能会悄悄引入不同的结果。

上下文衰减也是一个特别常见的问题。AI 代理是无状态的,当处理较大的项目时,我们经常因为上下文窗口限制而不得不开始新的聊天,实际上是从头开始沟通。

规范驱动开发(SDD)更接近传统的工程实践。我们不是直接跳入实现,而是先自己进行深入思考:做出架构决策,定义需求,并将这些内容记录在存储于仓库中的结构化 Markdown 规范中,并随项目一起更新。这带来了一个重要的转变:我们将规范(我们要构建什么以及为什么)与实现(实际代码)解耦。

SDD 通过在会话间(甚至在不同的 AI 代理间)保留上下文,同时使人类和代理围绕项目的非谈判核心达成一致,解决了氛围编码的核心问题。

SDD 工作流

典型的规范驱动开发工作流通常包括以下几个阶段。

第一步是定义宪法——即项目的关键决策协议。它通常包括几个核心文档:

  • 使命解释了“为什么”:我们为什么要构建这个项目,它的关键目标和功能是什么?
  • 技术栈记录技术决策,以及部署和更新过程。
  • 路线图概述了项目阶段、计划的功能,并随着项目的进展不断更新。

规范可以为新项目和现有项目创建,这使得这种方法非常灵活。

一旦项目级别的文档就绪,我们可以进入功能开发阶段,该阶段通常包括:

  1. 理解我们要构建的内容并编写详细规范。
  2. 实现更改。
  3. 验证实现是否符合预期。

成功实现第一个功能后,你可能会立即想要继续下一个功能。但其实这是暂停和重新思考的最佳时机。

这就是重新规划的阶段。这是一个专门的阶段,用于回顾项目章程,审查之前的功能决策和计划,确保它们仍然与项目目标一致。

现在我们已经了解了理论,让我们将其付诸实践。

构建

够了理论,是时候开始构建了。为了更好地理解规范驱动开发在实际中的工作方式,我决定将其应用于一个真正的绿地项目。

我首先为此项目创建了一个新的仓库(当然,花了一半的时间选择名称和标志):仓库。我还在我项目的 README.md 文件中记录了初始产品愿景。

规范驱动开发方法的一个优点是它对 LLM、代理或 IDE 的选择具有很大的灵活性,因此你可以使用你喜欢的任何设置。对于这个项目,我将使用带有 Claude Code 插件的 Visual Studio Code,因为它允许我在编辑器中直接使用 Claude 作为代理并审查所有代码更改。

创建章程

正如我们所讨论的,第一步是编写章程。当然,我们不需要手动完成,可以使用 LLM 基于初始产品愿景以及通过后续问题收集的附加上下文来生成章程。

code
我们正在构建 Trainlytics,一个个人健身追踪网络应用,
专为希望比标准健身应用提供更多控制、灵活性和洞察力的人群设计。
完整的功能需求请参见 README.md。

让我们在 specs 目录中创建一个“章程”,包括以下部分:
- mission.md - 我们在构建什么以及为什么;产品的主要使命
- tech-stack.md - 核心技术决策
- roadmap.md - 按实施顺序划分的项目阶段

重要提示:你必须使用你的 AskUserQuestion 工具获取我的反馈。

然后,代理会提出一系列澄清问题,帮助定义项目章程并创建初步的实施计划。

Image 1

图片由作者提供

最终,代理创建了我们要求的三个文件。

Image 2

图片由作者提供

此时,你可能会有立即要求代理开始构建项目的冲动,但这可能为时过早。

在继续之前,我们需要验证和细化章程。现在花时间对计划达成一致是值得的,因为这个规范后来将转化为数千行代码。及早解决模糊性和错误会更好。

我通常通过自己阅读文档并与代理迭代来完成这一步,提出澄清问题并逐步完善计划。一个好的做法是通过代理进行所有更改,而不是自己修补文档,以保持项目的一致性。例如,我告诉代理我们需要在应用中加入身份验证,因为我的用例是从桌面和移动设备记录锻炼。这导致了技术栈文档和路线图的更新。

Image 3

图片由作者提供

一旦你对审查满意,还可以要求另一个具有新鲜上下文的代理来批评计划。有大量证据表明反思可以提高输出质量。

当所有检查都完成后,是时候将章程提交到仓库中了。

第一个功能阶段

现在,是时候进入第一个功能阶段了。

根据我们的路线图,我们将从 MVP:核心活动记录 开始。在这个阶段结束时,用户应该能够在桌面和移动设备上登录,记录跑步和健身房训练,并在他们的历史记录中查看这些活动的全部细节。

正如我们所讨论的,每个功能阶段都遵循一个简单的周期:计划 → 实现 → 验证。所以让我们先定义规范并制定计划。

code
在 specs/roadmap.md 中找到下一阶段,并创建一个新的分支,
询问我关于规范中任何不清楚的步骤。

然后在 specs/ 下创建一个格式为 YYYY-MM-DD-feature-name 的新目录,
用于此功能,包含以下文件:
- plan.md - 编号任务组的结构化列表
- requirements.md - 范围、关键决策和上下文
- validation.md - 如何定义成功并确认实现可以合并

使用 specs/mission.md 和 specs/tech-stack.md 作为指导。

_提示:在 LLM 代理中启动一个具有清晰上下文的新会话是有价值的。_

代理很快就整理好了规范。

Image 4

图片由作者提供

此时,再次审查规范并确保一切与原始愿景一致是很重要的。如你所见,在代理工程中,开发者的角色转向了指导、审查和做出架构决策,而不是直接编写规范或代码。

一旦你对计划满意,就可以开始实施了。我更喜欢分别实现每个任务组,而不是一次性完成整个功能阶段,但这取决于功能的大小。对于这个项目,我使用了以下提示。

从 2026-05-04-phase-1-mvp/plan.md 中的下一个任务组开始实施。 使用 requirements.md 和 validation.md 作为指导。 完成后,在计划和验证文档中更新状态。

当代码准备就绪后,就到了审查阶段。这是最重要的步骤之一,因此值得在这里投入一些时间。

在与数据相关的应用程序中,我通常会重点关注核心业务逻辑,并检查数字是否符合我的预期。

我必须承认,我对前端技术几乎一无所知,因此很少详细审查前端代码。相反,我只是在本地测试界面,检查一切是否按预期工作。在这种情况下,我决定运行应用程序并看看它的表现如何。

经过几次与代理的迭代,我们成功地在本地运行了应用程序,并且它能够正常工作。我们已经可以添加不同的练习和活动类型,并记录有氧和力量训练。

Image 5

图片由作者提供

手动审查之后,使用反思并让新的代理验证实现是否与计划一致,以及检查 validation.md 中定义的要点也是很有用的。

理论上,基于规范的开发建议功能阶段以验证结束。但在实践中,这很少能如此顺利。你可能会发现某些部分的实现不符合预期。在这种情况下,你有两个选择:

  • plan.md 中再增加几个迭代,继续完善功能(这适用于较小的更改),或者
  • 如果问题较为严重,将其视为下一功能阶段的一部分,并在重新规划时处理它们。

需要注意的一点是:直接向 LLM 代理解释问题并要求修复,而不是更新规范和重新实现,这种捷径可能会很诱人。尽量避免这种捷径。保持规范作为事实来源是使这种方法稳健的关键。

所有检查完成后,我们可以创建并合并 拉取请求

此时,我们已经有一个可以工作的应用程序,结果确实令人满意。更令人惊讶的是,整个过程仅用了两个多小时(包括在代理工作时起草这篇文章的时间)。

重新规划

取得如此好的进展后,你可能会有继续构建的冲动。我理解这一点,但在当前的人工智能时代,人类的主要价值在于思考和架构。因此,现在实际上是退一步反思的好时机:我们是否仍然希望继续沿着同一个方向前进,我们应该在产品和流程中做出哪些改变?

当我开始自己使用这个应用程序时,我意识到它还不能完全支持我的用例。这意味着我们需要重新优先排序,以便我尽快能够在日常生活中使用它。因此,我使用了以下提示进行了重新规划。

code
让我们在 roadmap.md 中修订我们的计划。
我会按照以下顺序优先考虑接下来的阶段:
1. 力量训练模板
我可以没有计划功能,但需要模板,因为我经常记不住一个训练中的所有练习。

想法是:
- 如果日志中已存在模板,显示所有统计数据(练习、组数、次数、重量等)。允许编辑这些值并提交更改
- 如果有任何更改,询问用户是否要更新模板

2. 用户界面改进
当前的设计还不够精美,因此我会优先进行一轮用户界面改进:
- 在网站上添加标志和产品口号
- 添加设置标签以管理活动类型和练习
- 创建一个单一屏幕来记录有氧和力量训练
- 改进历史屏幕,提供更多活动详情
- 允许为活动(力量/有氧训练)和段落添加标题
- 支持指定时间,而不仅仅是日期
- 为界面添加更多颜色(我喜欢蓝色调)
- 对于有氧运动,调整单位为:分钟、公里和每公里配速

3. 基本分析
在历史屏幕上添加简单的分析,显示页面顶部的每周统计数据(例如,有氧和力量训练的总分钟数和卡路里消耗)

重新规划也是回顾我们自身流程的好时机。例如,我注意到我们没有一致地更新 roadmap.md,规范开始偏离。引入变更日志也很有用,这样我们就可以清楚地了解产品随时间的演变。

让我们请代理为我们完成这些任务。

code
请审查 plan.md,更新 roadmap.md 以反映已完成的工作,
并创建一个 CHANGELOG.md 文件,简要总结变更内容。

现在我们已经在方向上达成一致,并且有了正确的设置,让我们继续构建。

下一阶段

现在我们可以遵循相同的过程,通过各个阶段进行迭代。由于这是一个可重复的循环,讨论可能的自动化是一个好时机。

到目前为止,我们一直在手动编写所有提示,但这些工作流也可以作为“技能”在 Claude Code 或其他 LLM 编码代理中自动化。

此外,已经有一些现成的基于规范的开发实现。最流行的一个是由 GitHub 开发的 Spec Kit

你可以像这样安装它。

code
uv tool install specify-cli --from git+https://github.com/github/spec-kit.git
specify version # 检查是否安装成功

接下来,你需要在 Claude 中初始化这些技能。这将设置 .specify/ 文件夹并在 .claude/commands/ 中安装斜杠命令。

code
specify init . --integration claude 
# 有 30 种与代理的集成方式,请指定你正在使用的集成方式

当你在 Claude Code 中看到 speckit 命令时,就知道安装成功了。

Image 6

图片由作者提供

安装完成后,您可以遵循类似的工作流程:首先定义宪法,然后通过功能循环进行迭代。

Spec Kit 的一个不同之处在于,宪法更侧重于高层次的问题,如代码质量、测试标准、用户体验一致性以及性能要求。

坦率地说,我稍微更喜欢 JetBrains 提出的方法,因为它在宪法本身中保留了更多的上下文。但正如通常所说,没有万能的解决方案,根据您的使用情况,Spec Kit 可能会更合适。另外,已经为您实现了 SDD 工作流程,这也很方便。

使用 Spec Kit,我完成了上述两个阶段,效果很好。在第一个功能阶段之后,开发自然地成为了一个持续改进的循环,而不是线性过程。至此,我认为是时候结束这个故事了。

总结

总的来说,我花了大约 4.5 小时构建了一个可用于跟踪和分析数据的端到端产品。还有很多改进的空间,我会继续迭代。我已经看到了几个潜在的 UI 增强点,并且希望最终能够集成 AI 使应用程序更加智能。

坦率地说,按照如此结构化的开发流程工作是一次有趣的体验。在我的日常工作中,我经常依赖一次性 LLM 聊天来做出更改,而不会在仓库中维护完整的决策和规范记录。

然而,这里并没有一成不变的方法。

  • 如果您只是想进行一个小的改进或在另一个 Jupyter 笔记本中运行一些临时分析,事先编写完整的规范可能有些过度。
  • 但是当您正在处理一个较大的项目(尤其是与其他人合作时),规格驱动的开发肯定是我默认的方法。

观察工程师角色的变化也很有趣:从直接编写代码转向更多地关注架构决策、审查和系统设计。

虽然今天听起来可能有点极端,但我确实认为我们正逐渐迈向一个以英语为主要“编程语言”接口的世界。我们已经在这一方向上看到了早期尝试,例如 CodeSpeak,它探索了更自然语言驱动的编程范式。我将在下一篇文章中尝试 CodeSpeak,敬请期待。

参考

本文灵感来源于 DeepLearning.AI 的_“使用编码代理进行规格驱动开发”_短期课程。

AI 可能会生成不准确的信息,请核实重要内容