ReSum: Unlocking Long-Horizon Search Intelligence via Context Summarization

Paper: arXiv:2509.13313 Code: Alibaba-NLP/DeepResearch Code reference: main @ f72f75d8 (2026-02-27)

1. Motivation(研究动机)

LLM-based web agent 在知识密集型任务上的主要瓶颈,不是“不会搜索”,而是搜索得越久越容易被上下文窗口反噬。经典 ReAct 会把每一轮 <think> / <tool_call> / <tool_response> 都追加到历史中;对于 BrowseComp 这类需要跨实体、多轮核验和长证据链拼接的题目,agent 往往在问题还没收敛前就已经把 32k context 用完,只能截断、失败或在噪声历史中继续盲搜。论文 Figure 2 的统计直接说明了这一点:失败轨迹通常比成功轨迹消耗更多 token,意味着很多 hard case 不是 reasoning 能力本身不够,而是探索被上下文预算过早终止

论文要解决的具体问题是:如何在不改 agent backbone、不引入内嵌 memory token、也不要求从头重训 agent 架构的前提下,让现有 web agent 获得近似“无限探索”的能力。作者将问题界定为一个范式层面的冲突:真实 web search 需要长时探索,但现有 agent 的上下文管理策略基本等同于 append-all-history;因此需要一个能周期性压缩历史、又能让 agent 从压缩状态继续推理的 plug-and-play 机制。这个问题重要有三层原因。

第一,它触及 open-source deep research agent 的现实上限,特别是 BrowseComp、BrowseComp-zh、GAIA 这类 long-horizon benchmark。第二,现有 MEM1、MemAgent 一类方法虽然能缓解 context 问题,但往往依赖 architecture modification 或新增可学习 memory token,迁移到已有 agent 成本高。第三,如果仅通过外部 summary tool 与适配型 RL 就能提升长时搜索性能,那么 context management 就不必和模型结构强绑定,而可以演化成一种更通用的 agent interface。

从任务结构上看,这类题目之所以难,不只是因为需要“多查几个网页”,而是因为问题往往具有延迟可验证性。agent 前几轮搜到的线索通常只是局部事实,例如某个机构的历史名称、某个榜单的年份范围、某位作者与会议的对应关系;这些片段只有在后续和别的实体对齐后,才会变成真正有用的证据。ReAct 的 append-only history 会把这些半成品线索和大量无效页面、失败检索、重复尝试混在一起,导致真正重要的信息密度随轮数上升反而下降。 论文因此把 motivation 进一步从“上下文不够长”推进到“agent state 表示方式不对”。如果 state 仍然是无差别的 token 堆叠,那么无论把窗口从 8k 扩到 32k 还是 128k,hard query 终究会继续撞到上限,而且噪声占比会同步扩大。ReSum 的研究价值就在于,它尝试证明:对于 long-horizon search,更关键的不是无限拉长 memory,而是把 memory 组织成可持续迭代、可在阶段间传递的高密度 reasoning state。

2. Idea(核心思想)

核心 insight 是:把“完整对话历史”替换为“问题 + 面向目标的压缩摘要”作为新的 reasoning state,就可以在不改 ReAct 主循环的情况下解除上下文上限对探索长度的硬约束。 换句话说,ReSum 不是让 agent 永远记住所有 token,而是周期性把“已经找到的确定性证据”蒸馏成一个可重启的 summary state,然后让 agent 从这个 compressed state 继续搜。更进一步,作者意识到“能压缩”并不等于“会使用压缩状态推理”。

因此第二个创新是 ReSum-GRPO:把一次长轨迹在每个 summary 触发点切成多个 segment,并把最终 answer-level reward 归一化成 trajectory-level advantage 后广播给所有 segment。这样训练信号就不再只落到最后一段,而会反向鼓励前面那些“收集了有价值证据、最终被 summary 保留下来”的搜索步骤。它和 MEM1 / MemAgent 的根本差别在于,后者通常通过内嵌 learnable memory slots 或 iterative memory architecture 来解决上下文问题;ReSum 则坚持把“上下文压缩”外置为工具调用,agent 主体仍然是标准 tool-using LLM。

