Claude Code失智对策小妙招:从"差不多"到"双方签字"

发布于 阅读 0未分类

Claude Code失智对策小妙招:从"差不多"到"双方签字"

先说痛点:恃强而懈

Claude Code(下文都叫 cc)非常强大,绝对算是一个神队友。

但它有个要命的毛病:会偶尔失智关键是失智是随机出现的,且不低频。国内用第三方 API 调用,这种情况尤其明显,神队友秒变猪队友,坑死你没商量那种。

日常维护一个项目,当 CLAUDE.md 和 hooks 比较完善之后,在不失智时,cc 是非常稳的。简单的提示词,就能生成正确的代码。

之前跟 cc 配合其实很顺。简单需求一句提示词,它就懂我的意思,该查的查,该改的改,基本不用我多说。我就这么一路被它伺候着——但时不时它就降一轮智,挑不出规律。正好好的干着活,下一秒给你一个眼神迷离的答案,每次还都是不同的锅,这才是最头疼的地方。

CLAUDE.md 里有硬规:前后端改完必须通过编译。 cc 每次都能做到。所以时间长了,我也就不会上线前自己编译一下试试了。结果就大意了。需求一说,cc 直接写完提交上线,打开一看线上脚本报错,回头看后端编译就没通过。当时有点懵:多久没出过这种事了。

把报错粘给 cc,cc 态度那叫一个诚恳,说自己疏忽了,已经改好了,以后保证不再犯。再次提交,编译又报错。再粘给 cc,cc 再修改并道歉。再提交再报错,如此几轮彻底麻了。

心态崩了,破口大骂。这两年我对 AI 代码工具说的脏话,比这辈子加起来都多。


之前那次:为什么 cc 总是「差那么一点」

失智这事,大伙儿应该都见过。我把最常见的几种拉个清单:

失智模式具体表现
「应该没问题」型「我已经加完测试了」「应该编译过」,结果跑起来红一片
「一次梭哈」型一次甩出几千行代码,出问题就是大爆炸
「文档过期」型写完代码不更新文档,3 个月后自己都看不懂
「口头承诺型「我同步改了」,实际上根本没改
「为了绿而绿」型测试不过? 改期望值。 把 assert 写成跟 bug 一样

这一长串失智的根本原因只有一个:cc 没有「下一步会死」的紧迫感,它只是给你一个「看起来差不多」的答案。


我只压实了一道护栏:文档,文档能摁住

跌了几次坑之后,我反思「到底什么最重要」。

答案越缩越小,最后只剩一句话:在中型功能开发里,把文档当主战场,其他都是配套

文档不是写到 IDE 边上就行。文档是被我要反复锤的——锤到「任何 AI 工具拿到都能独立干活,不需要反过来问我」。

下面这几段,就是我怎么锤的。注意:这几段我都没让 cc 在场。 找 cc 来做「是不是真懂」的元话语陪练,讨论本身会把 cc 搞糊涂,所以我都是请另一 AI 工具当陪练,后面单独说。


一:把「理解」逼出来

文档我口述,第一稿让 cc 在一个 session 里整理成 markdown。这是体力活,不在这段讨论范畴

cc 写完会跟你说「明白了」。这俩字最坑。它只是没报错,不等于它懂了

我的做法是换另一个 AI 工具来当陪练,做法:

  1. 我把原始需求抄出来,扔给另一 AI(我现在用 workbuddy 的免费额度):「用你自己的话,把这条需求复述一遍,有任何不确定的也列出来」。
  2. 另一 AI 列出来 → 我逐条校对,跟我的原意有出入就当场标记。
  3. 不一致的条目我重新喂回另一 AI,让它自己说哪里理解了、哪里模糊了。
  4. 再让另一 AI 复述第二版。

反复到它的复述跟我的原意几乎逐字一致,「需求理解」这步才算过。

有个真实场景特别扎心:某次我描述一个边界条件,cc 复述的时候把它简化了。我没注意,直接进下一步。到了实施阶段它按简化版去做,上线后边界条件没覆盖,线上告警。回去看文档,我俩谁都没错——错在 cc 没复述、我没校对。 之后我把这一段改成另一 AI 来复述,cc 在原 session 里只管写,审稿交给陪练

cc 说「我懂了」不算数。要让它把理解倒出来,我校对了,才算数。


二:把「步骤」嚼烂

需求这头对齐了,接着看实施步骤。这一步我必须搞懂

不再让 cc 在元话语里跟我来回。我的做法是:

  1. 新开一个 session,让 cc 看上面定好的需求文档,出实施步骤。
  2. 逐条读,看不懂的就反问 cc 「为什么要这么做」
  3. cc 解释 → 我再反问**「如果换成 X 方案,你为什么没选」**,逼它说出取舍。
  4. 这里的关键:不光是 cc 解释清楚,还得我自己能讲出来——我得在脑子里 / 在纸上复盘一次,直到能口述给另一个人听。

