ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

接下来我将复现 10 篇强化学习算法:第 3 篇,一杯喜茶,搞定 Search-R1 的 config.toml 骨架与 TaoToken 接入

接下来我将复现 10 篇强化学习算法:第 3 篇,一杯喜茶,搞定 Search-R1 的 config.toml 骨架与 TaoToken 接入 1. 为什么 Search-R1 的 config.toml 值得单独写一篇Search-R1 是 Bowen Jin 等人在 2025 年提出的工作全名是 Search-R1: Training LLMs to Reason and Leverage Search Engines with Reinforcement Learning。它要解决的核心问题是让模型在回答过程中自己决定什么时候搜索、搜什么、看到结果后要不要继续搜最后再给出答案。传统 RAG 是「问题 → 检索 → 塞进 prompt → 回答」的单轮流程而 Search-R1 把搜索变成模型在整条推理轨迹里可以反复选择的动作。这个系列已经写到第三篇前两篇分别是 GRPO 和 OPD。到了 Agentic RL 这一篇训练链路一下子变长模型生成 → 工具调用 → 等待环境 → 模型继续生成 → 再调用工具。链路一长配置就成了第一道坎。很多人卡住不是因为算法看不懂而是因为 config.toml 里某个字段写错、某个路径对不上、某个 Key 没配好导致 rollout 根本跑不起来。这篇聚焦配置落地环节围绕 PyTRIO 与 LoRA 微调场景给出一份可以直接复制的 config.toml 骨架以及 TaoToken 统一 Key/API 通道的接入方式。目标很明确让你启动一次检索增强 rollout确认请求和日志都正常。适合已经了解 GRPO 基本概念、想动手跑 Search-R1 但被配置层拦住的人。读完你应该能拿到一份能跑的配置并且知道每个字段为什么这么写。2. TaoToken 前置统一 Key 与 API 通道在讲 config.toml 之前先把 TaoToken 的接入方式说清楚。Search-R1 的 rollout 阶段需要频繁调用模型采样接口如果每个实验都单独管理一套 Key很快就会乱。TaoToken 提供统一的 Key/API 通道把模型调用收敛到一个入口配置层只需要维护一份凭证。官网地址是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 。注意 API 地址不带 UTM 参数配置里填的就是这个干净地址。你需要先拿到 API Key。进入控制台的 API Keys 页面创建https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。创建后复制那串 Key后面会写进 config.toml 或者环境变量。这里有个容易踩的坑不要把 Key 硬编码进 config.toml 然后提交到 Git。推荐的做法是 config.toml 里写占位符真实值放在 .env 文件里通过环境变量注入。这样配置骨架可以安全地分享给队友。如果你只是想先验证模型通道是否通可以打开模型对话页面手动发一条消息https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。确认能正常返回再往下配训练侧。对于长期做编码和 Agent 实验的场景Coding Plan 会更省心https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。它适合需要反复跑 rollout、频繁切换模型的复现工作。3. 可复制的 config.toml 骨架下面这份骨架按 Search-R1 的训练链路组织分成模型通道、LoRA、rollout、搜索环境、训练循环五块。你可以直接复制然后按注释替换占位符。# 模型通道TaoToken 统一入口 [model] # 采样与训练都走 TaoToken 统一 API api_base https://taotoken.net/api api_key ${TAOTOKEN_API_KEY} # 从环境变量注入不要硬编码 base_model Qwen/Qwen3.5-4B # 采样温度Agentic RL 需要一定探索性 temperature 0.8 top_p 0.95 max_new_tokens 2048 # LoRA 微调 [lora] rank 32 alpha 64 dropout 0.05 target_modules [q_proj, k_proj, v_proj, o_proj] # 只训练 LoRA 权重基座冻结 # Rollout 状态机 [rollout] questions_per_batch 8 # 每个 step 8 道问题 group_size 8 # 每道问题 8 条轨迹 max_search_calls 4 # 单条轨迹最多搜索 4 次 max_assistant_turns 6 # 最多 6 轮 assistant 生成 max_trajectory_tokens 8192 # 单条轨迹最长 8192 tokens # 第一轮共享 prompt 用 num_samplesgroup_size # 首次搜索后每条轨迹独立推进用 num_samples1 并发 # 搜索环境 [search] provider zhihu api_keys ${ZHIHU_SEARCH_KEYS} # 逗号分隔的多个 key top_k 3 timeout_seconds 10 max_retries 2 # 记录 success_rate / error_rate / latency环境质量是实验变量 # 训练循环 [train] max_steps 20 save_every 5 loss_fn importance_sampling # micro-batch 约束 max_datum_tokens 8192 max_micro_batch_datums 32 max_micro_batch_tokens 64000 # 完整 group 算完 advantage 再拆 micro-batch # 整个逻辑 step 只做一次 optimizer step [optimizer] lr 1e-5 betas [0.9, 0.95] weight_decay 0.01几个关键点解释一下。api_base填 TaoToken 的 API 地址api_key用环境变量占位这样配置骨架可以安全分享。group_size 8对应每道题 8 条轨迹advantage 在组内计算A_i r_i - mean(r_1...r_8)。max_search_calls和max_assistant_turns一起限制轨迹长度防止模型无限搜索。micro-batch 那三个约束是给远端训练请求用的。单条 Datum 不能超过 8192 tokens单个 micro-batch 不超过 32 条且 micro-batch 内 items × max_sequence_length 不超过 64000。这些数字来自实际跑通的经验值你可以根据显存和序列长度微调。4. 验证请求启动一次检索增强 rollout配置写好后先别急着跑完整训练。用最小动作验证一次 rollout确认请求和日志正常。第一步准备环境变量。在项目根目录创建 .envTAOTOKEN_API_KEY你的_taotoken_key ZHIHU_SEARCH_KEYSkey1,key2,key3第二步写一个最小验证脚本只跑一个 step 的 rollout不更新参数import os import asyncio from rollout import run_rollout_group from search import ZhihuSearchClient async def main(): # 从环境变量读取确认注入成功 assert os.environ.get(TAOTOKEN_API_KEY), 缺少 TAOTOKEN_API_KEY keys os.environ[ZHIHU_SEARCH_KEYS].split(,) print(f搜索 key 数量: {len(keys)}) search_client ZhihuSearchClient(keyskeys, top_k3) # 只跑 1 道题、4 条轨迹验证链路 result await run_rollout_group( questionWho is the author of The Little Prince and where was he born?, group_size4, max_search_calls4, search_clientsearch_client, ) for i, traj in enumerate(result.trajectories): print(f轨迹 {i}: reward{traj.reward}, f搜索次数{traj.search_calls}, f最终答案{traj.final_answer}) print(f搜索成功率: {search_client.success_rate:.2%}) print(f搜索错误率: {search_client.error_rate:.2%}) asyncio.run(main())第三步运行并观察日志。正常的话你会看到类似输出搜索 key 数量: 3 轨迹 0: reward1.0, 搜索次数2, 最终答案France 轨迹 1: reward0.0, 搜索次数3, 最终答案Paris 轨迹 2: reward-0.1, 搜索次数4, 最终答案None 轨迹 3: reward1.0, 搜索次数2, 最终答案France 搜索成功率: 100.00% 搜索错误率: 0.00%看到 reward 有正有负、搜索次数在 1 到 4 之间、最终答案格式正确说明 rollout 链路通了。如果 reward 全是 -0.1多半是模型没输出Answer:格式如果搜索成功率低于 90%先检查 Key 额度。5. 本篇常见错排查配置层的问题往往有固定模式下面几个是我实际遇到过的。报错一api_key读取为空。现象是启动就报 401 或 unauthorized。原因是 .env 没被加载或者环境变量名拼错。检查方法在脚本开头 print 一下os.environ.get(TAOTOKEN_API_KEY)的前几位。如果为空确认用的是 python-dotenv 的load_dotenv()或者手动 export。报错二搜索返回 429。现象是search/error_rate飙升reward 集体下降。原因是单个 Key 触发额度限制。解决办法是配多个 Key 轮转config.toml 里api_keys用逗号分隔。如果三个 Key 都限流训练窗口就不可信了这时候应该停下来等额度恢复而不是继续跑。报错三degenerate_group_rate过高。现象是很多题目的 8 条轨迹 reward 完全一样advantage 全是 0这些题不提供梯度。原因可能是搜索环境不稳定导致整组一起失败也可能是题目太简单或太难。先看search/success_rate如果环境正常再考虑调整题目难度分布。报错四micro-batch 超限。现象是远端训练请求报 token 数超限。检查max_datum_tokens、max_micro_batch_datums、max_micro_batch_tokens三个约束是否同时满足。注意 advantage 缩放不同大小的 micro-batch 要按 n_k / N 缩放保证累积结果等价于完整 batch 的全局均值。报错五搜索结果被当成模型动作训练。现象是 loss 异常模型学会复述搜索结果。原因是 tool observation token 没有 mask。正确做法是给 observation token 填零 advantage 和零 old logprob只有 assistant 生成的 token 参与 policy loss。排查顺序建议先确认模型通道通用模型对话页面手动发一条再确认搜索通道通跑最小 rollout 脚本最后才跑完整训练。环境不稳的时候任何 reward 曲线都不能直接解释成算法效果。6. 下一步从配置层到完整训练配置跑通之后你就可以进入完整训练循环了。建议先跑 20 step每步 8 道问题、每道 8 条轨迹观察reward/format是否上升、模型是否开始稳定输出Answer:。Format reward 不依赖搜索结果只要模型最后正确输出一行答案就能计算所以它是验证 reward、advantage、loss mask 和 policy update 链路是否工作的可靠信号。如果你在接入过程中遇到 Key 或通道问题直接去 API Keys 页面重新生成https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。接入细节和字段说明看文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。想先手动验证模型行为用模型对话页面最直接。长期做 Agentic RL 实验的话Coding Plan 能省掉不少 Key 管理的琐事。配置这件事跑通一次之后就是复制粘贴。真正花时间的是 reward 设计和环境稳定性那才是 Search-R1 的核心。
返回列表