它和简单的 recent-history truncation 也不同:recent-history 只保留最后一段 token,容易丢掉早期关键证据;ReSum 则显式保留“与当前问题强相关的确定性事实和缺口”,因此不是粗暴截断,而是有目标的 context folding。这个思路还有一个容易被忽视的好处:它把“搜索能力”和“记忆管理能力”解耦了。ReAct agent 原本已经学会了什么时候调用搜索、什么时候阅读页面、什么时候产出答案;ReSum 不去推翻这套行为策略,而是只在状态即将膨胀失控时插入一个 summary operator。

这样做使得方法对现有 agent stack 的侵入性很低,也解释了为什么作者强调它是 training-free plug-and-play,并能在不同规模 web agent 上直接套用。

换个角度说,ReSum 的核心思想并不是“让模型写摘要”,而是把 summary 重新定义为下一阶段推理的状态接口。一个好的 summary 必须同时满足三件事:足够短,能够避开 context ceiling;足够准,不把未证实猜测混入 state;足够可执行,让后续 agent 能据此决定“下一步还缺什么、该去哪里查”。论文后续专门训练 ReSumTool-30B,以及用 ReSum-GRPO 让 agent 适应 summary-conditioned rollout,本质上都是在为这个 state interface 服务。

3. Method(方法)

3.1 整体框架:从 ReAct 到 ReSum

Figure 1 解读:左侧 ReAct 把每一轮思考、工具调用和返回结果全量堆进 history,所以 context 会单调增长,最终在多轮探索尚未完成时耗尽。右侧 ReSum 在接近上限时调用 summary tool,把已有历史压缩成一个紧凑 summary,再用“原始问题 + summary”重建上下文并继续搜索。图里最关键的不是“加了个 summary 框”,而是这个 summary 把 agent state 从原始 token 序列重参数化成了更短的 goal-oriented evidence state。

ReSum 的 rollout 起点与 ReAct 完全一致。给定 query ,agent 在第 轮从历史 生成 thought 和 action 环境执行工具并返回 observation ,历史更新为: 当 compression trigger 触发时,summary tool 基于当前历史生成压缩摘要: 然后把状态重写成: 这一步的直觉很重要:ReSum 不要求 summary 去“代替”agent 推理,而是要求它把历史中可确定的关键证据、尚未解决的信息缺口、以及下一步搜索方向以高密度状态保存下来。这样 agent 在重新启动时,面对的不是无序长记录,而是一个被人为提高了信息密度的 working memory。 从系统视角看,ReSum 等于在传统 ReAct 循环外再包一层“周期性状态折叠”。原始 history 是 execution trace,适合回放单步决策;summary state 则更像 task-level scratchpad,适合跨阶段延续问题求解。作者的设计并没有试图保留每个网页片段,而是默认大量中间 token 对未来决策并不重要,真正需要保存的是已经核实的 facts、事实之间的关系、以及尚未闭环的验证路径。 这也解释了为什么 ReSum 能自然兼容更长 context 的 backbone。即便模型上下文本来就比 32k 更长,只要任务 horizon 继续增加,append-only history 仍会遭遇同样的边际收益递减;而 summary-based state reset 会把“有限窗口”问题改写成“阶段性压缩是否足够保真”的问题。论文把这点作为范式贡献,而不只是一次工程 patch。

3.2 Summary trigger 与 compressed-state reasoning

论文实现中,summary trigger 采用的是规则触发而非 agent 自主触发:当上下文接近窗口上限时调用 ReSumTool-30B。附录 D.1 明确说明,作者选择这种 systematic trigger 是为了获得更稳定、可预测的行为;当前 agent 自主判断“何时该 fold context”往往本身就是更难的元策略问题。

released code 与论文在这里是一致的:WebAgent/WebResummer/src/react_agent.py 中,should_summarize = ((RESUM and token_count >= max_tokens * 0.9) or round % summary_iteration == 0) and num_llm_calls_available,即默认当 token 数达到 MAX_CONTEXT * 1024 - 1000 的 90% 时触发总结,也支持基于 summary_iteration 的固定轮次触发。

