
1. EXPEREPAIR 双记忆机制到底解决什么仓库级修复难题EXPEREPAIR 是一个把「情景记忆 语义记忆」双通道知识积累引入 LLM 仓库级程序修复Repository-Level Program Repair的框架。它能做什么简单说就是让模型不再把每个 bug 当成孤立事件而是像人类程序员一样从同一个仓库里已经修过的历史问题中翻出相似案例和抽象策略动态拼出上下文感知的提示词再去生成测试、生成补丁、验证补丁。适合谁适合正在复现 SWE-Bench 类基准、或者要给自家代码仓库做二次开发的 LLM 应用团队。我先说清楚它要打的痛点。传统基于 LLM 的自动程序修复APR在仓库级场景下有两个明显短板。第一孤立处理问题。每个 issue 进来模型从零开始定位、从零开始猜补丁完全无视这个仓库里上周刚修过一个几乎一模一样的 API 误用。现实中软件项目的 bug 是有重复模式的比如类型不匹配、资源没释放、参数顺序写反这些模式反复出现修复逻辑高度相似。第二静态提示策略。手工写死的 prompt 没法适配不同仓库的编码约定、架构风格和问题描述习惯你不可能给每个仓库都手搓一套提示词。EXPEREPAIR 的思路是模仿人类认知里的双记忆系统。情景记忆Episodic Memory存具体的修复案例比如「issue #123 的补丁长这样改了哪几个文件」语义记忆Semantic Memory存从历史修复轨迹里抽出来的抽象自然语言见解比如「这个仓库里凡是涉及 config 加载失败优先检查默认值覆盖顺序」。推理时两个记忆同时被激活情景记忆给出精确的实现参考语义记忆给出可泛化的策略方向两者协同生成动态提示。论文在 SWE-Bench Lite 上的数据是Claude 3.5 Sonnet V2 下 pass1 达到 47.7%Claude 3.7 Sonnet 下达到 49.3%优于所有开源基线。消融实验也验证了去掉经验模块修复率会明显下降。这说明双记忆不是花架子是实打实贡献了性能。但论文归论文工程落地是另一回事。你要复现它绕不开几个现实问题模型 API 怎么接、记忆模块的存储和检索怎么配、settings 文件里哪些字段对应双记忆的开关、跑起来之后怎么验证补丁真的修好了。这篇就按「能跟做」的标准把 EXPEREPAIR 的落地路径拆开讲重点放在 settings 配置和 API 通道参数上让你在本地把仓库级修复流程跑通。我试过把这类框架直接怼到生产仓库上踩过的坑主要集中在配置层模型 ID 写错、Base URL 没带对路径、记忆检索的 top-k 设太大导致提示词爆炸。下面按步骤来。2. TaoToken 前置把模型通道和 Key 准备好在跑 EXPEREPAIR 之前你得先有一个稳定的模型调用通道。EXPEREPAIR 本身不绑定特定厂商论文里用的是 Claude 系列但工程上你完全可以通过统一 API 网关来切换模型。这里我用 TaoToken 作为模型通道原因是它的接口兼容主流格式配置项清晰适合做仓库级修复这种需要反复调用的场景。先明确你要拿到的三样东西Base URL、API Key、Model ID。这三件套是后面所有配置的基础缺一个都跑不起来。Base URL 用https://taotoken.net/api注意这个地址不带任何查询参数直接作为 OpenAI 兼容接口的根路径。API Key 需要你去控制台生成路径是 console 页面进去之后找 API Keys 管理新建一个 key复制出来保存好。Model ID 根据你实际要用的模型填比如 Claude 系列就填对应的模型标识具体以你账号下可用的模型列表为准。这里有个细节要注意EXPEREPAIR 的修复模块会频繁调用模型测试代理和补丁代理各自都要发请求所以你的 Key 要有足够的调用额度不然跑到一半 429 会很尴尬。另外建议在 console 里给这个 Key 设一个备注比如「experepair-repo-repair」方便后面排查是哪个项目在用。如果你只是想先验证模型通道通不通可以走模型对话页面快速测一下确认 Key 和 Base URL 没问题再进配置环节。这一步别省很多后面的报错其实根源就是通道没通。对于需要长期跑仓库级修复、或者要做 Agent 式迭代的团队可以考虑 Coding Plan它在调用配额和稳定性上更适合这种持续性的编码任务。但如果你只是复现论文、跑几个 case 验证按量调用就够了。拿到三件套之后下一步就是把它写进 EXPEREPAIR 的 settings 配置里。这里的关键是EXPEREPAIR 的配置文件通常是一个 JSON 或 TOML里面会有 model provider 相关的字段你要把 Base URL、Key、Model ID 分别填到对应位置。具体字段名取决于你用的分支或二次开发版本但结构大同小异。下一节我给出一份可复制的配置片段。3. 可复制配置settings 文件与 API 通道参数这一节是核心直接给可复制的配置片段。EXPEREPAIR 的工程实现里模型调用和记忆模块的配置一般集中在settings.json或config.toml里。下面我按 JSON 格式给一份你可以直接改字段值用。{ model: { provider: openai_compatible, base_url: https://taotoken.net/api, api_key: sk-你的Key填这里, model_id: claude-3-7-sonnet, max_tokens: 8192, temperature: 0.2, timeout: 120 }, memory: { episodic: { enabled: true, store_path: ./memory/episodic, retrieval_top_k: 3, similarity_threshold: 0.75 }, semantic: { enabled: true, store_path: ./memory/semantic, retrieval_top_k: 5, reflection_interval: 10 } }, repair: { test_agent: { max_iterations: 5, generate_tests: true }, patch_agent: { max_iterations: 8, validate_patch: true } }, repo: { root: ./target_repo, language: python, test_command: pytest } }这份配置里几个关键点我逐个说。base_url填https://taotoken.net/api不要在后面加/v1之类的后缀除非你的客户端库要求EXPEREPAIR 的调用层一般会自己拼路径。api_key就是你从 console 拿到的那个。model_id填你实际要用的模型论文里 Claude 3.7 Sonnet 效果最好但你要根据自己账号下可用的模型来填。记忆模块这块episodic.retrieval_top_k设成 3 是保守值意思是每次从情景记忆里捞 3 个最相似的修复案例。设太大提示词会膨胀设太小又可能漏掉关键参考。semantic.retrieval_top_k设 5因为语义记忆存的是抽象见解单条信息量小多召回几条影响不大。similarity_threshold是相似度阈值低于这个值的案例不会被召回0.75 是个经验值你可以根据自己仓库的 bug 重复度调整。如果你用的是 TOML 格式等价写法是这样[model] provider openai_compatible base_url https://taotoken.net/api api_key sk-你的Key填这里 model_id claude-3-7-sonnet max_tokens 8192 temperature 0.2 timeout 120 [memory.episodic] enabled true store_path ./memory/episodic retrieval_top_k 3 similarity_threshold 0.75 [memory.semantic] enabled true store_path ./memory/semantic retrieval_top_k 5 reflection_interval 10配置写完之后还有一步容易漏环境变量。有些实现会优先读环境变量而不是配置文件所以你要确认OPENAI_API_KEY和OPENAI_BASE_URL这两个变量有没有被设置成别的值。如果之前配过其他通道建议先清掉避免配置被覆盖。export OPENAI_API_KEYsk-你的Key填这里 export OPENAI_BASE_URLhttps://taotoken.net/api注意环境变量和配置文件里的值要一致不然会出现「配置文件写的是 A实际请求走的是 B」这种诡异问题。我踩过一次排查了半天才发现是 shell 里残留了旧的 export。配置就绪后先别急着跑完整修复流程用一个小脚本验证模型通道能不能通。下一节给验证请求的具体动作。4. 验证请求与修复前后测试用例的跑通动作配置写好了先做最小验证发一个请求确认模型能返回。用一个简单的 Python 脚本走 OpenAI 兼容接口import os from openai import OpenAI client OpenAI( api_keyos.environ[OPENAI_API_KEY], base_urlos.environ[OPENAI_BASE_URL] ) resp client.chat.completions.create( modelclaude-3-7-sonnet, messages[ {role: user, content: 回复 OK 两个字母即可} ], max_tokens16 ) print(resp.choices[0].message.content)跑通的话你会看到输出OK。如果这里就报错先别往下走去第 5 节对照报错排查。通道验证通过后进入 EXPEREPAIR 的实际修复流程。整个流程分两个阶段初始阶段处理种子问题、构建初始记忆推理阶段检索双记忆、生成动态提示、执行修复。先准备一个目标仓库比如你本地 clone 一个带测试用例的小型 Python 项目把repo.root指向它。然后跑初始阶段让框架处理几个已知的 issue生成修复轨迹并写入记忆python -m experepair.init_memory \ --config ./settings.json \ --seed_issues ./data/seed_issues.jsonl \ --output ./memory这一步会调用模型生成测试和补丁把成功的修复案例存进情景记忆把抽象见解存进语义记忆。跑完之后你去./memory/episodic和./memory/semantic目录下看应该有对应的存储文件。然后是推理阶段针对一个新的 issue 做修复python -m experepair.repair \ --config ./settings.json \ --issue ./data/new_issue.json \ --repo ./target_repo \ --output ./patches框架会先检索双记忆拼出动态提示然后测试代理生成测试用例补丁代理生成补丁最后验证补丁。验证的核心动作是在修复前跑一遍测试确认失败应用补丁后再跑一遍确认通过。修复前的测试动作cd ./target_repo pytest tests/test_affected_module.py -v你会看到具体的失败用例比如FAILED tests/test_config.py::test_load_default。记下这个失败点。应用补丁后git apply ./patches/fix_issue_xxx.patch pytest tests/test_affected_module.py -v如果补丁有效之前失败的用例会变成PASSED。这一步是判断修复是否成功的硬标准别只看模型说「我修好了」一定要跑测试。如果你想对比双记忆的效果可以做一个消融验证把memory.episodic.enabled和memory.semantic.enabled都设成false再跑同一个 issue观察补丁质量和测试通过率的变化。论文里的消融实验就是这么做的你自己跑一遍会更有体感。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth跑 EXPEREPAIR 的过程中报错基本集中在通道和配置层。我按真实遇到的顺序列几个高频的。401 Unauthorized。这个最常见原因就三个Key 没填、Key 填错、Key 没生效。先检查settings.json里的api_key和环境变量OPENAI_API_KEY是否一致再确认 Key 有没有多余空格。如果 Key 是从 console 复制的注意别把前后引号也复制进去。还有一种情况是 Key 被禁用或额度耗尽去 console 的 API Keys 页面看状态。local proxy failed。这个报错通常出现在你本地有代理设置、但代理没启动或者端口不对的时候。检查你的 shell 里有没有http_proxy、https_proxy这类环境变量如果有但代理服务没跑请求就会失败。解决办法是清掉这些变量或者确保代理服务正常运行。注意这里说的是本地网络配置问题不是让你去搞什么特殊通道纯粹是环境变量残留导致的。reading choices 相关报错。典型的是KeyError: choices或者reading choices of undefined。这说明模型返回的响应结构和你代码里解析的字段对不上。常见原因是 Base URL 拼错了比如多加了/v1导致请求打到了错误的端点返回了一个非标准结构的响应。检查base_url是不是https://taotoken.net/api不要自作主张加后缀。另一个原因是模型 ID 写错请求被路由到了一个不存在的模型返回了错误信息而不是正常的 choices 结构。OAuth 相关报错。如果你用的是某些需要 OAuth 授权的客户端可能会遇到 token 过期或授权失败。EXPEREPAIR 本身走的是 API Key 模式不涉及 OAuth但如果你在二次开发里集成了别的认证方式要确保 token 刷新逻辑正确。最简单的办法是回到 API Key 模式用api_key字段直接认证绕开 OAuth 的复杂度。还有一个配置层的坑model_id和实际可用模型不匹配。比如你填了claude-3-7-sonnet但账号下没有这个模型请求会返回模型不存在。去 console 或模型对话页面确认一下可用模型列表填对的那个。排查顺序建议是先验证通道第 4 节的最小脚本再检查配置字段最后看记忆模块的存储路径有没有写权限。大部分问题在前两步就能定位。6. 把双记忆修复接进你的仓库工作流跑通单次修复之后你可以把 EXPEREPAIR 接进日常的仓库维护流程。我的做法是每次有新 issue 进来先让框架检索双记忆如果情景记忆里有高相似度的历史案例直接参考那个补丁改如果没有再走完整的测试生成和补丁生成流程。修完之后把这次的成功轨迹写回记忆让下一次修复更快。这里的关键是记忆的持续积累。reflection_interval设成 10 的意思是每处理 10 个 issue 做一次语义反思把零散的情景记忆抽象成更高层的策略。你可以根据仓库的活跃度调整这个值活跃仓库可以设小一点让语义记忆更新更频繁。如果你要长期跑这套流程建议把模型调用通道固定下来用 Coding Plan 这类适合持续性编码任务的方案避免按量调用时额度波动影响修复流程。配置上就是把base_url和api_key保持稳定model_id选一个你验证过效果好的模型别频繁换。最后给一个实用技巧在settings.json里给memory加一个backup_path字段定期把记忆目录备份。双记忆是这套框架的核心资产积累得越久越值钱别因为一次误删就从头再来。