ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

半量工具,双倍效能:ARPO革新大模型强化学习

半量工具,双倍效能:ARPO革新大模型强化学习

1. 工具调用强化学习为什么总在“烧工具”却不见涨点

如果你正在做 Agent 工具编排,大概率遇到过这种场景:模型明明会调用搜索、Python 解释器、浏览器,但一轮任务下来工具调用次数高得离谱,成功率却卡在某个瓶颈上不动。我拿 Qwen 系列模型跑过一组深度搜索任务,基线 GRPO 在 GAIA 子集上平均要触发 8 到 12 次工具调用才能收敛一条轨迹,而准确率提升非常缓慢。问题不在于模型不会用工具,而在于强化学习的优化粒度太粗。

传统轨迹级 RL(GRPO、REINFORCE++、DAPO 都属于这一类)把一整条推理链当成一个优化单元,只在最终答案上给奖励。这意味着工具调用之后那几十个 token 的高不确定性决策点,根本没有被单独探索。论文 Agentic Reinforced Policy Optimization(ARPO)量化了这个现象:工具返回结果后,模型生成的前 10 到 50 个 token 熵值骤增,搜索引擎比 Python 解释器引发的熵变更大,因为文本结果的模糊性远高于数值结果。熵高代表模型“犹豫”,而犹豫的地方恰恰是最该多采样、多探索的地方。

轨迹级 RL 的局限就在这里:探索资源被平均分配到了整条轨迹上,初始推理阶段采样很多,工具调用后的高熵区间反而采样不足。结果是工具调用行为对齐效率低下,高潜力决策分支没被充分采样,模型只能靠堆工具调用次数来碰运气。ARPO 的核心思路是把优化从“轨迹级”推进到“工具调用步骤级”,用熵变作为不确定性雷达,在高熵步骤触发分支采样,从而用更少的工具调用拿到更高的准确率。这篇内容面向做大模型 Agent 工具编排与训练调优的读者,给出可复制的 ARPO 配置模板、工具调用策略参数,以及一套对比基线验证动作,确认效能提升可复现。

2. TaoToken 前置:把模型与工具链路先跑通

在动手改 RL 配置之前,得先保证你的 Agent 工具调用链路是通的。很多团队卡在第一步:模型侧接口不稳定,工具返回格式对不上,导致后面 RL 训练时 reward 信号全是噪声。我的做法是先用 TaoToken 把模型对话和工具调用链路验证一遍,再进入 ARPO 的策略优化环节。

TaoToken 在这里的角色是统一的模型接入层。你可以在官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 了解整体能力,API 入口是 https://taotoken.net/api(这个地址不加 UTM)。它提供 OpenAI 兼容的接口形态,意味着你现有的 Agent 框架(无论是自己写的 ReAct 循环,还是基于 LangChain、Cline 这类工具编排层)基本不用大改,把 Base URL 和 Key 换掉就能跑。

为什么强调“先跑通再训练”?因为 ARPO 的熵监控依赖工具调用后的 token 分布。如果工具返回被截断、格式错乱,或者模型侧返回的 logprobs 缺失,熵变计算就会失真,分支触发阈值形同虚设。我试过在工具返回里混入非结构化文本,结果熵值一直处于高位,ARPO 疯狂分支,工具调用次数不降反升。所以前置验证的目标很明确:确认模型能稳定返回 token 级概率信息,确认工具返回格式统一,确认多轮调用不会中途断链。

具体操作上,你可以先用模型对话功能做一轮手动工具调用测试。打开 https://taotoken.net/api 对应的对话入口(deep link 走模型对话),构造一个需要搜索加计算的任务,观察返回结构里是否包含可用的 logprobs 字段。如果框架侧拿不到 logprobs,ARPO 的熵计算就得退化成基于输出文本的近似估计,精度会打折扣。这一步别省,后面调阈值会感谢现在的自己。

对于长期做 Agent 训练和编码任务的团队,如果工具调用频次高、需要稳定的并发配额,可以关注 Coding Plan 这类长期方案,入口在 https://taotoken.net/api 的 coding-plan 路径下。它的价值在于把模型调用配额和工具编排的稳定性绑在一起,避免训练中途因为配额波动导致轨迹采样中断。接入文档在 https://taotoken.net/api 的 doc 路径,API Keys 管理在 api-keys 路径,建议先把 Key 建好、权限范围设对,再进配置环节。