run_resum.sh 中默认开启 export RESUM=True,而 MAX_CONTEXTMAX_LLM_CALL_PER_RUN 作为环境变量可覆盖,说明训练外推理主路径确实是“接近 context limit 时压缩”,不是论文里未落地的理想化描述。这一步为什么有效?因为 long-horizon web search 的关键不是保留所有访问痕迹,而是保证“还没解完的问题在下一段推理里仍然带着关键证据和未解约束”。如果 summary 只做 surface-level abstract,agent 会丢链;如果 summary 精确保留人名、时间、机构、比较结果和缺失环节,后续搜索就能像接力一样继续推进。

作者在 prompt 层面对摘要内容施加的约束,本质上是在控制 compressed state 的信息分布。对 web search 来说,最危险的失败模式不是“漏掉一句修饰语”,而是把错误实体关系或未经核验的猜测写进 summary,因为这会把后续所有搜索带偏。于是 ReSumTool 的目标不是生成一段流畅概述,而是提炼出可继续行动的证据账本:哪些事实已经确认、哪些候选答案被排除、接下来还需验证哪个环节。

last_summary 再喂回新一轮 summary 也很关键。它意味着 ReSum 不是每次从零压缩最近窗口,而是在做逐轮的 summary refinement。这样旧摘要中的长期关键信息不会因为当前窗口切换而消失,而新的 observation 只是在原有 compressed state 上增量更新。对于跨多实体、跨多跳关系的查询,这种“滚动折叠”比单次截断式摘要更接近真正可持续的 working memory。

3.3 ReSumTool-30B:面向 web search 的专用摘要器

论文没有把 summary model 当成 generic chat model,而是专门训练了 ReSumTool-30B。原因是普通 LLM 在长搜索轨迹上容易把噪声、猜测和关键证据混在一起,而 ReSum 需要的是只保留确定信息、避免幻觉、还能暗示下一步方向的摘要器。

作者采用三阶段管线:

  1. Teacher selection:附录 E.1 比较后选用 GPT-OSS-120B 作为 teacher,因为 reasoning-enhanced model 在 evidence synthesis 和 source attribution 上强于 instruction-only model。
  2. Data synthesis:让 WebSailor 负责 explorer,teacher 负责 summary tool,在 SailorFog-QA 上执行 ReSum rollout,收集超过 9K 个 Conversation, Summary pair。
  3. Development / distillation:用这些 pair 对 Qwen3-30B-A3B-Thinking 做 SFT,得到 ReSumTool-30B。

附录 C 给出的 summary prompt 非常克制,强调三件事:只提取与问题直接相关的信息;不允许猜测;输出结构化 <summary>。released code WebAgent/WebResummer/src/summary_utils.py 也与论文一致:summarize_conversation 会将 questionrecent_history_messages,以及可选的 last_summary 填入 QUERY_SUMMARY_PROMPTQUERY_SUMMARY_PROMPT_LAST,然后调用 call_resum_server() 访问 RESUM_TOOL_URL。其中返回值会被强制规整到 <summary> ... </summary> 格式。这说明 ReSum 实际上依赖的是一个外部、可替换、可单独升级的 summarization service。

Figure 6 解读:这组定性案例用相同问题比较 ReSumTool-30B 与基线摘要器生成的 summary。重点不只是“写得更像总结”,而是 ReSumTool-30B 更稳定地保留关键 deadline、CCF rank、conference identity 这些真正决定后续搜索方向的事实。对于 ReSum 范式来说,summary 质量直接决定 compressed state 是否足够可用,因此专门训练 summary tool 不是锦上添花,而是系统成立的前提。

3.4 ReSum-GRPO:对 summary-conditioned reasoning 做范式适配

问题:summary 切断长轨迹

训练难点在于:一旦发生 summary,整条长轨迹就被切断成多个 segment,最后 reward 只在最终 answer 上出现。若仍按普通 ReAct-GRPO 训练,前面那些“为后续 summary 提供证据”的步骤很难得到信用分配。作者因此提出 ReSum-GRPO。

