AIsaAIsaStudio English 打开 AIsa Studio

Microsoft 与 Hugging Face 发布 ThinkingBox-Training,用数据库终态检查作 RL 奖励训练智能体

原标题:Turning Database Grading into RL Rewards: Post-Training Agents with ThinkingBox

Microsoft 与 Hugging Face 发布 ThinkingBox-Training 开源训练栈,把对智能体留下的数据库终态的可执行检查用作 GRPO 奖励,对 Qwen3.8-27B 做 50 步全参数 RL 微调。在从未进入训练池的 507 任务 ThinkingBox-Bench 上,pass@1 从 51.70% 升至 60.78%,20 次全过的任务从 38 个增至 107 个,每次可靠任务成本从 $24.36 降至 $8.00;pass@20 从 89.35% 微降至 87.97%。方法核心是离线策略相对难度筛选:先用基座策略多次探测候选任务,用 Beta 后验分桶,保留成功率 0.08–0.90 区间的任务以产生有对比度的奖励组;训练池含 187 个任务,在 24 张 H100 上用 token-mean GRPO 训练。数据选择、rollout、奖励和 Ver…

为什么值得看

原文给出把数据库终态检查用作 RL 奖励的完整训练流程和开源栈,读者可以据此复现或在自家智能体任务上迁移这套方法。

阅读原文 ↗10月23日 AI 日报

本页的摘要、推荐理由与解读出自 AIsa Studio 的 AI 风向智能体,原文版权归原作者所有。

深度解读

发生了什么

Microsoft 与 Hugging Face 联合发布 ThinkingBox-Training,并在 GitHub 开源了完整训练栈。这是继首篇博客《The Agent Said It Was Done. The Database Disagreed.》之后的延续工作。核心思路是:把原本用于基准评测的「数据库终态检查」复用为强化学习的奖励信号——智能体完成任务后,对最终数据库状态运行可执行检查,产出 1 或 0 的二值奖励,再据此对 Qwen3.8-27B 做 50 步 GRPO 全参数微调。

结果上,模型在从未参与训练的 507 个基准任务上,平均成功率(pass@1)从 51.70% 提升到 60.78%;更关键的是「20 次全部成功」的任务数从 38 个增至 107 个,接近原来的三倍。

关键细节

  • **任务选择比训练本身更重要。**团队提出「离线策略相对难度」:训练前用基础策略对候选任务反复探测,用 Jeffreys 后验估计成功率,按 0.08/0.40/0.60/0.90 五档分桶。总是失败的和总是成功的任务被丢弃,只保留「有时能解出」的任务——因为 GRPO 中全 0 或全 1 的奖励组无法提供学习信号,混合结果(如 [0,0,0,1,1,1,1,1])才有对比价值。最终训练池含 187 个任务。
  • **奖励与基准同源。**大多数奖励来自确定性的终态检查,少量无法从数据库状态判断的窄项要求才调用 LLM 评判。评测检查的是后端记录对不对,而非具体工具调用,从而鼓励模型发现新解法路径。
  • **可重复性提升有代价。**pass@20(至少解出一次的任务占比)从 89.35% 略降至 87.97%,团队称之为「锐化」:概率质量向可重复的成功轨迹集中,部分低概率路径消失了。分领域看,五个领域的 pass@1 与 20/20 全过数均上升,但零售、旅行、车险的 pass@20 下降。
  • **成本显著下降。**按同等成本测算,单个可靠任务的成本从 $24.36 降至 $8.00(−67.2%),每次成功尝试成本从 $0.177 降至 $0.139。微调后的 27B 模型在可靠任务数上(107)超过 Kimi-K3(68)、接近 GPT-5.4(128),但仍落后于 GPT-6 Astra(231)和 Claude Opus 5.5(241)。

为什么重要

第一篇博客揭示了一个被准确率掩盖的问题:Kimi-K3 至少解出过 93.89% 的任务,但 20 次全部成功的只有 13.41%。对触及生产数据库记录的应用来说,「偶尔能做对」和「每次都做对」是两回事。这项工作证明,数据库终态检查这种确定性、可执行的信号不仅适合作评测,也适合作 RL 奖励,且无需人工标注。文中也坦承迁移声明的局限:训练池与基准共享同一框架、模拟用户机制和类似任务风格。对从业者,作者给出三条可操作建议:训练前先探测任务的难度分布;确保训练与评测对模型输出的解析完全一致;同时报告覆盖率和可重复性两个指标。

对谁有影响

  • 构建触库智能体的工程团队:基准结果表明仅看 pass@1 选型会误判可靠性,20/20 全过数是更贴近生产需求的指标。
  • 做智能体后训练的从业者:开源的训练管线(含数据筛选、rollout、Verl 集成,参考配置为 24 张 H100)可直接复用;文中「零方差组替换 DAPO 式处理」等实现细节有参考价值。
  • 模型选型者:微调后的 Qwen3.8-27B 以更小的体量逼近了部分前沿模型在可靠性维度的表现,但这是基于合成任务集的对比,且成本数字是相对参考值而非账单。
全文翻译

以下翻译只覆盖原文的前一部分,其余内容请看下方原文。