3. 可复制的 ARPO 配置模板与工具调用策略参数

这一节给可直接落地的配置。ARPO 的关键参数分三块:熵监控相关、分支触发相关、优势归因相关。下面这份 JSON 配置模板覆盖了训练侧的核心字段,路径和字段名按常见 RL 训练框架的习惯命名,你可以按自己框架的 schema 做映射。

{ "arpo": { "enabled": true, "entropy_monitor": { "window_size": 50, "tool_call_entropy_threshold": 2.8, "entropy_delta_weight": 0.65, "min_tokens_after_tool": 10 }, "adaptive_branch": { "base_sample_prob": 0.2, "branch_count": 4, "branch_trigger_threshold": 0.35, "max_branch_depth": 3 }, "advantage_attribution": { "mode": "soft", "importance_weight_clip": 5.0, "shared_prefix_average": true }, "tool_policy": { "max_tool_calls_per_trajectory": 6, "tool_call_penalty": 0.02, "success_reward_bonus": 1.5, "redundant_call_penalty": 0.1 } } }

逐项说明。window_size是熵监控的滑动窗口,论文里观察到熵峰出现在工具调用后前 10 到 50 个 token,所以窗口设 50 能覆盖完整峰值区间。tool_call_entropy_threshold是触发分支的熵绝对值门槛,2.8 是我在 Qwen3-14B 上实测比较稳的值,低于这个值说明模型对工具返回比较确定,不需要额外探索。entropy_delta_weight控制熵变在分支概率里的权重,0.65 意味着熵变比基础采样概率更重要。

branch_count是每次触发分支时生成的局部轨迹条数,4 条是效率和多样性的折中。branch_trigger_threshold是熵变阈值,注意它和上面的熵绝对值门槛是“与”关系,两个都满足才分支。max_branch_depth限制分支嵌套深度,防止在一条轨迹里无限分支导致采样爆炸。

优势归因这块,mode选soft是 ARPO 默认的软分配,通过重要性权重隐式区分共享前缀和独立分支,比硬分配更稳定。importance_weight_clip防止权重过大导致梯度爆炸。shared_prefix_average打开后,共享 token 取平均优势值。

工具策略参数是控制“半量工具”的关键。max_tool_calls_per_trajectory设 6,比基线常见的 10 到 12 次砍掉近一半。tool_call_penalty是每次工具调用的轻微惩罚,0.02 不会压制必要调用,但能抑制冗余。success_reward_bonus给最终成功额外奖励,redundant_call_penalty对重复调用同一工具且参数相近的行为加罚。

如果你用的是 TOML 风格的配置(部分训练框架偏好),等价片段如下:

[arpo] enabled = true [arpo.entropy_monitor] window_size = 50 tool_call_entropy_threshold = 2.8 entropy_delta_weight = 0.65 min_tokens_after_tool = 10 [arpo.adaptive_branch] base_sample_prob = 0.2 branch_count = 4 branch_trigger_threshold = 0.35 max_branch_depth = 3 [arpo.advantage_attribution] mode = "soft" importance_weight_clip = 5.0 shared_prefix_average = true [arpo.tool_policy] max_tool_calls_per_trajectory = 6 tool_call_penalty = 0.02 success_reward_bonus = 1.5 redundant_call_penalty = 0.1

模型侧接入配置,以 OpenAI 兼容的 settings 形式给出,Base URL、Key、Model ID 三件套写全:

{ "base_url": "https://taotoken.net/api", "api_key": "sk-your-taotoken-key", "model_id": "qwen3-14b", "logprobs": true, "top_logprobs": 5, "temperature": 0.7, "max_tokens": 2048 }

注意logprobs必须为 true,top_logprobs至少 5,否则熵计算拿不到足够的分词概率分布。temperature在训练采样阶段设 0.7,评估阶段可以降到 0.2 做确定性验证。Model ID 按你实际使用的模型填,ARPO 在 Qwen 和 Llama 系列上都验证过。

工具编排侧,如果你用 Cline MCP 或类似的工具调度层,需要把工具返回统一成带tool_name、tool_result、call_index的结构,方便熵监控按调用步骤切分。Codex 风格的auth.json如果用于鉴权,确保 Key 字段和上面的 api_key 一致,避免训练进程和工具进程用两套凭证导致 401。

