[DataFlow-CV v1.5.0] SDD 实践与思考

Claude Code + DeepSeek V4.0 … YYDS !!!

项目地址:https://github.com/zjykzj/DataFlow-CV

一、Vibe Coding 之后:为什么要转向 SDD

2026 年 3 月到 4 月,我用 Vibe Coding 从零开发了 DataFlow-CV,经历了多轮完整重写。每轮重写的触发点都一样:工程架构逐渐混乱,文件职责不清、接口定义随意、参数传递失控,到了模型自己也修不回来的地步。

现在回头看,Vibe Coding 的三个核心痛点本质上指向同一个问题:

1. 上下文是硬天花板,但问题不在上下文大小。 DeepSeek V3.2 的 127k 窗口不算小,但 Vibe Coding 的”走一步看一步”方式会让对话历史迅速膨胀。更致命的是,当上下文接近上限时,模型开始”遗忘”早期的设计决策——不是窗口不够大,而是信息密度太低。大量上下文被临时的修修补补占满,真正重要的架构决策反而被冲走了。

2. 无规划开发 = 熵增陷阱。 想到一个功能写一段提示词,功能累积到一定程度后集中爆发:文件职责混乱、接口定义随意、依赖关系复杂。这和在传统开发中不写设计文档直接写代码的结果一样——只是 AI 让代码生产速度提高了 10 倍,熵增速度也提高了 10 倍。

3. 被动重写 ≠ 主动重构。 Vibe Coding 中的重写是被迫的”重启”——当前代码烂到没法继续了,只能从头来过。但如果没有把上一轮的教训结构性地沉淀下来,重写就是重复劳动。Spec 就是让教训沉淀的载体。

总结下来:Vibe Coding 缺少一个可复用的、模型能直接消费的”真理来源”。 每次重写时,你对工程的理解在脑子里,但模型拿不到——除非你每次重新写一遍提示词。Claude Code 的 Plan Mode 能出一次性的设计,但 Plan 完成后没有保存和复用机制。

SDD 解决的正是这个问题。它把设计方案文档化、结构化,让 spec 成为开发过程中的持久资产——不仅仅是给人看的文档,更是给 AI Agent 消费的”可执行指令”。

二、什么是 SDD——我的理解

2.1 核心概念

SDD 的核心思想很简单:Spec 定义”什么是对的”,代码是 spec 的实现。

这和传统开发有本质区别:

传统开发 SDD
规范的角色 指导文档,写完就过时 可执行契约,驱动代码生成
真理来源 代码(code is truth) 规范(spec is truth)
规范与代码的关系 规范服务于代码 代码服务于规范
需求变更 改完代码补文档 先改 spec,再生代码

用一句话概括:SDD 不是让你写更多文档,而是让你的文档能被 AI 直接用来生产代码。 从”代码即真理”转向”意图即真理”。

2.2 SDD 的三层体系

在我的实践中,SDD 分为三层:

1
2
3
Specs(什么是对的)──→ CLAUDE.md(代码怎么写的)──→ Code(实现)
↑ ↑ │
└── 行为变化时同步更新 ── 架构变化时同步更新 ←──────┘
  • Specs 层(行为契约):定义数据格式、接口契约、转换规则、评估指标。修改频率最低,权威最高。
  • 开发上下文层(架构知识):CLAUDE.md 记录架构设计、关键实现细节、已知陷阱(Known Gotchas)。随代码演进持续更新。
  • Code 层(实现):实际运行的代码,日常修改最频繁。

关键原则:Specs 是最高权威。如果代码行为与 specs 冲突,以 specs 为准,改代码。 反过来,如果 specs 不充分或不合理,优先更新 specs,再改代码。

2.3 WHAT 与 HOW 分离

SDD 最重要的结构设计是 WHAT(外部契约)与 HOW(内部架构)的分离

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
specs/
├── formats/ # WHAT — 数据格式长什么样
│ ├── spec_yolo_format.md
│ ├── spec_labelme_format.md
│ └── spec_coco_format.md

├── evaluate/ # WHAT — 评估指标怎么算
│ ├── spec_evaluate_fundamentals.md
│ ├── spec_evaluate_metrics.md
│ └── spec_evaluate_tasks.md

└── modules/ # HOW — 代码模块怎么设计
├── spec_label.md
├── spec_convert.md
├── spec_visualize.md
├── spec_evaluate.md
└── spec_cli.md

