被 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说“要不要休息”,这时候你的判断力比它更可靠,直接按自己的感受喊停就够了。