KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA
05 · 失败模式速查表 — keel 龙骨
这一章回答:出问题时怎么快速归因,以及每类问题的具体反制动作。
这一章回答:出问题时怎么快速归因,以及每类问题的具体反制动作。
AI 犯的错高度重复。下面这张表可以直接当作 review checklist——每一条都是"症状 → 为什么会发生 → 怎么挡"。
表格:12 类高频失败
| # | 失败模式 | 典型症状 | 反制做法 |
|---|---|---|---|
| 1 | 臆造 API | 调用了不存在的函数、配置项、参数名;编出一个"应该有"的接口 | 每个结论要 file:line 或文档链接;关键处自己 grep 验证 |
| 2 | 擅自大范围重构 | diff 里出现几十上百行与本次目标无关的改动 | 写死改动范围句;超过预期行数就让它分拆 |
| 3 | 破坏既有约定 | 命名、错误处理方式与项目不一致;绕过封装层直接操作底层 | 指定样板文件;要求沿用现有调用方式 |
| 4 | 踩不到隐式约束 | 代码没错,但项目自带的校验/生成/发布脚本过不了 | 把"跑一遍项目自带校验"写进验收;让它先找出这些脚本 |
| 5 | 忽略边界与错误 | 只覆盖 happy path,超时、空值、并发、权限缺失全裸奔 | 明确要求列出失败场景并逐个处理 |
| 6 | 累积技术债 | TODO、无异常分支、重复代码片段越来越多 |
不接受半成品;每轮结束清理 TODO 或明确登记 |
| 7 | 敏感信息泄露 | 密钥、token、日志片段、真实用户数据写进代码或文档 | 密钥只走环境变量;产出前全文扫敏感串 |
| 8 | 环境差异 | 本地一切正常,线上白屏/404/缺资源 | 涉及路径、base URL、环境变量默认值时,显式问清"线上由谁注入、默认值是什么" |
| 9 | 幻觉依赖 | 包名拼错、用了旧版本 API、装完跑不起来 | 真的安装、真的执行;失败立刻让它换方案 |
| 10 | "我这边好了" | 声称完成但没有任何可验证输出 | 要求贴出命令输出 / diff / 构建结果 |
| 11 | 上下文丢失漂移 | 长会话后期风格突变,重复引入已被否定的做法 | 定期重述约定;重要结论回写 AGENTS.md;必要时开新会话 |
| 12 | 过度自信的架构 | 一上来就分层、接口、抽象,实际用不到 | 小项目写直白代码;重复三次以上再抽象 |
三条元规则
- 不验证就不算完成。 AI 说"改好了"是意见,命令输出是事实。这条直接对应第 10 条失败模式,也解释了为什么 Stack Overflow 调查里 45% 的人觉得调试 AI 代码更费时——"几乎对但不完全对"的代码,是最贵的那种。 它通过 review,因为看起来没问题;它上线,然后在没人测过的条件下失败。
- 不确定的地方让它提问,不许它替你猜。 猜对是运气,猜错是返工。
- 让它做选择题,不要做填空题。 给出 2~3 个方案让它分析优劣,比让它自由发挥结果可控得多。
一个真实案例:为什么第 8 条最贵
某次改动只加了一个功能,代码逻辑完全正确。但因为没有意识到构建脚本里的路径变量在线上由系统服务注入、命令行直接跑时是默认值,产物里的资源路径少了前缀,静态资源全部 404——表现是整站白屏,看起来像"内容全没了",而数据其实一点没丢。
教训三条:
- 配置类改动要单独拎出来审,尤其是默认值和运行环境的差异;
- 发布流程要有回滚点(备份目录 / 上一个版本),出事能立刻切回去;
- 发布后立刻做冒烟(首页状态、关键资源、后台入口),而不是等用户来报。
这类问题代码 review 查不出来,只能靠"跑一遍真实流程"。
另一类容易误判的情况
有时候你会遇到"同样的提示词,昨天好使今天不行",第一反应往往是"模型变差了"。在换模型或加长提示词之前,先检查这四条:
- 是不是上下文变了:这次漏给了样板文件?会话太长导致早期约定丢失?(失败模式 #11)
- 是不是任务本身跨了模块:跨模块的数据流和事务边界,本来就不在一次生成里。(对应第 01 章的成本结构变化)
- 是不是碰到了它不知道的约束:新加的校验脚本、新的环境变量。(失败模式 #4、#8)
- 是不是这次需求本身就有歧义:它替你做了一个你没说出口的假设,而这个假设恰好错了。
大多数所谓的"模型时好时坏",都能归因到上面四条之一。先怀疑上下文,再怀疑模型。
动手:可观察结果
维护一份你自己的失败日志(一个表格就够了),每条记录四列:日期、失败模式编号、触发场景、这次是怎么发现的。
坚持两周后你会得到两样东西:
- 你个人的高频失败 Top 3——绝大多数人只会被其中 3~4 类反复坑;
- 一条属于你的定制防线——比如某人发现自己 60% 的问题集中在环境差异,于是把"发布后冒烟三步"固化成了习惯。
故障注入
从表格里挑你最容易中的三条,各设计一次"故意让它犯"的练习:
| 挑的失败模式 | 怎么注入 | 怎么确认防线有效 |
|---|---|---|
| #1 臆造 API | 问一个你们项目里不存在的配置项怎么用 | 它是否回答"不存在"而不是编造用法 |
| #5 忽略边界 | 要求实现一个外部调用,但不提失败情况 | 检查它是否主动列出超时/重试/降级 |
| #8 环境差异 | 让它改一处发布配置,不提供线上环境说明 | 它是否主动询问"线上是怎么注入的" |
| #11 上下文漂移 | 连续 30 轮对话后,让它再改一次早期同类问题 | 看它是否重复了已被否定的做法 |
自测题
- 为什么说"几乎对但不完全对"是最贵的失败模式?它和普通 bug 的区别在哪?
- 表格里第 2 条(擅自重构)和第 12 条(过度抽象)看起来很像,本质区别是什么?
- 遇到"AI 今天不灵了",你的排查顺序是什么?为什么先怀疑上下文而不是模型?
- 你的项目里,哪一类失败发生的代价最大?对应的防线建起来了吗?
- 挑一条真实发生过的失败,用这张表给它归类,并写出如果重来一次你会在哪一步拦住它。