这是我们第一篇博客文章的后续,代理说它完成了。数据库却不同意。 ThinkingBox-Training 现已在 GitHub 上提供。

我们构建 ThinkingBox 是为了通过比较最终数据库状态与预期结果来评估代理的工作。随后,我们在 ThinkingBox-Bench 之外的训练任务中使用了相同类型的可执行信号作为奖励。对于 Qwen3.8-27B,平均成功率从 51.70% 提升至 60.78%,而在 50 步 GRPO 训练后,二十次尝试全部正确完成的任务数从 38 个增加到 107 个。

fig1-hero

图 1. ThinkingBox 将终端数据库状态的可执行检查转化为 ThinkingBox-Bench 之外任务的代理后训练奖励。

这是微软和 Hugging Face 的联合博客文章,特别感谢来自微软的 Mirco Milletari 和 Xiang Jiang、来自 Hugging Face 的 Sergio Paniego 以及我们前实习生朱春(匹兹堡大学)在共同撰写/审阅方面所做的努力。

我们构建 ThinkingBox 是为了捕捉那些声称已完成但实际上并未完成的代理。

ThinkingBox-Bench(我们的基准数据集)中的每个任务都会向代理提供一个真实的后端和一组工具,让代理进行操作,然后检查数据库中实际发生了哪些变化。在第一篇文章中,我们发现一个模型将客户的工单标记为已解决,尽管背后的承运商异常仍处于打开状态。九次看似专业的工具调用,导致了一行错误的数据库记录。

接着我们注意到了自己构建的东西。对于大多数任务,可执行检查可以直接根据最终数据库状态返回 1 或 0。这不仅仅是一个评分器。这可以成为一个奖励函数。

因此,我们从基准测试之外的 ThinkingBox 格式任务中构建了一个训练池,并将它们的可执行结果用作奖励。关键在于选择哪些任务适合代理训练:大多数任务要么对当前模型来说已经解决,要么毫无希望,两者都无法教会模型任何东西。

难度是相对于策略而言的:对于一个任务,只有当当前模型尚未学会它时,它才是困难的。

我们称之为离线策略相对难度。我们在训练开始前使用基础策略对每个任务的成功概率进行了一次估计,并在整个运行过程中保持所选训练池固定不变。

训练后发生了什么

我们利用离线策略相对难度构建训练池,然后对 Qwen3.8-27B 进行了 50 步的 GRPO 微调。回顾一下,我们对 507 个基准任务中的每一个评估 20 次。pass@1 衡量所有 10,140 次尝试的平均成功率。pass@20 衡量至少成功解决一次的任务比例。Observed 20/20 衡量在所有记录的尝试中都通过的任务比例。

表 1. Qwen3.8-27B 在离线选择的训练池上进行 50 步 GRPO 前后的结果。

Metric Base RL fine-tuned Change
Observed 20/20 38 (7.50%) → 107 (21.10%) +69 tasks
pass@1 (successful attempts) 5,242 (51.70%) → 6,163 (60.78%) +9.08 pt
pass@20 (tasks solved at least once) 453 (89.35%) → 446 (87.97%) −7 tasks

训练显著增加了可重复的成功率,同时“至少一次”覆盖率略有下降。博客的其余部分解释了如何选择题练习任务、构建奖励循环以及如何衡量这种权衡。

在一个任务上,这种改进看起来是什么样的? 一位旅客要求降低房间等级,但公司政策要求先获得经理批准。在训练之前,代理在 20 次尝试中有 15 次未经批准就更改了预订并发出了退款。经过 RL 微调后,它在所有 20 次尝试中都保留了预订和支付状态。

fig2-hotel-task

图 2. 一个企业酒店预订任务,每个模型 20 次尝试。基础 Qwen3.8-27B 模型在 15 次尝试中未经必要的经理批准就更改了预订。RL 微调后的模型在所有 20 次尝试中都保留了预订和支付状态;其中 19 次的预期记录完全匹配。

目录

  1. 基准测试在六十秒内发现了什么
  2. 结果:可靠性列发生了变化
  3. 收益落在哪里
  4. 可靠性的代价是什么
  5. 训练循环
  6. 离线策略相对难度
  7. 什么能获得奖励
  8. 运行训练栈
  9. 下一步去向何方

赶时间吗?头条结果在上面。实现细节见运行训练栈。

基准测试在六十秒内发现了什么

ThinkingBox-Bench 根据代理留下的数据库记录对其进行评分。其 507 个任务中的每一个都会启动一个真实后端,向代理提供一组 MCP 工具和具有私有上下文的模拟 LLM 用户,最后在终端数据库状态下运行可执行检查。检查针对的是需要正确的后端记录,而不是特定的工具调用。这激励模型发现可能的新解决方案路径,而不是“重新发现”人类支持的解决方案,后者虽然正确但可能不是最优的。

在我们的第一篇文章中,我们将十八个模型逐一放入该基准测试中,每个模型运行二十次,并报告了 headline accuracy(总体准确率)所掩盖的差距。Kimi-K3 至少一次 解决了 93.89% 的任务,但在所有二十次记录的尝试中仅完成了 507 个任务中的 68 个(13.41%)。Claude Opus 5 则相反:覆盖率较窄,但一致性更高。