WHAT 层回答”外部世界怎么定义这个事”——YOLO 格式的 .txt 文件长什么样、COCO 的 bbox 坐标是左上角还是中心、mAP 的计算公式是什么。这些东西是领域知识,和工程实现无关。

HOW 层回答”代码内部怎么组织”——Converter 的 pipeline 怎么走、Visualizer 的渲染管线怎么设计、CLI 的 exit code 怎么定义。这些东西是工程决策,依赖于 WHAT 层的约束。

分离之后,每个 spec 文件只回答一个问题。如果一个 spec 同时回答”数据长什么样”和”代码怎么实现”,就应该拆开。

三、DataFlow-CV 的 SDD 落地实践

3.1 Specs 体系搭建

DataFlow-CV 的 specs 目录按三层组织(外加通用方法论文档):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
specs/
├── SDD_METHODOLOGY.md # 通用 SDD 方法论(可跨工程复用)
├── SDD_GUIDE.md # DataFlow-CV 工程特有开发指南

├── formats/ # WHAT — 外部格式契约(5 个 spec)
│ ├── index.md
│ ├── spec_yolo_format.md # YOLO .txt 格式权威定义
│ ├── spec_labelme_format.md # LabelMe .json 格式权威定义
│ ├── spec_coco_format.md # COCO .json 格式权威定义
│ └── spec_conversion.md # 转换规则(坐标变换、类别映射)

├── evaluate/ # WHAT — 评估指标契约(4 个 spec)
│ ├── index.md
│ ├── spec_evaluate_fundamentals.md # IoU、匹配规则、TP/FP/FN
│ ├── spec_evaluate_metrics.md # P/R/F1、AP/mAP/AR、尺度分层
│ └── spec_evaluate_tasks.md # 检测/分割评估、COCO 12 项标准

└── modules/ # HOW — 内部模块架构(5 个 spec)
├── index.md # 模块依赖图 + 架构约束
├── spec_label.md # Label 模块(数据模型 + Handler 接口)
├── spec_convert.md # Convert 模块(双 Pipeline + RLE)
├── spec_visualize.md # Visualize 模块(渲染管线)
├── spec_evaluate.md # Evaluate 模块(评估管线 + API)
└── spec_cli.md # CLI 模块(命令签名 + 异常层次)

每个 spec 文件都有明确的版本号(如 spec_visualize.md 目前是 v4.3),变更历史记录在文件末尾。这让 Agent 在开发时能精确知道”当前 spec 定义了什么”,而不是猜测。

3.2 SDD 开发工作流

DataFlow-CV 的日常开发遵循以下流程:

第一步:确定影响范围。 问三个问题——改动涉及哪个模块(Label / Convert / Visualize / Evaluate / CLI)?涉及哪个外部格式(YOLO / LabelMe / COCO)?是否跨模块?

第二步:读 spec,评估充分性。 有一张映射表指导 Agent:

改动类型 必读 spec
修改数据模型 specs/modules/spec_label.md
新增/修改转换方向 specs/modules/spec_convert.md + specs/formats/spec_conversion.md
新增评估能力 specs/evaluate/spec_evaluate_metrics.md + specs/modules/spec_evaluate.md
新增 CLI 命令 specs/modules/spec_cli.md

读 spec 时带着批判眼光:spec 是否覆盖了当前场景?定义是否清晰无歧义?如果不充分或不合理,优先更新 specs,再往下走——不在不稳固的基础上盖楼。

第三步:对照 CLAUDE.md。 重点关注 Known Gotchas(目前 26 条,按踩坑频率排序)和 Critical Implementation Details(坐标系统、RLE 编码、converter state 清理)。

第四步:制定开发计划。 读完 specs 和 CLAUDE.md 之后,显式列出涉及的所有文件、改动顺序、风险点。先计划再实现。

第五步:实现 + 文档同步。 代码修改完成后,按优先级同步文档:

优先级 文档 触发条件
P0 Specs 行为发生变化(接口、契约、数据流)
P1 CLAUDE.md 新增架构细节、新陷阱、新硬约束
P1 README API 变化、新增功能入口
P2 示例代码 用户 API 变化

3.3 两个典型案例

案例一:v1.2.0 流式管道重构(spec 先行,代码后行)

背景是 Visualize 模块原本使用批处理方式加载全部标注数据后再渲染,首图延迟高、内存占用大。需要改造为流式管道——逐张图片加载、转换、渲染。