segmented trajectory 形式化

完整 ReSum trajectory 若经历了 次 summary,可自然分成 个 segment: 其中第 次 summary 后的压缩输入写作:

trajectory-level reward 与 advantage

每个 segment 都是一个独立训练 episode,但最终只根据最后答案 计算 trajectory-level reward 。然后在同一 GRPO group 内做归一化,得到: 再把同一个 广播给这条 rollout 里的所有 segment:

Figure 3:advantage broadcast

Figure 3 解读:图中最重要的是“segmented trajectories + advantage broadcast”。一次 rollout 会因为 summary 被切成多段,reward model 只看最后答案 correctness,但 group computation 产出的 advantage 会广播回所有 segment。这样早期搜索步骤只有在最终答案正确时才一起受益,因此学习到的是“哪些早期检索与摘要值得长期保留”,而不是局部贪心式的短视搜索。

直觉:summary 是 credit assignment 中继器

这种设计背后的直觉是:summary 不是单独模块,而是长期 credit assignment 的中继器。早期一轮 search 也许并不能立刻带来答案,但如果它找到的证据最终被 summary 吸收,并在后续 segment 中解开问题,那么它应当获得正向奖励。ReSum-GRPO 正是在 reward 级别把“对 summary 有贡献的历史行为”重新连接起来。如果没有这一步适配,training-free ReSum 虽然能让 agent“走得更远”,却未必让 agent“更会在 summary 之后继续推理”。

与标准 RL 的差异

因为标准 RL 会默认 episode 内 token 是连续的,而 ReSum 打破了这种连续性:segment 边界前后的文本表面上断开了,但语义上又由 summary 串联。ReSum-GRPO 的作用,就是把这种新型状态转移明确纳入训练目标,让 policy 学会把 summary 视为可依赖的中间状态,而不是把它当作信息损失。从 credit assignment 角度,advantage broadcasting 其实在回答一个很具体的问题:当最终答案正确时,应把多少功劳分给“早期找到线索的人”?作者选择的答案非常直接,即在同一 trajectory 内让所有 segment 共享同一个归一化 advantage。

训练信号的取舍

它牺牲了更细粒度的 step-level 归因,但换来稳定、低复杂度、与 GRPO 兼容的训练信号。这也是论文强调 1K training samples 仍能带来明显提升的原因之一,因为方法没有引入昂贵的额外 value decomposition 或复杂 hindsight relabeling。进一步看,ReSum-GRPO 的训练范式也暗示了一个判断:summary quality 与 policy adaptation 是相互依赖的。summary tool 再强,如果 agent 不会读取 summary 中的“未解约束”并据此规划下一步,压缩仍然只能起到省 token 的作用;

反过来,policy 再强,如果 summary 丢掉决定性证据,也无法在后续 segment 恢复。论文把 ReSumTool-30B 和 ReSum-GRPO 分开设计,实际上对应了这两个耦合子问题:先保证 state 可用,再保证 policy 会用。

论文在方法层面的另一个重要判断,是把 ReSum 明确限定为search-time state management primitive,而不是通用 memory benchmark 上的抽象记忆模块。这一点体现在它的所有接口设计都围绕 web agent 任务展开:summary 输入是工具调用后的 conversation trace,而不是任意长文档;summary 输出强调与当前 query 的相关性,而不是对全局历史做均匀压缩;训练收益也通过 answer correctness 回传,而不是独立优化摘要本身的语言质量。这样的方法定位让 ReSum 更像是 deep research workflow 中的“状态压缩器”。

这个定位还带来一个工程上的优势:它允许不同角色模型各司其职。主 agent 负责检索、阅读、决策;summary tool 负责 evidence compression;judge model 负责 answer evaluation。论文没有追求单模型包揽全部能力,而是将 system decomposition 作为设计前提。对于 today 的 open-source agent stack,这通常比强行把所有功能塞进一个 backbone 更现实,因为每个子能力都能按自己的数据与目标单独优化。