更大或更好的模型并没有缩小这一差距。Claude Opus 5.5 在 pass@1 上的得分比 Claude Opus 5 高出 0.66 个百分点,但在所有二十次尝试中通过的任务数量完全相同,均为 241 个。总体准确率的提升并未带来任何额外的可靠性。

如果您正在为涉及生产数据库记录的工作选择模型,不应单独解读 pass@1。Observed 20/20 显示了哪些任务在每次尝试中都成功,这更接近生产可靠性所需的标准。

可执行的终端状态判决同时也是训练奖励。在展开训练循环之前,以下是密封基准测试发生的变化。

结果:可靠性列发生了变化

在对 Qwen3.8-27B 进行训练后,我们在其从未训练过的 507 任务基准测试上评估了选定的第 50 步检查点。这 507 个任务代表了一个分布外(out-of-distribution)测试集:它们的领域、数据库和大多数 MCP 工具在 RL 训练期间均未遇到过。

表 2. 按领域划分的 ThinkingBox-Bench pass@1 (%),包括我们第一篇博客的表 2中选定的模型以及我们针对不同领域的微调模型。Observed 20/20 数字涵盖整个包含 507 个任务的基准测试。每个模型在所有 507 个任务上均进行 20 次重复试验。粗体标记列领导者;下划线标记亚军。

Model Retail Auto insurance Travel Neobank Consulting Overall Observed 20/20
Claude Opus 5.5 80.97 68.40 54.28 71.25 61.58 67.16 241 (47.53%)
Claude Opus 5 80.71 65.80 49.95 70.62 66.19 66.50 241 (47.53%)
GPT-5.4 76.33 62.65 68.12 65.34 54.60 65.36 128 (25.25%)
GPT-5.6 Sol 67.65 65.30 60.34 59.09 57.52 61.91 82 (16.17%)
Qwen3.8-27B RLFT 67.91 56.45 62.69 62.40 54.51 60.78 107 (21.10%)
Claude Sonnet 4.6 72.35 54.40 58.94 56.39 54.31 59.19 102 (20.12%)
GPT-6 Astra 71.73 46.55 55.87 60.87 56.83 58.31 231 (45.56%)
Kimi-K3 82.24 50.80 61.83 41.35 51.63 57.37 68 (13.41%)
Qwen3.8-27B 64.03 47.85 53.41 47.88 45.69 51.70 38 (7.50%)

头条结果是表 1 中的 observed-20/20 行。 一个最初在每次尝试中仅完成 ThinkingBox-Bench 中 38 个(7.5%)任务的 27B 模型,现在在每次尝试中完成 107 个(21.1%)任务,几乎是原来的三倍。作为对比,Kimi-K3 的 observed 20/20 为 68,GPT-5.4 为 128,GPT-6 Astra 为 231,而 Claude Opus 5.5 以 241 领先。

平均成功率和可重复性产生不同的排序。 在表 2 中,我们注意到 GPT-5.6 Sol 在 pass@1 上的得分略高于 RL 微调的 Qwen3.8-27B(61.91% 对 60.78%),但在所有 20 次记录的尝试中通过的任务较少:82 对 107。Claude Sonnet 4.6 在 pass@1 上的得分较低,为 59.19%,但几乎每次都通过了相同数量的任务,即 102 个。单独看任何一个指标都无法捕捉全貌。

观察到的模式与锐化(sharpening)一致:可重复的成功率上升,而“至少一次”覆盖率略微下降。这与 prior work 一致。一种解释是概率分布移向了可重复工作的轨迹,而一些低概率路径消失了。

总体而言,模型并没有变得更广泛。它变得更具可重复性。下一个问题是这些收益落在哪里。

收益落在哪里

fig2-domains

图 3. 领域级别的基础分数、RLFT 分数和百分点变化。绿色变化单元格显示增益,红色单元格显示下降;蓝色阴影表示每个指标内的分数水平。

Pass@1 和 observed 20/20 在所有五个领域均有所上升。Pass@20 表现不一:在新银行和咨询领域有所增加,但在零售、旅行和汽车保险领域有所下降。汽车保险的广度损失最大(−7.0 点),而零售的 observed-20/20 增益最大(+24.5 点)。

可靠性的代价是什么

第一篇文章用简单的数学计算了一致性的成本:将完整 20 次运行活动的估计成本除以模型每次都通过的任务数量。

每个可靠任务的成本 = 507 × 20 活动的估计成本 ÷ 通过 20/20 的任务数

将相同的成本数学应用于微调检查点的测量令牌使用情况:

表 3. 基础和 RL 微调的 Qwen3.8-27B 的估计评估成本和可靠性。每次成功尝试的成本通过将总估计活动成本(507 x 20)除以通过尝试的数量来计算。

Measure Base RL fine-tuned Change
Campaign cost, 20 runs $925.80 → $855.58 −7.6%
Cost per successful attempt $0.177 → $0.139 −21.4%
Tasks passing 20/20 38 → 107 2.8× as many
Cost per dependable task $24.36 → $8.00 −67.2%

