2026年7月18日 1 分钟阅读

场景:AI 编码 Agent 反复修同一个 Bug?RegressionLedger 用跨会话指纹终结修复死循环

tinyash 0 条评论

用 Claude Code 或 Cursor 写代码时,你一定遇到过这样的场景:Agent 修了一个 Bug,测试挂了;它换了个姿势修,测试又挂了;再换,再挂……直到上下文窗口填满被重置,它忘了刚才所有失败尝试,重新从第一步开始,重复同样错误的修复路径。

这就是 AI 编码 Agent 最令人头疼的「修一个、坏两个」死循环(doom loop)。RegressionLedger 是一个零依赖的 Claude Code 钩子 + CLI,用跨会话的语义指纹追踪每一次编辑结果,在 Agent 试图重试已经失败的修复时,直接硬阻断而非仅仅建议。

死循环的根源

这个问题的症结在于三个环节的断裂:

  1. Agent 的失败记忆无法跨越上下文窗口填充——Claude Code 的上下文满后自动压缩(compaction),压缩后 Agent 忘了自己之前的失败尝试
  2. 现有的循环检测器只在一个会话内检测完全相同的工具调用——它们不跨会话记录”哪个修复试过了以及它为什么失败”
  3. 通用 Agent 记忆层(如 lessons learned)只是建议——模型可以自由忽略它不想听的建议

结果是:Agent 在一个会话内修同一个 Bug 修了 5 次,每次都用同样的错误方法;上下文重置后,第 6 次依然是同样的错误路径。

RegressionLedger 的解决方案

RegressionLedger 是四个环节的闭环:

指纹化(Fingerprint):每次 Agent 执行 EditWriteMultiEdit 时,对修改的代码生成语义指纹。指纹分为两个通道——原始通道保留字面量(只去除空白和注释),折叠通道将字符串/数字抽象为 STR/NUM 占位符。

结果关联(Outcome Linkage):Agent 运行 npm testpytesttsc 等命令后,钩子解析输出,将之前的编辑标记为 passfail,并捕获首个错误行作为签名。

持久化(Persistence):所有记录存入 .regressionledger/ledger.json——纯 JSON 文件,无数据库、无网络调用、无 API Key。

硬阻断(Hard Block):Agent 再次提交相同指纹的修改时,PreToolUse 钩子直接拒绝,并给出具体原因——”你在 2 小时前对 src/auth.js 试过同样的修复,失败原因是 AssertionError: expected 200, got 401,请更换策略。”

关键特性

双通道指纹

普通修复(改缩进、改注释)被原始通道匹配,触发硬阻断。修改常量值(timeout 500030000)只命中折叠通道,触发建议而非阻断——因为它可能是合理的参数调整。基准测试验证了这一点:60/60 次相同修复被 100% 阻断,40 次参数调整零误阻断。

跨会话简报

SessionStart 钩子在每次会话开始时注入一份紧凑的”过去失败总结”——包括在上下文压缩之后。这意味着 Agent 在构思失败修复之前就被阻止,而不是在已经写完后才被拦截。

震荡升级(Thrash Escalation)

当 3 种以上不同的修复尝试都撞在同一堵墙上时(同一个错不同修法),钩子会升级干预:”诊断有问题,不是补丁有问题——停下来,提出根本原因假设,验证一个,再修复。”

群体免疫

rl export / rl import 在不同机器和团队成员之间共享已确证的失败记录——你的 Agent 继承别人 Agent 已经走过的死胡同。

快速上手

作为 Claude Code 插件安装(推荐)

/plugin marketplace add anlor1002-alt/regressionledger
/plugin install regressionledger@anlor1002-plugins

钩子自动激活,无需编辑 settings.json

作为 npm 包安装

npx regressionledger init

init 会自动在 ./.claude/settings.json 中注册 PreToolUse / PostToolUse 钩子,并创建 .regressionledger/ 目录。重启 Claude Code(或运行 /hooks)即可生效。

验证安装

npx regressionledger doctor

包含实时钩子往返测试——首次编辑必须通过,预设的重复失败必须被拒绝。

常用命令

命令作用
rl demo在沙箱模拟中演示死循环被阻断
rl doctor验证安装,包含实时钩子测试
rl why 查看某个文件的历史失败记录和原因
rl show [file]显示完整尝试历史
rl stats统计摘要,包含被阻断的重复修复次数
rl unblock 在上下文确实变化时解除对文件的阻断
rl export / rl import跨机器共享已确证的失败记录
rl uninstall完全移除,不留痕迹

配置项

配置文件 .regressionledger/config.json 包含以下核心参数:

  • mode(默认 block):block 为硬阻断,warn 为仅警告
  • threshold(默认 0.9):指纹相似度阈值,越高越严格
  • minFailures(默认 1):失败多少次后才触发阻断,设为 2 更谨慎
  • crossSymbol(默认 true):是否跨符号匹配同一文件内的失败

第一天担心误判?以 rl init --warn 启动观察模式,rl stats 查看本应阻断的次数,确认准确后再切换到 block 模式。

对比其他方案

工具跨会话关联结果阻断/建议
会话内循环检测器警告
通用 Agent 记忆层建议
RegressionLedger硬阻断

与通用记忆层的本质区别:记忆层存储建议,模型可以忽略;RegressionLedger 发出 PreToolUse 拒绝命令,模型无法绕过。

适用场景

  • 复杂的多步骤修复:Agent 修复 A 功能,测试 B 功能,B 失败后 Agent 反复尝试相同路径
  • 跨会话的回归问题:同一类 Bug 在多个会话中被反复用错误方法修复
  • 团队共享学习成本:一个 Agent 发现的死胡同通过 rl import 让整个团队受益

局限

  • 当前仅支持 Claude Code 的钩子系统(Cursor/Windsurf 在路线图中)
  • 批量归因的噪音:一次测试运行同时判定多个编辑时,归因是近似的
  • 需要 Node ≥ 18

相关链接

发表评论

你的邮箱地址不会被公开,带 * 的为必填项。