如果把 ReSum 放到更广义的 agent memory 文献中,它的独特点在于:memory 并不是一个持续增长的外部数据库,也不是固定长度的 latent slot,而是一个可反复重写、与当前目标强耦合的文本状态。这使它既保留了文本 memory 易于解释和调试的优点,又避免了全量 history 的线性膨胀。作者借助这一点,把“长时探索”从模型结构问题转成了状态接口问题,这也是本文最值得记住的方法论贡献。

这一方法还有一个隐含前提:summary 必须足够结构化,才能在多次重写后保持语义稳定。若每次摘要都只是自由改写,agent 可能在第 3 次、第 4 次 fold 后逐渐偏离原问题。论文通过固定 prompt、强调事实性约束、并把旧 summary 作为输入的一部分,实际上是在给 compressed state 建立一种弱形式的“状态不变量”。 因此,ReSum 的 method 不能只理解成“压缩 token”。更准确地说,它是在设计一个能跨多段 rollout 持续传递任务关键信息的 textual state machine:state 如何生成、何时重写、如何被下游 policy 消费、以及 reward 如何跨 state rewrite 回流,四个环节共同构成了本文的方法闭环。

3.5 伪代码:按 released code 重建关键组件

下面的伪代码不是照抄论文算法框,而是结合 WebAgent/WebResummer/src/main.pyreact_agent.pysummary_utils.pyrun_resum.sh 的真实控制流整理。

def run_resum_rollout(agent, question, max_llm_calls=60, max_context_k=32):
    messages = [
        {"role": "system", "content": agent.system_message},
        {"role": "user", "content": question},
    ]
    full_trajectory = list(messages)
    last_summary = None
    remaining_calls = max_llm_calls
 
    while remaining_calls > 0:
        remaining_calls -= 1
        content = agent.call_server(messages)
        content = strip_partial_tool_response(content)
        messages.append({"role": "assistant", "content": content})
        full_trajectory.append({"role": "assistant", "content": content})
 
        if has_tool_call(content):
            tool_name, tool_args = parse_tool_call(content)
            result = agent._call_tool(tool_name, tool_args)
            tool_msg = {"role": "user", "content": f"<tool_response>{result}</tool_response>"}
            messages.append(tool_msg)
            full_trajectory.append(tool_msg)
        elif has_answer(content):
            return extract_answer(content), full_trajectory
 
        token_count = agent.count_tokens(messages)
        threshold = (max_context_k * 1024 - 1000) * 0.9
        if token_count >= threshold and remaining_calls > 0:
            recent_messages = messages[2:].copy()
            summary = summarize_conversation(question, recent_messages, last_summary)
            if summary:
                last_summary = summary
                new_user_msg = {
                    "role": "user",
                    "content": build_summary_conditioned_query(question, summary),
                }
                messages = [messages[0], new_user_msg]
                full_trajectory.append({"role": "assistant", "content": summary})
 
    return "[Failed]", full_trajectory
def summarize_conversation(question, recent_history_messages, last_summary=None):
    recent_history_str = "\n".join(str(msg) for msg in recent_history_messages)
    if last_summary is None:
        prompt = QUERY_SUMMARY_PROMPT \
            .replace("{{{question}}}", question) \
            .replace("{{{recent_history_messages}}}", recent_history_str)
    else:
        prompt = QUERY_SUMMARY_PROMPT_LAST \
            .replace("{{{question}}}", question) \
            .replace("{{{last_summary}}}", last_summary) \
            .replace("{{{recent_history_messages}}}", recent_history_str)
    return call_resum_server(prompt)
def run_resum_grpo_conceptually(segments, group_rewards):
    rewards = torch.tensor(group_rewards, dtype=torch.float32)
    advantages = (rewards - rewards.mean()) / (rewards.std() + 1e-6)
 
    losses = []
    for traj_idx, traj_segments in enumerate(segments):
        traj_adv = advantages[traj_idx]
        for seg in traj_segments:
            logprob_new = policy_logprob(seg)
            logprob_old = old_policy_logprob(seg)
            ratio = torch.exp(logprob_new - logprob_old)
            clipped = torch.clamp(ratio, 1 - eps, 1 + eps)
            loss = -torch.min(ratio * traj_adv, clipped * traj_adv).mean()
            losses.append(loss)
    return torch.stack(losses).mean()

