#JitRL:不用梯度更新,让 LLM Agent 在测试时做“即时强化学习”

论文:Just-In-Time Reinforcement Learning: Continual Learning in LLM Agents Without Gradient Updates

作者:Yibo Li, Zijie Lin, Ailin Deng, Xuan Zhang, Yufei He, Shuo Ji, Tri Cao, Bryan Hooi

时间:v1 2026-01-26;v3 2026-06-08

arXiv:<https://arxiv.org/abs/2601.18510>

代码:<https://github.com/liushiliushi/JitRL>

#0. 一句话先讲清楚

JitRL 想解决的是:LLM Agent 部署之后权重被冻结,怎么在不做梯度更新、不 fine-tune、不跑 PPO/GRPO 的情况下,仍然能从过去任务轨迹中学习,并在当前状态下改变行为策略。

它的做法可以概括成一句话:

把过去 episode 里的 (state, action, return) 存进非参数记忆;当前推理时检索相似状态,估计每个候选动作的 advantage,然后把这个 advantage 直接加到 LLM 输出 logits 上。

形式上就是:

其中:

  • :base LLM 对候选动作 的原始 logit;
  • :从历史相似轨迹里估计出的 advantage;
  • :控制记忆修正力度的温度参数;
  • :修正后的 logit,再 softmax 采样动作。

所以 JitRL 不是“把经验写进 prompt 里让模型读”,而是更接近:

用外部记忆构造一个非参数 critic,在测试时对 policy logits 做 closed-form policy improvement。

这点很有意思,因为它把三个方向接到一起了:

  1. RL 的 advantage-based policy improvement
  2. RAG / memory-based agent 的非参数经验检索
  3. test-time adaptation / continual learning 的无梯度更新版本

#1. 背景:为什么 LLM Agent 需要“部署后继续学习”?

LLM Agent 和普通聊天模型不一样。Agent 要长期和环境交互:

  • 在 WebArena 里点击网页、填表、导航;
  • 在 Jericho 这种文字游戏里输入命令;
  • 在真实软件环境里调用工具、处理错误、完成长程任务。

这类任务天然有一个问题:同一个 agent 会反复遇到类似状态、类似失败、类似局部决策。

比如:

  • 第一次找商品评价时,它可能直觉点击 Catalog,但后来发现评价入口其实在 Marketing
  • 第一次查 subreddit 帖子时,它可能用全局搜索,结果噪声很大;后来发现走 Forums 更稳定;
  • 第一次打开产品库存时,它可能点击 Products,但后来学到 hover 才会直接展开子菜单。

人类员工会从这些失败中学会“这个系统的门道”。但当前 LLM Agent 部署后通常是 frozen model:

  • 权重不变;
  • prompt 可以变;
  • memory 可以增加;
  • 但 policy 本身没有真正被优化。

传统 RL 可以优化 policy,但代价很高:

  • 要收集大量 trajectories;
  • 要训练 value model 或 reward model;
  • 要反复做梯度更新;
  • 容易 catastrophic forgetting;
  • 对线上 agent 来说更新频率和成本都很麻烦。

于是论文问了一个很直接的问题:

能不能保留 RL 的“根据 reward 改变策略”的能力,但不更新模型参数?

JitRL 的答案是:可以。不要把学习写进权重里,而是写进外部记忆和 logits 修正里。


#2. 和普通 memory / Reflexion 方法有什么区别?

很多 Agent 方法已经用了 memory:

  • Memory baseline:把过去完整轨迹塞进上下文;
  • Reflexion:任务结束后生成文字反思,下次放进 prompt;
  • AWM / Voyager 类方法:从成功轨迹里抽取 reusable workflow 或 skill;
  • EvoTest:用进化式策略优化 prompts / tests。

这些方法大多还是 in-context learning:把经验转成文本,让 LLM 自己读懂,然后希望它改变行为。

JitRL 的关键区别是:

