做 MCP 文件检索项目的时候,我撞上了一个认知转折点:我一直以为 vibe coding 就是”给 AI 一句话让它写代码”,但实际操作下来才发现,有效的 vibe coding 是一套工程流程,AI 在其中扮演的是有经验的同事,不是代码生成器。
SDD + TDD 驱动流程
经过这次项目,我总结出一个让 AI 协作可靠运转的流程:
Step 1: 接口规格(SDD)
↓
Step 2: 测试用例(TDD,从 spec 推导)
↓
Step 3: 实现代码(让测试从红变绿)
↓
Step 4: 验证(Inspector / 真实环境)
Step 1: Spec 文件要描述清楚什么
| 必须包含 | 为什么 |
|---|---|
| 输入参数(名字、类型、是否必填) | AI 生成代码需要明确的类型信息 |
| 输出格式(成功 + 失败的结构) | 不定义输出,AI 每次生成不一样的格式 |
| 行为规则(搜索范围、匹配方式等) | 消除歧义,不让 AI 自由发挥 |
| 边界情况表 | 逼自己想清楚”不正常输入怎么办” |
| 安全约束 | 尤其是涉及系统调用、用户输入时 |
| 设计决策 + 理由 | 记录”为什么这样做”比”怎么做”更重要 |
Step 2: 测试用例要覆盖什么
从 spec 推导测试时,我用三个问题检查:
- Happy path — 正常情况下的正确行为
- 每个边界条件 — spec 表格的每一行 = 一个测试
- spec 没写到的情况 — 写测试时发现 spec 的漏洞
这次暴露的测试思维盲区
我第一轮只列了 happy path,遗漏了:
- 安全类测试(shell 注入)
- 错误处理测试(目录不存在)
- spec 里已有的边界条件(路径分隔符、同名文件夹)
教训:把 spec 里的每个表格的每一行,都对应一个测试用例。如果 spec 觉得某个情况值得写下来,它就值得被测试。
Step 3: 实现的关键原则
- 包装已有工具,不造轮子 — MCP Server 的价值是暴露能力,不是重写能力
- 分层设计 — 可测试的内层(参数化)+ MCP 入口的外层(固定默认值)
- 用 subprocess 列表形式 — 从根源消除命令注入,不依赖输入过滤
Prompt 质量检查清单
这次项目让我意识到,写给 AI 的 prompt 本身也需要质量控制:
| 检查项 |
|---|
| 指定了驱动方式(TDD / SDD / 自由实现)? |
| 指定了你的参与方式(审核 / 写一部分 / 纯学习)? |
| 指定了学习目标(想理解什么)? |
| 包含了过程约束(每步暂停 / 并行推进)? |
反例——我最初的 prompt:
“读一下 project-brief.md,我们开始搭建 Phase 1。”
问题在于太开放,没有约束驱动方式、参与方式、学习目标。AI 会默认进入”全部帮你做完”模式,而我真正需要的是理解每一步决策。
信念更新
| 原信念 | 更新后 |
|---|---|
| ”Vibe coding = 让 AI 写代码" | "Vibe coding = 用 AI 做系统化工程,人负责决策和审查" |
| "测试是写完代码后的事" | "测试是 spec 的可执行版本,先于代码存在" |
| "Spec 只要写清楚功能就行" | "Spec 必须包含边界情况、安全约束、设计决策理由” |