3.6 Code-to-paper mapping 与 paper-vs-code 对照

Code reference: main @ f72f75d8 (2026-02-27) — pseudocode and mapping based on this commit

Paper ConceptSource FileKey Class/Function说明
ReSum rollout entryWebAgent/WebResummer/src/main.pyMultiTurnReactAgent, ProcessPoolExecutor, argument parser负责读取 benchmark、并行 rollout、写出 iter*.jsonl
ReAct / ReSum 主循环WebAgent/WebResummer/src/react_agent.pyMultiTurnReactAgent._run()统一处理 <tool_call><tool_response><answer>,并在高 token 占用时触发 summary
Context triggerWebAgent/WebResummer/src/react_agent.pyshould_summarize依据 token_count >= 0.9 * (MAX_CONTEXT * 1024 - 1000)round % summary_iteration == 0 触发
Summary tool 调用WebAgent/WebResummer/src/summary_utils.pysummarize_conversation(), call_resum_server()将 recent history / last summary 填入 prompt,调用外部 ReSum tool 服务
Summary promptWebAgent/WebResummer/src/prompt.pyQUERY_SUMMARY_PROMPT, QUERY_SUMMARY_PROMPT_LAST对齐附录 C,强调只保留确定且与问题直接相关的信息
ReSum 推理部署WebAgent/WebResummer/src/run_resum.shenv vars + vllm serve同时启动 infer model、visit summary model、ReSum tool;设置 RESUM=True
ReAct baseline 推理WebAgent/WebResummer/src/run_react.shbaseline launcher不启动 ReSum tool,形成 training-free ReAct 基线
Judge-based evaluationWebAgent/WebResummer/src/evaluate.pycall_llm_judge(), process_one_prediction()qwen2.5-72b-instruct 对 open-ended answer 做 correctness judging

论文公式与 released code 实现差异:论文 §3.1 将 summarization 触发描述为“approaching the context limit”的系统策略;released code 在此基础上额外支持 round % summary_iteration == 0 的固定轮次触发分支,因此代码实现比论文正文更宽松,但默认主路径仍是基于 token limit 的触发。除此之外,在可见 released code 范围内,summary prompt、external summary service、compressed-state restart 与论文描述一致。需要注意的是,公开仓库主要覆盖 inference 与评测实现,ReSum-GRPO 的训练代码并未在同一模块中公开,因此 advantage broadcasting 的精确训练实现无法逐行对照,相关处只能依据论文与 README 描述。

4. Experimental Setup(实验设置)

4.1 Datasets

  • BrowseComp:英文长时搜索 benchmark,论文在主实验中报告 Pass@1 / Pass@3
  • BrowseComp-zh:中文对应版本。
  • GAIA:开放式 assistant benchmark,用于验证 ReSum 对更一般 agent task 的迁移性。
  • SailorFog-QA:主要用于 ReSumTool-30B 的数据构建;作者记录 ReSum trajectory 并让 teacher summary tool 生成高质量 summary,构成超过 9KConversation, Summary 对。

论文在 released repo 的 WebAgent/WebResummer/README.md 中还给出示例评测数据文件名:browsecomp_en.jsonlbrowsecomp_zh.jsonlgaia.jsonl。README 还补充了一个 headline 结果:ReSum-GRPO 训练后的 WebSailor-30B-A3B 在 BrowseComp-zh 上达到 33.3% Pass@1,在 BrowseComp-en 上达到 18.3% Pass@1

4.2 Baselines

  • ReAct:append-all-history 的标准 agent 推理范式。
  • Recent History:上下文溢出时只保留最近 22k token。
  • MEM1:用固定大小 memory 迭代替换历史,作为结构化 memory baseline。
  • GRPO:基于 ReAct rollout 的标准 RL 训练。
  • MEM1-GRPO:在 MEM1 rollout 上做 GRPO。
  • ReSum-GRPO:本文提出的 summary-conditioned RL 适配算法。