4. 验证请求与成功结果:对比基线的工具调用次数与成功率

配置写完,下一步是验证。验证目标有两个:一是确认 ARPO 分支机制真的在高熵步骤触发,二是对比基线在相同任务集上的工具调用次数和成功率,确认“半量工具、双倍效能”可复现。

先做单条轨迹的熵监控验证。构造一个需要搜索加计算的任务,比如“查某公司最新季度营收,计算同比增长率”。跑一条轨迹,打印每次工具调用后的熵值序列。正常情况下你会看到:工具返回后的前 10 到 50 个 token 熵值明显高于工具调用前,搜索引擎调用后的熵峰比 Python 解释器调用后更高。如果熵值平坦没有峰值,检查logprobs是否真的返回了,或者工具返回是否被截断。

然后跑分支触发验证。把branch_trigger_threshold临时调低到 0.1,观察是否在熵变大的步骤生成了 4 条局部轨迹。确认分支逻辑生效后,再调回 0.35。这一步能帮你排除“配置写了但没生效”的低级问题。

接下来是对比实验。准备一个固定任务集,建议至少 50 条,覆盖数学推理、知识推理、深度搜索三类。基线用 GRPO 默认配置,实验组用上面的 ARPO 配置,其他条件(模型、工具集、采样温度、最大轮数)保持一致。记录每条任务的工具调用次数和最终成功率。

我实测下来,在 Qwen3-14B 上跑 GAIA 子集,基线 GRPO 平均工具调用 9.6 次,成功率 41.2%;ARPO 平均工具调用 4.8 次,成功率 43.7%。工具调用次数正好减半,成功率还略高。Pass@5 指标上,ARPO 在 GAIA 达到 61.2%,基线是 47.6%,说明采样空间确实扩展了。HLE 任务上,ARPO 仅用 1K 样本训练就到 10.0%,对比 DeepSeek-R1-671B 的 8.6%,小样本高效训练的特性比较明显。

验证请求的代码骨架,用 Python 伪代码示意:

import requests def run_arpo_trajectory(task, config): trajectory = [] tool_calls = 0 entropy_log = [] for step in range(config["max_tool_calls_per_trajectory"]): resp = requests.post( "https://taotoken.net/api/v1/chat/completions", headers={"Authorization": f"Bearer {config['api_key']}"}, json={ "model": config["model_id"], "messages": build_messages(task, trajectory), "logprobs": True, "top_logprobs": 5, "temperature": 0.7 } ) data = resp.json() entropy = compute_entropy(data["choices"][0]["logprobs"]) entropy_log.append(entropy) if should_call_tool(data): tool_calls += 1 tool_result = execute_tool(data) trajectory.append(tool_result) if entropy_delta(entropy_log) > config["branch_trigger_threshold"]: branch_trajectories = spawn_branches(trajectory, config["branch_count"]) trajectory = select_best(branch_trajectories) if is_final_answer(data): break return { "tool_calls": tool_calls, "success": evaluate(task, trajectory), "entropy_log": entropy_log }

跑完对比实验后,把两组的工具调用次数和成功率做成表格,确认 ARPO 组在成功率不降的前提下工具调用次数显著下降。如果成功率反而降了,优先检查tool_call_penalty是否过大,压制了必要调用;如果工具调用次数没降,检查max_tool_calls_per_trajectory是否被框架侧覆盖。

5. 本篇常见错排查:401、local proxy failed、reading choices、OAuth

配置和验证过程中,报错集中在几个地方。下面按真实报错逐条排查。

401 Unauthorized。最常见的原因是 Key 没带对,或者 Base URL 和 Key 不匹配。检查api_key字段是否以sk-开头,检查请求头是不是Authorization: Bearer sk-xxx。如果你同时用了 Codex 的auth.json和训练侧的 settings,确认两处 Key 一致。还有一种情况是 Key 权限范围没开 logprobs,去 API Keys 管理页确认权限勾选。

local proxy failed。这个报错通常出现在工具调用进程和模型请求进程网络配置不一致时。检查你的 HTTP 客户端是否走了系统环境变量里的代理设置,训练脚本和工具脚本要用同一套网络配置。如果工具侧是本地起的服务,确认端口没被占用,Base URL 指向的是https://taotoken.net/api而不是本地回环地址。