这一段的精髓是双向流动:不是我把需求丢给 cc 就不管了,也不是 cc 把步骤丢给我就不管了。反复「为什么这么做」、「为什么没选 X」,几轮下来**「我懂了 cc 的步骤」这一头才算过**。

但有个坑我也踩过:我懂了步骤不代表我没漏问。所以下一步还得让陪练再扫一遍——见下面「跨 AI 工具对账」。

这里有个小技巧,问cc的时候可以常用/btw,防止污染上下文。


三:对得上,才算初步定稿

需求、步骤反复锤完之后,有那个瞬间,两件事都成了:

  • 另一 AI 把我需求复述得跟我原意几乎逐字一致」(理解这头)。
  • 我把 cc 的实施步骤嚼到能口述给另一个人听清楚」(方案这头)。

「cc 理解了我的需求,我理解了 cc 的方案」。

两边都对得上,文档才算初步定稿。这是文档合格的最低线——不是「我自己看了觉得还行」,是**「我审过、cc 知道怎么动、cc 动的时候不需要再回头问我」**。

如果任何一边是糊的,继续锤。不要因为赶进度跳过这一步。跳过的代价,通常在生产环境兑现。


兜底:hook 是把护栏写进工具链

文档护栏是主战场,但有些规则写在文档里,cc 还是会忘。我见过最典型的是:

  • 它改某个契约文件,忘了同步重新生成下游代码。
  • 它甩出一个几千行的 commit,把分阶段铁律踩得稀碎。

光靠文档拦不住。得靠 hook 在它动手那一秒强行拦截。

我跑了几条 hook,挑三种最有叙事价值的、按拦截强度分梯度来列:

  • 真阻断 · 关键配置写保护: 任何写运维配置(关键 KV/secret 段)的动作,如果近 10 分钟内没有对应备份,exit 2 直接拒收。我有一次写新配置时手滑覆盖掉了同事刚加的 KV 段,补救花了一整个下午。这条上线后,这类失误就被彻底死锁了。
  • 强提示 · 迁移改动广播: 任何方式动到迁移文件(Edit/Write/Bash/手工 INSERT schema_migrations/db.AutoMigrate),都被 hook 截到,往 cc 的 stderr 里塞一段「上次同类事故怎么炸的 + 防御步骤」——故意不阻断,只强提示。我让 cc 看到提示就自己停顿想一下,这条比强制 reject 灵活得多。
  • 上下文注入 · 关键协议硬塞SessionStart 启动会话,或者用户消息里命中「数据库 / 部署 / 重启 / 上线」关键词时,把对应约束协议(「开发=生产=同库,改库必备份」 / 「部署走 build.sh,不要 mv bin/snow」)摘要直接塞进 cc 的 stderr,不阻断,只逼 cc 在第一个 turn 前就看见协议。这条是吃了亏才加的——cc 失智时根本不会主动读 CLAUDE.md,必须硬塞。

这三条上线后,拦下了若干次 cc 想要「图省事」的违规操作。 拦下来那一下心里特别爽,有种「这才是真的护栏」的感觉。

铁律必须落 hook,否则就是写在沙滩上。

但 hook 是兜底,不是主角。文档才是。反过来,hook 写错比没 hook 更危险——匹配错了该拦的没拦住、不该拦的反而拦截,我吃过一次亏。所有 hook 上线前必须人工跑几个场景验证(那次我为了一条钩子测了 8 个场景才安心)。

一个「不常见的需求」:写到 CLAUDE.md 里都不管用,只能靠 hook

我有个业务系统,开发库和生产库共用同一个 MySQL。这事我写得清清楚楚在 CLAUDE.md ,每次实施还反复叮嘱——「开发时改表 = 改了生产,任何 schema 变更必须走 migration 文件,不要直接 ALTER」。

结果 cc 还是经常搞错——CLAUDE.md 写了不读,提示词发了不听。

经典翻车剧本:

  1. cc 写代码过程中需要加个列,直接 mysql -e "ALTER TABLE" 改了表,顺手往 schema_migrationsINSERT 占了坑。
  2. 接着 cc 觉得「为了部署同步」,正经地新写一个 000025_add_xxx.up.sql 文件。
  3. 上线 → migrate.Up() 看到 000025 这条 → 执行 ADD COLUMN xxx1060 Duplicate column name → migrate fail-fast → 服务起不来。

过去几个月实打实踩过几次,每次 dev/prod 上抓狂几分钟才定位。

规则写进 CLAUDE.md 不管用,prompt 里反复叮嘱也不管用。最后还是只能靠 hook 兜底。我的 hook(脱敏伪代码):

  • 数据库结构变更日志 hook:cc 跑任何 ALTER / CREATE / DROP / TRUNCATE 之前,自动落一份日志,说明「这是 dev 还是 prod、是 migration 还是手工」——并强制 cc 在 PR description 里引用这条日志,让人审
  • migration 文件生成 hook:cc 写 0NNNNX_*.up.sql 之前,先跑 scripts/migration_check 取 max version +1,禁止手写编号,绕开「我以为下一个是 11,其实同事已经占了 11」这类连环撞号(我出过两次)。

