KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA
01 · 为什么 vibe coding 会在某个规模突然失灵 — keel 龙骨
这一章回答:这门课为什么存在。 如果你已经在大型项目上被 AI 坑过,这里给出的不是安慰,而是可以让你说服自己和团队的证据。
这一章回答:这门课为什么存在。 如果你已经在大型项目上被 AI 坑过,这里给出的不是安慰,而是可以让你说服自己和团队的证据。
现象:同一套提示词,突然不好用了
2025 年 Karpathy 提出 vibe coding 时,行业是亢奋的:描述需求,AI 出代码,十几分钟一个功能。到 2026 年,幻灭感出现了——很多人的体验高度一致:
- 几千行时:说什么它都能写出来,一天上线好几个功能;
- 几万到十几万行时:同样一句话,它改 A 就顺手动了 B,修好 B 又把 C 弄坏,一个功能反复几天。
多数人第一反应是"AI 变笨了"。这个判断是错的,而如果诊断错了,补救措施也会错(换个模型、写更长的提示词,都救不了)。
三条数据:这不是错觉
① 代码库在结构上持续劣化(GitClear,6.23 亿次代码变更,2023—2026)
| 信号 | 变化 |
|---|---|
| 重复代码块 | 每百万变更行 40.3 → 73.0,+81% |
| 被重构("移动")的代码占变更行比例 | 21%(2022)→ 3.8%,约 5 倍地倾向于复制而非整合 |
| 复制粘贴占比 | 9.4% → 15.7%,+67% |
| 函数复用(连通性) | 每千行调用数 343 → 223,-35% |
| 维护 12 个月以上旧代码的变更占比 | 1.7% → 0.46%,-74% |
| 错误掩盖结构(吞异常、宽泛捕获等) | +47% |
最后一行最值得注意:写代码时的理解最少、后来又最没人回去看的那一层,恰恰是系统的地基。
② 用得越多,信得越少(Stack Overflow 2025 开发者调查)
84% 的开发者在用或计划用 AI 工具,但信任度降到 29%(同比 -11 个百分点);明确不信任其准确性的人(46%)超过信任的人(33%)。而开发者最常报告的失败模式高度一致:66% 说"AI 给的方案几乎对,但不完全对",45% 说调试 AI 生成的代码比调试自己写的更花时间。
③ 感知与现实之间存在系统性偏差(METR 随机对照试验)
16 位资深开源开发者(在自己贡献多年的仓库上,平均星标 2.2 万+、代码量百万行级),246 个真实任务随机分配"允许/禁止使用 AI"。结果:允许用 AI 的任务平均慢 19%(置信区间 +2% ~ +39%)。而参与者事前预测会快 24%,做完后仍然认为自己快了约 20%。
研究者把这个称为 perception gap:AI 工具引入的摩擦足够细微,当下察觉不到,累积起来却真实拖慢产出。
注:METR 在 2026 年 2 月的更新中说明,后续实验因"开发者不愿在无 AI 条件下工作"的选择效应而失真,早期数据不应外推到今天的模型能力。但感知偏差这个结论没有失效——它恰恰是本章最重要的一条。
归因:不是智力问题,是三件事错位
错位一:成本结构变了,能力供给没跟上。
项目规模上去以后,开发的最大成本不再是"写代码",而是理解代码。成熟项目里最值钱的不是那几十万行代码,而是藏在背后的架构意图、模块边界、数据流和当初的决策理由。写代码 AI 很强,继承这些意图它天生不会——它们不在仓库里,或者说,不在它能读懂的形态里。
错位二:激励目标是错配的。
GitClear 的原话值得抄在这里:默认的 AI 工作流"被激励去交付原子化的代码——一个 happy path、一个通过的测试、一张关闭的工单,同时悄悄地对不可见和被推迟的东西征税"。
这句话解释了几乎所有让你难受的现象:它为什么总是只覆盖 happy path(税在边界上)、为什么喜欢复制而不是整合(税在重构上)、为什么 README 写得漂亮而架构却在漂移(税在设计一致性上)。这些税不在任何一次 diff 里,只在半年后的维护账单上。
错位三:你把"感觉顺畅"当成了"进展"。
METR 的 perception gap 说明:流畅的输出会制造效率幻觉。唯一可靠的解药是度量——度量产出质量、返工次数、缺陷密度,而不是体感。
因此,这门课只有三条主线
| 错位 | 对策 | 对应章节 |
|---|---|---|
| 它缺项目知识 | 给上下文:项目地图、运行契约、编码约定 | 01 |
| 它缺意图约束 | 定契约:把"想要什么"变成可校验的规格,而不是一次性对话 | 02、03 |
| 它的税看不见 | 加门禁与度量:自动校验 + 可观测指标 | 04、07 |
一句话:AI 缺的不是智力,是约束和判决标准;而这两样东西只能由你给。
上下文三件套
回到最具体的层面——开工第一分钟喂什么:
| 包 | 内容 | 给的方式 |
|---|---|---|
| 项目地图 | 目录结构、入口文件、模块职责、数据流向 | 贴目录树 + 关键文件路径,别让它猜 |
| 运行契约 | 怎么装、怎么跑、怎么测、怎么构建发布、需要哪些环境变量 | 贴这几条命令的真实输出 |
| 编码约定 | 命名、错误处理、日志、注释语言、格式规则 | 指一个"样板文件"让它照着写 |
可直接复制的开场白
这是一个 <技术栈> 项目,目录结构如下:
<tree 输出>
关键入口:<文件路径>,负责 <一句话职责>。
本地启动:<命令>;跑测试:<命令>;构建发布:<命令>。
编码约定参考 <样板文件路径>,请严格沿用它的命名、错误处理和日志风格。
本次任务:<一句话目标>。
在动手之前,请先回答三件事,只回答不改动任何文件:
1. 这件事在当前代码里应该发生在哪个文件、哪个函数?给出 file:line 证据。
2. 谁会调用它、改了之后影响面到哪?
3. 你觉得有哪些我不知道的坑或前置条件?
第 3 问最容易被忽略、回报最高:让 AI 主动暴露你不知道的约束,比事后 debug 便宜得多。
四条硬性做法
- 常驻约定文件:项目根放一份
AGENTS.md(或CLAUDE.md),写死技术栈、命令、目录约定、禁止事项、验收标准。每次开工第一句是"先读AGENTS.md"。这是把一次性交代变成永久资产。 - 给证据,不要给形容词:说"参照
src/services/order_service.py的错误处理方式",而不是"错误处理要规范"。形容词会被 AI 用自己的默认习惯填充,证据不会。 - 要求它自报读过的文件:让它在方案里列出"我读取了 X、Y、Z"。列不出来、或列的文件不存在,说明它在编。
- 不要一次性贴整个仓库:10~20 个相关文件远胜于 200 个。上下文不是越多越好——废弃代码会伪装成现行做法,误导它。
动手:可观察结果
做一个对照实验,大约 30 分钟:
- 挑一个你项目里真实的小需求(改一个接口、加一个参数)。
- A 轮:只丢一句话描述需求。
- B 轮:按上面的开场白模板给三件套。
- 两轮都记录下表数据:
| 指标 | A 轮 | B 轮 |
|---|---|---|
| 完成所需对话轮次 | ||
| 最终 diff 行数 | ||
| 无关改动文件数 | ||
| 一次跑通(是/否) | ||
| 你花在 review 上的时间 |
多数人会看到:轮次至少减半、无关改动接近 0。这张表就是你说服团队同事的证据,比讲道理有用。
故障注入:故意做错三次
每一次都故意省掉一样东西,观察它坏在哪里,并把现象记下来——这些现象日后会在真实项目里反复出现,认得它们才能快速归因:
| 注入的故障 | 观察它怎么坏 |
|---|---|
| 不给运行契约 | 它开始发明启动命令、猜测试框架、写错包管理器 |
| 不给样板文件 | 命名风格、异常处理、日志格式全按它的默认习惯来 |
| 一次塞 50 个文件 | 它可能被已废弃的旧实现误导,或忽略真正关键的文件 |
自测题
- METR 实验中,开发者"感觉更快"但实际慢了 19%。这个感知偏差对你意味着什么工作方式上的改变?
- GitClear 数据里"重构率下降 5 倍、复制率上升 67%",说明 AI 产出的是哪一类代码?为什么这会让系统在半年后变得难改?
- 上下文三件套各自防的是哪一类失败?分别举一个你会踩的例子。
- 什么情况下,上下文给得越多结果反而越差?
- 举出你当前项目里一条"AI 不可能从代码本身推断出来"的约束——如果举不出来,说明你们把它写在别的地方了,那个地方 AI 能看到吗?