4.3 Evaluation metrics

  • Pass@1 / Pass@3:主 benchmark 上的 answer correctness。
  • LLM-as-a-Judge:附录 G 说明作者采用 Qwen2.5-72B-Instruct 判断开放式回答是否语义正确;用于替代过于苛刻的 exact match。
  • Reward curves / training reward:比较 GRPO、MEM1-GRPO、ReSum-GRPO 的训练收敛行为。
  • Resource metrics:平均 token consumption、tool calls、单个 gradient step 的训练时间。

4.4 Training config

这里必须区分论文报告的训练配置released code 实际公开的可核验配置。公开仓库 Alibaba-NLP/DeepResearchWebAgent/WebResummer/ 模块主要放出了 inference / evaluation 代码,没有同步公开 ReSum-GRPO 的完整训练 launch script 或 experiment config。因此:

  • ReSum-GRPO 训练直接相关的 1K samples / batch 64 / G=8 / lr 2e-6 / 4 epochs、以及 GRPO 40 tool calls / ReSum-GRPO 60 tool calls / 32k budget,只能视为论文附录 D.2 报告值
  • 与 released code 可以逐项核对的,则是 run_resum.shrun_react.shreact_agent.py 中的推理与部署配置

论文附录报告的训练配置

  • ReSumTool-30B SFT:base model Qwen3-30B-A3B-Thinking,数据量 >9K 对,batch size 64,epochs 2,learning rate 7e-6
  • RL shared hyper-parameters:training samples 1K,batch size 64,group size 8,learning rate 2e-6,epochs 4
  • RL algorithm-specific:GRPO 最多 40 次 tool calls,ReSum-GRPO 最多 60 次 tool calls;前者 2k query + 30k response,后者 4k query + 28k response

released code 中可核验的实际推理/部署配置

  • WebAgent/WebResummer/src/run_resum.sh:infer model 在 port 6001,visit summary model 在 port 8001,ReSum tool 在 port 6002
  • run_resum.sh:GPU 分配为 infer model 0,1,2,3,summary model 4,5,ReSum tool 6,7
  • WebAgent/WebResummer/src/react_agent.pyMAX_LLM_CALL_PER_RUN 缺省值为 60
  • react_agent.pyMAX_CONTEXT 缺省值为 32k

因此,本节把“论文附录提供的训练数字”和“代码公开可核验的推理配置”分开陈述,避免把未公开训练脚本误写成已在 released code 中核对过的事实。

5. Experimental Results(实验结果)

5.1 Training-free ReSum 相比 ReAct 的收益

论文主结论之一是:即便不做训练,只把范式从 ReAct 切到 ReSum,也能获得明显收益。摘要和 README 都给出一个总体结论:training-free ReSum 相比 ReAct 平均提升约 4.5%。这说明仅靠 context summarization 就足以让 agent 把原本会被截断的长问题继续做完。

Figure 7a 解读:这张图比较了不同范式在性能与 token 成本之间的关系。ReSum 相比 ReAct 会增加少量 token 开销,因为 summary 本身也是额外调用;但收益来自它把原本失败的长轨迹变成可继续探索的轨迹,因此单位 token 带来的有效探索深度更高。图中更值得关注的是 ReSum-GRPO 点进一步右移却也显著上移,说明训练后 agent 更愿意主动依赖 summary 维持长时搜索。

5.2 ReSum-GRPO 的增益与代表性数字

论文摘要给出最紧凑的 headline 数字:ReSum 在 training-free 设定下比 ReAct 再提升 4.5%,而 ReSum-GRPO 在此基础上进一步带来 8.2% 的增益。README 进一步给出代表性结果:只用 1K 个训练样本,WebSailor-30B-A3B 就能在 BrowseComp-zh 达到 33.3% Pass@1,在 BrowseComp-en 达到 18.3% Pass@1,并超过多个开源 research agent。

附录正文中还给出一个更细的例子:在 WebSailor-3B 上,ReSum-GRPO 可把 BrowseComp-zh 的 Pass@1 从 8.2% 拉到 20.5%。这说明 summary-conditioned reasoning 的范式适配对小模型尤其关键,因为它们更难在原始长历史中稳定维持高质量推理。

