把数据库校验变成奖励信号:ThinkingBox训练Agent实录

0 阅读

为什么Agent总爱“嘴硬”

如果你用过任何声称能操作数据库或业务系统的AI Agent,大概率遇到过这种情况:Agent信誓旦旦地说“任务已完成”,甚至列出了一堆看似专业的工具调用记录,但你去后台一看,数据根本没变,或者改错了字段。

这就是微软和Hugging Face在上一篇博客《Agent说搞定了,数据库说没有》里指出的痛点。传统的评估往往依赖模型生成的文本轨迹,或者简单的通过率(pass@1),但这掩盖了一个致命问题:稳定性。一个模型可能在20次尝试中有一次蒙对了,但在生产环境里,我们需要的是它每次都能做对。

为了解决这个问题,他们构建了ThinkingBox-Bench基准测试,包含507个任务,每个任务都连接真实的后端数据库。Agent操作完后,系统不检查它调用了什么工具,而是直接查询数据库的最终状态是否符合预期。这种“executable check”(可执行校验)不仅用于评估,现在也被直接用作强化学习(RL)的奖励信号。

这次发布的ThinkingBox-Training项目,就是展示如何利用这种基于数据库状态的奖励信号,对开源模型进行后训练(Post-Training)。结果相当直观:经过50步GRPO微调的Qwen3.8-27B,在完全未见过的新任务分布上,可靠性大幅提升。

核心发现:从“偶尔做对”到“稳定输出”

在深入技术细节前,先看最核心的数据变化。研究团队使用离线策略相对难度(Offline Policy-Relative Difficulty)筛选出187个适合训练的任务,对Qwen3.8-27B进行了微调。

评估是在ThinkingBox-Bench的507个任务上进行的,每个任务重复运行20次。这里有两个关键指标:

  1. pass@1:所有尝试中的平均成功率。
  2. Observed 20/20:在20次尝试中全部成功的任务比例。这个指标更接近生产环境对“可靠性”的定义。

微调前后的对比如下:

  • 平均成功率(pass@1):从51.70%提升至60.78%,提升了9.08个百分点。
  • 全对任务数(Observed 20/20):从38个(7.50%)激增至107个(21.10%),增加了69个任务,几乎是原来的三倍。

值得注意的是,pass@20(至少成功一次的任务数)略有下降,从453个降至446个。这说明模型并没有变得更“博学”或覆盖更广的任务类型,而是变得更“专注”和“稳定”。它放弃了一些低概率的侥幸路径,转而巩固那些能反复成功的路径。

举个具体的例子:在一个酒店预订降级的任务中,公司政策要求必须先获得经理批准。微调前,基础模型在20次中有15次无视审批直接修改订单;微调后,模型在20次中全部正确保留了预订和支付状态,等待审批。

成本账:可靠性是有价格的,但更划算

很多人担心,为了追求稳定性,是否需要付出巨大的推理成本?研究团队算了一笔账。

他们定义了一个指标:“每个可靠任务的成本”(Cost per dependable task)。计算公式是:完成507×20次评估的总预估成本,除以那些20次全对的任务数量。

  • 基础模型:每个可靠任务成本约24.36美元。
  • 微调后模型:每个可靠任务成本降至8.00美元。

成本下降了67.2%。虽然微调后的模型在单次尝试的成功率上还不如GPT-5.4或Claude Opus 5.5等顶级闭源模型,但在“每美元获得的可靠性”这一指标上,它已经非常接近这些昂贵模型的水平(GPT-5.4为6.80美元,Claude Opus 5.5为7.80美元)。

这意味着,对于预算有限但需要高可靠性的企业场景,使用开源模型配合针对性的RL微调,是一个极具性价比的选择。

技术核心:如何挑选“值得教”的任务

强化学习不是喂越多数据越好。如果给模型喂它已经完全掌握的任务,或者它完全不会的任务,梯度几乎为零,学不到任何东西。

  • 太简单:8次 rollout 全部成功,奖励向量全是1,中心化后优势函数为0。
  • 太难:8次 rollout 全部失败,奖励向量全是0,同样没有对比度。
  • 适中:有的成功,有的失败。这种“混合组”才能提供有效的学习信号。

这就是“离线策略相对难度”的概念。难度是相对于当前模型而言的。