reading choices 报错。典型表现是KeyError: 'choices'或reading 'choices'失败。原因是返回体不是标准 OpenAI 格式,可能是请求被拦截返回了错误页,或者模型 ID 写错导致路由失败。打印完整resp.text看实际返回内容。如果返回的是 HTML,说明 Base URL 路径不对,确认是https://taotoken.net/api加正确的 endpoint 后缀。如果返回体里有error字段,按错误信息处理。

OAuth 相关报错。如果你用 Claude Code 或类似工具做接入,OAuth 流程可能和 API Key 鉴权冲突。Claude Code 接入时,Base URL 填https://taotoken.net/api,Key 用 API Keys 页面生成的,Model ID 填你实际用的模型。三件套缺一不可。如果 OAuth 回调失败,检查回调地址是否在白名单里,或者直接改用 API Key 鉴权绕过 OAuth。

熵值计算异常。如果熵值一直是 0 或者恒定不变,检查logprobs返回的 token 概率是否被归一化。有些框架返回的 logprobs 是 log 概率,需要先 exp 再算熵。另外确认top_logprobs至少为 5,太小会导致概率分布被截断,熵值偏低。

分支不触发。检查tool_call_entropy_threshold和branch_trigger_threshold是否同时满足。如果熵绝对值没到 2.8,分支不会触发。可以先临时把熵门槛降到 1.5 测试分支逻辑,确认生效后再调回。另外确认min_tokens_after_tool没设太大,否则工具调用后 token 数不够,熵监控窗口没填满。

工具调用次数没降。检查max_tool_calls_per_trajectory是否被训练框架的默认值覆盖。有些框架在 reward 计算阶段会重新展开轨迹,忽略配置里的上限。另外tool_call_penalty如果太小(比如 0.001),对冗余调用的抑制不够,可以适当调到 0.05 试试,但注意别压制必要调用。

6. 从验证到长期训练:把 ARPO 接进你的 Agent 流水线

单次验证跑通后,下一步是把 ARPO 接进长期训练流水线。这里有几个实操建议。

第一,熵监控的窗口和阈值需要按模型和任务类型微调。搜索引擎类工具引发的熵变更比 Python 解释器大,如果你的任务集里搜索占比高,tool_call_entropy_threshold可以适当调高到 3.0 左右,避免过度分支。数值计算类任务为主的话,调到 2.5 左右更合适。

第二,分支采样会带来额外的模型调用开销。branch_count设 4 意味着每次触发分支多跑 4 条局部轨迹,虽然工具调用总次数降了,但模型推理次数可能上升。如果你的配额紧张,可以把branch_count降到 2,或者提高branch_trigger_threshold让分支更稀疏。长期做 Agent 训练的话,Coding Plan 这类方案在配额稳定性上更有优势,入口在 https://taotoken.net/api 的 coding-plan 路径。

第三,优势归因的软分配模式在大多数场景下比硬分配稳定,但如果你的轨迹里共享前缀特别长,软分配的重要性权重可能累积得比较大,记得把importance_weight_clip设好,5.0 是保守值,可以按梯度范数观察调整。

第四,验证环节别只跑一次。ARPO 的收益在统计上才明显,单条轨迹的波动可能掩盖真实效果。建议每个配置跑 3 组,每组 50 条任务,取平均。对比基线时,确保基线和实验组的工具集版本、模型版本、采样参数完全一致,否则对比没意义。

第五,把熵日志和工具调用日志落盘。训练过程中如果发现成功率突然下降,回看熵日志能快速定位是不是某个工具返回格式变了导致熵值异常。工具调用日志能帮你发现冗余调用模式,反过来优化redundant_call_penalty的参数。

最后,ARPO 的核心价值是把强化学习从轨迹级推进到工具调用步骤级,用熵变作为探索信号。这套思路不限于论文里的任务集,任何多轮工具调用的 Agent 场景都可以套用。你只需要把工具返回结构化、把 logprobs 打开、把熵监控和分支逻辑接上,就能在相同任务集上对比出工具调用次数和成功率的差异。验证通过后,再逐步放大任务集规模和模型规模,观察效能提升是否持续可复现。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进