Tessl 工程博客:AI 不是笨,是瞎——企业级 Agent 记忆的三个关键设计决策
Your AI isn't stupid. It's blind.
作者基于为跨公司工作的 Agent 构建记忆系统一年的经验指出,AI 失败的常见原因不是模型推理差,而是它看不到关键决策上下文,多数 agent memory 只是给瞎子更大的档案柜。
作者以自建系统的一手实测数据说明为何该把记忆当受治理的记录而非存储,三个设计决策和成本数字可直接迁移。
我们为跨整个公司协作的智能体构建记忆系统时学到了什么
一个智能体即使拥有对 wiki、任务追踪器、CRM 以及三年 Slack 记录的读取权限,仍然不知道一项决策由谁负责。它不知道四份文档中哪一份是当前版本,团队上个季度尝试过什么又放弃了什么,或者它可以向谁重复什么内容。
于是它开始猜测。而且信心十足。
我们通常归咎于模型。这是错误的诊断。模型对一个它从未真正见过的公司推理得很好。真正重要的决策是在某个话题串、某次会议或某条私信中做出的,而没有任何东西以智能体可用的形式将其记录下来。
AI 并不愚蠢。它只是看不见。而我们构建的所谓“智能体记忆”大多并不能解决这个问题。它只是给这种失明配了一个更大的文件柜。
为什么智能体记忆现在很重要
我写软件已经 35 年了,并且维护着 yfinance,它每月大约有 3000 万次下载。过去一年在 VarOps,我一直在为跨整个组织协作的智能体构建记忆系统。上个月我们发布了结果:三个公开基准、一个测试框架,以及保留在其中的负面结果。
今年有两件事发生了变化。
智能体离开了个人开发者的终端。一旦团队共享记忆,它就会继承个人聊天历史从未有过的问题。事实会变化。人们会有分歧。有些人无权看到别人说过的话。
而且开放权重模型已经足够好,可以在我们控制的硬件上完成严肃的工作。这比听起来更重要,因为这意味着公司的知识不必存在于别人的模型里。
常见的错误是把记忆当作存储。保留一切,做嵌入,把最近的片段拉进提示词,然后要求模型好好表现。我称之为检索、塞入、祈祷。它在演示中效果很好。在生产环境中,它会以四种方式出问题。模型会填补片段之间的空白,而没人注意到。旧片段会因为排名更高而胜过新片段。证据会随着上下文窗口消失。访问控制由模型来执行,而模型正是我们试图约束的对象。
在 AI DevCon 上,我会完整讲解这套设计。现在,先说说最重要的三个决策。
1. 存储主张,而不是片段
传统观点认为记忆越多越安全。保留对话记录,之后总能找到答案。
但对话记录不是知识。我们俩都不会记住这篇文章的每一个字。我们会记住它确立了什么。所以我们用同样的方式构建系统。每一条传入的观察都会被提炼成主张。每条主张都说明谁陈述了什么、何时陈述、在什么时间段内为真,以及源文本的哪一段可以证明它。其他所有内容都被有意丢弃。
这听起来有风险。数字却说明并非如此。这种提炼是有意有损的,但在 LongMemEval 这个包含 500 个问题、基于长聊天历史的公开基准上,正确的证据仍然能在 99.8% 的问题中进入前十结果。摄取约 3500 万 token 花费了 8.24 美元,运行在两颗 CPU 上,没有 GPU,并使用免费的本地嵌入模型。
执行提炼的模型也不必是前沿模型。我们用 Gemma 4 这个 310 亿参数的开放权重模型,在一台租来的 GPU 上重建了整份记录。它写下的主张数量与前沿提取器大致相同。答案质量只波动了一到两个点。
蒸馏还让记忆有了一个单一的前门,而这扇门可以说不。在一次基准测试运行中,一个转换 bug 开始输出人类可读的日期,而不是机器可读的时间戳。这扇门隔离了 5,732 条提交,接受了零条。一个普通的存储会把它们全部索引。
2. 让时间和缺失变得明确
传统做法是追加和检索,然后让模型去理清其余部分。
问题就在这里。一条来自三月的片段和一条来自六月的关于同一事实的片段,就只是两条片段。哪条排名更高哪条就胜出。而当检索返回空时,模型无法区分“我们什么都没找到”和“我们根本不追踪这个”,于是它就填补空白。
我们改了两件事。什么都不被覆盖。一个新事实取代一个旧事实,两者都连同日期留在记录中。而每个问题都会归结为一个明确的状态:已回答、已搜索但未找到,或超出系统所知范围。
我们通过移除它来衡量这种拒绝的价值。同一个系统,同样的数据,被指示永远不要说信息缺失。总体得分几乎没有变化,从 88.0 到 87.2。但 30 次诚实的拒绝变成了 30 个编造的答案。只按可回答的问题评分——也就是从不拒绝的系统所采用的报告方式——同样的答案读数为 92.8。下次当某个记忆产品发布一个头条数字却使用不拒绝协议时,值得记住这一点。
3. 在模型运行之前决定权限
大多数团队用两种方式之一处理权限。要么所有人共享一个上下文,要么提示词告诉模型它不能说什么。
第一种意味着系统永远无法持有任何敏感信息。第二种意味着由模型来执行策略。而蒸馏无论如何都会破坏文档级访问控制。一条断言可能由四个来源构建,而这四个来源有四种不同的权限级别。
所以我们先解析身份,在该人的授权下检索,然后才调用模型。模型永远不会收到提问者不被允许看到的内容。披露级别在事实被写入时就确定,而不是在读取时进行删减。
报告中有一个具体的测试。一位财务读者询问一个收入数字,得到 2,140,000。一位销售读者询问同一主题,得到一个 2.0M 到 2.5M 的区间和一个趋势,“上升”。他们的证据中没有一个字节的精确值。而权限范围之下的人无法区分“被隐瞒”和“空”,所以没人能通过缺失的内容来探查秘密。一次跨越五对隔离记忆存储的对抗性探查拒绝或遏制了全部 45 次攻击。
记忆在软件工厂中的位置
软件工厂是智能体、人、工具和上下文作为一条生产线协同工作。大多数工厂设计把上下文当作输入,每次运行都重新喂入。工厂在两次运行之间遗忘,并付出代价去重新发现同样的事情。
同样的缺口存在于每一个编码智能体之下。它读过仓库的每一行,却没读过任何一个决策。为什么那个抽象很奇怪。哪条评审意见被否决了。团队在六月的一个讨论串里达成了什么共识。
记忆是工厂中唯一应该比其中每一个模型都活得更久的部分。当记忆是一份受治理的记录,而不是一堆文本时,模型就变成了我们可以随时更换的座位。把记录保存在我们拥有的硬件上,只租用一个前沿模型来回答,并让它一次只看到一个问题的证据。这在三个基准测试中得到了全前沿结果的 96-99%。完全本地化、不租用任何东西时,它得到了 84-96%。
而一个会记忆的工厂开始注意到重复出现的形态。我们现在正把这些转化为标准流程,并由此进一步转化为狭窄的、专用型智能体或普通代码。这就是接下来的方向。
要点速览
- 把记忆蒸馏为带有证据和时间的断言。把原始记录丢掉。
- 永不覆盖,并标注缺失。诚实的拒绝胜过自信的猜测。
- 在模型运行之前就决定谁能看到什么,而不是在提示词里决定。
模型是我们租来的座位。记忆才是我们拥有的资产,所以我们应该像对待资产一样去构建它。
完整报告、测试框架以及每一道题的结果都已公开:Own the Knowledge, Rent the Thinking(doi.org/10.5281/zenodo.22775192)。我将在 AI DevCon New York 上详细讲解这套设计。
来源:Tessl:产品与工程博客 · tessl.io