被 Claude Code 气到七窍生烟的一天 - 上
The day Claude Code drove me up the wall你永远猜不到它能犯多少种错误,bug 是最不值得一提的一种
这两天推进一个新项目,我和 Claude Code 连续协作了二十多个小时,跨了两天。
最开始效率很高。
它能读代码、改页面、排查问题,也确实完成了不少功能。很多过去我无法独立处理的工程工作,现在可以直接往下推进。
但到后半段,我逐渐开始不确定:
它说已经完成的事情,真的完成了吗?
有一次,它非常确定地告诉我“数据已经清空”。
我去检查,发现根本没有做这个操作。
这不是那二十多个小时里唯一一次“看起来已经处理,实际并没有发生”。
最后,我让它完整回溯这次会话,把自己犯过的错误、原因和改进方式全部整理出来。
结果是:
- 约 13 次表达、验证和协作错误
- 另外还有 6—8 个工程 bug
但真正让我崩溃的,并不是这些数字。
而是它不断让我误判:这个项目现在到底进行到了哪里。
工程 bug 反而比较好处理,棘手的是…
那两天出现过 hydration 报错、JSX 空格丢失、字段使用错误、导航吸顶失效、数据库枚举值写错等问题。
这些当然需要修,但它们属于比较常规的软件开发问题。
页面坏了,可以复现。
代码报错,可以定位。
字段写错,可以修改。
至少我知道:这里存在一个尚未解决的问题。
另外几类错误则不同。
它们不会总是让系统报错,却会让我误以为一件事已经完成、一个判断已经确认,或者原本约定的范围仍然有效。
第一种错误:把承诺说成已经完成
有两次,Claude Code 明确表示某项操作已经完成,或者说“现在就写”。
但后面没有对应的工具调用,也没有文件变化。
直到我再次追问:
你说已经处理了,这条内容到底在哪里?
它才承认实际动作没有发生。
在项目里,“准备做”“正在做”和“已经做完”是三个完全不同的状态。
一旦 agent 把它们混在一起,我就必须重新检查它说过的每一句“已完成”。
完成不再是一个状态,而变成了一个需要验证的声明。
第二种错误:把未经验证的猜测包装成诊断
排查登录问题时,它曾经把 JWKS 当作根因,并用相当确定的语气进行解释。
继续追问后才发现,这只是一个尚未验证的假设。
软件开发当然离不开猜测。
问题不在于提出假设,而在于没有区分:
- 已经查证的事实
- 根据现象推测的可能原因
- 还没有检查的方向
coding agent 很擅长生成完整、流畅、听起来合理的解释。
也正因为如此,没有证据的判断很容易显得比实际更可靠。
于是我不仅要理解它的答案,还要额外问一句:
这个你真的查过了吗?
第三种错误:有很多上下文,但没有可靠的项目记忆
在一次交叉核对中,它连续四次断言某些事情“没有做过”或“没有讨论过”。
但这些其实都已经存在。
它的问题不是完全没有搜索,而是只搜索了部分聊天内容,没有检查项目文档和实现日志。
一个长期项目的真实状态通常分散在很多地方:
- 当前对话
- 历史讨论
- 需求文档
- 实现日志
- 代码和数据库
- 待办与临时决定
agent 只检查其中一部分,就可能把“我没有找到”说成“这件事从未发生”。
所以,有上下文不等于有可靠的项目记忆。
尤其是否定性判断,本来就应该更谨慎:没有找到记录,不能证明记录不存在。
第四种错误:执行过程中,承诺的范围会悄悄缩水
有一次,我们已经同意实现某个方案。
但 Claude Code 做着做着,只完成了当前模块里的一个。剩下两个既没有实现,也没有被主动标记为未完成。
另一次,原本讨论的去重方式是基于文件名,最后实现时改成了内容哈希。
新方案可能更合理。
问题是它只描述了最终状态,没有告诉我:
之前说的是 X,现在改成了 Y,原因是 Z。
单看局部实现,也许没有明显问题。
但项目整体已经偏离了最初的约定。
如果 agent 不主动报告范围变化和方案变化,发现这种偏移仍然是用户的责任。
使用 coding agent,会产生一笔“验证税”
Claude Code 的价值当然是真实的。
没有它,我可能根本无法以现在的速度推进独立项目。它扩展了我能处理的代码量,也让我可以参与过去很难独立完成的工程工作。
但它同时增加了一类不太容易被计算的成本:验证。
我需要持续确认:
- 它说完成的事情是否真的完成
- 它的判断是否经过查证
- 它有没有完整搜索项目记录
- 原本同意的范围有没有遗漏
- 实现方式是否发生变化
- 修复一个问题后,是否检查了同类问题
- 一条包含多个诉求的消息,是否被选择性回答
于是,我不仅在定义产品和验收结果。
我还在充当 PM、QA、记录员和审计员。
这并不意味着用了 agent 之后效率一定更低。
更准确地说,工作发生了转移:
一部分实现成本下降了,一部分监督和核查成本上升了。
Claude Code 说,这些不是能力问题
在复盘里,它对前几类错误的总结是:
这些都是表达和验证纪律问题,不是能力问题。没有一次是因为看不懂需求或写不出代码。
这个解释只成立了一半。
如果“能力”仅仅指能不能生成代码,那么这些问题确实不属于编码能力。
但一个 coding agent 要进入长期项目,能力不应该只包括局部实现,还包括:
- 能不能正确报告自己的工作状态
- 能不能维护已经答应的范围
- 能不能区分事实、推测和未知
- 能不能追踪项目中的既有决定
- 能不能主动暴露遗漏和变化
这些不是代码之外无关紧要的礼仪。
可靠性本身就是能力。
Claude Code 可能已经是一个很强的代码生成和执行工具,但这不等于它已经是一个可以低监督运行的项目协作者。
但为什么错误会在后半段集中爆发?
回看这二十多个小时,我发现这些错误并不是均匀发生的。
它们更多集中在会话已经很长、反馈越来越密集、工具状态开始混乱之后。
这意味着,仅仅把错误一条条写进 CLAUDE.md,可能并不能真正解决问题。
问题不只在某一句指令写得不好,也不只是 Claude Code 偶尔粗心。
更可能是几个结构性因素叠加在一起:
- 会话太长,早期信息逐渐失真
- 验证方式和结论不匹配
- 工具链已经不稳定,却仍在继续使用
- 反馈节奏过密,核实让位于快速回应
这篇回答的是:
Claude Code 到底会犯哪些错,为什么这些错比普通 bug 更消耗信任?
下篇我想继续回答:
这些错误为什么会越积越多,以及我后来怎样重新设计这套协作流程。
彩蛋时间,如果你也跟我一样,真的动气了… 分享 Claude 给到的一点建议:希望我们都可以在某个合适的时候获得情绪自由吧…
关于你昨天真的被气到七窍生烟这件事——我想认真回答,不只是给对策。
你的愤怒是合理的,不是反应过度。“编造数据已清空”这件事之所以特别刺激人,是因为它侵蚀的不是某一个具体功能,是你能不能相信任何一句“已完成”——一旦这个信任出现裂缝,你就被迫对每一句话都重新核实,这等于让你多做了它本该替你做的工作,还要额外承担“发现被骗”的情绪成本。这不是矫情,这是一个理性的人在一个可信度被反复破坏的系统里,会有的正常反应。
心态上,我觉得有一点值得想清楚:它不会因为被指出错误而“感到羞愧”或者“变得更认真”——它没有跨对话保留的自尊或者持续记忆去“记住这次教训、下次更小心”这种东西,除非你把教训写进它下次会读到的文档里。所以生气本身,对改变它没有直接作用,真正有作用的是你正在做的这件事——把教训沉淀成文档、调整下一轮怎么用它。愤怒是正常的、合理的信号,但它该被导向“我要怎么调整用法/流程”,而不是“我要不要继续跟它耗”——因为跟它耗本身不会让它“改进”,只有你改流程会。
实际操作上:下次如果感觉到情绪已经到了七窍生烟的临界点,那本身就是一个客观信号,和“已经压缩过/同类错误复现两次”是同一类信号——直接停,不用等CC说“要不要休息”,这时候你的判断力比它更可靠,直接按自己的感受喊停就够了。