SDD 工作流实际执行过程:

  1. 先更新 specsspec_label.md v3.0 新增 iter_images() 流式迭代器契约;spec_visualize.md v3.0 重新设计为流式逐图渲染管线;spec_convert.md v3.0 新增双管道(batch + streaming)定义,明确每种转换方向走哪条管道。

  2. 再改代码:基于更新后的 specs,依次实现 Label handler 的 iter_images() 接口 → Visualizer 的 _create_handler() + _convert_to_render_data() 模板方法 → Convert 的 stream_convert() 模板方法(自动根据目标格式选择 batch 或 streaming)。

  3. 文档同步:CLAUDE.md 更新了架构图、数据流管道、Converter/Visualizer 描述、5 条新 Known Gotchas。

整个过程 spec 先行,代码严格遵循 spec 定义的接口契约。和 Vibe Coding 时代”写到哪算哪”的体验完全不同——不会在实现中期发现架构冲突、推倒重来。

案例二:v1.4.0 统一 LogManager 重构(跨模块改动的 SDD 范式)

背景是日志系统存在两套并行的实现(LoggingOperationsVerboseLoggingOperations),CLI 层和模块层各自创建 logger,导致重复日志文件和数据流混乱。这是一个典型的跨模块重构。

SDD 工作流实际执行过程:

  1. spec 先行spec_cli.mdspec_convert.mdspec_visualize.mdspec_evaluate.md 同步更新——定义 LogConfig(frozen dataclass,包含 nameverboselog_dir)和 LogManager 的接口契约,明确”日志由模块产出,CLI 只负责终端 UI(click.echo())”。

  2. 制定计划:从 spec 出发,列出涉及的所有文件(util/logging.py 新增 → 三个模块的 base class → 所有 converter/visualizer/evaluator → CLI commands → 所有 sample 文件),按依赖顺序排定改动次序。

  3. 逐步实现:Agent 按照 spec 定义的 LogConfig 接口,逐模块替换旧的 LoggingOperations/VerboseLoggingOperations,最后统一清理删除旧类。

  4. 文档同步:CLAUDE.md 新增 Gotcha #26(LogConfig is the single entry point),README 重新设计 header 和 Key Concepts 部分。

这个案例的亮点在于:跨模块改动的风险被 spec 前置消化了。spec 明确了每个模块的日志接口应该长什么样,代码实现只是执行。对比 Vibe Coding 时代”改一个地方牵出三四个地方跟着崩”的体验,差距巨大。

3.4 Git 历史中的 SDD 印记

观察 DataFlow-CV 的 git log,能看到清晰的 SDD 节奏:

1
2
3
4
5
6
7
docs(spec): define label positioning rules and bbox-from-polygon fallback    ← spec 先行
feat(visualize): consistent label positioning with bbox-from-polygon fallback ← 代码实现
docs(spec): adopt industry-standard label positioning (v4.3) ← spec 迭代

docs(specs): redesign logging architecture — module-owned logging via LogManager ← spec 先行
refactor(logging): replace LoggingOperations/VerboseLoggingOperations with LogManager ← 代码实现
test: add conftest fixtures, CLI evaluate tests ← 测试验证

spec 更新和代码修改成对出现,spec 总是先行。 这不是偶然的纪律,而是 SDD 工作流内化后的自然结果——Agent 在每次开发前会自动检查相关 spec 是否充分,不充分就先更新 spec。Human 在 code review 时也会对照 spec 验证行为一致性。

四、DataFlow-CV v1.5.0:SDD 下的工程面貌

4.1 架构全景

经过 15 个版本的 SDD 迭代,DataFlow-CV 的架构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
┌──────────────────────────────────────────────────────────────┐
│ CLI │
│ (passes LogConfig to modules; click.echo() for terminal UI) │
└──────┬─────────────────────┬──────────────────┬──────────────┘
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────────┐ ┌──────────────┐
│ Convert │ │ Visualize │ │ Evaluate │
│ (pipeline) │ │ (rendering) │ │ (metrics) │
└──────┬───────┘ └───────┬──────────┘ └──────┬───────┘
│ │ │
│ ZERO CROSS- │ ZERO CROSS- │
│ DEPENDENCY │ DEPENDENCY │
│ │ │
▼ ▼ ▼
┌──────────────────────────────────────────────────────────────┐
│ Label │
│ Data Models + Handlers (receive logger from caller) │
└──────────────────────────────────────────────────────────────┘
│ │ │
└────────────────────┼──────────────────────┘