筛选流程

  1. 探针测试:在训练前,用基础模型(Base Policy)对候选任务集进行多次试探性运行(例如8次)。
  2. 贝叶斯估计:根据成功次数k和总次数n,计算潜在成功概率的后验分布 Beta(k + 0.5, n - k + 0.5)。
  3. 分桶筛选:
    • 极少成功(概率<0.08):丢弃,目前教不会。
    • 几乎全对(概率>0.90):丢弃,已经学会了。
    • 中间区间(0.08-0.90):保留。特别是0.40-0.60的“中等难度”和0.08-0.40的“困难”任务,是训练的主力。

最终,他们从大量候选任务中筛选出了187个任务用于Qwen3.8-27B的全参数微调。这187个任务与最终的测试集(ThinkingBox-Bench)是完全隔离的,确保了评估的公正性。

奖励机制:数据库不说谎

在这个框架中,奖励函数极其简洁:0或1。

当Agent完成一个episode后,沙箱环境会提取数据库的最终状态,并运行确定性的检查脚本。

  • 可执行检查(主流):绝大多数任务的结果可以直接通过数据库字段验证。比如“订单状态是否为approved”、“余额是否扣减正确”。只要状态对,就给1;否则给0。不需要LLM裁判介入。
  • 裁判辅助检查(少数):极少数细微的规则无法直接从数据库体现,这时会调用配置好的LLM Judge(如GPT-5 Chat)回答一个二元问题,再转化为奖励。

这种设计避免了传统RLHF中人类标注的主观性和高昂成本,同时也消除了LLM裁判可能出现的幻觉或不一致。

动手实践:运行训练栈

微软已开源完整的训练代码库 microsoft/thinkingbox-training。如果你想在本地复现或基于自己的业务数据训练,以下是关键步骤。

1. 环境准备

需要Linux或WSL环境,Python 3.12,以及NVIDIA GPU(推荐H100,但也支持其他兼容CUDA的显卡)。还需要本地部署Qwen3.8-27B的checkpoint,以及用于模拟用户和裁判的OpenAI兼容接口。

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

2. 安装依赖

使用 uv 管理环境,确保Verl库的版本正确 patched。

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

# 验证Verl安装
python scripts/verify_verl_install.py

3. 准备训练数据

你可以使用公开的示例任务,也可以导入自己的业务数据(需符合ThinkingBox格式)。运行数据准备脚本,它会自动执行前述的难度筛选和基准排除逻辑。

python data/prepare_data.py --help

生成的 train.yaml 将包含筛选后的187个任务(如果使用默认配置)。

4. 启动训练

参考 docs/reference-q38-run.md 配置Ray集群。在24张H100 GPU上,运行50步训练大约需要数小时。

# 启动Ray头节点和工作节点
./scripts/start_ray.sh

# 启动训练
export RAY_ADDRESS=auto
./scripts/run_train.sh \
  trainer.project_name=thinkingbox-training \
  trainer.experiment_name=q38-full-rlft \
  trainer.total_training_steps=50

5. 评估

训练完成后,合并checkpoint,并通过vLLM提供服务。使用OpenEnv框架运行完整的507×20次评估。

# 启动vLLM服务
vllm serve "$MERGED_MODEL" \
  --served-model-name q38-rlft \
  --tensor-parallel-size 8 \
  --dtype bfloat16 \
  ...

# 运行评估
uv run --project envs/thinkingbox_env --frozen \
  thinkingbox-eval \
  --config "$PWD/thinkingbox.yaml" \
  --dataset "$THINKINGBOX_DATA" \
  --repeat 20 \
  --coverage-profile full

给开发者的建议

这项工作的价值不仅仅是一个微调好的Qwen模型,而是一套方法论。如果你正在构建涉及真实数据库操作的Agent,以下几点至关重要:

  1. 先探针,后训练:不要盲目开始RL。先用你的基础模型跑一遍任务集,看看成功率的分布。如果大部分任务要么全对要么全错,说明你需要调整任务难度或模型基座。
  2. 检查解析一致性:确保训练时的奖励解析器和评估时的解析器完全一致。如果训练时认为某个工具调用是成功的,而评估时解析失败,模型就会学到错误的行为。
  3. 同时报告覆盖率和重复率:只看pass@1会误导人。一定要报告“在k次尝试中全部成功”的比例。一个偶尔能解题的模型,和一个每次都能解题的模型,在生产环境中的价值天差地别。

结语

ThinkingBox-Training证明了,对于状态复杂的业务代理(Stateful Agents),基于最终状态的可执行奖励比基于文本轨迹的奖励更有效、更廉价。随着开源生态中这类高质量训练框架的成熟,企业自建垂直领域Agent的门槛正在迅速降低。

相关资源: