跳到正文

devlog/flow-recipes/making-error-messages-in-your-own-code-easier-for-ai-to-fix-515.md

终端报错多写四个字段,让 AI 少烧几轮令牌

先算一次修复到底烧了多少令牌

每天在编辑器和终端之间切换,最贵的报错往往不是程序崩了,而是只留下一句“请求失败”。把它交给 AI,接下来通常是翻日志、搜调用链、猜配置,再跑一次。每轮都可能重新读上下文。省钱的起点不是把提示词压成电报,而是让自己的代码在失败时提供足够的定位证据。

我会给修复任务记三项数据:模型请求次数、输入输出令牌、测试是否通过。经过 Fluxo 调用时,还要分别看缓存读取和写入用量,因为它按真实令牌计费,缓存读写也计入账单,没有月费。一次回答短,不代表整个修复便宜;最终要比较完成同一项修复的总费用。

把“请求失败”换成可验证的错误契约

例如,订单导入器收到空的客户编号。原来的异常只有“无效参数”,AI 就得猜是哪个参数、在哪一层被清空。我会改成下面这种消息,让终端输出本身成为调查入口。

错误码:IMPORT_CUSTOMER_ID_EMPTY;位置:src/import/parse-row.ts,parseRow;预期:customer_id 是非空字符串;实际:第 18 行读取到空字符串;复现:运行 npm test -- parse-row.empty-id.test.ts。

这里最值得补的四个字段是稳定错误码、预期值、实际值和复现入口。文件与函数负责导航,行号只作提示,因为改几行代码就会过期。错误码则应该保持稳定,方便搜索抛出位置、关联测试,也方便统计同一种失败是否反复出现。

  • 预期值应写清类型、范围或格式,不要只说输入必须合法。
  • 实际值应保留影响判断的结构,同时隐藏令牌、密码和个人信息。
  • 复现入口应指向最小测试或命令,不要让模型重新启动整套系统。
  • 错误码应描述具体失败条件,不要让所有异常共享同一个失败标签。

保留异常原因,别把猜测写成修复命令

在 JavaScript 里,包装异常时可以使用 Error 的 cause 选项保留原始原因。业务层补充“正在导入哪个批次”,底层保留解析失败或连接超时的信息,避免每层都把细节替换成“操作失败”。日志输出端还需要确认自己确实会展示原因链。

错误消息可以说明“配置项缺失”,但别直接要求“关闭校验后重试”。那会把推测包装成权威答案,AI 很容易顺着错误方向修改。来自文件、网页或接口响应的文本也应标为外部数据,截断后记录,不要让其中的指令混进修复要求。

给 AI 一份最小证据包,而不是整屏日志

我通常先贴错误契约、触发它的测试,以及相关函数,再要求 AI 先解释失败路径,提出最小补丁。缺少证据时,让它明确索取文件,而不是自由浏览整个仓库。不要为了省几个令牌删掉单位、版本或输入类型,这些恰好是区分根因的线索。

  • 先提供一个失败样例和预期结果,让模型知道修复后的验收边界。
  • 只附上相关调用链和必要堆栈,删除重复日志以及无关构建输出。
  • 要求补丁同时覆盖失败测试和正常路径,避免只把报错信息消掉。
  • 每次只验证一个假设,再根据新的运行结果补充下一段上下文。

用同一条错误比较模型,而不是反复换工具

先拿 Claude Haiku 4.5 处理定位明确的小修复;如果连续两轮仍无法解释失败路径,再试 Claude Sonnet 5.5。这里不是保证哪一个更便宜,而是设定升级条件,避免低价请求因为反复猜测而累积更高账单。比较时使用同一份证据包,并记录测试结果。

这也是我在终端工作流里使用 Fluxo 的方式:一个密钥和一个基础地址 https://api.fluxorelay.com,可以访问 Claude、GPT、Gemini、DeepSeek、Kimi、GLM、Qwen、Grok 等系列;工具侧可用于 Claude Code、Codex、Gemini CLI,以及任何使用 OpenAI SDK 的应用。切换调用入口时,仍需按具体工具核对模型名、协议和配置。

如果你想拿自己的失败测试做一次费用对照,可以创建一个 Fluxo 账号,从一条最常见的报错开始。需要帮助时,登录后在联系页面留言即可。邀请机制也提供被邀请者付费后的分成,但这部分应与修复成本分开记,别让收益掩盖了不必要的重试。

把“是否方便修复”加入代码审查

下次审查新增异常时,多问一句:只看到这条消息,另一个人能找到失败条件并运行验证吗?如果答案是否定的,就补上缺失字段,再为错误码和关键上下文写断言。好的报错不会替 AI 思考,却能减少它寻找事实的轮次。真正省下来的,是读完整个仓库之前就能结束的那几次调用。

缓冲区里的下一篇

一分钟注册,赠送额度足够把文中提到的模型都试一遍。 注册 →