方法经验怎么用本质
Memory把历史 transcript 放进 prompt文本上下文增强
Reflexion把失败总结成自然语言反思prompt-level self-improvement
AWM存储成功 workflow程序/流程记忆
JitRL存储 (state, action, return),检索后估计 advantage,直接改 logits非参数 RL / test-time policy improvement

直白说:

  • Reflexion 告诉模型:“上次你错在这里,下次注意”;
  • JitRL 则在动作层面说:“在这个状态附近,click(MARKETING) 历史回报高,click(CATALOG) 回报低,所以现在直接提高前者 logit、压低后者 logit。”

这也是为什么论文强调:JitRL 不是简单检索文本,而是把 memory 当成一个 non-parametric policy distribution / value estimator


#3. 方法总览:JitRL 的循环

JitRL 的整体循环分成两部分。

#3.1 推理时:即时检索、估值、改 logits

每一步 agent 面对当前 observation:

  1. 把原始 observation 抽象成紧凑 state
  2. 从记忆库 中检索 top-k 个相似状态;
  3. 用这些历史 transition 的 return 估计当前 state value
  4. 对每个候选动作估计 action value
  5. 得到 advantage:
  1. 用 advantage 修正 logits:
  1. 从修正后的 softmax 分布里采样动作。

#3.2 episode 结束后:反思打分、更新记忆

一次任务结束后,JitRL 会让一个 LLM evaluator 对完整 trajectory 做 step-wise reward assignment。

假设 trajectory 是:

Evaluator 输出每一步 reward:

然后计算每一步的 discounted return:

最终把每一步 transition 存成:

加入动态记忆库

这就形成了一个持续循环:

做任务 → 得到轨迹 → evaluator 做信用分配 → 存入 memory → 下次相似状态即时检索 → 改变 logits → 得到更好轨迹。

注意这里没有任何 weight update。


#4. 关键细节一:state 怎么表示?

原始 agent 状态通常很脏:

  • WebArena 里可能是巨大的 HTML DOM;
  • Jericho 里可能是冗长的游戏文本;
  • 真实软件环境里可能有大量无关 UI 元素和历史记录。

如果直接拿这些原始文本做检索,相似度会很差。JitRL 的原则是:

不要追求完整复现 observation,而要让“功能等价”的状态映射到相近表示。

例如 WebArena 中,“找商品评论”任务下不同页面 DOM 可能差异很大,但它们的关键状态可能都是:当前在商品管理界面,需要找到 review 入口。

所以 JitRL 会构造 compact structured state,保留任务相关语义,丢掉无关噪声。这个设计非常重要,因为整个方法的 critic 是 retrieval-based:检索质量基本决定 value estimate 质量。

如果 state abstraction 做不好,就会出现两类问题:

  1. 相似状态检索不到,memory 不能复用;
  2. 不相似状态被误检索,错误经验污染当前决策。

这也是 JitRL 最像“非参数 RL”的地方:它不是把世界规律压进神经网络 value function,而是依赖 state representation + nearest-neighbor retrieval。


#5. 关键细节二:怎么估计

记忆库里存的是:

当前状态 来了以后,先检索 top-k 邻居:

#5.1 state value:邻居平均回报

意思是:当前状态附近,历史上平均能拿多少回报。

#5.2 known action 的 Q:同动作邻居平均回报

对某个候选动作 ,找到邻居里也做过这个动作的 subset:

如果这个集合非空:

意思是:在相似状态下,历史上执行这个动作平均效果怎么样。

#5.3 unseen action:乐观探索

如果相似状态里没人做过这个动作,JitRL 不能简单认为它不好,否则 agent 会过早锁死在旧动作里。

所以论文引入 optimism under uncertainty:以概率 给 unseen action 一个探索 bonus:

这里 的含义是:

  • 当前附近经验越少,越应该探索;
  • 经验越多,bonus 越小,逐渐从 exploration 转向 exploitation。

以概率 ,则给 unseen action 中性值 0,避免过度探索。

#5.4 advantage:相对当前状态平均水平的收益

最后:

这一步很关键。JitRL 不直接用 return,而用 advantage,因为它想知道:

在当前状态下,这个动作比“平均动作”好多少?