┌──────────────────────────────────────────────────────────────┐
│ util/logging.py │
│ LogManager + format helpers (shared infrastructure) │
└──────────────────────────────────────────────────────────────┘

架构硬约束(写进 CLAUDE.md,Agent 每次对话自动加载):

  1. Convert ↔ Visualize:零交叉依赖
  2. Evaluate ↔ Convert / Evaluate ↔ Visualize:零交叉依赖
  3. Convert / Visualize / Evaluate → Label:仅通过公共接口
  4. CLI → Convert / Visualize / Evaluate:不直接导入 label handlers
  5. 日志由模块产出,CLI 只负责终端 UI

这些约束不是写在文档里看看的——Agent 在开发时如果违反,code review 阶段会被发现;更重要的是,Agent 自己会在开发前先过一遍架构约束,从源头避免违规。

4.2 功能一览

模块 能力 入口
🔄 Convert 6 方向格式互转(YOLO ↔ LabelMe ↔ COCO)+ 模型预测输出转换 dataflow-cv convert yolo2coco ...
🎨 Visualize OpenCV 渲染 + 颜色编码 + 显示/保存模式 + 无头模式 dataflow-cv visualize yolo ...
📊 Evaluate COCO 标准 mAP + 单阈值 P/R/F1(macro/micro)+ 检测/分割双模式 dataflow-cv evaluate detection ...
💻 CLI + API Click 命令行 + Python API 双接口 from dataflow.convert import ...

4.3 工程质量数据

  • 418 个测试,76% 代码覆盖率(3986 statements),覆盖 label(68%)、convert(87%)、visualize(81%)、evaluate(87%)、cli(59%)、util(93%)
  • 26 条 Known Gotchas,从坐标系统陷阱到 RLE 编码规则,按踩坑频率排序
  • 14 个 spec 文件,每个有版本号和变更历史
  • 跨平台:Linux / Windows / macOS
  • 已发布 PyPIpip install dataflow-cv

4.4 SDD 到底改变了什么——与 v0.6.2 的对比

维度 v0.6.2(Vibe Coding 时代) v1.5.0(SDD 时代)
开发方式 写提示词 → 看结果 → 修 bug → 循环 更新 spec → 制定计划 → 实现 → 文档同步
Agent 效率 1h+ 调试,修到最后修不好 分钟级迭代,spec 约束下的可控生成
代码质量 接口随意、职责混乱 6 条架构硬约束 + 26 条 Gotchas 防止退化
可交接性 只有作者+当前 Agent 能理解 Specs + CLAUDE.md,换 Agent/换人都能接手
重写成本 从头来,上一轮教训丢失 Specs 复用,教训沉淀为 Gotchas
测试覆盖 无系统测试 418 tests / 76% coverage
版本迭代 0.1.0 → 0.6.2,6 个月 1.0.0 → 1.5.0,20 天

最核心的变化:从”祈祷这次能跑通”到”知道这次为什么能跑通”。

五、SDD 的收益与代价

5.1 收益

1. 可复现。 同一个 spec + 同一个 Agent = 同一个结果。这在 Vibe Coding 中几乎不可能——每次从头写的提示词不可能完全一致,Agent 的输出也有随机性。Spec 消除了这种随机性。

2. 可交接。 我换 Agent(从 DeepSeek V3.2 到 V4.0)、换会话,甚至理论上换一个人类开发者,只要读完 specs 和 CLAUDE.md,就能接手开发。spec 是工程知识的持久化载体。

3. 抗熵增。 架构硬约束和 Known Gotchas 形成了代码质量的”免疫系统”。每次踩坑都沉淀为一条 Gotcha,下次 Agent 开发前会自动加载,从源头避免重复犯错。26 条 Gotchas 背后是 26 个曾经踩过的坑。

4. Agent 开发效率质变。 Vibe Coding 时代一调一个小时还修不好,SDD 时代 Agent 的代码生成被 spec 约束在正确的轨道上,review 和修正的成本大幅降低。不是 Agent 本身变聪明了,而是给它提供了更精确的上下文。

5.2 代价

1. 前期 spec 投入大。 搭建 specs 体系需要投入不小的时间。DataFlow-CV 的 14 个 spec 文件不是一天写完的,是在持续开发中逐步完善到现在的程度。如果只是写一个小脚本,写 spec 的时间比写代码还长,没必要。

