通过多Agent哈利波特游戏案例揭示:即使推理正确,上下文记忆管理失效仍会导致Agent频繁失败,关键在于记忆策略设计。
Harry 有完美的推理能力,却有 77% 的失败率
解决了成本问题之后(第一部分),我仍然有一个谜团:Harry 一直在输。
不是因为他不擅长推理,而是当给他正确、相关的上下文时,Harry 在超过 95% 的情况下都能做出最优决策。我通过手工制作完美上下文并喂给模型来测试这一点。每次都是精彩的决策。
但他的游戏胜率只有 23%。从"完美的推理能力"到"实际游戏表现"之间,有什么东西在摧毁他的表现。
我跑了 100 局游戏并追踪每一次失败。每一局都追溯到同一个根本原因:Harry 记住了错误的东西。
不是推理问题。是记忆架构问题。
对抗性记忆压力测试
Horcrux Hunt 不只是一个游戏,它是一个被意外设计出来又被刻意完善的记忆压力测试。它暴露了 Agent 管理上下文的每一个弱点,因为它有一个主动篡改记忆的思考型对手。
在 50 回合内追踪 15 个地点的概率
每个观察提供一个信号(正向、负向,或"已被摧毁,但那是诱饵!")
从被植入来浪费他行动的诱饵中区分真正的魂器
每回合降低不确定性,同时伏地魔在反击
伏地魔的反记忆策略:
游戏中途重新放置魂器 → Harry 的旧信号变成谎言
在高频概率地点植入诱饵 → 注入虚假置信度
在 Harry 锁定后重新放置 → 最大化浪费的行动
每回合 Harry 越接近就增加不确定性
这个游戏本质上是场熵的竞赛——Harry 在降低不确定性,伏地魔在增加它。

这和你的客服 Agent 面临的问题一样(用户改变意图),和你的代码 Agent 面临的问题一样(仓库状态变化),或你的研究 Agent 面临的问题一样(新证据与旧结论矛盾)。Horcrux Hunt 只是把对手显式化了。
四种记忆失败模式
我观察到的每一种失败都属于四类之一。

发生了什么:Harry 基于第 12 回合的正向信号高置信度地攻击了霍格沃茨。但伏地魔在第 24 回合重新放置了魂器。Harry 在第 25 回合攻击,没找到东西,浪费了一次宝贵的行动。
根本原因:第 12 回合的正向信号已经过时了 13 回合。伏地魔的重新放置使其失效。Harry 的推理是完美的("攻击最高概率地点")。但他的记忆在骗他。
发生了什么:Harry 重新搜索了一个他已经确认空的地点。第 8 回合存在的负向信号在他的上下文中,但被随后 4,800 个 token 的历史埋没了。
根本原因:相关信息存在但功能上不可见。在 6,000 个 token 的上下文中,模型的注意力找不到 40 回合前一个关键的 20-token 信号。信号在那里。但 Harry 在噪音中找不到它。
发生了什么:到第 40 回合,Harry 的上下文有 6,000 个 token。生成需要 25 秒。Lambda 在 30 秒时超时。游戏崩溃。Harry 默认输了。
根本原因:太多记忆了。上下文窗口变成了负担,不是因为信息错了,而是携带所有这些信息在物理上太慢了。
发生了什么:第 3 回合的一个关键正向信号在第 40 回合时仍然有效(伏地魔没有重新放置那个特定的魂器)。但 Harry 在随后 37 回合的噪音中找不到它。他搜索了其他地方,错过了一个轻松的胜利。
根本原因:重要的早期观察被最近但不太重要的观察淹没了。没有时间加权。没有相关性评分。只有原始的时间顺序上下文。
模式:每一种失败都是伪装成推理失败的记忆架构问题。LLM 的推理没问题。它接收到的信息是错的、过时的、不完整的或压倒性的。
记忆税:伏地魔最好的武器
上下文窗口不是固定费用。它们是复利税,伏地魔无情地利用这一点:
每回合伏地魔篡改(重新放置、诱饵)都会在 Harry 的上下文中添加实际上是误导的 token。Harry 为携带谎言付出代价。游戏越久,Harry 为处理越来越腐败的记忆付出的代价越多。
这是"快速失败、免费失败"视角下的记忆:Harry 不需要的每个 token 都是一次微失败,在处理不帮助或主动伤害他决策的信息上浪费钱。
记忆即熵管理
改变一切的洞察:记忆架构就是熵管理。
香农熵测量不确定性。在 15 个等概率魂器地点下:
H = log₂(15) = 3.9 bits(最大不确定性)
Harry 的任务:每次观察应该降低熵(将概率集中到更少的地点)。伏地魔的任务:每次行动应该注入熵(将概率散开)。
第 1 回合:H = 3.9 bits(均匀分布,什么都不知道)
第 10 回合:H ≈ 2.8 bits(在收窄,排除了部分地点)
第 30 回合:H ≈ 1.4 bits(置信度高,2-3 个可能地点)
第 50 回合:H ≈ 0.6 bits(几乎确定,准备攻击)
但伏地魔在反击:
第 25 回合:Harry 在 H = 1.8 bits(越来越近!)
第 26 回合:伏地魔重新放置 → Harry 在 H = 2.5 bits(挫折!)
第 27 回合:伏地魔植入诱饵 → Harry 在 H = 2.9 bits(更退后了!)
记忆问题变成了:Harry 应该携带什么进入上下文以尽可能快地最小化熵?答案是:不是 50 回合的叙事。而是当前概率分布。
三层记忆框架
三层,每层有特定任务,成本截然不同。