这正是 policy gradient 里 advantage 的作用。


#6. 关键细节三:为什么“加 logits”是合理的?

这是论文最核心的理论点。

JitRL 把当前推理时的 policy update 写成一个 KL-constrained optimization:

这是什么意思?

  • 第一项:希望新 policy 多选 advantage 高的动作;
  • 第二项:希望新 policy 不要偏离 base LLM 太远,保留语言能力和先验;
  • :控制“相信 memory”还是“相信 base model”。

这个目标的 closed-form 解是:

如果 base LLM 的概率来自 logits:

那么上式等价于:

所以 JitRL 的 logit update 不是拍脑袋 heuristic,而是这个 KL 约束策略优化目标的闭式解。

这点可以理解成:

PPO / GRPO 通过梯度更新参数,间接改变 logits;JitRL 直接在当前候选动作层面,用检索到的 advantage 对 logits 做一次解析形式的 policy improvement。

当然,它优化的是局部候选动作集合,不是整个 token vocabulary 或完整 policy 参数空间。但对 agent action generation 来说,候选动作通常本来就是有限集合,这个近似是实用的。


#7. 算法伪代码:把 JitRL 写成可实现流程

下面是一个简化版:

memory = []  # stores (state, action, return)

for episode in episodes:
    traj = []

    while not done:
        obs = env.observe()
        s = abstract_state(obs)

        # 1. retrieve similar transitions
        neighbors = top_k(memory, key=lambda x: sim(s, x.state))

        # 2. estimate V(s)
        V = mean([x.return_ for x in neighbors])

        # 3. get LLM candidate actions and logits
        candidates, logits = llm.propose_actions(obs)

        # optional: add actions appearing in memory neighbors
        candidates = union(candidates, [x.action for x in neighbors])

        advantages = {}
        for a in candidates:
            same_action = [x for x in neighbors if x.action == a]

            if len(same_action) > 0:
                Q = mean([x.return_ for x in same_action])
            else:
                if random() < lambda_explore:
                    Q = V + alpha / max(len(neighbors), 1)
                else:
                    Q = 0

            advantages[a] = Q - V

        # 4. normalize advantage in practice
        advantages = normalize(advantages)

        # 5. closed-form policy update in logit space
        new_logits = {
            a: logits.get(a, 0.0) + beta * advantages[a]
            for a in candidates
        }

        action = sample_softmax(new_logits)
        traj.append((s, action))
        env.step(action)

    # 6. after episode: evaluator assigns step-wise reward
    rewards = evaluator(traj)
    returns = discounted_returns(rewards, gamma)

    for (s, a), G in zip(traj, returns):
        memory.append((s, a, G))

实现上有几个工程点:

  1. 候选动作可以来自 LLM,也可以把 memory 中出现过的 action 加进来;
  2. memory-only action 没有原始 LLM logit,论文算法里可初始化为 0;
  3. advantage 实际会做归一化,避免 logit 修正过大;
  4. 检索相似度论文里使用了针对 state 的相似函数,例如 Jaccard 类方法;
  5. evaluator 的质量会影响 step-wise reward,从而影响后续 memory。

#8. 实验:WebArena 和 Jericho 上效果如何?

论文主要在两个环境上验证:

  1. WebArena:真实网页导航任务,涉及 Admin、GitLab、Map、Reddit、Shopping 等站点;
  2. Jericho:文字冒险游戏,测试长程文本交互,包括 Library、Zork1、Zork3。

#8.1 WebArena:training-free 方法里明显最强

论文报告 WebArena 平均 success rate:

MethodAvgFinal
Static35.6336.30
Memory41.3643.00
Reflexion41.0842.12
AWM39.3740.32
EvoTest39.2442.49
JitRL46.9851.35

这里 Avg 表示所有 episode 的平均成功率,Final 表示最终阶段成功率。Final 高于 Avg,说明方法确实在持续交互中变强。

按站点看,JitRL 在五类站点上 final success 都是最高:

  • Admin:56.59
  • GitLab:45.00
  • Map:42.19
  • Reddit:61.98
  • Shopping:45.83

