合作研究

当智能体的记忆被压成短编码,两个 AI 会不会在同一个错误答案上达成一致?

与 Mohan Bheemadolu · AI 智能体开发者,雷德蒙德 · FlyHash for LLM agent memory 的合著者

半分钟读完

Mohan Bheemadolu 和 Chrisogonas O. Odhiambo 博士写了 FlyHash:一种把 AI 智能体的记忆存成极短二进制编码的方法,灵感来自果蝇的鼻子如何分辨气味。在编码长度相同的情况下,它找到正确记忆的次数大约是常用的 SimHash 的 2.5 倍。这引出了一个我们谁也无法单独回答的问题。智能体常常由第二个 AI 来核查,但两个 AI 读的是同一份检索出来的记忆。如果更小的记忆更常漏掉关键事实,这两个核查者会不会开始在同一个错误答案上达成一致? 用普通记忆做的第一次运行表明有这种可能:当记忆漏掉了证据时,两个 AI 一致同意的答案中有 45% 是错的;而当记忆包含证据时,这个比例是 3%。那只是一个检索器、一个随机种子,所以显示的是关联,而不是因果。Mohan 的计划是在同一个基准上用四种编码长度来测量 FlyHash,并把检索到的记忆发给我们;一致性检查随后就在这些记忆上运行。

这篇论文

一个会记住过往对话的智能体,得把它们存在某个地方,并能快速找到合适的那一段。FlyHash 借鉴了果蝇的嗅觉:它把每条记忆的嵌入向量变成一段简短而稀疏的编码,其中只有少数"活跃位"被打开。编码短,记忆就小。

论文里的结果平实得让人耳目一新。在编码长度相同时,FlyHash 检索到正确记忆的次数大约是 SimHash 的 2.5 倍(0.27 对 0.11)。当记忆空间不紧张时,标准的 HNSW 索引仍然胜过两者,作者也如实写了出来。肯说明自己方法在哪里输掉的论文,比应有的少,这正是我们决定给他们写信的原因。

代码是开放的:github.com/mohanji/flyhash-agent-memory。

交流是怎么展开的

一切始于 Hugging Face 上这篇论文下面的评论。我们问,编码如何应对被改写的、而非模板化的问题。Mohan 回答说,到目前为止的测试用的都是模板化的措辞,并问我们建议用哪个数据集。我们建议了两个由真实的长篇多轮对话构成的数据集:LoCoMo 和 LongMemEval。他决定先从 LoCoMo 开始,再做 LongMemEval。

接着我们问了那个把他的工作和我们的工作连在一起的问题:最短的编码在涉及时间的问题("她是什么时候搬家的?")上,会不会比在单一事实的问题上损失更多?

为什么记忆对互相核查的两个 AI 很重要

来自不同公司的两个模型对一个答案达成一致,通常被当作好兆头。但在智能体里,两个模型往往读的是同一份检索出来的记忆。如果检索漏掉了那个事实,它们就不再相互独立:它们可能信心十足地,在同一个错误答案上取得一致。

为了看看这种情况有多常见,我们在 LoCoMo 上搭了一个小型的公开检查,memory-agreement-check,并用普通的关键词记忆(BM25,取前 10 条对话轮次)跑了一次。GPT 和 Claude 分别作答,Kimi 盲评打分。

63 个里 2 个记忆包含全部证据时,一致的答案中有错的(3%)
33 个里 15 个记忆漏掉了部分证据时,一致的答案中有错的(45%)
40% 对 20%两者同时答错的实测比例,对比错误相互独立时应有的比例

两个模型的错误高度相关(φ = 0.81)。那只是一个检索器、一个随机种子,所以显示的是关联,而不是因果。但它给 FlyHash 提出了一个明确的问题。

我们正在一起做的实验

Mohan 提出由他负责检索这一侧;其余由我们接手。

Mohan 这边 LoCoMo 长对话 FlyHash 和 SimHash 16 · 32 · 64 · 128 位 top-k 记忆 k = 10 和 k = 5,JSONL 格式 我们这边 GPT Claude 分别作答,记忆相同 盲评者 第三家公司 答案 一致且错误, 按编码长度 单跳 多跳 时间类
Mohan 的 FlyHash 构建记忆;与第一次运行相同的检查,用来测量两个 AI 因此在错误答案上达成一致的频率。
  1. Mohan 先测量检索:针对 LoCoMo 的每个类别(单跳、多跳、时间类),在多种 FlyHash 和 SimHash 编码长度(16、32、64 和 128 个活跃位)下测 recall@k,每个问题取前 10 条记忆,与第一次运行一致。
  2. 我们建议再加上前 5 条:记忆条数更少意味着更多漏检,这应该能显示出"信心十足却答错的一致答案"的占比增长得有多快。
  3. 他把检索出来的上下文以 JSONL 发给我们,每个问题一行。
  4. 我们在每个文件上运行一致性检查,并把结果发给他。

最后我们要读出的问题是:随着编码变短,两个 AI 一致同意却答错的占比会不会上升?对涉及时间的问题,是不是上升得最快? 如果是,说明更小的记忆有一种隐藏的代价,第二个 AI 的核查是发现不了的。如果不是,FlyHash 看起来比论文说的还要好。

代码

这个检查可以接收任何检索器的输出。每个问题一行:

{"qid": "conv-26/0", "memories": [{"text": "[D1:3 | 1:56 pm on 8 May, 2023] Caroline: I went to a LGBTQ support group yesterday...", "dia_id": "D1:3", "score": 0.82}]}

仓库里已经有一个示例,用 Mohan 代码中的 FlyHash 和 SimHash 类来生成这些上下文:

git clone https://github.com/mohanji/flyhash-agent-memory
pip install numpy sentence-transformers
python examples/flyhash_contexts.py --flyhash-src flyhash-agent-memory/src \
  --method flyhash --active-bits 32 --out flyhash-k32.jsonl
python -m memcheck run --backend cli --contexts flyhash-k32.jsonl --memory-name flyhash-k32

在多种编码长度下跑同样的问题,或者以 --method dense 作为参照,就能得到对比。

最初的数字能说明什么、不能说明什么

  • 它们来自一个检索器(BM25)、一对模型、一个评判者和一个随机种子,共 200 个问题。换成别的检索器和模型,每个数字都可能变动。
  • BM25 漏掉证据的那些问题与其他问题不同(多跳和开放域的问题漏得多得多),所以比较也在每个类别内部进行。
  • 因果检验需要把同样的问题,在有证据轮次和没有证据轮次的情况下各回答一遍。在多种编码长度下测 FlyHash 是朝这个方向自然的一步:问题相同,模型相同,只有记忆变化。

时间线

  1. Mohan Bheemadolu 和 Chrisogonas O. Odhiambo 在 arXiv(2611.05791)上发布了 FlyHash。
  2. 论文出现在 Hugging Face Papers 上。我们在评论里询问被改写的问题;Mohan 问该用哪个数据集;我们建议了 LoCoMo 和 LongMemEval,他先选了 LoCoMo。
  3. 我们问短编码在涉及时间的问题上是否损失更多。公开检查首次在 200 个 LoCoMo 问题上运行,并附带了一个 FlyHash 示例,我们把数字发给了 Mohan。
  4. Mohan 列出了计划:按类别测量 16、32、64 和 128 位下、k = 10 时的检索召回,上下文以 JSONL 提供。我们同意,并加上 k = 5。

← 所有合作 · 提议一项合作