第一层:工作记忆(上下文窗口)
Harry 现在看到的。每 token 在每回合都花钱的最昂贵地段。
# Harry 的 LLM 实际接收到的(55 个 token):
AgentContext(
turn=25,
budget_remaining=3,
available_allies=["ron"],
cooldowns={"dumbledore": 2},
belief_map={"Hogwarts": 0.34, "Azkaban": 0.22, "Ministry": 0.18},
entropy=1.4,
last_signal="negative @ Godrics Hollow"
)
规则:只有这个决策需要的。没有历史。没有可推导的。没有冗余。
第二层:检索记忆(计算层)
概率在这里计算,熵在这里追踪,信号在这里处理。这一层在 LLM 之外做重活。
class HorcruxBeliefMap:
def update(self, location, signal, turn):
if signal == "positive":
self.beliefs[location] *= 3.0
elif signal == "negative":
self.beliefs[location] *= 0.1
elif signal == "destroyed":
self.beliefs[location] = 0.0
# 衰减旧信念(伏地魔可能已重新放置)
for loc in self.beliefs:
if self.last_updated[loc] < turn - 10:
self.beliefs[loc] *= 0.7 # 不确定性随时间增长
self.normalize()
成本:0 个 token。几微秒的 Python。比让 Claude 推理 50 回合叙事便宜得多。
第三层:持久记忆(事件存储)
完整游戏记录。每个信号、每个行动、每个状态变化。存储在 DynamoDB。永不直接进入上下文窗口。
# DynamoDB 条目 - 便宜、完整、永久
{
"game_id": "horcrux_42",
"turn_log": [...每个事件...], # 5-10 KB
"current_state": {...}, # 最新快照
"belief_history": [...], # 概率随时间变化
"ttl": epoch + 30_days # 自动清理
}
这是"真相来源",如果第二层需要重新计算,它从第三层拉取。但第三层永远、永远不进入 LLM 的上下文。
第三层存储所有内容(¢)
▼ 计算成
第二层产生压缩状态($)
▼ 注入为
第一层只接收需要的($$$)
关键修复:动态上下文压缩
之前(朴素方法,把所有东西都塞进上下文):
第 1 回合:Harry 搜索了霍格沃茨 → 负向
第 2 回合:Harry 搜索了对角巷 → 正向
第 3 回合:Harry 攻击了对角巷 → 诱饵!
第 4 回合:伏地魔重新放置...
第 5 回合:Harry 在阿兹卡班使用罗恩 → 正向
...(50 回合 = 2,000+ token 的叙事)
Harry 的 LLM 读取所有这些。花费 $0.015。耗时 8 秒。而且一半信号都是过时的(从那之后伏地魔已经重新放置了)。
之后(压缩后,只有当前信念):
# 55 个 token。$0.0002。<1 秒。
"魂器可能在:霍格沃茨(34%)、阿兹卡班(22%)、魔法部(18%)。
熵:1.4 bits(中等置信度)。剩余行动次数:3。
罗恩在 2 回合后可用。最后信号:Godric's Hollow 负向。"