特别是 Shopping 上,JitRL 从 Memory 的 33.16、Reflexion 的 31.25 提到 45.83,说明它对复杂 UI 操作和站点经验复用有帮助。

#8.2 和 weight-update 方法 WebRL 比:更便宜,还更高

论文还在 WebArena-Lite held-out test set 上和 SFT、WebRL 比较 final success:

MethodAverage Final
SFT23.00
WebRL46.06
JitRL60.00

这个结果是论文最强的 claim 之一:JitRL 不更新参数,却超过了计算代价更高的 WebRL。

需要谨慎看待的是:不同方法的训练数据、模型配置、评测设置细节会影响公平性。论文附录也做了 identical settings 和 same-backbone controlled comparisons 来补充。但即便如此,JitRL 至少说明一件事:

对很多 agent adaptation 场景,把经验变成可检索的 action-level value signal,可能比直接微调权重更经济、更有效。

#8.3 Jericho:长程文字游戏也有效

Jericho 结果:

MethodLibrary FinalZork1 FinalZork3 Final
Static10100
Memory14251
Reflexion18351
AWM10442
EvoTest26544
GRPO11102
JitRL30695

这里比较有意思的是 GRPO 表现不强。原因可能不是 GRPO 本身弱,而是这类长程、稀疏、环境交互任务上,在线或小规模 RL 很容易遇到:

  • rollout 成本高;
  • credit assignment 难;
  • reward 稀疏;
  • 训练不稳定;
  • 泛化不一定好。

JitRL 用 evaluator 做 step-wise credit assignment,再通过 memory 检索复用局部经验,反而更适配这类“重复尝试、逐渐摸清环境规则”的任务。


#9. 泛化:JitRL 是不是只记住了训练任务?

论文做了两个方向的泛化实验。

#9.1 不同 backbone 上有效

在 Gemini-2.5-flash、GPT-5-mini、DeepSeek-V3.2 上,JitRL 基本都能超过其他 training-free baselines。

这说明它不是依赖某个特定模型内部机制,而是更像一个外接 policy improvement module:只要模型能给候选动作和 logits,就可以接上。

#9.2 cross-task memory 也能迁移

论文模拟 cold-start:当前任务不能检索同任务 memory,只能检索 disjoint tasks 的经验。

WebArena 上 JitRL 仍然优于 baselines:

MethodAdminGitLabMapRedditShopping
Static36.9637.2531.1936.4323.44
Memory47.8337.7533.0350.3926.04
Reflexion46.7434.8031.1948.8431.77
AWM47.2836.2734.8653.4923.44
EvoTest43.4835.7834.8649.6118.75
JitRL48.3738.7335.7855.0436.98

论文还统计了 cross-task memory utilization,平均约 47.03%。这说明 memory 不是只在复用具体答案,而是在复用一些抽象过程知识,例如:

  • 某类站点入口常在特定菜单;
  • 全局搜索不如局部导航稳定;
  • hover / dropdown / filter 等 UI 操作模式;
  • 长程游戏里某类动作顺序的价值。

这点对 Agent 很重要,因为真实世界任务很少完全重复,但局部结构会重复。


#10. 机制案例:JitRL 怎么纠正 base model 的错误先验?

论文给了几个 qualitative cases。

#10.1 找 customer reviews

Base model 觉得 Catalog 看起来很像入口:

  • click(CATALOG) base logit 0.90;
  • click(MARKETING) base logit 0.70。

但 memory 发现历史上 review 在 Marketing 下,所以修正后:

  • click(CATALOG) 降到 0.40;
  • click(MARKETING) 升到 1.40。

这就是典型的“语义直觉错了,环境经验纠正直觉”。

#10.2 找 subreddit posts

Base model 倾向全局搜索:

  • fill(Search, "..") base logit 0.95;
  • click(Forums) base logit 0.80。

但 memory 发现全局搜索噪声大,走 Forums 更稳定:

  • 搜索动作降到 0.45;
  • Forums 升到 1.80。

#10.3 产品库存页面