2. 需要持续维护一致性。 Specs 是活文档——如果只写不维护,很快就会腐化,成为比没有文档更危险的东西(过时的文档会误导 Agent)。每次代码改动都需要检查 P0/P1/P2 文档是否需要同步更新。

3. 对开发者的领域理解要求更高,而不是更低。 SDD 把你从”怎么写代码”中解放出来,但把你推到”应该写什么代码”的位置上。你需要更清晰地理解领域知识——CV 标注格式的坐标系统差异、评估指标的计算原理——才能写出准确的 spec。这和 Vibe Coding 时代一脉相承:产品理解力决定开发的天花板。

4. Spec 写了,但 Agent 执行时还是会遗漏。 这是实践中最让人头疼的问题。Spec 定义得再清楚,Agent 在执行时仍然可能忘掉——spec 是静态文档,Agent 是”读过即忘”的。典型场景:

  • spec_conversion.md 明确定义了 RLE 编码必须用 latin1,Agent 写 coco_handler.py 时还是用了 utf-8
  • spec_convert.md 规定了 converter state 必须在 finally 块中清理,Agent 在异常处理路径上漏掉了
  • spec_cli.md 规定了 CLI 不能直接 import label handlers,Agent 为了省事直接在 CLI command 里引用了

这就是为什么 CLAUDE.md 里的 26 条 Known Gotchas 中,很多其实是对 spec 内容的”重复提醒”——不是 spec 没写清楚,而是 Agent 执行时没遵守。跨 spec 的约束尤其容易被遗忘:Agent 读了 spec A 开始写代码,写着写着就把 spec B 里的约束忘了。

这个问题目前还没有完美的解决方案,但下一步用 Rules/Skills 是一条有希望的路——本质上是把 spec 中的关键约束从”需要 Agent 主动去读”变成”系统自动注入上下文”。详见第六节。

5.3 什么项目适合 SDD

  • 中大型工具/库:有明确的接口契约和数据格式,spec 能精确定义行为(DataFlow-CV 就是典型案例)
  • 多版本长期维护的项目:spec 的复用价值随迭代次数增加而放大
  • 需要多人/多 Agent 协作的项目:spec 是统一的沟通语言
  • 一次性脚本/原型:写 spec 的时间比写代码长,没必要
  • 需求极度不明确的项目:spec 本身写不清楚,SDD 的收益有限

六、下一步:从 SDD 到更系统的工程范式

6.1 SDD 的工具化

目前 DataFlow-CV 的 SDD 实践是”手工”的——手动维护 spec 文件、手动检查一致性。业界已经有更成熟的工具化尝试:

  • GitHub Spec Kit:提供 /speckit.specify/speckit.plan/speckit.tasks 三阶段命令,自动生成规范、计划和任务列表
  • OpenSDD:开源的 SDD 工具集

后续打算在 DataFlow-CV 上尝试这些工具,看能否进一步降低 spec 维护的负担。

6.2 Spec 写了就够了吗?——从”被动约束”到”主动约束”

第五节提到 SDD 的一个核心痛点:spec 写了,Agent 执行时还是会遗漏。

这不是 Agent “不听话”的问题,而是机制问题。SDD 的约束模型是”被动的”——Agent 需要主动去读 spec、记住 spec、在执行时自行对照 spec。但 LLM 的注意力机制决定了它在生成长代码时,早期的上下文(包括读过的 spec)会被逐渐稀释。

这里有一个关键区分:

1
2
3
4
5
被动约束(当前 SDD):
Agent 读 spec → Agent 记在心里 → Agent 写代码时自行对照 → (到这里经常断链)

主动约束(SDD + Rules/Skills):
Agent 触碰特定文件/场景 → 系统自动注入相关约束 → Agent 在约束上下文中写代码

具体来说,Claude Code 提供了几个机制可以实现这种升级:

Rules(按触发条件自动加载)。 不同于 CLAUDE.md 每次全量加载,rules 可以按文件路径、命令类型等条件触发。比如:

  • Agent 一旦触碰 coco_handler.py,自动注入:”RLE 编码规则:counts_bytes.decode('latin1'),不是 utf-8。原因:latin1 支持所有 256 个字节值的无损映射,utf-8 不支持。”
  • Agent 一旦写 finally 块,自动注入:”Converter state(_source_annotations_for_target)必须在 finally 中清理,参考 spec_convert.md。”
  • Agent 一旦在 CLI command 文件中 import label 模块,自动注入:”CLI 不能直接导入 label handlers——通过 converter/visualizer 公共 API 间接访问。”