Figure 4 解读:训练 reward 曲线显示 ReSum-GRPO 整体高于普通 GRPO。论文的解释很合理:ReSum 避免了许多“本来会因超长 context 被迫提前终止”的轨迹,因此训练时能从更长的探索路径收集有效 credit。随着训练推进,agent 不只是学会“更会搜”,而是学会“在 summary state 下怎么继续搜”。

5.3 与 MEM1 的比较:效果相近但成本更低

作者并不声称 ReSum 永远优于 MEM1。相反,论文相当诚实地指出:在某些 benchmark 上 MEM1-GRPO 的 Pass@1 可能略高,例如 BrowseComp 上比 ReSum 再多约 1.2%。但附录 F.3 同时强调,这一边际提升对应的是接近 的 token 开销。换句话说,MEM1 在精度上可能略占优,但其 iterative memory architecture 的成本更高。

Figure 8 解读:三组图把 GAIA、BrowseComp-zh、BrowseComp 上的“平均成功轨迹 token 消耗”与 Pass@1 放在一起比较。MEM1 / MEM1-GRPO 的点明显向右,表明每成功解一个样本需要更多 token;ReSum-GRPO 在更靠左的位置达到相近甚至更高的成功率。作者据此主张 ReSum 的实用价值在于更好的 efficiency-performance balance,尤其适合资源受限部署。

5.4 Context limit 扩展实验与 summary tool 价值

论文 Table 3 研究了更长 context 模型上 ReSum 是否仍有价值。对 Tongyi-DeepResearch-30B-A3B,作者在 32k / 48k / 64k / 96k / 128k 五个 context limit 下比较 ReAct 与 ReSum,发现即便在更大上下文窗口下,ReSum 多数情况下仍然更强:

  • BrowseComp-zh / 32k:ReAct 41.2 / 57.4,ReSum 43.8 / 62.3
  • BrowseComp / 32k:ReAct 27.7 / 43.1,ReSum 34.5 / 53.3
  • BrowseComp-zh / 64k:ReAct 43.6 / 60.9,ReSum 48.6 / 66.1
  • BrowseComp / 64k:ReAct 36.3 / 52.4,ReSum 40.3 / 57.8
  • BrowseComp-zh / 128k:ReAct 45.7 / 62.3,ReSum 46.6 / 62.6
  • BrowseComp / 128k:ReAct 42.2 / 59.2,ReSum 44.5 / 59.5

这组数字很有启发性:ReSum 的价值不是只在“小 context 模型”上成立,而是在更长窗口下仍能通过结构化压缩提升 history 的信息密度。也就是说,更长 context 并不会自然消除 long-horizon search 的噪声累积问题。

5.5 Training efficiency、inference cost 与局限性

附录 F.1 给出单步训练耗时:

  • WebSailor-3B:GRPO 0.62h,ReSum-GRPO 1.05h
  • WebSailor-7B:GRPO 0.96h,ReSum-GRPO 1.44h
  • WebSailor-30B:GRPO 0.94h,ReSum-GRPO 1.25h

因此 ReSum-GRPO 相比 GRPO 会带来约 33% 到 69% 的训练时间增长。作者认为这是可接受的,因为它换来了显著更高的可学习轨迹长度与最终性能。

方法的局限也很明确:

  • ReSum 仍然依赖一个足够强的 summary tool;如果 summary model 质量差,压缩状态可能丢关键证据。
  • 公开仓库主要放出了 inference / evaluation 实现,ReSum-GRPO 的训练代码没有在同一模块中完整公开,因此训练细节的可复现实证仍不如推理链路充分。
  • 规则触发虽然稳定,但离“agent 自主决定何时 fold context”还有距离;这意味着 ReSum 目前更像一个高效的 context manager,而不是 fully RL-driven working memory。

总体上,实验结果证明了一个很关键的结论:长时 web search 的瓶颈不仅是搜索策略,也是上下文表示方式。 ReSum 通过把历史折叠成 summary state,提供了一条比 architecture-level memory 改造更轻量、更可迁移的路径。