CLAUDE.md 写规则、prompt 里反复强调都不保险的时候,只剩 hook 能帮 cc 守住边界——不常见的需求尤其如此,因为没人会主动防御。


跨 AI 工具对账 — 找茬的工艺

回到文档主战场。一、二、三只是把「理解」和「步骤」对齐了,文档里仍可能藏着歧义、漏边界条件、术语不一致——这本质上是多模型互补的一个具体玩法: 用一个独立 AI 来挑刺,比 cc 自己复审彻底得多。这些不是 cc 能发现的,因为 cc 既当运动员又当裁判,会自然地把文档讲通顺,不会暴露矛盾

需要一个独立的 AI 工具,专职挑刺。这就是「对账」。

我的工艺:

  1. 喂文档给另一 AI(不是 cc,不是 cc 的同一型号兄弟,是另一个独立陪练):
    • 「请你扮演一个新接手这个项目的工程师 + 另一个 AI 工具,只看这份文档,你要把它实现出来。找出所有让你走不动的地方,一条一条列出来」。
  2. 陪练会列出几类问题:
    • 歧义:「这个字段到底允许 NULL 吗」「失败是软失败还是硬失败」。
    • 漏边界:「迁移 10000 条数据并发多少」「客户端掉线重试几次」。
    • 术语打架:「你说的『快照』和你步骤 3 里的『快照』不是一回事」。
    • 隐式假设:「你假设客户端在线,如果整个客户端群组都掉线,这流程怎么退化」。
  3. 逐条修文档,改完再喂回去,让陪练再扫一遍。

反复几轮,直到陪练再也挑不出刺(或者只剩「这条属于实现细节,放到下一步细化了)。2-3 轮是我的经验上限,再多就是陪练在凑数,边际收益快速递减。

而且我审我自己永远审不干净——这才是跨 AI 工具挑刺存在的意义。cc 偏偏既当运动员又当裁判,会自然地把文档讲通顺,暴露不出矛盾,这一步不得不做。

这一段本质上是:复盘前我」假装」是别人看自己的文档,逼自己写得不依赖任何上下文

对账不是请 cc 写第二遍,是请另一个 AI 工具证明这一遍够干净。两种 AI 视角各自带盲区,擦一次比 cc 自己擦十次更彻底。

这套工艺我之前专门拆过一遍——多个 AI 互喷到一方服的 具体 prompt 模板,有兴趣可以翻翻那一篇。

对账结束后,文档真的到了「任何 AI 拿到都能独立干活」的水位。这时再开新 session 把文档丢给 cc,cc 看一眼,直接写代码,不需要反复回头问我

这一步有时候让我感觉——文档终于不是 cc 的陪练了,是 cc 的施工图


完成一个需求的流程

一句话先说清楚:我有需求 → 跟 cc 反复对齐 → 多 AI 找茬 → 实施 + 每功能 e2e。完整流程图如下:

完成一个需求的流程

走完这一整套,中型功能来回 2-3 天是常事。不是每次小修小补都要走,改动 > 几百行 或 涉及 schema 变化才走完整锤法;小改动反而 cc 一把梭更高效。


写在最后

回头看,cc「失智」这事,我现在的态度跟半年前不一样了。

半年前我会拍桌子:「AI 怎么这点事都做不好!」

现在我反而觉得:cc 失智是 feature,不是 bug。 它逼着我把模糊的「需求」逼成清晰的「文档」,把单视角的「答案」逼成跨 AI 工具对账的「共识」。

AI 不会替你做决定,它会逼你把决定想清楚。

这套「文档护栏 + 跨工具对账 + hook 兜底」我建了一年多,中间被无数次 cc 失智打过脸,但每一道护栏都是被真实事故逼出来的。

工程这件事,从来不是「我一个人 hold 得住」——是「我 + cc + 一份跨工具对账过的文档 + 一组 hook」一起 hold 住。


不过几句丑话得说在前头,免得大家觉得捡到宝:

  • CLAUDE.md 是活的护栏 —— 它既是你跟 cc 之间的「项目说明」,也是「约束清单」:项目情况写到位、不允许 cc 自由发挥的边界写清楚。写完别扔,每隔几周回来重读一遍,跟代码一起演进。 cc 失智的很多次其实是文件里某条约定已经过时、没人更新,等于没写
  • /clear 别心疼 —— 主动 /compact 压缩上下文、常用 /clear,跨主题就开新 session,同主题段落结束就清一次上下文。一个 session 聊久了上下文会互相干扰,cc 会跟着胡说八道。
  • 闭环不是装上 hook 就完了 —— 事故 → 文档 → 铁律 → hook 这条链每一步都得有人主动触发。忙起来一周不复盘,事故就在脑子里飘着,下次同类问题还会再发生。
评论 (0)
0 / 500
暂无评论,快来抢沙发~