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 包含四步:

  1. Self-play tournament:当前 context population 与 baseline/default-context agent 对战,非对称游戏通过 role swap 降低 first-move bias。

  2. Score calculation / selection:论文使用 TrueSkill,把每个 context 的 skill 表示为 Gaussian ,并用保守下界打分: 时,高不确定性的 context 即使偶然赢了几局也会被惩罚。

  3. Trajectory reflection + memory update:从 completed trajectories 中抽取 typed insights,如 legality constraints、rule clarifications、strategy priors。

  4. 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_promptmemory_system.get_shared_memory() 读取 insights,默认最多随机采样 8 条写入 prompt。

论文公式与 released code 实现差异:论文主文强调 TrueSkill score ;代码确实有 AgentPool.batch_update_trueskillfitness_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 字段聚合进 TrajectoryMemorySystemTrajectoryMemorySystem._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.pushplayed_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 ConceptSource FileKey Class/Function
End-to-end MEMO optimization loopmpr/self_play_prompt_evolution_memory.pySelfPlayPromptEvolution.run_evolution, _update_memory_from_generation, _update_global_memory_from_reflections
Candidate prompt population and evolution operatorsmpr/prompts/prompt_evolution_engine.pyPromptEvolutionEngine.create_initial_population, evolve_generation, _generate_random_prompt, _generate_memory_guided_prompt
Tournament executionmpr/tournament/tournament.pyTournament.run_generation
Ranking and TrueSkill/win-rate fitnessmpr/tournament/agent_pool.pyAgentPool.batch_update_trueskill, get_ranked_agents, AgentPerformance.win_rate
Trajectory reflection and memory bankmpr/memory/trajectory_memory_system.pyTrajectoryMemorySystem.process_trajectory_folder, _apply_memory_operations_with_logging, MemoryEnhancedAgent._use_simple_memory
XML-style memory CRUDmpr/memory/xml_crud_operations.pyXMLCRUDParser.parse_operations, apply_operations
Prioritized replaympr/replaybuffer/replaybuffer.pyReplayBuffer.push, sample_prioritized, sample_strategic_states
Actual launch scripts / task configsscripts/tests_latest/*.sh, scripts/run_example.sh, scripts/run_quick_test.shshell 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-miniQwen2.5-7B-Instruct;held-out opponent/evaluation models 包括 Grok-4-Fast-Non-ReasoningGemini-2.5-Flash-LiteQwen3-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=5TOURNAMENT_ROUNDS=25EVAL_ROUNDS=25POPULATION_SIZE=8USE_REPLAY=trueBETA=0.4REPLAY_TOPK=10MAX_GAMES_PER_AGENT_REFLECTION="20"TEMPERATURE=1.0INSIGHT_SAMPLING_MODE="sample"SelfPlayPromptEvolution.__init__ 中 replay defaults 为 buffer_capacity=100000alpha=0.6beta=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 modelMethodSimpleNegotiationTwoDollarKuhnPokerBriscolaSimpleTakMean Win RateMean RSE
GPT-4o-minibaseline31.3%32.2%39.1%0.3%21.4%25.1%44.9%
GPT-4o-miniMEMO54.9%52.4%55.6%42.7%41.8%49.5%6.4%
Qwen2.5-7B-Instructbaseline24.0%17.1%45.3%2.8%15.1%20.9%30.1%
Qwen2.5-7B-InstructMEMO48.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

OptimizerSimpleNegotiationKuhnPokerSimpleTakAvg. output tokens
TextGrad842986938922
MIPRO145,864162,084754,534354,161
GEPA110,325119,365111,907113,865
MEMO87,36494,16089,15290,575

MEMO 的 token cost 约为 MIPRO 的四分之一,也比 GEPA 低约 20%。TextGrad token 极少,但胜率明显不足,说明“少反思”并不能处理复杂多轮行为;MEMO 的优势在于把少量高价值 insight 留在 memory bank 中跨 generation 复用。

5.3 Ablation: retention and exploration are both necessary

TournamentMemoryReplayTwoDollarKuhnPokerBriscolaMean
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%。