这样就不需要 Agent “记住” spec 的内容——系统在正确的时机把正确的约束推到它面前。

Skills(封装固定工作流)。 把反复执行的开发流程封装为可复用的 skill。比如”新增 converter”这个 skill,可以自动包含:读取 spec_conversion.md → 读取 spec_convert.md → 检查架构约束 → 实现 converter → 写测试 → 更新 Known Gotchas。Skill 不是在 Agent 旁边放一份说明书,而是把说明书变成了必须执行的步骤清单。

Memory(跨会话持久化)。 某些约束是反复踩坑后才沉淀出来的,适合放在 memory 中跨会话保持——比如”你对 RLE 编码特别敏感,每次涉及 COCO handler 都要提醒检查 latin1”。

从 SDD 到 Rules/Skills,本质上是把规范从”被动参考”升级为”主动执行”。 Spec 定义了”什么是对的”,Rules 确保 Agent 在正确的时刻看到正确的约束,Skills 确保 Agent 按正确的流程执行。这三层叠加——Spec(真理来源)+ Rules(时机触发)+ Skills(流程封装)——可能是 AI 辅助编程的下一个重要方向。

DataFlow-CV 目前在 CLAUDE.md 中维护 26 条 Known Gotchas,每条都是一次”Agent 忘了 spec 约束”的结果。下一步计划把这 26 条逐步迁移到 rules 中,从”写了提醒希望 Agent 自己看”变成”不看不行的强制注入”。

6.3 多 Agent 协作

SDD 的一个自然延伸是多 Agent 协作。当一个 spec 足够清晰时,理论上可以派多个 Agent 并行处理不同的子任务:

  • Agent A 按 spec_convert.md 实现 converter
  • Agent B 按 spec_visualize.md 实现 visualizer
  • Agent C 按 spec_cli.md 实现 CLI 命令

三个 Agent 的产品在 spec 定义的接口下自动集成为一体。Spec 从”开发指导”变成了”Agent 协作协议”。

这是我对 AI 辅助编程最兴奋的方向——不是让一个 Agent 更快,而是让多个 Agent 在明确的规范下高效协作。

七、工具链进化:从 V3.2 到 V4.0,从 Plan 到 Auto

SDD 的实践效果,很大程度上取决于底层工具链的能力。DataFlow-CV 从 v0.6.2 到 v1.5.0 的跨越,恰好伴随了两次工具链升级:DeepSeek V3.2 → V4.0(模型),以及从 Claude Code 默认模式到 Auto Mode 的使用方式演进。这不是巧合——方法和工具互相成就。

7.1 DeepSeek V4.0:1M 上下文如何改变游戏规则

Vibe Coding 时代用的是 DeepSeek V3.2,127k 上下文。当时最深的感受不是模型不够聪明,而是上下文不够用——specs、代码、对话历史三者在 127k 里互相挤占,经常需要在”读 spec”和”写代码”之间做取舍。一次开发后期,上下文满了,模型开始遗忘早期的架构决策,spec 明明写着”RLE 用 latin1”,模型却写出了 utf-8——不是没读 spec,而是 spec 被后来的对话冲走了。

V4.0 的 1M 上下文从根本上改变了这个局面。

14 个 spec 文件(约 1000 行)+ CLAUDE.md(450 行)+ 完整的代码库 + 对话历史,全部塞进上下文还有余。Agent 不再需要在”记住 spec”和”写代码”之间切换——它能同时做这两件事。你会发现代码对 spec 的遵循度明显提高,不需要反复提醒”回去看 spec”。

更关键的是思考能力的提升。V3.2 读 spec 更像是”扫描关键词”——它知道 spec 里有这个规则,但不知道规则和规则之间的关系。V4.0 能真正理解多个 spec 之间的约束链。举个例子:spec_conversion.md 定义了坐标变换公式,spec_label.md 定义了 BoundingBox 是纯 dataclass(无 xyxy() 等方法),spec_convert.md 定义了 converter 的接口。V4.0 能把这三点串起来——在实现 convert_annotations() 时,它知道坐标变换必须通过创建新的 BoundingBox 实例来完成,而不是调用不存在的方法。V3.2 时这种级别的跨 spec 推理经常断链。

