论文链接:VibeMemBench: Evaluating Memory Systems for Coding Agents on Real Repository Coding Tasks 发表时间:2026 年 9 月(arXiv v1, 2609.23570) 机构:中科院深圳先进院 SIAT + 阿里巴巴 Token Hub / 阿里巴巴集团 + SUAT(🌟高校 + 企业联合,共 12 位作者) 代码:https://github.com/AlibabaResearch/DAMO-ConvAI/tree/main/VibeMemBench 领域标签:cs.SE / Software Engineering / Agent Memory
一、论文背景:记忆系统「到底有没有用」没人能量
过去两年,coding agent(编程智能体)从「能改几行代码」走向「能在一个真实仓库里修 issue、加功能、改配置」。随着任务变长,社区自然提出一个需求:能不能让 agent 把过去在仓库里干过的活「记下来」,下次遇到类似任务时复用? 这正是「持久记忆系统」(persistent memory)要做的事——它负责把历史交互写成经验、存储、并在需要时检索回上下文。
但论文开门见山地点出一个尴尬的测量难题:有用记忆(useful memory)是「潜伏」的。一个可执行测试能告诉你「这个任务修没修好」,却不会告诉你「哪条历史经验该被写下来、该被检索回来」;反过来,一个 gold retrieval label(标准答案式的最优记忆)只能说明「该回忆什么」,却回答不了「回忆它对修仓库到底有没有帮助」。换句话说,记忆的「价值」和编程任务的「结果」是两件事,而现有评测只照亮了其中一面。
更具体地说,现有的两大评测家族都只看了一半信号:
- 记忆基准(memory benchmark)——例如 LoCoMo、LongMemEval,给模型一段长对话历史,然后问「某句话是谁说的」「上周发生了什么」。它们测的是回忆准确率(recall),但回忆得好 ≠ 能帮 agent 修好一个真实仓库。
- 仓库基准(repository benchmark)——例如 SWE-bench,给 agent 一个 GitHub issue 和可执行测试,看它能不能改对代码。它测的是可执行结果,但并没有把「持久记忆干预」单独隔离出来比较。
这就留下了一个空白:既在真实仓库任务上、又让记忆成为唯一变量地去评测记忆系统。VibeMemBench 就是来补这个洞的。它的核心直觉非常朴素——同一道题,让 agent 跑两遍,一遍不开记忆、一遍开记忆,其他一切(任务、agent、工具、沙箱、预算)完全相同,然后看「开记忆」到底有没有让可执行结果变得更好。
二、论文定位与关联工作
VibeMemBench 处在三条研究谱系的交汇处,而它补的是三者都没覆盖的「交叉点」。
谱系 A:Coding 仓库基准。 从 SWE-bench(Jimenez et al., 2024)用可执行测试判定 GitHub issue 的解决,到 RepoBench / RepoCoder / Hierarchical Context Pruning 研究仓库级上下文检索,再到 GitTaskBench、DSCodeBench 把仓库制品与可执行校验显式化,以及 SWE-Bench-CL 把任务排成持续学习序列。这些工作没有一个把「匹配式的持久记忆干预」从编程结果里隔离出来——它们要么默认全量上下文塞进窗口,要么根本不引入记忆变量。
谱系 B:长程 agent 基准。 DMT-RoleBench、RealWebAssist、ProBench 等也做长程多轮评测,但它们的主要信号是对话、网页或 GUI 行为,不是「记忆开/关对可执行仓库修复的配对差异」。
谱系 C:记忆基准与记忆系统。 LoCoMo、LongMemEval、MemBench 测的是「在存储历史上答一道查询题」,信号是 queried answer,并不衡量潜在有用记忆是否改变了可执行编程成功率。而在「被评测的记忆系统」这一侧,MemGPT、MemoryBank、MEMORYLLM、MemoryART、LightMem 等发展了分层上下文管理、长期个人存储、自更新潜记忆等写/更新/保留/检索策略。VibeMemBench 把 Mem0、SimpleMem、MemoryOS、A-MEM 这 4 个现代记忆系统,放到同一个「可执行仓库任务协议」下作为「记忆开启」组件来评——这正是前两类家族留下的空白。
| 路线 | 任务形态 | 判定 oracle | 是否隔离记忆干预 | 与 VibeMemBench 的关键差异 |
|---|---|---|---|---|
| SWE-bench 系 | 真实 GitHub issue | 隐藏测试通过 | 否(默认全上下文) | 不评记忆系统,只评 agent 修代码 |
| LoCoMo / LongMemEval | 长对话历史问答 | 答案匹配 | 否 | 测回忆,不测对可执行编程的帮助 |
| MemGPT / Mem0 等记忆系统 | 对话/个人助理 | 任务完成或 QA | 各系统自定 | 多在非仓库场景,缺统一可执行协议 |
| VibeMemBench | 真实仓库 SWE 式任务 + 可执行测试 | 测试通过(Resolved) | 是(memory on/off 配对) | 首个在可执行仓库任务上受控评测记忆系统 |
定位结论:VibeMemBench 不是「又一个记忆基准」或「又一个仓库基准」,而是把两者缝合——用仓库任务的可执行结果当尺子,去量记忆系统交付的经验到底有没有用。
三、问题定义:把「记忆有用」变成可测的配对差异
抛开工程细节,论文要解决的深层问题是一个**「受控干预下的下游价值」问题**:
- 具体任务:给定一个真实仓库状态、一个编程指令、一段来自同一仓库的历史轨迹,以及一个可执行测试谓词(predicate),agent 跑一遍,测试通过就算成功。
- 抽象问题:在其他所有条件都锁死的前提下,仅仅「打开记忆」(注入检索到的历史经验)这件事,能不能提升测试通过率?提升多少?同时,agent 的 token 消耗和步数是变多还是变少?
形式化地,论文定义了一组要素:
- 目标集合 T、种子集合 S,配对评估集 P = T × S(每个「目标×随机种子」跑一次)。
- 固定 agent 配置 A:包含模型、prompt、工具、沙箱镜像、上下文预算、资源限制、任务顺序、聚合规则——所有这些在两次运行间都不变。
- 记忆条件 m ∈ {off, on}:只有「声明的持久化与检索机制」可以变。off 时不注入任何检索记录;on 时注入一条检索到的经验。
于是对每个配对 (t, s),比较 A(t, s, off) 与 A(t, s, on)。观察到的任何差异都只归因于记忆,而不是 agent 配置漂移。这是整个基准成立的方法论基石——也是它区别于「直接拿 SWE-bench 分数排记忆系统」的根本。
论文还区分了「记忆有用」的两个子问题,并用两个评估层分别回答:
- A 层(冻结经验迁移):假设我们已经提前确认「某条经验对这个目标有用」(由参考设置用执行验证过),把它冻结后直接迁移给 5 个未见过的 solver,问「已知有用的经验,solver 用得上吗?」
- B 层(现有系统检索):让 4 个现有记忆系统自己从同一段合格历史里写、检索出 top-1 经验注入,问「现有记忆系统能否交付有用经验?」
这两层的对照,正是论文标题里「availability(历史里有没有有用经验)」与「use(系统能不能把它交付成有用上下文)」之间那道鸿沟的 operational 定义。
四、基准构建方法:SIEVE 四阶段流水线
VibeMemBench 基于 SWE-rebench V2(一个语言无关、带可执行校验的大规模软件工程任务库)构建。它用一个名为 SIEVE 的四阶段流水线筛出「历史里确实藏着有用经验」的目标——SIEVE 不是缩写,只是因为它像筛子一样层层过滤。
阶段 1:来源校验(Source Validation)。 用声明的测试 + 目标 gold patch 跑一遍,凡是 gold patch 自己都过不了测试的目标直接丢弃。这一步保证「目标本身是干净可解的」。
阶段 2:补丁模式筛选(Patch-Pattern Screen,oracle 辅助离线)。 只保留来自同一仓库的更早实例,并排除任何目标自身的标识符,确保「目标不会进到自己的历史池里」(防止泄漏)。一个确定性打分器基于共享文件、目录、清洗后的标识符做短名单,再由 LLM 用结构化证据判断每个修复模式是否相关。关键点:目标 gold patch 只进这个离线筛选,目标 test patch 始终是 evaluator-only,二者都不进入经验构建、运行时检索或 solver 上下文——从设计上切断了「答案泄漏」。
阶段 3:历史执行 + 经验蒸馏(History Execution & Distillation)。 对筛选后的每个历史任务做完整执行,保留完成的轨迹;再用「目标感知经验构建」从「目标问题描述 + 历史问题描述 + 压缩后的历史轨迹 + 历史最终补丁」中蒸馏出每条经验,记录 bug class(缺陷类别)、root cause(根因)、fix pattern(修复模式)、reusable lesson(可复用经验) 四个字段。蒸馏过程看不到目标 gold patch、test patch、测试结果,每个具体断言都锚定在历史轨迹或补丁上。
阶段 4:验证 uplift 并冻结(Verify Uplift & Freeze)。 这是 SIEVE 的「灵魂」。对每个保留目标,它在参考设置(deepseek-v4-flash + MiniSWEAgent,每条件 4 个种子)下比较「注入候选经验」与「不开记忆」的解决率,uplift = bpref(t,k) − bpref(t,0)。保留条件:bpref(t,0) < 1 且 uplift > 0;冻结的「已验证经验」就是 uplift 最大的那条组合 k*。
这条规则保证了:每一个发布的目标都带有一条「在该参考设置下被执行验证过有用」的经验。换句话说,VibeMemBench 发布的不是一堆随机任务,而是「历史里确实藏着能提升可执行结果之经验」的任务子集。最终规模:111 个目标、跨 90 个仓库、3634 条已完成的历史轨迹,每个目标保留来源、测试命令与执行结果,可审计、可复现。
设计上有两个边界要清醒认识:(1) 这 111 个目标是「按正 uplift 规则筛选」出来的,所以它天然适合做「已知可迁移经验下游价值」的基准,而不代表真实部署中 agent 有多常能撞上这种配对;(2) 冻结经验只是「见证历史里有什么可用」,是 availability-to-use 鸿沟的下界,而非上界。
五、评估协议与设计:只动记忆开关的匹配干预
论文把「匹配干预协议」写成一份可审计的契约(manifest),每个被报告的 run 都要填固定字段。记忆开启侧必须声明:写策略、检索触发条件、上下文插入规则、记录截断规则;记忆关闭侧在同一固定上下文预算下替换掉这些记录。
两个评估层的具体设置:
- A 层(冻结经验迁移):把 deepseek-v4-flash 参考设置识别出的冻结经验,固定下来,去评 deepseek-v4-pro、glm-5、glm-5.2、kimi-k2.7-code、qwen3.8-max 五个 solver(每条件 4 种子),看经验能否跨模型迁移。还设了一个「无关记忆控制」:注入一段没有软件内容的日常句子作为干扰,其他设置全不变——用来排除「仅仅是往上下文里塞了点文字」带来的虚高。
- B 层(现有系统检索):Mem0、SimpleMem、MemoryOS、A-MEM 摄取目标可用的全部合格历史,组织完成后用一个声明的目标查询选出 top-1 经验,注入 MiniSWEAgent。注意这是离线检索(检索发生在目标 solver 轨迹之前,而非在线闭环记忆),衡量的是「系统交付的经验能否改善下游执行」。
指标:主指标是 Resolved(通过声明测试的目标-种子占比)。每个配对 (t,s) 在条件 m 下 y(t,s)=1 当且仅当测试通过。配对记忆效应 b∆ = bpon − bpoff。不确定性单位是「目标」,所以论文用「把 111 个目标连同其 4 种子整体重采样 10000 次」的百分位 bootstrap 给出 95% CI——所有报告区间都跨零,意味着在 111 目标规模下这些增益仍是方向性证据,而非能从零分离出的显著效应。每个结果行还报告 solver 资源使用:输入/输出 token 均值、agent 步数均值——它们量的是「solver 使用情况与交互长度」,不是延迟,也不记录记忆系统侧 token 消耗。
六、外部交叉验证:记忆基准与「长上下文反而伤」的共识
论文把「记忆有用」拆成「能不能回忆」和「回忆能否改善执行」两层,而外部研究强烈支持这种分离。检索到 ≠ 用得上,且「往上下文里塞越多历史,性能未必越好」已是被反复验证的现象。
1)记忆基准家族:recall 饱和但行动场景低迷。 LoCoMo(Maharana et al., 2024,ACL 2024,arXiv:2402.09155)和 LongMemEval(Wu et al., 2025,ICLR 2025,arXiv:2502.01428)在长对话回忆上已近乎饱和,但它们都是「静态问答」,不涉及环境动态与决策依赖。MemoryArena(arXiv:2602.16313)则明确指出:在 LoCoMo 这类基准上接近饱和的 agent,到了「多会话、子任务相互依赖」的 Memory-Agent-Environment 闭环里任务完成率极低,暴露了「recall 成功 ≠ 能指导未来行动」的鸿沟——这与 VibeMemBench 把记忆塞进真实仓库可执行任务、用 Resolved 当尺子的取向高度一致。换言之,VibeMemBench 把 MemoryArena 的「行动耦合」思路落到了可执行的仓库修复这一更硬的 oracle 上。
2)「长上下文反而伤」:transcript 体积危害的外部旁证。 VibeMemBench 的 strip 消融(见第八部分)证明现有记忆系统的危害来自原始 transcript 体积而非指令语义,这与「lost in the middle / 长上下文稀释」文献同构。Liu et al. (2023) 的「Lost in the Middle」(arXiv:2307.03172)在 20 文档 QA 中显示:关键文档放在上下文中部时检索准确率从位置 1 的约 75% 跌到中部的约 53%,再回升到尾部的约 63%——U 形曲线说明模型并不均匀利用长上下文。Needle-in-a-Haystack 系列进一步指出,随 fillers 增多,注意力被稀释,相关事实信号变弱(dejan.ai 概念解释)。这与 VibeMemBench 的发现互相印证:注入 65 行原始 transcript 比 5 行四字段经验更伤,本质都是「无关/嘈杂长文本淹没关键信息」——只不过 VibeMemBench 把这一现象从「问答检索」推进到了「真实代码修复的执行结果」。
可核验链接汇总:LoCoMo arXiv:2402.09155;LongMemEval arXiv:2502.01428;MemoryArena arXiv:2602.16313;Lost in the Middle arXiv:2307.03172;DMV-Bench(交互式视觉记忆诊断)arXiv:2606.27499。
七、核心实验结果:冻结经验有用,现有系统大多翻车
A 层——冻结的、已验证经验确实能迁移(但幅度小、且非均匀)。 表 1 给出在 111 个「结果筛选」目标上、444 个目标-种子配对的结果:
| Solver | Memory off | 冻结经验 | 变化(pp) | 4/4 目标数 |
|---|---|---|---|---|
| deepseek-v4-pro | 67.1% | 67.1% | +0.0 | 49 → 51 |
| glm-5 | 55.0% | 57.4% | +2.4 | 35 → 34 |
| glm-5.2 | 76.8% | 80.4% | +3.6 | 67 → 74 |
| kimi-k2.7-code | 69.8% | 74.3% | +4.5 | 56 → 62 |
| qwen3.8-max | 79.1% | 80.2% | +1.1 | 68 → 70 |
三个规律:(1) 冻结经验让 5 个 solver 中的 4 个 Resolved 提升 1.1~4.5 个百分点,deepseek-v4-pro 不变,效应正向但不均匀;(2) 所有 5 个 bootstrap 区间都跨零,所以在这 111 目标规模下仍是方向性证据;(3) 「无关记忆控制」在 3 个跑了它的 solver 上反而比 memory-off 低 0.7~3.4 个百分点,说明「单纯往上下文塞文字」复制不出这些增益。两个最大增益各自多拿下 6 个和 7 个「4/4」目标,不只是单种子翻转。注入还让每个 solver 的 agent 步数下降、5 个里 4 个输入 token 下降——记忆缩短交互而非增加上下文成本。
B 层——现有记忆系统整体没能超过配对基线。 表 2 给出 4 个系统 × 3 个 solver(deepseek-v4-pro、glm-5、kimi-k2.7-code)共 12 组。结果令人警醒:11/12 组停留在或低于 matched memory-off 基线,没有任何一组的区间在零以上;且 glm-5 + Mem0 的区间完全落在零以下([-10.59, -0.45])。唯一的例外是 glm-5 + MemoryOS 提升 2.0 个百分点(57.0% vs 55.0%),但它仍落后于冻结经验。四个系统都大幅削减了 glm-5 的 token 和步数,但只有一组把更短的交互转化成了解决率增益——轨迹变短本身不等于记忆有用。
跨 1332 个「目标×solver×系统」配对,净效应是损失 127 个解决种子。结构性根源在 solver headroom(余量):42.0% 的配对里,memory-off 已经 4/4 满分,注入记录只能丢分不能加分;低于天花板处,现有系统「帮得又太少」。更宽检索预算也修不好这道缺口——附录里 Mem0 在 deepseek-v4-pro 上从 1 到 5 条记录的剂量曲线始终低于 memory-off 基线。这恰好对应那少见的 ranking miss(扩大预算能修的),说明主因不在排序而在记录本身。
八、根因分析:失败在「记录形态」,且危害来自体积
论文做了预先声明的失败归因(在查轨迹前就定好规则),对 B 层里 deepseek-v4-pro 与 kimi-k2.7-code 的 231 个失败配对(覆盖 85 个目标)逐一定「第一个坏掉的环节」。锚点是共享的文件/目录/标识符;「使用失败」要求有轨迹证据表明 solver 真的读了这条记录。诊断参照是「已知有用」而非 gold 检索标签。
| 第一个坏掉的环节 | 定义 | 配对数 | 占比 |
|---|---|---|---|
| Coverage miss(覆盖缺失) | 源历史从未进入系统存储 | 37 | 16.0% |
| Ranking miss(排序失误) | 存了,但注入记录与它无锚点 | 3 | 1.3% |
| Form degradation(形态崩坏) | 相关历史到了,但修复模式被丢进原始 transcript 或被埋 | 160 | 69.3% |
| Use failure(使用失败) | 记录锚点与修复原则都对,run 仍失败 | 31 | 13.4% |
主因一目了然:form degradation 占 69.3%,而 ranking miss 仅 1.3%。也就是说,现有系统通常「找得到」相关历史,败在「怎么把它渲染成记录」。注入记录平均 65 行,对照冻结的四字段记录;一半触发词汇指令污染标记。
表 5 进一步分解 form degradation:(instruction pollution) 指令污染 40.0%、(overgeneralized fix pattern) 过度泛化的修复模式 18.1%、(tool/shell noise) 工具/Shell 噪声 10.0%、(schema omits fix field) schema 漏掉修复字段 8.8%、(fix replaced by symptom) 修复被换成表象 3.8%、其他 19.4%。transcript 系系统(MemoryOS、A-MEM)注入原始对话块,制造了全部指令污染与 Shell 噪声;atomic 系系统(Mem0、SimpleMem)存 LLM 抽取的事实,制造了全部过度泛化、schema 遗漏、表象替换——这是设计选择之差,不是调参之差。
strip 消融——危害来自体积而非语义。 在 64 个指令污染配对里取 62 个,把每条记录「去掉被标记的行」重注入,并对照「随机去掉同样多未标记行」。两臂都比原记录多恢复约 0.60 与 0.48 个种子,且目标级置换检验拒绝空假设。因为随机删除恢复得差不多,说明危害走的是 transcript 体积,而非指令语义——那个词汇污染标记标记的其实是一条「臃肿记录」,而不是某种失败机制。图 5 的实例极具说服力:aiohttp-7907 上,A-MEM 的 334 行记录(大半是另一个 issue 的报告、复现脚本、任务提交指令)把 deepseek-v4-pro 从 4/4 打到 0/4;而冻结的 5 行记录(写明修复模式与 client_reqrep.py 锚点)让它在每颗种子都解决。配对轨迹显示:不开记忆时 agent 锁定了目标升级语义并修复;注入记录后却被重定向去修记录里那个不相关的 except 块。
一个反直觉的边界:记录是否有用,取决于 solver 不开记忆时的余量,而非记录本身。在 deepseek-v4-pro 与 kimi-k2.7-code 都跑完 4 种子的 444 个配对里,当两条 solver 都移动时(118 对),64 对方向相反;其中 61 对是「不开记忆时较弱的那个受益、较强的那个受损」。用「只看 memory-off 余量」的规则能预测 56.5% 配对效应符号,高于「只看记录内容」的 52.4%——检索分数无法表达这种依赖。
九、总结、局限与可提取的启示
一句话总结:VibeMemBench 把「记忆系统有没有用」从「回忆题」变成「真实仓库可执行任务上的配对干预」,并暴露了一道尖锐的鸿沟——历史里有有用经验(冻结经验迁移让 4/5 solver 提升 1.1~4.5pp),但现有系统交付不出有用上下文(12 组里 11 组没超过不开记忆的基线)。失败的主战场不是检索排序(ranking miss 1.3%),而是记录形态(form degradation 69.3%),且 strip 消融证明危害来自原始 transcript 的体积而非指令语义。
三条设计启示(论文给的):
- 按 solver 余量门控注入,而非无差别统一注入。当 solver 不开记忆就失败、且记录至少带目录/标识符锚点时,这类配对有 55.2% 提升且无观测损失;而 4/4 满分级连冻结经验都会在 25.7% 的配对上拉低解决率。
- 压缩到「写明修复的那一段」,而不是按表面标记过滤指令文本。因为危害在体积,系统应把检索到的轨迹压到陈述修复的 span,而非滤掉指令污染词。
- 保留 fix 字段是必要的但不充分。保留修复模式的记录并没有降低损失率,所以抽取 schema 必须保留把修复锚定到目标的约束。
局限(论文自陈):(1) 评测在「声明的 agent 配置 + 固定记账规则」下进行,111 目标来自「oracle 辅助补丁筛选 + 正 uplift 规则」,没有 gold 检索标签;(2) solver 池因推理预算原因排除了 Claude、GPT 等私有前沿模型,solver-无关协议对它们尚未验证;(3) 检索层天花板反映的是 solver 强度,不是「失去的机会」——140 个天花板配对在参考 solver 下都低于 4/4,是迁移后才浮现的。
对读者的可迁移启发:这不仅是「记忆系统评测」的结论,更是一则关于「长上下文使用」的普遍教训——往 agent 上下文里塞原始长 transcript,往往比塞一条精炼、锚定、带约束的经验更伤;判断一条经验「有没有用」,要绑在下游可执行结果上,而不是绑在「检索召回分数」上。这与第六部分外部交叉验证里的 Lost-in-the-Middle 与 MemoryArena 结论彼此支撑:recall 饱和不等于行动有效,体积稀释是真实存在的执行危害。
论文原文与数据、协议 manifest、复现脚本见官方仓库:https://github.com/AlibabaResearch/DAMO-ConvAI/tree/main/VibeMemBench