在每个可靠任务 8.00 美元的情况下,微调模型在伴随比较中接近 GPT-5.4(6.80 美元)、GPT-6 Astra(7.45 美元)和 Claude Opus 5.5(7.80 美元)。

单次尝试视角

图 4 将 每次成功尝试 的成本与 pass@1 进行对比。

[![fig3-cost-frontier](https://cdn-uploads.huggingface.co/production/uploads/64b8491203124195cd795cad/HPq2TNCT8ys

查看原文

This is the follow up to our first blog post, The Agent Said It Was Done. The Database Disagreed. ThinkingBox-Training is now available on GitHub.

We built ThinkingBox to evaluate an agent's work by comparing the final database state with the expected outcome. We then used the same kind of executable signal as a reward on training tasks outside ThinkingBox-Bench. For Qwen3.8-27B, average success rose from 51.70% to 60.78%, while tasks completed correctly on all twenty attempts rose from 38 to 107 with 50 GRPO steps.

fig1-hero

Figure 1. ThinkingBox turns executable checks of terminal database state into rewards for post-training agents on tasks outside ThinkingBox-Bench.

This is a joint blog by Microsoft and Hugging Face, special thanks to Mirco Milletari and Xiang Jiang from Microsoft, Sergio Paniego from Hugging Face and our former intern Zhuochun Li (University of Pittsburgh) for co-authoring/reviewing efforts.

We built ThinkingBox to catch agents that say they are done when they are not.

Each of its 507 tasks in ThinkingBox-Bench (our benchmark dataset) hands an agent a real backend and a set of tools, lets it work, then checks what really changed in the database. In the first post, we caught a model closing a customer's ticket as resolved while the carrier exception behind it was still open. Nine competent-looking tool calls, one wrong database row.

Then we noticed what we had built. For most tasks, an executable check can return 1 or 0 directly from the final database state. That is not just a grader. This can be a reward function.+

So we constructed a training pool from ThinkingBox-format tasks outside the benchmark and used their executable outcomes as rewards. The catch was choosing which tasks are suitable for agent training: most tasks are either already solved or hopeless for the model in front of you, and both teach it nothing.

Difficulty is policy-relative: a task is hard for the current model only until that model learns it.

We call this offline policy-relative difficulty. We estimated each task's success probability once using the base policy before training and kept the selected training pool fixed throughout the run.

What happened after training

We used offline policy-relative difficulty to build the training pool, then fine-tuned Qwen3.8-27B with GRPO for 50 steps. To recap, we evaluate each of the 507 benchmark tasks 20 times. pass@1 measures average success across all 10,140 attempts. pass@20 measures the share of tasks solved at least once. Observed 20/20 measures the share of tasks that pass every recorded attempt.

Table 1. Qwen3.8-27B results before and after 50 steps of GRPO on the offline-selected training pool.

Metric

Base

RL fine-tuned

Change

Observed 20/20

38 (7.50%)

→

107 (21.10%)

+69 tasks

pass@1 (successful attempts)

5,242 (51.70%)

→

6,163 (60.78%)

+9.08 pt

pass@20 (tasks solved at least once)

453 (89.35%)

→

446 (87.97%)

−7 tasks

Training sharply increased repeatable success, with a small decline in at-least-once coverage. The rest of the post explains how we selected practice tasks, built the reward loop, and measured that tradeoff.

What does that improvement look like on one task? A traveler requests a room downgrade, but company policy requires manager approval first. Before training, the agent changed the booking and issued refunds without approval in 15 of 20 attempts. After RL fine-tuning, it preserved the booking and payment state in all 20.

fig2-hotel-task

Figure 2. One corporate hotel-booking task, 20 attempts per model. The base Qwen3.8-27B model changed the booking without required manager approval in 15 attempts. The RL fine-tuned model preserved booking and payment state in all 20; all expected records matched in 19.

Contents

  1. What the benchmark found, in sixty seconds
  2. Results: the dependability column moved
  3. Where the gains landed
  4. What dependability costs
  5. The training loop
  6. Offline policy-relative difficulty
  7. What earns a reward
  8. Run the training stack
  9. Where this goes next

In a hurry? The headline result is above. The implementation is in Run the training stack.

What the benchmark found, in sixty seconds

ThinkingBox-Bench grades agents on the database records they leave behind. Each of its 507 tasks starts a real backend, hands the agent a set of MCP tools and a simulated LLM user with private context, and at the end runs executable checks against the terminal database state. Checks are against the backend record that needs to be correct, not the specific tool calls. This incentivizes the model to discover possibly new solution paths rather than “rediscover” the human-backed solution, that might be suboptimal albeit correct.

In our first post we ran eighteen models through that benchmark twenty times each and reported a gap that headline accuracy hides. Kimi-K3 solved 93.89% of tasks at least once but completed only 68 of 507 tasks (13.41%) on all twenty recorded attempts. Claude Opus 5 inverted it: narrower coverage, far more consistency.

And bigger or better model did not close it. Claude Opus 5.5 scored 0.66 percentage points higher than Claude Opus 5 on pass@1, yet passed exactly the same number of tasks, 241, on all twenty attempts. That gain in headline accuracy bought zero additional dependability.

If you are choosing a model for work that touches production database records, pass@1 should not be read alone. Observed 20/20 shows which tasks succeed on every attempt, which is closer to what production reliability requires.

The executable terminal-state verdict was also the training reward. Before unpacking the training loop, here is what changed on the sealed benchmark.

Results: the dependability column moved

After training Qwen3.8-27B, we evaluated the selected step-50 checkpoint on the 507-task benchmark it had never trained on. The 507 tasks represent an out-of-distribution test set: their domains, databases, and most MCP tools were not encountered during RL training.

Table 2. ThinkingBox-Bench pass@1 (%) by domain, for selected models from our first blog's Table 2 and our fine-tuned model for different domains and overall. Observed 20/20 numbers are over the entire benchmark with 507 tasks. Each model is evaluated on all 507 tasks for 20 repeated trials. Bold marks the column leader; underline marks the runner-up.

Model

Retail

Auto insurance

Travel

Neobank

Consulting

Overall

Observed 20/20

Claude Opus 5.5

80.97

68.40

54.28

71.25

61.58

67.16

241 (47.53%)

Claude Opus 5

80.71

65.80

49.95

70.62

66.19

66.50

241 (47.53%)

GPT-5.4

76.33

62.65

68.12

65.34

54.60

65.36

128 (25.25%)

GPT-5.6 Sol

67.65

65.30

60.34

59.09

57.52

61.91

82 (16.17%)

Qwen3.8-27B RLFT

67.91

56.45

62.69

62.40

54.51

60.78

107 (21.10%)

Claude Sonnet 4.6

72.35

54.40

58.94

56.39

54.31

59.19

102 (20.12%)

GPT-6 Astra

71.73

46.55

55.87

60.87

56.83

58.31

231 (45.56%)

Kimi-K3

82.24

50.80

61.83

41.35

51.63

57.37

68 (13.41%)

Qwen3.8-27B

64.03

47.85

53.41

47.88

45.69

51.70

38 (7.50%)

The headline result is the observed-20/20 row in Table 1. A 27B model that initially completed 38 (7.5%) of ThinkingBox-Bench on every attempt now completes 107 (21.1%) on every attempt, almost thrice. For comparison, observed 20/20 for Kimi-K3 is 68, GPT-5.4 with 128, GPT-6 Astra has 231, and Claude Opus 5.5 leads with 241.

Average success and repeatability produce different orderings. In Table 2, we notice that GPT-5.6 Sol scored slightly higher on pass@1 than the RL fine-tuned Qwen3.8-27B (61.91% versus 60.78%) but passed fewer tasks on all 20 recorded attempts: 82 versus 107. Claude Sonnet 4.6 scored lower on pass@1, at 59.19%, yet passed nearly the same number of tasks every time, at 102. Neither metric alone captures the full picture.

The observed pattern is consistent with sharpening: repeatable success rose while at-least-once coverage fell slightly. This is in-line with prior work. One explanation is that probability distribution moved toward trajectories that work repeatedly while some low-probability paths disappeared.

Overall, the model did not become broader. It became more repeatable. The next question is where those gains landed.

Where the gains landed

fig2-domains

Figure 3. Domain-level base scores, RLFT scores, and percentage-point changes. Green change cells show gains and red cells show declines; blue shading indicates the score level within each metric.

Pass@1 and observed 20/20 rose in all five domains. Pass@20 was mixed: it increased in neobank and consulting, but declined in retail, travel, and auto insurance. Auto insurance had the largest breadth loss (−7.0 points), while retail had the largest observed-20/20 gain (+24.5 points).

What dependability costs

The first post priced consistency using simple math: divide the estimated cost of the full 20-run campaign by the number of tasks the model passed every single time.

Cost per dependable task = estimated cost of the 507 × 20 campaign ÷ tasks passing 20/20

Applying the same cost math to the fine-tuned checkpoint's measured token usage:

Table 3. Estimated evaluation cost and dependability for base and RL fine-tuned Qwen3.8-27B. Cost per successful attempt divides total estimated campaign cost (507 x 20) by the number of passing attempts.

Measure

Base

RL fine-tuned

Change

Campaign cost, 20 runs

$925.80

→

$855.58

−7.6%

Cost per successful attempt

$0.177

→

$0.139

−21.4%

Tasks passing 20/20

38

→

107

2.8× as many

Cost per dependable task

$24.36

→

$8.00

−67.2%

At $8.00 per dependable task, the fine-tuned model came close to GPT-5.4 ($6.80), GPT-6 Astra ($7.45), and Claude Opus 5.5 ($7.80) in the companion comparison.

The single-attempt view

Figure 4 prices cost per successful attempt against pass@1.

fig3-cost-frontier

Figure 4. The golden arrow traces Qwen3.8-27B base pareto cost position to the RLFT (diamond): pass@1 rises from 51.70% to 60.78% while estimated cost per successful attempt falls from $0.177 to $0.139. Ringed circles mark the Pareto cost frontier.

The move places the fine-tuned checkpoint close to GPT-5.6 Sol, although GPT-5.6 Sol remains cheaper and slightly higher on pass@1. Four models priced in our paper fall outside the plotted range.

The dollar values are a comparative serving index, not invoice or cloud bills. Serving the fine-tuned checkpoint would be the same as the base model. The calculation includes model inference cost, and excludes training run and policy-probe cost for curating the training dataset.

These results tell us what moved. The next sections explain the training loop and why selecting the right tasks matters the most.

The training loop

fig4-training-overview

Figure 5. The six stages, now in context: candidate tasks feed in, the first three run once offline, the last three repeat for every group in the training run. The trained checkpoint is evaluated against ThinkingBox-Bench.

Selection runs once, offline, against the base policy model, i.e in this case Qwen3.8 27B; training then uses that fixed pool that has been curated. The dashed amber arrow in Figure 5 marks the path we did not take: re-probing difficulty during the training run.

Every rollout is a complete episode, not a text completion. It gets a fresh backend, an isolated MCP session, and GPT-5 Chat as the simulated user. Most rewards come from deterministic terminal-state checks; a minority of narrow rubric requirements can invoke the configured judge (GPT-5 Chat).

Training and evaluation must interpret Qwen output identically. That includes reasoning extraction, tool calls, argument typing, rendering, and isolated task state. Otherwise the reward measures a different agent from the one evaluated. The shared interpretation code is in trainer/core/tb_interpret.py.

For the reference run, we ran full-parameter RL fine-tuned Qwen3.8-27B on 187 tasks using token-mean GRPO. Each update generated 18 groups of 8 rollouts, or 144 episodes, across 24 H100s. Training ran synchronously with parameter and optimizer offload; AdamW used a 1e-6 learning rate and zero weight decay. We ran the training for 50 steps.

Zero-variance groups were replaced DAPO-style during training. System errors were handled separately: a backend timeout is not an incorrect agent outcome, so affected groups were refilled rather than scored as failures.

That explains how retained tasks were trained. The remaining question is which tasks entered the training pool.

Offline policy-relative difficulty

Before diving deep into the selection of training tasks, a disclaimer:

No ThinkingBox-Bench task was included in the RL training pool. The benchmark was reserved for evaluation.

ThinkingBox-Bench is out-of-distribution relative to the RL training pool: its domains, databases, policies, and most tools were not encountered during RL training. The two sets still share the ThinkingBox framework, simulated-user machinery, executable terminal-state grading, a few common tools, and a similar task style. These shared elements limit the scope of the transfer claim.

Why selection matters comes down to one arithmetic fact about GRPO. If all eight rollouts fail, the reward vector is [0, 0, 0, 0, 0, 0, 0, 0]. If all eight succeed, it is [1, 1, 1, 1, 1, 1, 1, 1]. In either case, centering within the group produces no task-reward advantage because no trajectory did better than another.++

A mixed group such as [0, 0, 0, 1, 1, 1, 1, 1] supplies the contrast GRPO can learn from. That distinction is expensive for a stateful agent: every rollout provisions an isolated backend, runs a real tool session, and calls a separate model to play the user.

The question that shaped this work was therefore not only which model or optimizer? It was: which candidate tasks should enter the fixed training pool?

We used an offline pass-rate filter on the posterior to select the training pool. It estimates which tasks are likely to produce contrasting terminal rewards under the base policy.

So we probe. Each candidate task is run repeatedly against the base policy model. The plain-language rule is simple: tasks the model always fails are unlikely to teach it yet; tasks it always passes are already learned; tasks it solves sometimes are where outcomes can provide contrast.

Estimating difficulty from limited probes

Each candidate task is run n times, producing k successes. We model its latent success probability with Jeffreys posterior probability:

success probability | k successes in n probes ~ Beta(k + ½, n − k + ½)

fig5-policy-relative-difficulty

Figure 6. Offline policy-relative difficulty is estimated from repeated base-policy probes and used to retain tasks likely to produce contrasting rewards.

We partition the unit interval into five buckets with boundaries at 0.08, 0.40, 0.60, and 0.90, chosen as hyperparameters for these runs. Each task is assigned to the bucket containing the greatest posterior mass:

  • Rarely solved [0, 0.08): drop
  • Difficult [0.08, 0.40): keep
  • Intermediate [0.40, 0.60): keep
  • Frequently solved [0.60, 0.90): keep for full-parameter RLFT
  • Nearly always solved [0.90, 1]: drop

Further details are in Appendix C.4 of our ThinkingBox paper.

One task, end to end

fig6-worked-example

Figure 7. Zooming in, one task through all six stages: GPT-5.4 screening, base-model probes, difficulty classification, a rollout group, terminal-state grading, and a GRPO update.

Figure 7 follows one candidate task that can potentially enter the training pool. For the Qwen3.8 27B full-parameter pool, GPT-5.4 first served as a solvability screen. The base policy then succeeded on few of the probes e.g 3 of 8, producing a Beta(3.5, 5.5) posterior. Its largest mass, 54.0%, fell in the Difficult band.

When sampled for training, the task produced the mixed reward group [0, 0, 0, 0, 1, 1, 1, 1]. Successful trajectories therefore received above-mean task advantage and failed trajectories below-mean advantage, giving GRPO contrast to learn from. A different policy model could place the same task in a different difficulty band.

The final Qwen3.8-27B curated training pool contained 187 tasks.

What earns a reward

Nothing about the trajectory. The reward is the task's own executable verdict.

When an episode ends, the sandbox extracts what actually changed in the backend and runs the task's deterministic checks against the terminal state. Any trajectory that produces the correct end state passes. Wrong, missing, or extra side effects fail. The reward is 1 or 0.

In the benchmark, the database grader can be thought of as the “examiner”: it caught agents that reported success and left the wrong record. In training, the same kind of check can be seen as the “teacher” on a different, disjoint set of tasks.

Two reward paths, one binary verdict

  • Executable check (the large majority). When the required outcome is represented in terminal state or side effects, a deterministic test accepts or rejects it; no LLM judge call is needed.
  • Judge-assisted check (a minority). When a narrow requirement cannot be determined cleanly from database state, the configured LLM judge answers a binary rubric question used by the executable test.

Run the training stack

We release the data-selection, rollout, reward, and Verl integration used to train Qwen3.8-27B in microsoft/thinkingbox-training. The repository README is the entry point. The detailed guides are:

Before you start

Tested on Linux and WSL with Python 3.12 and uv. You need NVIDIA GPUs with a compatible CUDA/NCCL stack, a local Qwen3.8-27B checkpoint, and OpenAI-compatible endpoints for the simulated user and judge. The validated reference configuration uses 3 nodes x 8 H100 GPUs; smaller custom configurations depend on model size, context length, and rollout concurrency.

The public sample task list exercises the interface. It is not the private 187-task training pool used for the reported run. Supply an authorized training source that remains disjoint from the public benchmark.

Install

Keep the three repositories side by side:

mkdir -p ~/thinkingbox-workspace
cd ~/thinkingbox-workspace

git clone https://github.com/microsoft/thinkingbox.git
git clone https://github.com/microsoft/thinkingbox-data.git
git clone --branch main https://github.com/microsoft/thinkingbox-training

git -C thinkingbox checkout 892964e7226044e5463ad188da119df838f4bec1
git -C thinkingbox-data checkout thinkingbox-bench-v1.0

Create the validated environment

The released stack targets Linux, Python 3.12, Verl 0.9.0, and the pinned package lock:

cd ~/thinkingbox-workspace/thinkingbox-training

uv venv --python 3.12
source .venv/bin/activate

uv sync --frozen --extra fast --extra tracking --extra eval-proxy
uv pip install -e ../thinkingbox
uv pip install --config-settings editable-mode=compat \
  -e ../thinkingbox-data/servers/thinkingbox_tools
uv pip install --config-settings editable-mode=compat \
  -e ../thinkingbox-data/servers/tb_business_ops_servers_202606

python scripts/prepare_verl.py --dest .deps/verl --install
python scripts/verify_verl_install.py
uv pip check

The final two commands should report a verified patched Verl checkout and no broken requirements. Do not run another automatic package sync afterward: it can replace the patched source installation with the vanilla Verl wheel.

Prepare the training data

Start with the publicly provided samples, or add your own authorized dataset in ThinkingBox format. Then run the repository's preparation script:

cd ~/thinkingbox-workspace/thinkingbox-training
source .venv/bin/activate
python data/prepare_data.py --help

The script aggregates policy probes, applies offline policy-relative difficulty filters and benchmark exclusions, and writes the selected train.yaml and test.yaml files. docs/data-preparation.md documents the input fields, loader contract, and complete command.

Configure and inspect the launch

Follow docs/reference-q38-run.md to start Typesense and the MCP servers, configure the simulated user and judge, set the model, task-list, checkpoint, and topology variables, and prepare the Ray cluster. Keep credentials in runtime secret injection rather than committed files or shell history.

Before allocating a training job, use the guide's dry-run command:

DRY_RUN=true ./scripts/run_train.sh \
  trainer.total_training_steps=50 \
  trainer.save_freq=5

It must exit zero without starting Ray or allocating GPUs. Read the emitted python -m verl.trainer.main_ppo command and every resolved override before launching the run.

Train

The launcher configures training; it does not provision hosts. On the reference three-node topology, export the same environment on every node, mount CHECKPOINT_DIR at the same absolute path, then start Ray:

# head node
ROLE=head NODE_IP="$HEAD_IP" GPUS_PER_NODE=8 \
  ./scripts/start_ray.sh

# each worker node
ROLE=worker NODE_IP="$WORKER_IP" \
  HEAD_ADDRESS="$HEAD_IP:6379" GPUS_PER_NODE=8 \
  ./scripts/start_ray.sh

After ray status reports all 24 GPUs, launch once from the head node:

export RAY_ADDRESS=auto
export GPUS=0,1,2,3,4,5,6,7

./scripts/run_train.sh \
  trainer.project_name=thinkingbox-training \
  trainer.experiment_name=q38-full-rlft \
  trainer.total_training_steps=50 \
  trainer.save_freq=5

Evaluate the checkpoint through OpenEnv

The first ThinkingBox post covers Typesense, the MCP Session Proxy, and OpenEnv setup. Merge the trained checkpoint following docs/evaluation.md, then serve it with vLLM.

From the OpenEnv repository root, set MERGED_MODEL to the merged model directory and THINKINGBOX_DATA to the pinned benchmark checkout. The historical checkpoint evaluation used this eight-A100 serving configuration:

vllm serve "$MERGED_MODEL" \
  --served-model-name q38-rlft \
  --host 127.0.0.1 \
  --port 8001 \
  --tensor-parallel-size 8 \
  --dtype bfloat16 \
  --max-model-len 262144 \
  --gpu-memory-utilization 0.85 \
  --max-num-seqs 16 \
  --max-num-batched-tokens 8192 \
  --language-model-only \
  --enable-chunked-prefill \
  --enable-prefix-caching \
  --reasoning-parser qwen3 \
  --enable-auto-tool-choice \
  --tool-call-parser qwen3_xml

In a separate terminal, start the OpenEnv compatibility proxy for the Qwen chat template from the ThinkingBox Training checkout. It listens on port 8014 and forwards to vLLM on 8001:

cd ~/thinkingbox-workspace/thinkingbox-training
source .venv/bin/activate
bash scripts/launch_sysmerge.sh

Keep it running during evaluation. From another terminal, check readiness:

curl --fail http://127.0.0.1:8014/readyz

Update the agent entry in the existing thinkingbox.yaml; retain its MCP, simulated-user, and judge configuration:

orchestrator:
  agent_model:
    type: aoai
    endpoint_url: http://127.0.0.1:8014/v1/chat/completions
    deployment: q38-rlft
    credential:
      type: api-key
      api_key: <your_api_key>
    is_reasoning: true
    temperature: 1.0
    top_k: 20
    top_p: 0.95
    max_completion_tokens: 8192
    timeout: 1800

Start OpenEnv as in the first post, with OPENENV_TB_CONFIG pointing to this thinkingbox.yaml and OPENENV_TB_DATASET to $THINKINGBOX_DATA. Once /ready succeeds, run the full protocol of 507 tasks × 20 attempts:

uv run --project envs/thinkingbox_env --frozen \
  thinkingbox-eval \
  --config "$PWD/thinkingbox.yaml" \
  --base-url http://127.0.0.1:8000 \
  --dataset "$THINKINGBOX_DATA" \
  --output q38-rlft-full.jsonl \
  --errors-output q38-rlft-full-errors.jsonl \
  --repeat 20 \
  --coverage-profile full \
  --aggregate-output q38-rlft-full-aggregate.json \
  --message-timeout 1800

The full profile validates all 10,140 expected task/repetition keys before aggregation.

Where this goes next

The useful part of this work is not one Qwen3.8-27B checkpoint. It is the training loop and training data curation that turns executable outcomes into rewards.

If you are training or evaluating an agent that touches real database records:

  1. Probe before you train. Take your own agent task set, run the base policy against it n times, and look at the band histogram. In our experience teams often have not inspected this distribution, and it is usually more lopsided than expected.
  2. Check your parity. Replay the same recorded model output through the training and evaluation parsers, and verify that both extract identical tool names and arguments. Otherwise, training may reward behavior that evaluation interprets differently.
  3. Report both coverage and repeatability. State how many tasks pass at least once in k attempts and how many pass all k. A model that occasionally finds a solution is not necessarily one that repeats it consistently.

Further details can be found in the following links:

Cite the paper

@article{li2026thinkingbox,
  title   = {One Success Isn't Reliability: Thinkingbox, a Sandbox and Benchmark for Agents in Stateful Business Workflows},
  author  = {Li, Zhuochun and Ko, Youngmin and Keramati, Ali and Kundu, Tuhin and
             Tsai, Liang-Chun and Ferri, Nicola and Milletari, Mirco and Liu, Jiaxiang and
             Lopez Pelaez, Susana Palmaz and Wang, Yuepeng and Smolyakov, Vadim and
             Jiang, Xiang and Olafsson, Kjartan and Guy, Tommy},
  journal = {arXiv preprint arXiv:2608.19741},
  year    = {2026},
  url     = {https://arxiv.org/abs/2608.19741}
}

ThinkingBox code is MIT-licensed; the benchmark data is CDLA-Permissive-2.0.

Disclaimer: every task in the public benchmark is a synthetic reconstruction. The workflows and policies are modeled on real enterprise agent patterns; the customers are not real.

ThinkingBox, ThinkingBox-Bench and ThinkingBox-Training is built by the Microsoft Copilot Studio team in partnership with Toloka with collaborators from the University of Pittsburgh, Northwestern University, Columbia University and UC Irvine who interned at Microsoft. Questions are welcome in the comments section below or on github or by email at firstnamelastname@microsoft.com.

  • A minority of tasks also include narrow binary rubric requirements for outcomes that the database cannot capture cleanly; those checks can invoke the configured LLM judge.

++ That zero-gradient problem has a standard batch-time fix: oversample, discard the degenerate groups, refill. The full-parameter run did exactly that, similar to DAPO with replacement of zero-variance groups. But refilling still pays full price for every wasted rollout before throwing it away.

原文版权归 Hugging Face Blog 及原作者所有,本站转载仅供阅读。如需删除,请联系 support@aisa.one。