97% 压缩率:2,000+ token → 55 token。
为什么有损压缩是有效的:信念图是一个充分统计量。如果霍格沃茨有 p=0.34,那它来自第 3 回合的正向信号还是 20 回合内没有负向信号都不重要。概率编码了所有决策相关信息。
Harry 用 55 个专注的 token 比用 6,000 个嘈杂的 token 做更好的决策。更少的上下文 = 更少的噪音 = 更少的干扰 = 更好的信噪比。
熵门控检索:记忆的快速失败、免费失败
不是每个 Harry 的决策都值得相同的记忆投入。熵告诉你哪些决策是困难的:
def harry_decide(game_state, belief_map):
entropy = calculate_entropy(belief_map)
if entropy < 1.0: # 低不确定性,Harry 很自信
# 不需要 LLM。启发式:攻击最高目标。
return HeuristicDecision(belief_map.top_target()) # 0 token,$0
elif entropy < 2.5: # 中等不确定性,有些模糊
# 压缩的信念图足够作为上下文
context = compress_to_55_tokens(belief_map) # 55 token
return llm_decide(context)
else: # 高不确定性,真的很难
# 值得投入:更丰富的检索
context = build_full_context(belief_map, recent_signals) # 200-500 token
return llm_decide(context)

这是记忆检索的"快速失败、免费失败"。当熵低时,Harry 已经知道该做什么,花 200 个 token 去确认一个显而易见的决策是浪费。熵检查在它产生任何成本之前捕获那种浪费:
35% 的 Harry 决策花费零 token。熵门控在计时器开始之前就捕获了"我不需要考虑这个"。
ε-贪婪探索:即使熵低,10% 的情况下 Harry 探索一个非最高目标地点。这防止了隧道视野,这对被能够利用可预测行为的伏地魔至关重要。
同一个 Harry。同一个伏地魔。同一个 Claude 3 Sonnet。同样的 50 回合游戏。截然不同的记忆架构:
减少幻觉是最令人满意的:有了 5,000 个 token,Harry 有更多材料可以捏造("我记得在...有一个正向信号")。有了 55 个干净的 token,没什么可以幻觉的。
而且 Harry 赢得更多,因为伏地魔的记忆篡改策略不再有效。重新放置魂器只有在 Harry 携带过时信号时才会伤害他。有了自动衰减旧信念的贝叶斯图,重新放置会被数学地计入。伏地魔无法篡改数学。
五个记忆设计原则(从 Horcrux Hunt 学到)
LLM 应该消费记忆,而不是产生记忆。贝叶斯图计算信念。LLM 接收结果。伏地魔无法像篡改叙事那样篡改数学。
匹配记忆深度到决策难度。用熵门控你的检索。简单的决策不值得昂贵的上下文。快速失败,免费失败。
在边界压缩,而不是在 LLM 内部压缩。从 2,000 token 压缩到 55 token 发生在确定性 Python 中,而不是通过 LLM 摘要(后者花费 token 并可能产生幻觉)。
丰富持久化,选择性检索,最小化呈现。DynamoDB 存储一切。第二层计算重要的。第一层只显示需要的。
更少的上下文 = 更好的决策。Harry 用 55 个专注的 token 比用 6,000 个嘈杂的 token 表现更好。信噪比 > 信号量。永远。
Harry 输不是因为他不擅长推理。他输是因为他记住了错误的东西。
修复记忆。推理随之而来。
每个不必要的上下文 token 都是在该记忆层应用"快速失败、免费失败"的失败。在开始思考之前检查是否需要思考。在检索之前门控。最便宜的记忆是你从不加载的记忆。
💬 快速记忆测试给你的 Agent:
让你的 Agent 通过相同的多次任务运行 5–10 次。
然后故意引入它在几回合前被告知的东西。
🧠 记得正确?→ 你的记忆架构可能在正常工作。 🔄 有时记得?→ 你可能有检索或上下文选择问题。 ❌ 遗忘、矛盾或重复自己?→ 你的 Agent 可能根本没有推理问题。它可能有记忆问题。 🤷 从未测试过?→ 现在你知道该测试什么了。
在评论区留下你的 Agent 最奇怪的"我明明告诉过你这个"或"我从来没说过那个"的时刻。👇 我会告诉你可能面对的是哪种记忆失败模式。
如果你想关注 Horcrux Hunt 生产 saga,
→ 阅读这篇博客了解更多"快速失败、免费失败"流程:第 0 部分:快速失败、免费失败
→ 接下来:第三部分:当 Harry 的工具背叛他。我们看到记忆是固定的。成本是固定的。但当我添加工具(搜索咒语、盟友能力、预兆神器)时,Harry 开始调用错误的工具。60% 的工具交互失败了,不是因为 Harry 不能推理该用哪个工具,而是因为工具本身有歧义的描述。*
我是一名生成式 AI 开发者布道者兼架构师。我构建了一个多 Agent AI 游戏来娱乐会议观众,却意外创造了有史以来最昂贵的多 Agent 系统压力测试。这个游戏教会我,AI 最难的问题不是推理。所以我改编了经典的"故障安全",想出了"快速失败、免费失败",因为这一切都是关于在正确的时间记住正确的事情。