Base model 认为应该点击 Products:

  • click(Products) base logit 0.95;
  • hover(Products) base logit 0.40。

但 memory 发现 hover 可以直接展开子类:

  • click 降到 -0.28;
  • hover 升到 0.90。

这些例子很好地说明了 JitRL 的定位:

LLM 的语义先验负责提出合理动作;环境 memory 负责纠正那些“看起来合理但在这个系统里不对”的动作。

这对真实 agent 很关键,因为很多错误不是语言理解错误,而是环境 affordance 错误。


#11. 成本:为什么它比 RL 便宜?

传统 RL 的成本主要来自:

  1. 大量 rollout;
  2. reward / value 估计;
  3. 梯度反传;
  4. 多轮参数更新;
  5. 可能还要保存、部署新 checkpoint。

JitRL 避免了参数训练,只增加:

  • episode 后 evaluator 的调用成本;
  • memory 存储和检索成本;
  • 推理时候选动作 logits 修正成本。

论文声称相对 expensive fine-tuning methods 成本降低超过 30 倍。

更本质地说,JitRL 把“学习成本”从 parameter update 转移到了 memory update + retrieval-time computation

路径学到哪里成本形态风险
PPO/GRPO/WebRL模型权重训练成本高遗忘、部署复杂
Reflexionprompt 文字token 成本随上下文增长经验利用不稳定
JitRL外部 transition memory检索 + evaluator 成本检索质量和 reward 质量依赖强

这也是它对长期 agent 系统有吸引力的原因:外部记忆可以持续增长、可删除、可审计、可跨模型迁移,而权重更新更重、更不可控。


#12. 和 wenjun 关心的 model-based RL / 长轨迹 Agent RL 的关系

这篇文章和“直接在超长 agent 轨迹上做 RL 是否可持续”这个问题非常相关。

它隐含的判断是:

对 deployed LLM Agent 来说,很多 adaptation 不一定要通过端到端梯度 RL 写入权重;可以通过外部经验、局部价值估计和测试时策略修正完成。

这和 model-based / memory-based agent learning 有相通处:

  1. 都不满足于纯 prompt engineering:它们都希望 agent 真正利用 reward/return 改变行为;
  2. 都不想每次都重训大模型:学习应该更多发生在外部结构、世界模型、记忆、规划器、critic 上;
  3. 都强调长程轨迹的信用分配:JitRL 用 evaluator 做 step-wise reward,model-based RL 可能用 learned dynamics / value 来做更系统的 credit assignment;
  4. 都适合持续部署场景:agent 在环境中不断积累经验,而不是离线训练一次就结束。

但 JitRL 不是 model-based RL。它没有显式学习环境 dynamics,也不 roll out future states。它更像:

retrieval-based non-parametric actor improvement。

如果放进更大的 Agent RL 图谱里,我会把它放在这个位置:

Prompt / ICL memory
    ↓
Reflexion / workflow memory
    ↓
JitRL: memory as non-parametric critic, logit-level policy improvement
    ↓
Learned value / world model / model-based planning
    ↓
Gradient-based continual RL / self-evolving agent

JitRL 的价值在于:它给了一个很轻的中间层。它比 prompt memory 更 RL,比 full RL 更便宜。


#13. 局限:哪些地方可能会卡住?

#13.1 它高度依赖 state abstraction

如果 state 表示不稳定,检索会失效。真实环境里 UI、DOM、任务描述、用户偏好变化都可能导致相似状态难以匹配。

未来更强的版本可能需要:

  • learned state embedding;
  • task-aware abstraction;
  • hierarchical memory;
  • 把状态拆成 goal、subgoal、UI affordance、history summary 等多粒度表示。

#13.2 evaluator 的 step-wise reward 可能有偏

JitRL 用 LLM evaluator 给每一步打分。这比只用最终 success/fail 更细,但也引入了 evaluator bias。

如果 evaluator 错把某个无关动作评成关键动作,memory 里就会存入错误 return,后续 logits 会被错误修正。

这在长程任务里尤其危险,因为 credit assignment 本来就是难点。