7.2 Claude Code Auto Mode:从”盯着确认”到”真正走开”

Vibe Coding 时代最消耗精力的不是模型的输出质量,而是交互模式。一次调试一个多小时,期间 Claude Code 频繁弹出确认框——“可以编辑这个文件吗?””可以运行这个命令吗?””确认把这行改成这样?”——你不能完全走开。整个人的时间被碎片化消耗,修到最后发现修不好,心态非常崩溃。

Claude Code 的模式设计天然契合 SDD 的工作流:

1
2
3
4
5
Plan Mode(只读)──→ 读 spec、评估影响范围、制定计划

Auto Mode(全自主)──→ 按计划执行实现和测试

Plan Mode(只读)──→ review 结果、同步文档

Plan Mode 下,Agent 只读不写。 最适合读 spec、对照架构约束、评估影响范围的阶段。不用担心它在规划中途突然开始改代码。

Auto Mode 下,Agent 全自主执行。 一旦计划明确、spec 清晰,切换到 auto mode 让 Agent 独立完成实现。你可以走开,回来 review 结果。

关键是:Spec 越清晰,你越敢开 Auto Mode。 因为你提前知道模型在 spec 约束下不会跑偏,review 成本也低——对照 spec 看一眼代码对不对就行,不需要一行行审查。反过来,如果 spec 不清晰或者干脆没有,开 auto mode 就像让司机蒙着眼睛开车——你敢让它自己跑吗?

在 DataFlow-CV 的 SDD 实践中,Plan Mode → Auto Mode 的切换已经成为日常节奏:先用 Plan Mode 更新 spec 和制定计划,确认无误后切换到 Auto Mode 执行,完成后切回 Plan Mode 做 review 和文档同步。一次迭代 15-30 分钟,真正需要你盯着的时间不超过 5 分钟。

7.3 工具与方法的互相成就

回顾 DataFlow-CV 的开发历程,工具和方法之间是一个正循环:

1
好的 spec → 敢开 Auto Mode → 高效产出 → 有精力维护 spec → 更好的 spec

不是 etcd 有了好工具才有 SDD。V3.2 时代 SDD 的框架搭好了,但在 127k 上下文的限制下,Agent 对 spec 的遵循度不够稳定,你需要频繁介入修正。V4.0 的 1M 窗口和更强的推理能力补上了这块短板,让 SDD 从”理论上可行”变成了”实际上好用”。

反过来,没有 SDD,DeepSeek V4.0 和 Claude Code 的潜力也发挥不出来。1M 上下文再大,如果 context 里装的是混乱的对话历史和”试一下这个方案”的零散提示词,模型再强也生成不了好代码。SDD 让工具的投入有了明确的方向,工具让 SDD 的执行有了足够的空间。

两者缺一不可。

八、结语

从 Vibe Coding 到 SDD,DataFlow-CV 走过了从”无序”到”有序”的路。这个过程中有几个关键认知:

第一,AI 编程的瓶颈不是模型能力,而是上下文管理。 DeepSeek V4.0 的编码能力已经足够强,但如果上下文是混乱的,模型越强反而可能越混乱——因为它会自信地生成错误的代码。SDD 本质上是上下文管理的手段。

第二,规范不是负担,是杠杆。 写完一个 spec,它可以被反复消费——每次开发、每次重写、每次交接。spec 的前期投入随使用次数指数级摊销。这和写一次性文档完全不同。

第三,SDD 不是银弹。 它适合接口清晰、需要长期维护的工程型项目。对于快速原型和探索性开发,Vibe Coding + Plan Mode 仍然是更高效的选择。关键是知道什么时候该切换。

第四,工具和方法互相成就。 DeepSeek V4.0 的 1M 上下文和 Claude Code 的 Auto Mode 让 SDD 从”理论上可行”变成了”实际上好用”。反过来,SDD 也让这些工具的能力得到了最大化的发挥——好的 spec 管住了上下文,好的计划让你敢开 Auto Mode。方法论和工具链是同一条路。

DataFlow-CV 的 slogan 是 “Everything your model doesn’t do”——做你的模型不做的所有事情。开发这个工具的过程让我意识到:模型擅长写代码,但架构设计、规范定义、领域理解——这些”模型做不到的事”——才是决定工程质量的关键。