Spec 驱动开发把规格当作真相源:你精确地定义要造什么,实现从 spec 推导而来——而且越来越多是由 Claude Code、Cursor 这样的 AI 编码 agent 写的。它一直好用,直到 spec 和代码开始分叉。spec 躺在一份文档里,agent 照着一份副本写,上游某个决策一变,于是 spec、代码、agent 的上下文三者悄悄各说各话——直到出事。Draftlize 把 spec 做成 agent 动手前经 MCP 会先读的可寻址卡片,一旦实现和它对不上,就把状态翻成 drift_detected。
Spec 驱动开发的成败,全看 spec 是否还和代码对得上。一份 markdown spec 无法告诉你它什么时候对不上了;一张知道自己依赖的卡片可以。
| Draftlize | 文档 / markdown 里的 spec | |
|---|---|---|
| agent 读到的是什么 | 经 MCP 读活的卡片 | 贴进 prompt 的一份副本 |
| 某个决策变了 | 依赖它的 spec 标 stale | spec 悄悄变错 |
| 实现状态 | 自己翻成 drift_detected | 文档上次写的那样 |
| 一个决策,六份 spec | 一张卡片,被六处引用 | 六份副本各自漂移 |
| 谁让 spec 和代码对齐 | substrate 替你追踪 | 你的记忆 |
你写 spec,agent 照着造,第一天两者都对。然后代码在 spec 听不见的一个个 PR 里演进,spec 在代码看不见的一次次编辑里演进。两个真相源,各自漂移——这和没有真相源是一回事。
当你把一份 spec 贴进 prompt,agent 是照着复制那一刻冻结的快照在造。之后某个决策一变,agent 还在照旧的实现——而且很自信,因为没人告诉它地基已经动了。
翻掉一个 API 契约赖以成立的决策,凡是假设过它的 spec 全错了。没有任何东西把决策连到这些 spec,于是它们读着像真的,直到工程师——或 agent——在 review 里撞上矛盾。
Claude Code 或 Cursor 在写下第一行前,经 MCP 把相关 spec 和它底下的决策一并拉出来——于是它实现的是当前定义,而不是上周贴进去的副本。spec 成了 agent 每一轮都读的上下文,而不是只看过一次的文档。
每张 spec 卡片都声明它依赖什么。改一个上游决策,所有建立在它之上的 spec 自动变 stale——就像构建系统会让某个被改文件的所有下游全部失效。
代码写完后 spec 又动了,实现状态就自己翻成 drift_detected——于是 spec 和代码之间的缝,在它裂开那一刻就浮现,而不是三个 sprint 后在复盘里。
Spec 驱动开发有多强,取决于 spec 和代码之间那条链有多牢。把这条链交给 substrate 维护,而不是靠你记着。spec 写一次。让 agent 每一轮读到的都是活的那一版。
Spec 驱动开发是这样一种做法:一份精确的规格是真相源,实现从它推导而来,而不是让设计在你边写边改的代码里自己长出来。在 AI 时代,spec 往往是人写的、代码是 agent 从 spec 生成的,这让「让两者保持同步」成了核心问题。
测试驱动开发先写一个失败的测试,再写代码让它通过。Spec 驱动开发先写规格,再实现以满足它——而测试可以是这份规格的一种表达。两者互补:spec 说明造什么、为什么,测试检查造出来的是否对得上。
可以说这正是它最要紧的场景。Claude Code 或 Cursor 这样的 agent 照着给它的 spec 实现,所以 spec 的新鲜度直接决定代码。失败模式就是 agent 照着一份旧副本造——而一份可寻址、agent 能读的 spec 正好避开这一点。
别再把 spec 存成静态副本。Draftlize 把 spec 做成 agent 动手前经 MCP 会读的卡片,把每份 spec 接到它依赖的决策上,上游决策一变就把实现状态翻成 drift_detected——于是分叉在发生那一刻就浮现,而不是等到 review。
把 spec 写成卡片,经 MCP 接上 Claude Code 或 Cursor,让实现在决策一动那一刻就标出 drift。看看 给开发者的 Draftlize。
用 $5 免费开始