#13.3 它主要优化候选动作,不是生成任意新策略

JitRL 很依赖候选动作集合。如果正确动作从来不在候选集合里,或者 memory-only action 没被检索出来,它就很难凭空创造新行为。

所以它更像“在已有候选动作中重排序和校正”,而不是完整策略搜索。

#13.4 memory 增长后的检索和污染问题

长期运行后,memory 会越来越大,可能出现:

  • 过时经验;
  • 任务分布变化;
  • 相互矛盾的经验;
  • 用户偏好变化;
  • 检索延迟上升;
  • bad trajectory 污染好策略。

因此真实部署需要 memory management:

  • aging / decay;
  • confidence weighting;
  • source tracking;
  • task clustering;
  • failure memory 和 success memory 分开;
  • 对高影响动作设置安全约束。

#13.5 logit access 不是所有 API 都方便提供

JitRL 需要候选动作 logits。很多闭源聊天 API 不直接暴露完整 logits,或者只暴露 top-logprobs。

实际落地可能要做近似:

  • 让模型先生成候选动作列表;
  • 用 logprob API 估计每个候选动作概率;
  • 或者在本地 open-weight model 上实现更完整的 logits modulation。

#14. 我对这篇文章的判断

JitRL 的核心贡献不是“又一个 memory agent baseline”,而是给出了一个很干净的连接:

外部经验记忆 → advantage estimate → KL-constrained policy improvement → logit additive update。

这个链条让 memory-based agent 从“把经验写进 prompt”升级为“把经验作为即时 critic”。

我觉得它最值得关注的点有三个。

#14.1 它提供了一个轻量级 continual learning 接口

不更新权重也能持续改策略,这对部署型 agent 很重要。尤其是在个人助理、浏览器 agent、代码 agent、企业流程 agent 中,很多知识是局部、环境相关、长期积累的,不一定值得写进基础模型权重。

#14.2 它把 RL 的一部分能力拆出来了

传统 RL 里,policy improvement、value estimation、credit assignment、parameter update 常常绑在一起。

JitRL 把它们拆开:

  • credit assignment:LLM evaluator;
  • value estimation:retrieval over memory;
  • policy improvement:closed-form logit update;
  • parameter update:不要。

这套拆法很适合 LLM Agent,因为 agent 的可解释轨迹、文本状态和动作候选本来就比较结构化。

#14.3 它可能是未来“agent 外脑”的一个组件

如果未来 agent 系统有一个外部长期学习层,里面可能包括:

  • episodic memory;
  • semantic memory;
  • procedural memory;
  • value memory;
  • learned world model;
  • user preference model;
  • tool affordance model。

JitRL 可以看作 value memory / procedural memory 的一种简单实现:它记录“在类似状态下,哪个动作带来更高回报”,并在测试时直接改变动作分布。


#15. 总结

JitRL 解决的问题很明确:让 frozen LLM Agent 在部署后持续学习,但不做梯度更新。

它的核心机制也很明确:

  1. episode 结束后,用 evaluator 给 trajectory 做 step-wise reward;
  2. 把每一步存成 (state, action, return)
  3. 当前推理时检索相似状态;
  4. 用历史 return 估计
  5. 根据 KL-constrained policy optimization 的闭式解,把 advantage 加到 logits 上;
  6. 得到一个被历史经验即时修正后的动作分布。

最关键的公式是:

它让 JitRL 成为一种很轻量的 test-time RL:没有反传,没有 checkpoint,没有 catastrophic forgetting,但能利用 reward signal 改变 policy。

如果用一句更偏研究判断的话说:

JitRL 的意义在于,它把 Agent 的持续学习从“更新基础模型权重”转向“维护一个可检索、可解释、可增长的非参数价值记忆”,并用一个有 RL 理论解释的 logit update 把这份记忆接回行动策略。

这未必是长期 agent RL 的终局,但很可能是一个实用中间形态:比 Reflexion 更结构化,比 PPO/GRPO 更轻,比纯 RAG 更像真正的 policy improvement。