500 次 Agent 内存实验:绑定问题比遗忘更核心
实验驱动的深度研究,发现 Agent 内存的真实瓶颈不是检索而是上下文绑定。对构建可靠 Agent 的工程师有高价值指导。
实验驱动的深度研究,发现 Agent 内存的真实瓶颈不是检索而是上下文绑定。对构建可靠 Agent 的工程师有高价值指导。
超越快乐路径测试的严谨性
这是《我试图把 AI 智能体内存变成管道而不是哲学》的后续。如果你还没读过,简短版本是这样的:我为 AI 智能体构建了一个持久化内存系统,称为 OrKa Brain,运行了 30 个基准任务,获得了 63% 的配对胜率和 +0.10 的评分改进,然后得出结论"该模型已经知道了 Brain 回忆的大部分内容"。然后我收到了一些很好的评论,让我感到不舒服。这就是接下来发生的事情。
第一次基准测试后,我有一个听起来很合理的叙事:内存系统有效,数字是正面的,混杂变量也被承认了,更多数据会澄清一切。
最后那部分"更多数据会澄清一切",是工程师们在不想承认自己可能犯错时说的话。我也说过。然后我去获取了更多数据。
250 个任务。五个专门的轨道。500 次总运行(有 brain vs. 无 brain)。一个单独的评判模型,这样 LLM 就不会给自己的作业评分。十一次代码改动,解决我在第一轮中识别的五个根本原因问题。
结果出来了。它们没有澄清一切。它们让事情变得更糟。
我不会假装我只是盲目地重新运行同样的实验。第一篇文章发布后,我在基准 v1 和 v2 之间做了真正的工作。第一篇文章的评论指出了几件事,我都解决了:
问题 1:技能存储的是原始 LLM 输出,而不是抽象模式。
这是关键问题。当 Brain 从数据工程任务中学习一项技能时,它存储的是字面步骤:"使用 pandas read_csv 加载 CSV 文件到临时表,带有错误处理。"这不是可转移的知识,这是对模型已经知道的东西的改述。我重写了抽象层(orka/brain/constants.py, brain.py, brain_agent.py),以提取动词-目标模式:"implement [target]"、"validate [component]"、"trace [target]"。想法是抽象模式能更好地跨领域转移。
问题 2:回忆阈值为零。
min_score=0.0 意味着任何模糊相关的技能都可能被调用。我把它提高到了 0.5,并在 transfer_engine.py 中添加了一个语义下界,如果嵌入相似度低于 0.1 且结构匹配低于 0.6,候选项会被完全拒绝。
问题 3:模型在给自己的输出评分。
v1 对执行和评估使用了同一个 LLM。v2 使用一个单独的评判模型(qwen/qwen3-coder-30b),带有专门的评分标准和两两比较工作流 YAML。执行和评判完全分离,不同的脚本,不同的模型,不同的运行。
问题 4:轨道多样性。
v1 有一个轨道。v2 有五个:
每个轨道 50 个任务,共 250 个。所有任务都可在基准数据集中获得。
问题 5:单遍基线。
无 brain 的条件现在通过一个适当等效的管道运行,相同的结构,相同数量的智能体,只是没有 Brain 回忆/学习步骤。不再有可能让无 brain 分数膨胀的两遍优势。基线工作流:baseline_track_a.yml、baseline_track_b.yml 等。
我也把管道分成三个独立脚本,执行、评判、聚合,这样你可以独立重新运行任何阶段。总共十一次代码改动,全部提交并测试。3,014 个单元测试通过。你可以在结果目录中验证一切。
我对此感觉很好。我已经解决了每一个有效的批评。是时候重新运行了。
以下是来自 250 个任务的总体汇总,有 brain vs. 无 brain:
评分标准增量为 +0.06(跨 250 个任务)。
作为参考,v1 在 30 个任务中是 +0.10。所以效应随着更多数据而变小,而不是变大。这不是你想看到的。
Brain 胜率:61.6%
事情从这里变得不舒服。配对评判模型说 brain 62% 的时间赢了。评分标准评判模型说 brain 是 +0.06 更好,这在 9.3/10 的基线上是噪音。这两个指标应该一致。它们没有。
我之前见过这个模式。这是长度/位置偏差。Brain 的回复往往更长,因为管道中有更多智能体在链中,这意味着更多上下文,这意味着更多文本。配对评判倾向于更长的答案。评分标准不关心长度,它独立评分每个维度。
这就是故事变得有趣的地方:
轨道 C 脱颖而出。它是最难的轨道,无 brain 的得分仅为 8.12,比每个其他轨道低将近一个完整点。并且它是 brain 显示有意义评分标准增益的唯一轨道:跨六个维度 +0.40。
轨道 E 的配对胜率最高(76%)但评分标准增益最小(+0.06)。这是长度偏差的特征,配对评判喜欢 brain 的较长输出,但评分标准说它们实际上并不更好。
轨道 B 本质上是抛硬币。52% 配对,+0.00 评分标准。Brain 对伦理推理任务添加了什么都没有。
这里真正击倒我的东西。我深入研究了个别结果,看有多少任务实际上使用了它们的回忆技能:
尝试了技能回忆的任务:51 / 250(20%)
实际使用了回忆技能的任务:0 / 250
平均语义匹配分数:~0.02(接近零)
零。在 250 个任务中没有一个使用了回忆的技能。模型读取了技能,评估了它,并且每一次都决定它没有帮助。而抽象技能和实际任务之间的语义相似度本质上是随机噪音。
我为之自豪的抽象层,那个把"使用 pandas 加载 CSV 文件到临时表"转换为"implement [target]"的,产生的技能太抽象了而显得空洞。两个字的内容。嵌入模型没有看到"implement [target]"和任何真实任务之间的关系。执行模型正确地认识到"implement [target]"告诉它它不知道的任何事情。
我从太具体的技能(字面 LLM 改述)走到了太抽象的技能(空壳)。甜蜜点,实际的可转移知识,是我还没有找到的地方。
我老实说会发生什么。我在 OrKa 上工作已经超过一年了。四十篇博文。一篇关于机器智能的农业阈值的研究论文。一个开源框架,允许我用真实的 AI 运行来测试、实验和探索我的想法。而核心论点,持久化内存让智能体变得更好,继续在数字上失败。
我考虑放弃整个 Brain 系统。让 OrKa 只是一个编排框架。更简单。更容易解释。没有尴尬的基准。但然后我再看了一遍轨道 C。
轨道 C 是无 brain 唯一的挣扎。它得分 8.12,不错,但不是很好。任务涉及复杂的路由决策,其中模型必须考虑多条路径和权衡。这是模型实际上需要帮助的唯一轨道。
而它是 brain 提供有意义帮助的唯一轨道。+0.40 评分标准增量不是噪音。跨 50 个任务和六个评分维度,那是一致的、可衡量的改进。
模式很简单:当模型需要帮助时,Brain 有帮助,当模型不需要帮助时,Brain 没有帮助。
回顾起来这听起来很明显。但它意味着论点不是错的,它只是在错误的条件下被测试。你不会通过把救生衣穿在站在干地上的人身上并衡量他们是否更干来评估救生衣。
这是故事改变的地方。因为与其问"内存有帮助吗?",我开始问"内存到底是什么?"
想想你如何记住怎样开车。当你接近一个不熟悉的十字路口时,你的大脑中会激发什么?
它不是一件事。它不是"转动方向盘,踩油门"。那是程序部分,是的,它就在那里。但它与其他事物结合在一起:
你几乎被 T 形车祸撞到,因为你假设绿灯意味着它是安全的,而没有检查十字交通。那是情节记忆,一个具有情感分量的特定事件。
"路权不等于安全权"。那是语义记忆。一个你学到的一般事实,也许来自驾驶教练,也许来自经验。
"在进入十字路口前检查镜子防止盲点碰撞,因为转弯会减少你的视野"。那是因果推理。你知道为什么序列很重要,不仅仅是它很重要。
当你遇到十字路口时,所有这些一起激发。程序告诉你做什么。情节告诉你上次发生了什么。语义事实告诉你一个原则。因果链接告诉你为什么。那个组合,那个绑定,就是让内存有用的东西。任何单一组件单独都远不那么有帮助。
现在看看 OrKa Brain 目前作为"技能"存储的东西:
implement [target]
trace [target]
就是这样。没有情景记忆,没有语义上下文,没有因果推理。只有两个抽象的动作动词。难怪模型会忽略它。这就像递给司机一张写着“操纵 [车辆]”的纸条,却期待它能在十字路口提供帮助。
为此,我一头扎进了认知科学文献的深坑。结果发现,神经科学家几十年来一直在争论这个问题。他们称之为“绑定问题”:大脑如何将存储在不同系统中的独立记忆痕迹组合成统一的体验?
海马体并不存储记忆。它存储的是索引,也就是一种绑定关系,将运动皮层中的程序性记忆、杏仁核中的情绪痕迹、顶叶皮层中的空间上下文,以及颞叶中的语义事实连接起来。当你回忆起其中一项时,也会同时回忆起其他所有内容,因为它们被绑定在一起。
而我构建的海马体和运动皮层,是两个从未建立联系的独立系统。
下面是 OrKa 目前实际拥有的系统:
技能系统(已完全投入运行,并用于基准测试):
情景系统(已完整构建并经过测试,但从未在任何基准测试中使用):
两个系统都已达到生产就绪状态。两个系统都有完整的测试覆盖。两个系统都集成到了 Brain 类中。我编写了 record_episode()、recall_episodes()、EpisodeStore、EpisodeRecall 等所有组件。语义搜索、保留策略和四维评分一应俱全。
然后,我却从未将它们连接起来。
Skill 没有 episode_id 字段。Episode 没有 skill_id 字段。brain.learn() 会创建 Skill,却不会创建 Episode。brain.recall() 会返回 Skills,却不会返回 Episodes。基准测试工作流会运行 brain_learn 和 brain_recall,却从不运行 brain_record_episode 或 brain_recall_episodes。
两个完整的记忆系统位于同一个代码库中,却不共享任何信息。
看到这一点时,我觉得自己很愚蠢。但与此同时,我也意识到了另一件事:整个架构其实已经完成了 80%。真正困难的部分——嵌入存储、语义搜索、衰减策略、评分系统——都已经完成。缺失的并不是一个新系统,而是现有系统之间的连接。
下面是我现在称为“记忆包”的概念:
┌─────────────────────────────────────────┐
│ 记忆包 │
│ │
│ ┌───────────┐ ┌──────────────────┐ │
│ │ 流程 │ │ 情景(1..N) │ │
│ │(步骤) │──│ 哪些方法有效 │ │
│ │ │ │ 哪些方法失败 │ │
│ └───────────┘ │ 经验教训 │ │
│ │ "X+Z → Y" │ │
│ ┌───────────┐ └──────────────────┘ │
│ │ 语义 │ │
│ │(领域 │ ┌──────────────────┐ │
│ │ 事实) │ │ 因果链接 │ │
│ │ │ │ "A because B" │ │
│ └───────────┘ └──────────────────┘ │
│ │
│ transfer_score = f(all_components) │
└─────────────────────────────────────────┘
系统从一次执行中学习时,会同时创建一个 Skill 和一个 Episode,并通过 ID 将二者关联起来。Skill 存储抽象流程。Episode 存储实际发生的事情:具体结果、哪些方法有效、哪些方法失败,以及最关键的经验教训:“在去重之前运行验证,发现了 30% 原本会被重复处理的错误记录,因此始终应该先验证。”
系统执行召回时,会返回 Skill,并附带与之关联的 Episodes。提供给模型的提示词不再是“实现 [目标]”,而是:
下面是一个抽象流程:实现 [目标] → 验证 [组件] → 追踪 [目标]。
这项技能此前已经应用过 3 次:
数据工程(ETL):在去重之前执行验证,发现了 30% 的脏数据。经验:任何去重步骤之前都必须先执行验证。
API 集成:目标实现成功,但追踪遗漏了异步回调。经验:追踪需要考虑异步执行路径。
日志分析:该模式表现良好。在分析前过滤噪声条目,使误报率降低了 40%。
这才是模型能够真正利用的记忆。它既包含抽象模式(可迁移),也包含具体证据(提供现实依据)。模型可以根据真实结果判断该模式是否适用于当前场景,而不是仅凭结构相似性进行判断。
迁移评分也会随之改变。一个由五次成功情景和清晰经验支撑的 Skill,其评分应该高于没有任何 Episode 支撑的 Skill。情景质量会成为迁移决策的一部分。
反馈也会同时更新两者:Skill 的置信度发生变化,同时为本次应用记录一个新的 Episode。情景链会随着时间不断增长,而未来的召回将获得更加丰富的上下文。
我的研究论文主张:只有通过递归式的环境控制循环,智能才能扩展到文明尺度——推演、行动、观察、修正、复合增长。农业是人类首次大规模完成这一循环。我把它称为“农业阈值”。
当前的 Brain 系统并没有跨过这道阈值。它会推演(学习一项 Skill),也会行动(召回该 Skill),但并不会真正地观察或修正。Skill 从不从自身的应用过程中学习。它只是不断积累抽象模式,却与真实结果毫无联系。
记忆包改变了这一点。每个 Episode 都是一次观察。每条经验都是一次修正。此后每次包含这些经验的召回,都是一次复合积累。循环由此闭合:
学习:执行任务 → 创建 Skill 并记录 Episode(包括哪些方法有效/失败)
召回:找到匹配的 Skill → 将其 Episodes 作为证据一并提供
应用:模型使用流程和具体经验
反馈:为本次应用记录新的 Episode → 更新 Skill 的置信度
复合:下一次召回拥有更丰富的信息——更多 Episodes、更多经验、更多证据
这就是递归循环。这就是农业阈值。实现它所需的架构已经存在,只差绑定。
这也解释了为什么 Track C 是唯一表现出提升的测试轨道。Track C 的任务属于路由决策:复杂、具有多条可选路径,而且模型必须权衡各种取舍。这类任务恰好最能从情景证据中获益。
如果有人说:“上次我们在类似的路由问题中尝试了路径 A,但它因为 X 而失败;路径 B 则因为 Y 而成功。”这就是实实在在的新信息。模型无法从自身权重中推导出这些信息。它们是特定于系统、特定于运行过程、特定于结果的信息。
即使没有 Episodes,当前的 Brain 也能帮助 Track C,因为这些任务足够困难,任何额外上下文——哪怕只是模糊的抽象 Skill——都能提供有用的脚手架。但想象一下配备记忆包的 Track C:模型将同时获得抽象模式和此前路由决策的具体结果。
Tracks A、B、D 和 E 没有提升,是因为模型在这些测试上的得分已经达到 9.3+/10。它不需要帮助。无论提供多少记忆——程序性记忆、情景记忆或其他任何记忆——都无法把 9.5/10 的回答提升为 10/10。任务还不够难,不需要依赖累积知识。
这并不是记忆系统的失败,而是一个边界条件。当任务超出单次推理能力时,记忆才会有所帮助。如果没有记忆时模型已经接近完美,记忆就不会带来帮助。
这里我想谨慎一些,因为我以前曾因自己的判断超前于证据而吃过亏。
我并没有声称记忆包一定会带来大幅提升。我的主张是,当前系统存储的记忆过于贫乏,无法发挥作用,而我现在已经理解了更丰富的记忆应该是什么样子。
我并没有声称天花板效应是唯一的问题。成对比较与评分标准之间的结果存在分歧——前者为 62%,后者仅提升了 +0.06——这表明位置/长度偏差仍在污染成对比较的结果。无论采用何种记忆架构,这一混杂因素都存在。
我并没有声称这是一个新想法。认知科学家几十年来一直在研究记忆绑定。可能称得上新颖的地方,是将这一概念应用于智能体记忆系统;在这类系统中,默认假设似乎通常是单一类型的记忆——一般是 RAG 风格的文档检索——就已足够。
我也不会假装社区反馈没有影响我的思考。当 TechPulse Lab 写道,情景记忆和组织记忆比程序性记忆更重要时,他们描述的正是我最终发现的缺口。当 Nova Elvaris 指出 Skill 只能增长、永远不会衰减时,这实际上反映了失败情景的缺失。当 Kuro 说记忆维护比存储更重要时,他讨论的是绑定质量,而不是存储数量。
直到数据迫使我深入审视,我才理解他们想告诉我什么。
所需的代码变更出乎意料地小。Episode 系统已经构建完成,episode.py、episode_store.py、episode_recall.py 都已是生产就绪的,带有测试。需要的是:
绑定:在 Skill 中添加 episode_ids[],在 Episode 中添加 skill_id。当 brain.learn() 触发时,它会创建两者并将它们链接。
统一检索:当 brain.recall() 找到匹配的技能时,它会自动获取关联的 episodes。提示模板同时包含抽象过程和具体教训。
转移评分:Episode 质量成为转移分数的一个组成部分。具有成功 episodes 的技能评分更高。
反馈循环:brain.feedback() 为当前应用记录新的 episode,因此技能的证据库随时间增长。
然后重新运行基准测试。特别是在 Track C 难度的任务上,模型实际需要帮助的地方。
我不会承诺这次数字会不同。我之前错过了,现在已经两次了,根据我自己的基准测试衡量,为所有人公开发布。但我理解了之前不理解的东西:没有经验的记忆只是一个笔记。有经验的记忆是一个技能。
第一篇文章中的管道隐喻仍然成立。但我在铺设一根管道,而系统需要至少四根,都流入同一个龙头。
所有基准测试数据、脚本和结果都在 OrKa 存储库中公开可用。完整的结果文件包含每个单独的任务响应、评判分数和两两比较。如果你想重新运行分析:
python aggregate_benchmark.py --judge-tag local
如果你曾在 AI 智能体内存系统上工作过,发现过类似的障碍,或找到穿过它们的方法,我真诚地想听听。第一篇文章上的评论比我读过的大多数这个话题的论文都有用。
这是关于构建 OrKa(一个开源的 YAML-first AI 智能体编排框架)的系列文章的一部分。前面的部分:第 1 部分:管道而非哲学。
有些评论可能只对已登录的访问者可见。登录以查看所有评论。
如需进一步操作,您可能需要考虑屏蔽此人和/或举报滥用。