微软用 ThinkingBox 把数据库评分变成 RL 奖励,微调 Qwen3.8-27B
Turning Database Grading into RL Rewards: Post-Training Agents with ThinkingBox
微软 Copilot Studio 团队与 Toloka 等合作,将 ThinkingBox-Bench 的数据库终态可执行检查直接作为强化学习奖励,对 Qwen3.8-27B 做全参数 RL 微调。在 507 个未参与训练的分布外任务上,该模型 20 次全部通过的任务数从 38 个(7.5%)升至 107 个(21.1%),pass@1 从 51.70% 升至 60.78%,单次成功成本从 0.177 美元降至 0.139 美元。训练池用离线策略相对难度筛选,最终保留 187 个任务,训练与评测代码已开源在 microsoft/thinkingbox-training。
推荐理由
AI 评分 59
原文给出可复用的训练数据筛选与奖励设计流程,并展示可重复性指标与成本口径的变化。
主题
正文 · AI 翻译
目录
基准测试在六十秒内的发现
结果:可靠性一列发生了变化
离线策略相对难度
时间紧迫?核心结果见上文。实现细节见“运行训练栈”一节。
基准测试在六十秒内的发现
ThinkingBox-Bench 根据智能体留下的数据库记录对其进行评分。它的 507 个任务中,每个任务都会启动一个真实后端,向智能体提供一组 MCP 工具和一个带有私有上下文的模拟 LLM 用户,并在最后针对终端数据库状态运行可执行检查。检查针对的是需要正确的后端记录,而不是具体的工具调用。这会激励模型去发现可能的新解决路径,而不是“重新发现”人类支持的解决方案——后者虽然正确,但可能并非最优。
在我们的第一篇博文中,我们让十八个模型各运行该基准测试二十次,并报告了总体准确率所掩盖的差距。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。观测到的 20/20 显示了哪些任务在每次尝试中都能成功,这更接近生产可靠性所要求的水平。
可执行的终端状态判定同时也是训练奖励。在展开训练循环之前,先看看密封基准测试上发生了什么变化。
结果:可靠性一列发生了变化
在对 Qwen3.8-27B 进行训练后,我们在其从未训练过的 507 任务基准测试上评估了选定的第 50 步检查点。这 507 个任务构成一个分布外测试集:它们的领域、数据库以及大多数 MCP 工具在 RL 训练期间均未出现过。
表 2. 按领域划分的 ThinkingBox-Bench pass@1(%),包括我们第一篇博文表 2 中的部分模型以及我们针对不同领域和整体微调的模型。观测到的 20/20 数字基于整个 507 任务基准测试。每个模型都在全部 507 个任务上进行 20 次重复试验评估。粗体标记该列领先者;下划线标记第二名。
核心结果是表 1 中观测到的 20/20 一行。一个最初在每次尝试中完成 38 个(7.5%)ThinkingBox-Bench 任务的 27B 模型,现在在每次尝试中完成 107 个(21.1%),几乎达到三倍。作为对比,Kimi-K3 的观测 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。单靠任一指标都无法反映全貌。
观测到的模式与“锐化”一致:可重复的成功率上升,而至少成功一次的覆盖率略有下降。这与先前的研究一致。一种解释是,概率分布向能够反复奏效的轨迹移动,而一些低概率路径消失了。
总体而言,模型并没有变得更广。它变得更可重复。下一个问题是这些增益落在了哪里。
增益落在了哪里
图 3. 领域级基础分数、RLFT 分数以及百分点变化。绿色变化单元格表示增益,红色单元格表示下降;蓝色阴影表示各指标内的分数水平。
Pass@1 和观测到的 20/20 在所有五个领域均上升。Pass@20 则好坏参半:在 neobank 和咨询领域上升,但在零售、旅行和汽车保险领域下降。汽车保险的广度损失最大(−7.0 个百分点),而零售的观测 20/20 增益最大(+24.5 个百分点)。
可靠性的代价
第一篇博文用简单数学计算了一致性的代价:将完整 20 次运行活动的估计成本除以模型每次都通过的任务数。
每个可靠任务的成本 = 507 × 20 活动的估计成本 ÷ 通过 20/20 的任务数
将同样的成本计算应用于微调检查点测得的 token 用量:
表 3. 基础版和经 RL 微调的 Qwen3.8-27B 的估计评估成本与可靠性。每次成功尝试的成本等于总估计活动成本(507 x 20)除以通过的尝试次数。
以每个可靠任务 8.00 美元计算,微调模型在配套比较中接近 GPT-5.4(6.80 美元)、GPT-6 Astra(7.45 美元)和 Claude Opus 5.5(7.80 美元)。
单次尝试视角
图 4 将每次成功尝试的成本与 pass@1 进行对比定价。
图 4. 金色箭头追踪 Qwen3.8-27B 基础版的帕累托成本位置到 RLFT(菱形):pass@1 从 51.70% 升至 60.78%,而每次成功尝试的估计成本从 0.177 美元降至 0.139 美元。带环圆圈标记帕累托成本前沿。
这一变化使微调检查点接近 GPT-5.6 Sol,尽管 GPT-5.6 Sol 仍然更便宜且在 pass@1 上略高。我们论文中定价的四个模型落在绘图范围之外。
这些美元数值是比较性的服务指数,而非发票或云账单。服务微调后的检查点与基础模型相同。计算包含模型推理成本,不包含训练运行和用于整理训练数据集的策略探测成本。
这些结果告诉我们哪些因素发生了变化。接下来的章节将解释训练循环,以及为什么选择正确的任务最为重要。
训练循环
图 5. 六个阶段,现在置于上下文中:候选任务输入,前三个阶段离线运行一次,后三个阶段在训练运行中为每个组重复。训练后的检查点针对 ThinkingBox-Bench 进行评估。
选择阶段离线运行一次,针对基础策略模型,即本例中的 Qwen3.8 27B;随后训练使用该已整理的固定池。图 5 中的琥珀色虚线箭头标记了我们未采取的路径:在训练运行期间重新探测难度。
每次 rollout 都是一个完整回合,而非文本补全。它获得全新的后端、隔离的 MCP 会话,以及作为模拟用户的 GPT-5 Chat。大多数奖励来自确定性的终态检查;少数狭窄的评分标准要求可以调用配置的评判器(GPT-5 Chat)。
训练和评估必须以相同方式解释 Qwen 输出。这包括推理提取、工具调用、参数类型化、渲染和隔离的任务状态。否则,奖励衡量的智能体与评估的智能体不同。共享的解释代码位于 trainer/core/tb_interpret.py 。
对于参考运行,我们使用 token 均值 GRPO 在 187 个任务上对 Qwen3.8-27B 进行全参数 RL 微调。每次更新在 24 块 H100 上生成 18 组、每组 8 次 rollout,即 144 个回合。训练同步运行,并采用参数和优化器卸载;AdamW 使用 1e-6 学习率和零权重衰减。我们训练了 50 步。
训练期间,零方差组按 DAPO 风格被替换。系统错误单独处理:后端超时不是智能体的错误结果,因此受影响的组被重新填充,而非计为失败。
这解释了保留任务是如何训练的。剩下的问题是哪些任务进入了训练池。
离线策略相对难度
在深入探讨训练任务的选择之前,先做一个免责声明:
RL 训练池中未包含任何 ThinkingBox-Bench 任务。该基准保留用于评估。
ThinkingBox-Bench 相对于 RL 训练池是分布外的:其领域、数据库、策略和大多数工具在 RL 训练期间未曾遇到。两个集合仍共享 ThinkingBox 框架、模拟用户机制、可执行终态评分、少数通用工具以及相似的任务风格。这些共享元素限制了迁移主张的范围。
为什么选择很重要,归结为关于 GRPO 的一个算术事实。如果八次 rollout 全部失败,奖励向量为 [0, 0, 0, 0, 0, 0, 0, 0] 。如果八次全部成功,则为 [1, 1, 1, 1, 1, 1, 1, 1] 。无论哪种情况,组内中心化都不会产生任务奖励优势,因为没有轨迹比其他轨迹表现更好。++
像 [0, 0, 0, 1, 1, 1, 1, 1] 这样的混合组提供了 GRPO 可以学习的对比。对于有状态智能体来说,这种区分代价高昂:每次 rollout 都要配置隔离的后端、运行真实的工具会话,并调用单独的模型来扮演用户。
因此,塑造这项工作的核心问题不仅是哪个模型或优化器?而是:哪些候选任务应进入固定训练池?
我们使用对后验的离线通过率过滤器来选择训练池。它估计哪些任务在基础策略下可能产生对比性的终态奖励。
因此我们进行探测。每个候选任务针对基础策略模型重复运行。通俗的规则很简单:模型总是失败的任务不太可能现在就能教会它;模型总是通过的任务已经学会;模型有时能解决的任务才是结果可以提供对比的地方。
从有限探测中估计难度
每个候选任务运行 n 次,产生 k 次成功。我们用 Jeffreys 后验概率对其潜在成功概率建模:
成功概率 | n 次探测中 k 次成功 ~ Beta(k + ½, n − k + ½)
图 6. 离线策略相对难度由重复的基础策略探测估计,并用于保留可能产生对比奖励的任务。
我们将单位区间划分为五个桶,边界为 0.08、0.40、0.60 和 0.90,作为这些运行的超参数选择。每个任务被分配到后验质量最大的桶:
很少解决 [0, 0.08):丢弃
困难 [0.08, 0.40):保留
中等 [0.40, 0.60):保留
经常解决 [0.60, 0.90):保留用于全参数 RLFT
几乎总是解决 [0.90, 1]:丢弃
更多细节见我们 ThinkingBox 论文的附录 C.4。
一个任务,端到端
图 7. 放大来看,一个任务贯穿全部六个阶段:GPT-5.4 筛选、基础模型探测、难度分类、一个 rollout 组、终态评分,以及一次 GRPO 更新。
图 7 跟踪了一个有可能进入训练池的候选任务。对于 Qwen3.8 27B 全参数池,GPT-5.4 首先充当可解性筛选器。随后基础策略在少数探测中成功,例如 8 次中成功 3 次,产生 Beta(3.5, 5.5) 后验。其后验质量的最大部分,即 54.0%,落在“困难”区间。
当被采样用于训练时,该任务产生了混合奖励组 [0, 0, 0, 0, 1, 1, 1, 1]。因此,成功的轨迹获得了高于均值的任务优势,失败的轨迹获得了低于均值的优势,从而为 GRPO 提供了可供学习的对比。不同的策略模型可能将同一任务归入不同的难度区间。
最终 Qwen3.8-27B 精选训练池包含 187 个任务。
什么能获得奖励
与轨迹无关。奖励是任务自身的可执行判定。
当一个 episode 结束时,沙箱会提取后端中实际发生的变化,并针对终态运行任务的确定性检查。任何产生正确最终状态的轨迹都会通过。错误、缺失或多余的副作用都会失败。奖励为 1 或 0。
在基准测试中,数据库评分器可以被视为“考官”:它抓住了那些报告成功却留下错误记录的智能体。在训练中,同一类检查可以被视为另一组不相交任务上的“老师”。
两条奖励路径,一个二元判定
可执行检查(占绝大多数)。当所需结果体现在终态或副作用中时,确定性测试会接受或拒绝它;无需调用 LLM 评判器。评判器辅助检查(占少数)。当某个狭窄要求无法从数据库状态中清晰判定时,配置的 LLM 评判器会回答一个二元评分标准问题,供可执行测试使用。
运行训练栈
我们发布了用于训练 Qwen3.8-27B 的数据选择、rollout、奖励和 Verl 集成,位于 microsoft/thinkingbox-training。仓库 README 是入口。详细指南包括:
docs/data-preparation.md 用于任务水合、策略探测、基准排除以及训练/验证划分; docs/reference-q38-run.md 用于经过验证的 24-H100 Qwen3.8 配置; docs/evaluation.md 用于合并检查点并运行 ThinkingBox-Bench 507 x 20。
开始之前
已在 Linux 和 WSL 上使用 Python 3.12 和 uv 测试。你需要具备兼容 CUDA/NCCL 栈的 NVIDIA GPU、本地 Qwen3.8-27B 检查点,以及用于模拟用户和评判器的 OpenAI 兼容端点。经过验证的参考配置使用 3 个节点 x 8 块 H100 GPU;更小的自定义配置取决于模型大小、上下文长度和 rollout 并发度。
公开示例任务列表用于演练接口。它不是所报告运行中使用的私有 187 任务训练池。请提供与公开基准保持不相交的授权训练源。
安装
将三个仓库并排放置:
创建经过验证的环境
发布的栈面向 Linux、Python 3.12、Verl 0.9.0 以及固定的包锁:
最后两条命令应报告已验证的已打补丁 Verl 检出,且没有损坏的依赖项。之后不要运行另一次自动包同步:它可能会用原版 Verl wheel 替换已打补丁的源码安装。
准备训练数据
从公开提供的样本开始,或以 ThinkingBox 格式添加你自己的授权数据集。然后运行仓库的准备脚本:
该脚本汇总策略探测结果,应用离线策略相对难度过滤器和基准排除,并写出选定的 train.yaml 和 test.yaml 文件。docs/data-preparation.md 记录了输入字段、加载器契约和完整命令。
配置并检查启动
按照 docs/reference-q38-run.md 启动 Typesense 和 MCP 服务器,配置模拟用户和评判器,设置模型、任务列表、检查点和拓扑变量,并准备 Ray 集群。将凭据保存在运行时密钥注入中,而不是提交到文件或 shell 历史记录中。
在分配训练作业之前,使用指南中的 dry-run 命令:
它必须在不启动 Ray 或分配 GPU 的情况下以零退出。在启动运行之前,阅读输出的 python -m verl.trainer.main_ppo 命令以及每个解析后的覆盖项。
训练
启动器负责配置训练;它不负责配置主机。在参考的三节点拓扑上,在每个节点上导出相同的环境,将 CHECKPOINT_DIR 挂载到相同的绝对路径,然后启动 Ray:
在 ray status 报告全部 24 块 GPU 后,从头节点启动一次:
通过 OpenEnv 评估检查点
第一篇 ThinkingBox 文章涵盖了 Typesense、MCP Session Proxy 和 OpenEnv 设置。按照 docs/evaluation.md 合并训练后的检查点,然后用 vLLM 提供服务。
在 OpenEnv 仓库根目录下,将 MERGED_MODEL 设置为合并后模型的目录,将 THINKINGBOX_DATA 设置为固定版本的基准测试检出目录。历史检查点评估使用了以下八卡 A100 服务配置:
在另一个终端中,从 ThinkingBox Training 检出目录启动针对 Qwen 聊天模板的 OpenEnv 兼容代理。它监听端口 8014,并转发到 8001 上的 vLLM:
在评估期间保持其运行。从另一个终端检查就绪状态:
更新现有 thinkingbox.yaml 中的 agent 条目;保留其 MCP、模拟用户和评判器配置:
如第一篇文章所述启动 OpenEnv,将 OPENENV_TB_CONFIG 指向此 thinkingbox.yaml,将 OPENENV_TB_DATASET 指向 $THINKINGBOX_DATA。一旦 /ready 成功,运行完整协议:507 个任务 × 20 次尝试:
完整配置在聚合前验证全部 10,140 个预期任务/重复键。
接下来走向何方
这项工作有价值的部分不是一个 Qwen3.8-27B 检查点,而是将可执行结果转化为奖励的训练循环和训练数据整理流程。
如果你正在训练或评估一个会触及真实数据库记录的 agent:
先探测再训练。取你自己的 agent 任务集,让基础策略对其运行 n 次,并查看分带直方图。根据我们的经验,团队往往没有检查过这个分布,而它通常比预期更不均衡。
检查你的对齐性。将同一份记录的模型输出分别通过训练解析器和评估解析器重放,并验证两者提取出完全相同的工具名称和参数。否则,训练可能奖励那些被评估以不同方式解读的行为。
同时报告覆盖率和可重复性。说明有多少任务在 k 次尝试中至少通过一次,以及有多少任务在全部 k 次尝试中都通过。一个偶尔找到解决方案的模型,未必是一个能稳定复现该解决方案的模型。
更多细节可在以下链接中找到:
环境:envs/thinkingbox_env
OpenEnv:ThinkingBox 环境文档
框架:microsoft/thinkingbox · 教程
基准测试:microsoft/thinkingbox-data · v1.0 版本
数据集查看器:microsoft/ThinkingBox-Bench
论文:arXiv:2608.19741 或 HF
RL 训练:microsoft/thinkingbox-training
博客:The Agent Said It Was Done. The Database Disagreed.
引用论文
ThinkingBox 代码采用 MIT 许可证;基准数据采用 CDLA-Permissive-2.0。
免责声明:公开基准测试中的每个任务都是合成重建。工作流和策略以真实企业 agent 模式为蓝本;客户并非真实存在。
ThinkingBox、ThinkingBox-Bench 和 ThinkingBox-Training 由 Microsoft Copilot Studio 团队与 Toloka 合作构建,合作者包括曾在微软实习的匹兹堡大学、西北大学、哥伦比亚大学和加州大学欧文分校的研究人员。欢迎在下方评论区、GitHub 或通过电子邮件 firstnamelastname@microsoft.com 提问。
+ 少数任务还包含针对数据库无法清晰捕获的结果的狭窄二元评分标准要求;这些检查可以调用已配置的 LLM 评判器。
++ 那个零梯度问题有一个标准的批处理时修复方法:过采样、丢弃退化组、重新填充。全参数运行正是这样做的,类似于 DAPO 对零方差组的替换。但重新填充仍然要为每个被丢弃的浪费 rollout 支付全额代价。
本文提及的数据集 1
microsoft/ThinkingBox-Bench
本文提及的论文 1
One Success Isn't Reliability: Thinkingbox, a Sandbox and Benchmark for Agents in Stateful Business Workflows
更多来自该作者
The Agent Said It Was Done. The Database Disagreed.
本文提及的数据集 1
microsoft/ThinkingBox-Bench
本文提及的论文 1
One Success Isn't Reliability: Thinkingbox, a Sandbox and Benchmark for Agents in Stateful Business Workflows