阿里云 Agent 记忆实验:检索满分,真去做事只有六成过关
一句话定位:这不是"哪个模型的记忆力更好",而是"它查到的那条记忆,在做出这个决定时还算不算数"——被测对象是记忆库的时效状态,不是模型的检索能力。同样的断言可迁移到客服工单的历史备注、订单退款的政策版本、权限变更后的旧角色残留、地址修改后的旧收货信息。
摘要
阿里云社区 11 月 3 日刊出的一个开源记忆项目,公开了两个差距很大的数字:离线合成夹具上,检索召回 1.000、过期率 0.000;十个真实场景的实时评测里,任务成功率只有 0.60。作者自己的解释是"检索到一条事实,和正确使用这条事实,是两种技能"。这篇把这两个数字读成一份测试设计说明:记忆系统要分层测、过期要有独立的断言、以及"复审"这种人工环节为什么是必须付出的成本。项目属黑客松参赛作品,数字为作者自报。
两个数字,同一套系统,相隔一周公布。
一个是 1.000。在六个人设、24 条查询组成的离线合成夹具上,这套记忆系统的上下文召回是 1.000,过期率是 0.000,在 8 到 64 token 的预算区间里都成立。换句话说,在这套题上它一个都没漏,也一条都没用错。
另一个是 0.60。换到十个场景的实时评测,要求"决策结果、记忆库状态、决策前是否真的查过记忆"三件事同时通过,成功率只有 0.60。
同一个系统,同一批作者,一周之内。这个落差不是 bug,是两类测试在量两件事。
Qwen Memory Agent 是阿里云社区在 2026 年 11 月 3 日刊出的一个开源项目文章,作者 Ryan Duffy,参加的是 Qwen Cloud 全球 AI 黑客松。必须说清楚属性:这是个人作品,不是阿里云官方的生产系统,也不代表任何一代 Qwen 模型的记忆能力基准。我关心它,是因为它把两个通常被合并成一个数字的东西,拆开公布了。
这在测试行业里很少见。多数记忆类项目只公布召回率,因为召回率好看。
为什么"查到了"和"用对了"必须分开测
原文有一句话,我认为是整篇的技术核心:Retrieving a fact and correctly using a fact are different skills, and most systems conflate them.
翻成测试语言:检索链路的输出,和决策链路的输入,中间隔着一个"要不要采信"的判断。这个判断在模型里,不在检索里。所以召回率再高,也只证明了前半段。
原文对这个差别的解释比一句口号具体:一条旧的偏好或约束,在"搜索"这件事上可能完全相关,但对"下一个决定"来说已经彻底错了。这句话点出了一个很容易被忽略的测试对象——相关性是对的,时效性是错的,两者同时成立。
举个业务上常见的例子。客服 Agent 的记忆里存着"该客户不接受电话回访",三个月前记的。今天客户在工单里写了"下午三点后随时可以打给我"。如果系统只做了追加不做作废,检索时会同时命中两条,按相关度排序,旧的很可能因为被引用过多次而排得更靠前。召回率不会掉,因为该命中的都命中了;但如果它采信了旧的那条,这个工单就处理错了。
这就是 0.60 的来源。它量的是"三件事同时成立",而 1.000 只量了第一件事。
两个数字对应的三层判据画成同心结构:外层是检索,中层是记忆库状态,内层是决策前的实际查询。越往里越难,也越接近业务。
过期这件事,工程上是怎么处理的
原文给的机制值得抄进测试用例:用精确的 subject/type 匹配加语义相似度,把被取代的事实"退休"掉,而不是让它一条条堆起来。
关键词是退休,不是删除。删除会让审计断链——你不知道它曾经存在过。退休保留了"这条曾经是对的、什么时候被谁取代"这条线,同时让它不再进入检索。
这个设计直接决定了测试怎么写。如果实现是"删除",那么过期测试只需要断言"查不到"。如果是"退休",断言要复杂一些,但更接近真实业务:查不到(不进检索结果),查得到(审计可追溯),且后继关系指向被采信的那一条。
我把这三条写成一组,用一个很朴素的场景跑:先告诉 Agent "这个客户不接受电话回访"(记一条),三天后告诉它"下午三点后可以打"(记第二条),再问"这个客户现在能不能打电话"。
三条断言分别对应:检索结果里不能出现第一条;审计接口能列出第一条及其被取代时间;回答里引用的依据必须是第二条。第三条最容易挂,因为模型完全可以答对("可以打"),但依据写的是"客户说不接受电话回访"——答案对,推理错,这种错误在人工抽查里几乎抓不到。
0.60 里最有价值的那个条件:决策前到底查没查
十场景评测里,第三个条件是我认为整篇文章最被低估的部分:recall-before-decision。
它问的不是"记得对不对",而是"做决定之前,你有没有去查"。这两个问题在日志里长得完全不一样。前者看记忆库,后者看调用链路。
测试上这条的意义在于:它把"偶然答对"和"依据记忆答对"分开了。一个模型可能凭上下文里的残余信息猜对了答案,但如果它在决策前没有调用记忆工具,这次通过是不可复现的——换个措辞就会错。
这里还有一个更隐蔽的分支:查了,但没查全。检索返回了三条,它引用了其中两条,漏掉的那条恰好是决定性的。这种情况在结果上表现为"答错了",在归因上既不是检索的问题也不是记忆库的问题,是采信环节漏了。要抓住它,断言不能只检查"依据里有没有那条",要检查"应当出现的依据是否全部出现"。我写的是全包含断言:要求的依据 id 必须一个不少,多出来的不管。
实现这条断言的工程前提是:记忆必须被暴露成可观测的工具调用。原文的设计正好是这样:记忆是模型自己选择调用的一组工具,通过 HTTP 和八个 MCP 工具暴露。这就让"查没查"变成一个可以看日志回答的问题。
如果你们的记忆系统是隐式的(在 prompt 里拼接、在中间件里注入),这条断言写不出来。这是一个需要在选型阶段就想清楚的点,不是测试阶段能补的。
人工复审:看起来是退化,其实是保险
原文有一处细节,我认为是最值得争议也最值得学的:系统里有一个单独的"dreaming"过程,负责提出记忆合并的建议,但变更必须经人工批准。
从效率角度看,这是退化。一个能自己整理记忆的系统,最后一步还要人点确认,那它整理的意义在哪。
从测试角度看,这是唯一能拦住"错误合并"的闸。记忆合并的风险在于:两条看起来相似但实际冲突的记录被合成一条,之后所有引用都建立在错误的前提上。这类错误不可逆,而且极难从结果反推——因为合并后的记录看起来更整洁、更可信。
所以这一层在验收里要单独列一条:合并产出必须可拆分。原始两条记录即使被合并,也必须保留指向合并前的引用,能在审计里还原出"合并前是什么、按什么规则合的"。没有这个,合并就是不可撤销的破坏性操作,而不可逆动作需要的是人签名,不是一个自动化流程。
把合并的三个分支画成漏斗:进去的是候选记忆,出去的三条路是保留、退休、合并,其中合并这一路被人工闸门。
这组数字该怎么读,以及不该怎么读
先说该读出来的部分。它证明了一件事:记忆系统的质量不能用一个数表达,因为它的失败模式分布在不同层上,且层与层之间不能互相代替。离线夹具上的 1.000 不是注水,它真的把检索做好了;0.60 也不是翻车,它是另一件事的真实水平。两个数一起公布,才是完整的。
再说三件不该读出来的事。
第一,不能读成"某模型的记忆能力是 0.60"。这是十场景、作者自建评测、一个黑客松项目的结果,样本量和口径都不支持对模型能力下结论。
第二,不能读成"离线评测没有价值"。恰恰相反,离线夹具能把检索和过期这两层单独隔离出来,这个价值实时评测给不了。问题只在于不能只做离线。
第三,不能读成"记忆做得越复杂越好"。这个项目公开的失败里,有一类正是"机制齐全但决策前没查"。机制多不等于用得上。
四类记忆问题按"能不能离线复现"和"要不要看调用链"两个维度放进去,用来决定每一类该在哪一层测。
如果只能加一条用例
加这条:在记忆里放一条三个月前的旧事实和一条今天的冲突事实,然后问一个只涉及旧事实领域的新问题,断言回答引用的依据是新的那条。
它便宜,一次能跑,不需要改造系统。它同时压了三个点:检索会不会同时返回两条、排序会不会偏向旧的高引用记录、以及模型会不会采信旧的。
这条用例红的时候,你大概不会立刻知道该改哪一层。但那正是它的价值——它逼你去分层。测试团队在记忆这个问题上最容易犯的错,是把"回答不对"直接扔给模型团队;实际上有一半的错在检索排序和过期机制上,跟模型无关。
本文部分内容参考了霍格沃兹测试开发学社整理的相关技术资料,主要涉及软件测试、自动化测试、测试开发及 AI 测试等内容,侧重测试实践、工具应用与工程经验整理。
- 点赞
- 收藏
- 关注作者
评论(0)