MEMO: Memory-Augmented Model Context Optimization for Robust Multi-Turn Multi-Agent LLM Games
Paper: arXiv:2603.09022 Code: openverse-ai/MEMO Code reference:
main@0685102c(2026-05-10)
1. Motivation (研究动机)
多轮、多智能体 LLM game evaluation 的核心问题不是“模型能否在单轮题目上答对”,而是:一次回答会成为下一轮输入,早期小偏差会沿着 trajectory 被放大;多个 agent 互相响应时,一个 agent 的不稳定输出还会改变另一个 agent 的 best response。因此,用单一 prompt 跑一次 tournament 得到的 win rate 容易带有很高 run-to-run variance,模型排序也会随 prompt 变体而改变。
这篇论文要解决的具体目标是:在不更新模型权重、不依赖外部 reward model 的前提下,把 inference-time context(system prompt + injected memory)当成可优化对象,让 agent 在多轮自博弈中把可复用的策略经验留下来,并在后续 tournament 中继续利用这些经验,从而同时提高 mean win rate 和 ranking stability。
这个问题值得研究有两个原因。第一,game-based benchmark 覆盖 negotiation、imperfect information、planning 等真实交互能力,比静态 QA 更接近 agentic deployment;如果评估本身不稳定,就无法可靠比较模型或优化方法。第二,RL/self-play 虽然能学习策略,但通常要更新权重、消耗大量 environment interactions;MEMO 试图证明仅靠 context optimization 和 memory retention,也能在 2,000 self-play games/task 的预算内取得接近或超过 prompt optimization baseline 的效果。
Figure 1 解读:左侧展示不同 prompt optimization 方法的 mean win rate 与 stability 权衡,MEMO 同时靠近高胜率、低方差区域;右侧以 KuhnPoker 为例展示 sample efficiency,说明 MEMO 在较少 self-play budget 下能更快达到较高 win rate。这里的关键信息不是单个点数,而是“性能提升”和“run-to-run 稳定性”被同时优化。
2. Idea (核心思想)
核心 insight:多轮游戏中最有价值的监督信号不是一次胜负本身,而是从 completed trajectories 中抽取出的可迁移策略经验;如果这些经验被结构化存入 persistent memory bank,再用于生成和执行后续 contexts,prompt optimization 就不会在每代之间“失忆”。
MEMO 的创新可以概括为 retention + exploration:retention 通过 trajectory reflection 和 memory CRUD 把经验积累到 ;exploration 通过 tournament-based context evolution、TrueSkill/fitness selection 和 prioritized replay 让候选 context 接触更多 rare/decisive states。最终优化对象不是模型参数 ,而是 context :prompt 加上从 memory bank 采样出的 memory subset 。
与 TextGrad/MIPRO/GEPA 等 prompt-only optimization 的根本差异是:这些方法主要把当前 trajectory feedback 转化为下一版 prompt,信息容易随 prompt revision 被覆盖;MEMO 显式维护跨 generation 的 memory bank。与 SPIRAL/UnstableBaselines 这类 RL 方法的差异是:RL 通过 sparse outcome reward 更新权重,MEMO 只更新 inference-time context,因此交互成本更低,但在 perfect-information games 上也承认 RL 仍可能更强。
Figure 2 解读:图中比较三种学习范式。Self-play prompt optimization 每轮生成/修改 prompt,但历史经验没有持久载体;RL 把胜负信号压进模型权重,样本预算更大;MEMO 则在 trajectory 与新游戏之间增加“pattern recognized / insights apply to new games”的 memory path,让策略知识作为 context prior 被复用。
3. Method (方法)
3.1 Problem formalization: context as policy interface
论文把任务形式化为 two-player turn-based zero-sum partially observable Markov game 。动作 是完整模型回复,观测由 给出,terminal reward 为 。一条 trajectory 写作 ,Player 0 的结局为 。
MEMO 把 context 定义为: 其中 是 game-start instruction/system prompt, 是 inference-time 注入的 memory。 不来自参数更新,而是从 persistent memory bank 中采样的结构化 insight subset。因此,MEMO 优化的是“agent 看到什么上下文”,而不是“模型本身学到了什么权重”。
Full-context evaluation 用 次独立 pipeline run 产生 ,每个最终 context 在固定 game suite 与 opponent pool 上评估。稳定性指标是 relative standard error: 其中 是第 次 run 的平均 win rate。RSE 越低,说明不同随机 run / prompt variation 得到的 ranking 越稳定。
3.2 Overall framework
Figure 3 解读:左侧从 base prompt 生成 context candidate pool;中间每个 candidate 被放进 self-play tournament,并可从 replay state 开始,以覆盖更多 decisive prefixes;右侧根据游戏结果计算 score、更新 candidate pool,同时把 trajectory reflection 写入 memory bank。memory bank 中的 ADD/UPDATE/DELETE 结果又回流到下一代 context generation,形成跨 generation 的闭环。
一个 generation 包含四步:
-
Self-play tournament:当前 context population 与 baseline/default-context agent 对战,非对称游戏通过 role swap 降低 first-move bias。
-
Score calculation / selection:论文使用 TrueSkill,把每个 context 的 skill 表示为 Gaussian ,并用保守下界打分: 时,高不确定性的 context 即使偶然赢了几局也会被惩罚。
-
Trajectory reflection + memory update:从 completed trajectories 中抽取 typed insights,如 legality constraints、rule clarifications、strategy priors。
-
Context evolution:保留 persistent candidate pool 中的高分 context,再用 random proposal 与 memory-augmented update 填满下一代 population。
直觉上,MEMO 把“赢过的 prompt”与“为什么赢/输的经验”拆开保存:candidate pool 负责保留可执行 context,memory bank 负责保留可组合的策略知识。这样即使某个 prompt 在后续 generation 被淘汰,它贡献出的高质量 insight 仍可继续影响新 prompt。
3.3 Tournament-based context optimization
MEMO 维护 个 candidate contexts。第 代 population 为 ,持久候选池为 。每代 tournament 后, 会从 中保留 top candidates;下一代 由两类 proposal 补齐:
- Random proposals:从固定 style catalog 采样 playstyle(aggressive、defensive、analytical、creative、strategic、adaptive、balanced 等),对 base context 做受限编辑,目标是扩大探索而不破坏 game rules / output schema。
- Memory-augmented updates:从 采样 insights,要求 optimizer LLM 生成 grounded in proven approaches 的新 prompt。
论文的 algorithm 写作:
最终输出:
released code 中,PromptEvolutionEngine.evolve_generation 先从 AgentPool.get_ranked_agents(fitness_method=...) 取排序,再按 keep_ratio/random_ratio/memory_guided_ratio/trajectory_ratio/crossover_ratio 构造新 population。_generate_memory_guided_prompt 从 memory_system.get_shared_memory() 读取 insights,默认最多随机采样 8 条写入 prompt。
论文公式与 released code 实现差异:论文主文强调 TrueSkill score ;代码确实有 AgentPool.batch_update_trueskill 与 fitness_method="trueskill" 路径,但 released task scripts(如 scripts/tests_latest/simplenegotiation.sh, briscola.sh, simpletak.sh)显式设置 FITNESS_METHOD="winrate"。因此,当前仓库的公开复现实验入口更接近 win-rate selection,而非论文公式中的 conservative TrueSkill lower bound。
3.4 Trajectory reflection and persistent memory bank
每代 self-play 完成后,MEMO 从 trajectory 中抽取 insights。输入包括 state/action sequence、final outcome、format errors 等,输出是若干“可复用经验”,例如:何时应该加压下注、何时先试探对手 valuation、哪些 move format 容易非法。
Memory bank 用三类 operation 维护:
- ADD:新 insight 与现有内容不相似,直接加入。
- REMOVE:新旧 insight 冲突,删除以避免误导 agent。
- EDIT:新旧 insight 相似,将其合并、泛化或改写为更 actionable 的版本。
这个设计解决的是 prompt optimization 中的“短期反馈污染”问题:单条 trajectory 可能只反映偶然局面,直接改 prompt 会过拟合;CRUD memory 要求新经验与已有库对齐或冲突检测,能把局部反馈压缩成更稳定的策略 prior。
released code 中,SelfPlayPromptEvolution._update_memory_from_generation 并行处理 generation trajectory file,调用 _extract_game_reflections 收集 reflections,然后 _update_global_memory_from_reflections 把 reflection 的 insight 字段聚合进 TrajectoryMemorySystem。TrajectoryMemorySystem._apply_memory_operations_with_logging 用 LLM 产生 XML-style CRUD operations,再由 XMLCRUDParser 解析和应用。MemoryEnhancedAgent 在 inference 时把 GAME INSIGHTS 拼进 observation/context。
3.5 Prioritized replay: rare state coverage
Memory retention 只能保存已经见过的经验;如果 self-play 总是走向常见 early moves,memory bank 会缺少 rare but decisive states。MEMO 因此加入 replay buffer ,保存 trajectory prefixes、environment seed、played actions、state、next state 等。对每个 prefix ,论文定义 inverse-frequency priority: 采样第 个 prefix 的概率为: 控制稀有 trajectory 的上采样强度, 控制从 replay buffer 初始化游戏而非 fresh start 的概率。replayed trajectory 不要求覆盖完整游戏;它保存 prefix 与 seed,使环境能从过去的关键局面继续展开。
released code 的 ReplayBuffer.push 用 played_actions 的 SHA-256 hash 统计 occurrence count,并把 episode priority 设为 ;sample_prioritized 对 priority 做 次方后用 random.choices(..., weights=probs) 采样。sample_strategic_states 还按 state 的 win/loss variance 与出现次数寻找 interesting states,用于 replay/abstract memory。
3.6 Pseudocode grounded in released code
Tournament + memory optimization loop
def memo_run_evolution(engine, base_prompt, num_generations, tournament_rounds, eval_rounds):
population = engine.prompt_engine.create_initial_population(base_prompt)
agent_pool = AgentPool(prompt_debug=engine.prompt_debug)
for gen in range(num_generations):
if gen > 0:
agent_pool.clear_prompt_agents()
model_names = [engine.model_name] * len(engine.prompt_engine.population)
engine.prompt_engine.setup_agents_in_pool(agent_pool, model_names)
result = engine.tournament.run_generation(
generation_id=gen,
env_id=engine.env_id,
agent_pool=agent_pool,
rounds=tournament_rounds,
phase="evolution",
folder_name=f"gen{gen}",
replay_buffer=engine.replay_buffer,
)
if gen < num_generations - 1:
trajectory_path = engine.output_manager.trajectories_dir / f"gen{gen}_trajectories_gen{gen}_evolution.json"
engine._update_memory_from_generation(gen, agent_pool, str(trajectory_path))
engine.memory_system.current_generation = gen
engine.memory_system._save_current_generation()
best = engine.prompt_engine.get_best_candidate(agent_pool, fitness_method=engine.fitness_method)
engine.evaluate_best_candidate(best, agent_pool, eval_rounds)
engine.prompt_engine.evolve_generation(agent_pool, base_prompt, trajectory_path=str(trajectory_path))
return engine.prompt_engine.get_best_candidate(agent_pool, fitness_method=engine.fitness_method)Memory-guided prompt generation
def generate_memory_guided_prompt(prompt_engine):
shared_memory = prompt_engine.memory_system.get_shared_memory()
if not shared_memory or not shared_memory.get("insights"):
return prompt_engine._generate_random_prompt()
insights = shared_memory["insights"]
if prompt_engine.insight_sampling_mode == "sample":
k = min(8, len(insights))
selected = random.sample(insights, k)
elif prompt_engine.insight_sampling_mode == "single":
selected = [choose_unused_or_reset(insights)]
else:
selected = partition_next_slice(insights, prompt_engine._insight_partitions)
memory_context = "\n".join(f"{i + 1}. {x}" for i, x in enumerate(selected))
prompt = f"""
Generate a creative and strategic prompt for {prompt_engine.env_id}
using insights from shared memory.
KEY INSIGHTS FROM SHARED MEMORY:
{memory_context}
Requirements: incorporate proven patterns, focus on winning strategy,
keep it concise, and preserve move formatting.
"""
return prompt_engine.analyzer(prompt).strip().strip('"')Memory update with CRUD operations
def update_global_memory(memory_system, old_memory, reflections, generation):
new_insights = [r["insight"] for r in reflections if r.get("insight")]
wins = sum(r["result"] == "win" for r in reflections)
losses = sum(r["result"] == "loss" for r in reflections)
draws = sum(r["result"] == "draw" for r in reflections)
new_performance = {
"overall_win_rate": wins / max(1, len(reflections)),
"total_wins": wins,
"total_losses": losses,
"total_draws": draws,
}
critique_prompt = memory_system._build_insight_critique_prompt(
old_insights=old_memory.get("insights", []),
new_insights=new_insights,
memory_merge_style=memory_system.memory_merge_style,
)
llm_response = memory_system.analyzer.analyzer(critique_prompt)
xml_ops = XMLCRUDParser().parse_operations(llm_response)
updated_insights = XMLCRUDParser().apply_operations(old_memory.get("insights", []), xml_ops)
return {
"generation": generation,
"format": "simple",
"insights": updated_insights,
"performance": new_performance,
}Prioritized replay buffer
def replay_push_and_sample(buffer, game_result, batch_size):
for step_idx, step in enumerate(game_result.trajectory[:-1]):
played_actions = [(t["player_id"], t["action"]) for t in game_result.trajectory[: step_idx + 1]]
h = sha256(repr(played_actions).encode("utf-8")).hexdigest()
buffer.occurence_counts[h] = buffer.occurence_counts.get(h, 0) + 1
inv_priority = 1.0 / buffer.occurence_counts[h]
buffer.buffer.append({
"hash": h,
"played_actions": played_actions,
"state": json.dumps(step["state"]),
"next_state": json.dumps(game_result.trajectory[step_idx + 1]["state"]),
"priority": inv_priority,
"seed": game_result.metadata.get("seed"),
})
weights = [episode["priority"] ** buffer.alpha for episode in buffer.buffer]
probs = [w / sum(weights) for w in weights]
return random.choices(list(buffer.buffer), weights=probs, k=batch_size)Ranking / selection path
def rank_candidates(agent_pool, match_results, fitness_method):
if fitness_method == "trueskill":
for match in match_results:
rewards = match["rewards"]
ranks = rewards_to_ranks(rewards) # higher reward gets lower rank id
current = [(agent_pool.performance[a].trueskill_rating,) for a in match["agents"]]
updated = agent_pool.trueskill_env.rate(current, ranks=ranks)
for agent_id, rating_group in zip(match["agents"], updated):
agent_pool.performance[agent_id].trueskill_rating = rating_group[0]
return sorted_by_trueskill_mu(agent_pool.performance)
if fitness_method == "winrate":
return sorted(agent_pool.performance.items(), key=lambda kv: kv[1].win_rate(), reverse=True)3.7 Code-to-paper mapping
Code reference:
main@0685102c(2026-05-10) — pseudocode and mapping based on this commit
| Paper Concept | Source File | Key Class/Function |
|---|---|---|
| End-to-end MEMO optimization loop | mpr/self_play_prompt_evolution_memory.py | SelfPlayPromptEvolution.run_evolution, _update_memory_from_generation, _update_global_memory_from_reflections |
| Candidate prompt population and evolution operators | mpr/prompts/prompt_evolution_engine.py | PromptEvolutionEngine.create_initial_population, evolve_generation, _generate_random_prompt, _generate_memory_guided_prompt |
| Tournament execution | mpr/tournament/tournament.py | Tournament.run_generation |
| Ranking and TrueSkill/win-rate fitness | mpr/tournament/agent_pool.py | AgentPool.batch_update_trueskill, get_ranked_agents, AgentPerformance.win_rate |
| Trajectory reflection and memory bank | mpr/memory/trajectory_memory_system.py | TrajectoryMemorySystem.process_trajectory_folder, _apply_memory_operations_with_logging, MemoryEnhancedAgent._use_simple_memory |
| XML-style memory CRUD | mpr/memory/xml_crud_operations.py | XMLCRUDParser.parse_operations, apply_operations |
| Prioritized replay | mpr/replaybuffer/replaybuffer.py | ReplayBuffer.push, sample_prioritized, sample_strategic_states |
| Actual launch scripts / task configs | scripts/tests_latest/*.sh, scripts/run_example.sh, scripts/run_quick_test.sh | shell variables for model, env, generations, rounds, population, replay, ratios, temperature |
4. Experimental Setup (实验设置)
4.1 Games / datasets
论文使用五个 text-based games,覆盖三类 multi-agent problem:
- Negotiation:SimpleNegotiation;TwoDollar。SimpleNegotiation 是资源交换谈判,玩家通过 offer/counteroffer 最大化 inventory value;TwoDollar 是固定 \2$ 分配谈判,存在 private role pressure 与有限轮次。
- Imperfect Information:KuhnPoker;Briscola。KuhnPoker 是三张牌、单轮下注的简化 poker;Briscola 是 40-card trick-taking game,需要在 trump suit 与手牌价值之间做取舍。
- Perfect Information:SimpleTak。两人 connection game,目标是在棋盘两侧建立连续路径。
规模上,MEMO 的主实验对每个 task 使用 个 candidate contexts、 个 optimization generations、每 generation 每 candidate self-play games,总计 games/task。最终 context 在 held-out opponent pool 上评估:每个 run 对每个 opponent 50 games,并进行三次 independent optimization runs。
4.2 Baselines
- Static prompting:default TextArena baseline prompt、CoT、ToT。
- Prompt optimization:TextGrad、MIPRO、GEPA。
- RL / weight update:UnstableBaselines、SPIRAL。
- Ours:MEMO,只优化 context/memory,不更新 base LLM 权重。
4.3 Evaluation metrics
- Mean win rate:跨 game、opponent、run 的平均胜率;主表按每个 game 和 overall mean 报告。
- RSE:relative standard error,用于衡量 end-to-end optimization run 的稳定性;越低表示 prompt/context 变化下 ranking 更稳。
- Output token cost:prompt optimization 阶段输出 token 数,用于衡量优化方法的 token efficiency。
- Cross-task / cross-model transfer:把一个 source game 学到的 context zero-shot 应用到 target game 或其他 model,观察 context 是否是 game-specific 还是可迁移 scaffold。
4.4 Models, hardware, and hyperparameters
论文报告的 base models 是 GPT-4o-mini 与 Qwen2.5-7B-Instruct;held-out opponent/evaluation models 包括 Grok-4-Fast-Non-Reasoning、Gemini-2.5-Flash-Lite、Qwen3-235B-A22B-Instruct-2507。论文未详细说明 GPU 硬件,因为 prompt/context optimization 主要通过 API / hosted LLM 调用完成,而不是本地梯度训练。
论文主文固定配置:population ,generations ,self-play budget games/task,TrueSkill penalty ,memory initialization fraction ,replay buffer capacity ,priority exponent ,replay gate ,sampling temperature 。
released code 的实际 launch scripts 需要分开看:scripts/tests_latest/simplenegotiation.sh / briscola.sh / simpletak.sh 设置 MODEL="gpt-4o-mini"、BASELINE_MODEL="gpt-4o-mini"、GENERATIONS=5、TOURNAMENT_ROUNDS=25、EVAL_ROUNDS=25、POPULATION_SIZE=8、USE_REPLAY=true、BETA=0.4、REPLAY_TOPK=10、MAX_GAMES_PER_AGENT_REFLECTION="20"、TEMPERATURE=1.0、INSIGHT_SAMPLING_MODE="sample"。SelfPlayPromptEvolution.__init__ 中 replay defaults 为 buffer_capacity=100000、alpha=0.6、beta=0.4,对应论文的 。公开脚本没有在 tests_latest/ 中提供所有五个 paper tasks 的完整一一对应脚本;TwoDollar 未在该目录出现,KuhnPoker 主要见于 scripts/run_example.sh / run_quick_test.sh。
论文公式与 released code 实现差异:论文把 描述为“candidate population 接收 memory initialization 的比例”;公开脚本中相近控制量是 MEMORY_GUIDED_RATIO,且按 task 不同:SimpleNegotiation 为 0.75,Briscola 为 0.65,SimpleTak 为 0.55,quick/example 脚本也不同。因此复现实验时应以具体 shell script 为准,而不能只引用论文主文的统一 。
5. Experimental Results (实验结果)
5.1 Main benchmark results
主结果显示,MEMO 在两个 base model 上都大幅提高平均胜率并降低 RSE。
| Base model | Method | SimpleNegotiation | TwoDollar | KuhnPoker | Briscola | SimpleTak | Mean Win Rate | Mean RSE |
|---|---|---|---|---|---|---|---|---|
| GPT-4o-mini | baseline | 31.3% | 32.2% | 39.1% | 0.3% | 21.4% | 25.1% | 44.9% |
| GPT-4o-mini | MEMO | 54.9% | 52.4% | 55.6% | 42.7% | 41.8% | 49.5% | 6.4% |
| Qwen2.5-7B-Instruct | baseline | 24.0% | 17.1% | 45.3% | 2.8% | 15.1% | 20.9% | 30.1% |
| Qwen2.5-7B-Instruct | MEMO | 48.0% | 48.4% | 60.0% | 31.1% | 34.0% | 44.3% | 6.1% |
对 GPT-4o-mini,MEMO 的 mean win rate 从 25.1% 提到 49.5%,RSE 从 44.9% 降到 6.4%。对 Qwen2.5-7B-Instruct,mean win rate 从 20.9% 提到 44.3%,RSE 从 30.1% 降到 6.1%。这说明 MEMO 的收益不仅是平均性能提升,也包括 end-to-end ranking 的稳定化。
与 prompt optimization baseline 比,GPT-4o-mini 上 MEMO 的 mean win rate 为 49.5%,高于 TextGrad 34.6%、MIPRO 36.7%、GEPA 32.0%;Qwen 上 MEMO 为 44.3%,高于 TextGrad 29.9%、MIPRO 33.4%、GEPA 28.8%。与 RL 比,Qwen 上 UnstableBaseline 在 Briscola 53.3%、SimpleTak 47.3%、mean 45.0% 上仍略强于 MEMO 的 31.1%、34.0%、44.3%,论文据此指出 perfect-information / sparse-reward settings 下 RL 仍可能更有效。
5.2 Token efficiency
| Optimizer | SimpleNegotiation | KuhnPoker | SimpleTak | Avg. output tokens |
|---|---|---|---|---|
| TextGrad | 842 | 986 | 938 | 922 |
| MIPRO | 145,864 | 162,084 | 754,534 | 354,161 |
| GEPA | 110,325 | 119,365 | 111,907 | 113,865 |
| MEMO | 87,364 | 94,160 | 89,152 | 90,575 |
MEMO 的 token cost 约为 MIPRO 的四分之一,也比 GEPA 低约 20%。TextGrad token 极少,但胜率明显不足,说明“少反思”并不能处理复杂多轮行为;MEMO 的优势在于把少量高价值 insight 留在 memory bank 中跨 generation 复用。
5.3 Ablation: retention and exploration are both necessary
| Tournament | Memory | Replay | TwoDollar | KuhnPoker | Briscola | Mean | |
|---|---|---|---|---|---|---|---|
| 32.2% | 39.1% | 0.3% | 23.8% | — | |||
| ✓ | 24.7% | 54.7% | 2.0% | 27.1% | +3.3 | ||
| ✓ | 34.2% | 42.0% | 26.3% | 34.2% | +10.4 | ||
| ✓ | ✓ | 32.0% | 54.2% | 38.7% | 41.6% | +17.8 | |
| ✓ | ✓ | 48.7% | 57.2% | 38.4% | 48.1% | +24.3 | |
| ✓ | ✓ | ✓ | 52.4% | 55.6% | 42.7% | 50.2% | +26.4 |
Ablation 的主要结论是 memory 是最大贡献来源:单独 tournament 只有 +3.3 mean gain,memory-only 有 +10.4;tournament + memory 达到 +24.3;再加 replay 达到 +26.4。也就是说,随机/锦标赛探索本身不足以稳定地产生可迁移策略,必须有 persistent memory 才能跨代积累。

Figure 11 解读:前三个 panel 分别扫 replay buffer size 、priority exponent 、replay gate ,最后一个 panel 扫 memory initialization fraction 。默认点为 、、、。结果显示 buffer 越大越有利, 在 0.3—0.6 附近较稳, 太高会损害 fresh exploration; 也不是越高越好,中间值保留了 memory prior 与无引导探索之间的平衡。
5.4 Generalization and transfer
Cross-task transfer 说明 learned context 不只是 game-specific prompt hack,也包含一些 protocol-level scaffold。例如 GPT-4o-mini context 从 SimpleTak 转到 KuhnPoker 提升 +25.9%,从 TwoDollar 转到 SimpleTak 提升 +26.4%。但 transfer 有方向性:TwoDollar 到 SimpleNegotiation 有 +5.6%,反向只有 -0.2%;Briscola 到 SimpleTak 为 -7.1%,说明结构不对齐时 memory 会成为负迁移。

Figure 4 解读:GPT-4o-mini 学到的 context 转给较弱模型 Grok-4-Fast-Non-Reasoning 时收益更一致;转给 Gemini-2.5-Flash-Lite 时结果更混合。论文解释为:强模型已经有部分策略能力,外部 context prior 可能与自身策略冲突;弱模型更依赖显式 context scaffold。
Figure 5 解读:appendix 中的 KuhnPoker ranking sensitivity 分析固定 environment/evaluator pools,只改变 prompt variants,观察 Kendall 排序相关性。该图支撑论文动机:多智能体游戏评估的模型 ranking 对 prompt/context 很敏感,因此报告单 prompt 的 win rate 可能误导。
5.5 Case analysis: what memory stores

Figure 26 解读:case study 展示 memory insight 如何把局部棋局/谈判局面转化为可复用策略。例如 KuhnPoker insight 强调 aggression 与 hand strength 的平衡,SimpleNegotiation insight 发现对手资源 valuation 不对称,TwoDollar insight 利用有限轮次形成 time pressure。这些不是原始规则复述,而是 self-play 后提炼出的策略 prior。
5.6 Limitations and conclusions
作者给出的边界很清楚:MEMO 在 negotiation 与 imperfect-information games 上收益最大;在 perfect-information settings 中,RL 仍可能更有效,因为权重更新能学习更深的 planning policy。MEMO 也依赖 LLM reflection 的质量;如果 trajectory reflection 产生错误 insight,memory bank 需要通过 REMOVE/EDIT 自我修正,否则可能负迁移。
总体结论是:multi-turn multi-agent LLM games 的性能与稳定性可以通过 context-level memory optimization 显著改善。MEMO 证明 persistent memory bank、structured reflection、tournament selection、prioritized replay 组合后,可以在不更新模型权重的情况下,把 GPT-4o-mini mean win rate 提到 49.5%、Qwen2.5-7B-Instruct 提到 44.3%,并把 RSE 降到约 6%。