三个月墙
先说一个让我真正警觉起来的场景。
去年 Q1,我用 Cursor + Claude 搞了一个内部运营平台的原型。体验一个字:爽。三天出 MVP,一周跑通主流程,两周后产品经理已经开始在 demo 上点来点去提反馈了。那时候我发了一条朋友圈:「不写代码的 TL 才是好 TL」。
三个月后,这个平台要正式交付了。我打开代码仓库——一个 order-handler.ts 文件 2400 行,状态机的字符串字面量 "PENDING_TO_SHIPPED" 在整个项目里出现了 29 次,其中 12 次拼写不一样。同一个日期格式化逻辑有 5 种实现方式。测试用例全绿,但点一下「导出报表」按钮,整个页面白屏。
这不是 AI 的锅。这是我的问题——我用 Vibe Coding 的方式做了一个需要长期维护的项目,就像用便利贴盖了一栋房子,风一吹就倒。
后来我看到一篇分析文章叫《大组织内的 AI Coding 过度推行是一种饮鸩止渴》,里面提到某万人规模企业把 AI 代码生成率 KPI 定到 80%,结果三个月后技术债指数环比上升 60%,PR 总量翻了一倍但评审质量断崖式下跌。还有一组数据更扎心:AI 生成代码的 bug 数量比人工编码多出 70%,高危漏洞是人工的 2.74 倍。
这些数字不意外。因为我亲身经历了那堵墙。
这篇文章想聊的,是我在撞墙之后摸索出来的东西——AI 编程正在经历三次范式跃迁,每一层解决上一层的核心矛盾。作为一线 TL,我觉得有必要把这条路理清楚,因为太多人还在第一层打转。
第一范式:Vibe Coding
定义
Vibe Coding 这个词是 Andrej Karpathy 在 2025 年 2 月造的。原话是:
“There’s a new kind of coding I call ‘vibe coding’, where you fully give in to the vibes, embrace exponentials, and forget that the code even exists.”
翻译过来就是:凭感觉写 Prompt,让 AI 直接出代码,你基本不看 diff,跑通就算完。
Collins 词典把这个词选为 2025 年度词汇,说明它确实出圈了。但出圈不等于正确——很多人把 Vibe Coding 当成了 AI 编程的全部,这才是问题所在。
适用场景
Vibe Coding 不是没用,而是用处有边界。它适合:
- 原型验证:老板说「这个想法能不能做」,你半天搞个 demo 出来,验证商业假设
- 一次性脚本:数据迁移、批量处理、内部工具,用完就扔
- 学习探索:想试一个新框架,Vibe Coding 比读文档快十倍
真实案例
我的一个典型 Vibe Coding session 是这样的:
我:帮我用 Next.js 写一个用户反馈表单,支持上传截图,提交后发邮件通知
AI:[生成了一堆代码]
我:跑起来了,不错
我:再加个历史反馈列表
AI:[又生成了一堆]
我:列表能分页吗
AI:[继续生成]
全程我没有看过一行生成的代码。三天后功能完整,但没有人能解释为什么路由嵌套了三层、为什么状态管理混用了 Zustand 和 Context API、为什么有个 utils.ts 里塞了 17 个不相关的函数。
核心问题
Vibe Coding 的致命缺陷是三个「不可」:
- 不可追溯:你不知道 AI 为什么做了这个决策。没有 Spec,没有 Plan,Prompt 就是全部上下文。三个月后你回头看 git log,每个 commit message 都是 “fix bug” 或 “update”。
- 不可复现:同样的需求你重新 Prompt 一遍,出来的代码结构完全不一样。你无法保证两次生成的一致性。
- 不可验证:你说「加个分页」,AI 加了。怎么验证?跑一下看看能翻页——这就是验证了。但边界条件呢?空数据呢?一万条数据呢?你不会问这些问题,因为你根本没想到。
这三个「不可」叠加起来,就是我说的「三个月墙」——项目在头三个月看起来很美好,但到了需要持续迭代的节点,你会发现代码库已经变成了一个没人敢碰的黑箱。
第二范式:SDD(Spec-Driven Development)
撞墙后的反思
我在那坨 2400 行的 order-handler.ts 面前坐了两个小时,脑子里反复想一个问题:Vibe Coding 到底缺了什么?
答案很明确:缺了一个「唯一的真相源」。
Vibe Coding 的真相是什么?是对话记录。是你和 AI 之间那些散落的、模糊的、充满口语的 Prompt。这些信息既不可检索,也不可验证。你没有办法在第三周回头确认第一周的某个决策。
这就是 SDD 要解决的问题。
定义
SDD 的核心思想用一句话概括:Spec 是唯一真相源,代码从 Spec 派生。
不是写完代码再补文档,而是先写清楚 Spec,然后让 AI 基于 Spec 生成代码、测试、甚至设计方案。Spec 不是一份 Word 文档躺在一堆没人看的 Confluence 页面里——它是结构化的、可执行的、人和 AI 共同遵守的契约。
微软工程博客对 SDD 的定义很精准:
“Instead of prompting first and aligning later, teams align first and let AI accelerate execution from a clear spec.”
四步流程
SDD 的实践流程是四步循环:
Step 1: Specify(规格化)
把需求写成结构化的 Spec。不是 PRD 那种长篇大论,而是一份精确的行为描述。
举个例子,同样是「用户反馈表单」,Vibe Coding 的 Prompt 是:
帮我写一个用户反馈表单,支持上传截图
SDD 的 Spec 是:
## Feature: User Feedback Submission
### Preconditions
- User is authenticated
- User has not submitted more than 5 feedbacks in the past 24 hours
### Behavior
1. User fills in feedback content (required, max 2000 chars)
2. User optionally uploads one screenshot (JPEG/PNG, max 10MB)
3. On submit:
- Validate input
- Store feedback in DB with status=PENDING
- Resize image to 1024px max dimension
- Send email notification to ops team
- Return feedback ID to user
### Edge Cases
- Image upload fails: show retry dialog, preserve form data
- Rate limit exceeded: show countdown timer, disable submit
- Content contains XSS: sanitize on server side, reject on client side
### Non-functional Requirements
- Submit response time < 2s (p95)
- Support Chrome, Firefox, Safari last 2 versions
看到区别了吗?Vibe Coding 的 Prompt 里,AI 需要猜的东西太多了——截图格式有没有限制?上传失败怎么办?有没有频率限制?这些决策在 Vibe Coding 里是隐式的,在 SDD 里是显式的。
Step 2: Plan(技术方案)
AI 基于 Spec 生成技术方案。这一步的关键是人在 loop 里——你审阅方案,确认技术选型、数据模型、API 设计,然后才进入实现。
## Implementation Plan
### Tech Stack
- Frontend: React + React Hook Form + Zod validation
- Backend: Next.js API Route
- Storage: S3 for images, PostgreSQL for feedback records
- Image processing: sharp (server-side)
### Data Model
```sql
CREATE TABLE feedbacks (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id),
content TEXT NOT NULL CHECK (char_length(content) <= 2000),
image_url TEXT,
status VARCHAR(20) DEFAULT 'PENDING',
created_at TIMESTAMPTZ DEFAULT NOW()
);
API Contract
POST /api/feedback
- Request: multipart/form-data (content: string, image?: File)
- Response: { id: string, status: string }
- Errors: 400 (validation), 429 (rate limit), 500 (server)
**Step 3: Implement(实现)**
这一步才是 AI 写代码。但和 Vibe Coding 不同的是,AI 有 Spec 和 Plan 作为约束,生成的代码是有边界的。
Based on the spec and plan above, implement the feedback submission feature. Follow these rules:
- Use the exact data model from the plan
- Handle all edge cases listed in the spec
- Generate corresponding unit tests for each behavior
**Step 4: Verify(验证)**
不是跑一下看看能用的「验证」,而是基于 Spec 逐条检查。Spec 里写的每个 Behavior、每个 Edge Case,都要有对应的测试用例。AI 生成的测试不够——因为 AI 不知道运营反馈的真实边界条件,但你知道。
### 为什么 SDD 比 Vibe Coding 好
核心差异就一个:**结果可追溯、可验证**。
| 维度 | Vibe Coding | SDD |
|------|-------------|-----|
| 需求来源 | 散落的对话记录 | 结构化的 Spec 文件 |
| 决策记录 | 无 | Spec + Plan 完整记录 |
| 验证标准 | 能跑就行 | Spec 逐条对照 |
| 三个月后 | 屎山 | 可以追溯每个决策的 Why |
| 换人接手 | 看天 | 读 Spec 就能上手 |
我用 SDD 重构了那个运营平台。同样的功能,代码量反而少了——因为 Spec 消除了大量「AI 自由发挥」的部分。更重要的是,三个月后产品经理说要加一个新功能,我能在 10 分钟内搞清楚现有系统的边界在哪里,而不是对着 2400 行的文件发呆。
### 工具实践
SDD 对工具的要求是:能管理 Spec 文件、能在上下文中保持 Spec 的一致性。
我目前的实践是用 CodeFuse(蚂蚁自研的 AI IDE)作为主力开发工具。它的 AI Partner 模式支持多文件生成和修改,配合项目根目录下的 `spec/` 文件夹,可以做到每次 session 自动加载 Spec 作为上下文。配合 `.cursorrules` 或 `AGENTS.md` 这类约定文件,可以进一步约束 AI 的行为边界。
但工具不是重点。SDD 的重点是**思维方式的转变**——从「我要让 AI 写代码」变成「我要让 AI 按 Spec 写代码」。
---
## 第三范式:Harness
### SDD 的天花板
SDD 解决了单人或小团队的 Spec 管理问题。但当你面对一个复杂系统——比如一个涉及前端、后端、数据管道、部署流水线的中大型项目——你会发现 SDD 也到了天花板。
天花板在哪?**在多 Agent 协作的治理上。**
当你的项目不是一个 AI 在干活,而是多个 AI Agent 并行工作(一个负责前端、一个负责后端、一个负责测试、一个负责 Code Review),问题来了:
- 谁来决定 Agent 之间的通信协议?
- 谁来保证前端 Agent 和后端 Agent 对 API 契约的理解一致?
- 谁来管理 Agent 的执行状态和回滚策略?
- 谁来在 Agent 之间做权限隔离——测试 Agent 不应该有权限改生产配置?
这就是 Harness 要解决的问题。
### 定义
Harness 的核心思想:**文件即通信协议,状态机驱动多 Agent 协作。**
它不是一个具体的框架,而是一种范式。它的本质是把 Agent 的治理从「口头约定」变成「声明式文件」——就像 Infrastructure as Code 把基础设施从手动配置变成了 Terraform 文件一样,Harness as Code 把 Agent 行为从 Prompt 约定变成了可版本控制、可 Review、可测试的治理文件。
一个 Harness 文件长这样:
```markdown
# Coder Agent Harness
## Role
You are a frontend developer agent.
## Tools Allowed
- read_file, write_file, run_tests
- NO access to: deploy, database_migrate, env_config
## Communication Protocol
- Input: spec.md (from Planner Agent)
- Output: implementation + unit tests
- Handoff: trigger Validation Agent on completion
## Constraints
- Must follow spec.md exactly, no creative additions
- All edge cases from spec must have corresponding tests
- Code must pass ESLint + TypeScript strict mode before handoff
## State Transitions
- IDLE → WORKING (on receiving spec)
- WORKING → REVIEW (on completion)
- REVIEW → WORKING (on rejection with feedback)
- REVIEW → DONE (on approval)
与前两个范式的关系
Harness 不是替代 SDD,而是在 SDD 之上的升级。三者的关系是:
- Vibe Coding:人和 AI 之间靠「感觉」通信
- SDD:人和 AI 之间靠「Spec」通信
- Harness:多个 AI 之间靠「声明式协议」通信
Harness 把 SDD 的 Spec 理念从「人机协作」扩展到了「Agent 间协作」。
模型越强,Harness 越厚
这里有一个反直觉的观察:模型能力越强,Harness 不是越薄,而是越厚。
为什么?因为模型越强,它能做的事情越多,你需要治理的维度就越多。就像公司里的明星员工——能力越强,你越需要明确的流程来保证他不会「自由发挥」出问题。
具体来说:
- 模型弱的时候,它做不了太多事,你的 Prompt 约束就够了
- 模型中等的时候,它能做多文件生成,你需要 SDD 来管 Spec
- 模型很强的时候,它能自主规划、调用工具、执行多步任务,你需要 Harness 来管权限、状态、回滚、审计
复杂度从「能力层」转向了「协作层」。这不是 Harness 的缺陷,恰恰是它的价值所在。
实践场景
我目前在一个中台项目里实践 Harness。架构大概是这样的:
harnesses/
├── base/
│ ├── permission-framework.md # 权限控制
│ ├── handoff-protocol.md # Agent 交接协议
│ └── audit-logging.md # 审计日志
├── frontend-harness.md # 前端 Agent 配置
├── backend-harness.md # 后端 Agent 配置
├── qa-harness.md # 测试 Agent 配置
└── review-harness.md # Review Agent 配置
每个 Agent 有明确的权限边界、输入输出协议和状态转换规则。前端 Agent 不能直接调后端 API,测试 Agent 不能改业务代码,Review Agent 的输出是结构化的反馈而不是自由文本。
这不是过度设计。当你有三个以上 Agent 并行工作的时候,没有这套治理,项目一定会乱。
三个范式的关系
写到这里,可能有人会觉得:是不是应该全面拥抱 SDD 和 Harness,彻底告别 Vibe Coding?
不是。
这三个范式不是「先进替代落后」的关系,而是不同场景选不同工具的关系。我的原则是:
| 场景 | 推荐范式 | 理由 |
|---|---|---|
| 原型验证、黑客马拉松 | Vibe Coding | 速度优先,不需要长期维护 |
| 个人项目、一次性脚本 | Vibe Coding | 投入产出比最高 |
| 团队项目、持续迭代的业务系统 | SDD | 需要可追溯和可验证 |
| 多 Agent 协作的复杂系统 | Harness | 需要治理和协议 |
作为 TL,我最大的教训是:不要用 Vibe Coding 的方式做需要长期维护的项目,也不要用 Harness 的方式做一个周末 hackathon 的 demo。
前者会害死你的项目,后者会害死你的效率。
给一线 TL 的三条建议:
- 先判断项目的生命周期。如果这个项目三个月后还在迭代,就别 Vibe Coding。
- Spec 是最小可重复的投资。写一份好的 Spec 可能要多花 30 分钟,但它能帮你省下三个月后的三天重构时间。
- 不要迷信工具,迷信流程。CodeFuse 好用、Cursor 好用、Claude Code 好用——但工具不解决治理问题。流程才解决。
AI 时代不变的东西
最后聊点虚的,但我觉得比前面所有技术细节都重要。
我在 AI 编程上踩过的坑,归根结底不是技术问题,是判断力问题。我判断错了项目的生命周期,所以选了错误的范式。我太信任 AI 的输出,所以放弃了人类的审阅责任。
AI 编程的三次范式跃迁,变的是工具和方法论,不变的是这几样东西:
产品思维
AI 能写代码,但不能决定该不该做这个功能。Spec 里的 Behavior 和 Edge Case,是人类基于产品理解写出来的。没有产品思维,你写出来的 Spec 就是垃圾,AI 基于垃圾 Spec 生成的代码就是精致的垃圾。
架构设计
AI 能生成 2000 行代码,但不会主动告诉你这 2000 行该不该拆成三个模块。架构决策——数据怎么流、模块怎么划分、接口怎么设计——这些需要人来拍板。SDD 的 Plan 阶段和 Harness 的治理文件,本质上都是架构决策的外化。
技术判断力
什么时候该用 Vibe Coding,什么时候该上 SDD,什么时候需要 Harness——这个判断本身就是技术判断力。工具越强,判断力越重要。因为工具能帮你做更多的事,但做「对的事」还是「错的事」,取决于你的判断。
Karpathy 最近在一次访谈里说了一句话,我觉得说得很好:
“You can outsource your thinking, but you can’t outsource your understanding.”
你可以把思考外包给 AI,但你不能把理解力外包出去。理解为什么做这件事、理解系统的边界在哪里、理解哪些决策是不可逆的——这些永远是你的工作。
一句话总结
AI 不会取代研发,但会用 AI 的研发会取代不会用的。
这句话已经快被说烂了,但我还是想说。因为「会用」不是「能 Prompt」,而是知道什么时候该 Vibe、什么时候该 Spec、什么时候该治理。
这中间的差距,就是范式跃迁的真正意义。
评论 (0)
还没有评论,来说两句吧。