ARTICLE · INTELLIGENCE

战地情报 · 详情页

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

slime Agentic RL 接入技术路线:从多轮工具调用、Agent Runtime Adapters 到 test-based reward 的完整实战指南

slime Agentic RL 接入技术路线:从多轮工具调用、Agent Runtime Adapters 到 test-based reward 的完整实战指南 slime Agentic RL 接入技术路线从多轮工具调用、Agent Runtime Adapters 到 test-based reward 的完整实战指南【免费下载链接】slimeslime is an LLM post-training framework for RL Scaling.项目地址: https://gitcode.com/GitHub_Trending/slime12/slimeslime 的定位并不只是跑单轮 RL而是把高性能训练Megatron 后端、SGLang rollout serving以及可插拔的数据生成接口组合起来支持 agent 时代常见的多轮工具调用、sandbox 交互、subagent 分支、context compact 与 test-based reward。本文以 docs/zh/get_started/agent.md 为主线结合仓库源码与端到端样例给出把 agent workflow 接入 slime 的完整路线先判断该走哪条自定义接口再理解Sample的 token 语义与 fan-out 规则接着掌握 Agent Runtime Adapters 与 serving 性能配置最终落到可运行的参考样例上。读完本文你将能够基于--custom-generate-function-path/--custom-rm-path组合为任意多轮 agenttool call、RAG、sandbox、subagent编写可训练的 rollout 逻辑。一、从哪里开始按目标选择接入入口agentic RL 场景五花八门但接入 slime 的入口高度统一。原文档给出了一张目标 → 推荐入口对照表这里完整保留并补充每个入口所在的文档与代码位置目标推荐入口给每条 sample 跑自定义 agent loop、tool call、RAG、browser/terminal/sandbox 交互--custom-generate-function-path、编写自定义生成函数做 verifier reward、test-based reward、环境成功判定或外部 reward 服务--custom-rm-path、编写自定义奖励函数一个 prompt 会产生多个训练样本例如 subagent、multi-agent、context compactcustom generate 的 fan-out 返回、examples/multi_agentagent rollout 有长尾耗时希望训练不要被最慢样本卡住examples/fully_asyncagent 需要 sandbox、真实代码修改、测试验证和完整端到端样例examples/coding_agent_rl多轮 agent 需要更高 SGLang serving 吞吐PD 分离、SGLang Config想开启 SGLang 的优化 flag、router 策略或多模型 servingsglang 使用方法、SGLang Config、投机采样、低精度训练选择原则可以概括为一句话先用最细粒度的接口解决 per-sample 的定制只有默认 rollout 循环本身无法表达你的 workflow 时才去覆盖整个 rollout 编排。绝大多数 agentic 任务都落在前两行的--custom-generate-function-path--custom-rm-path组合上这也是 slime 官方推荐的最小侵入路径。二、推荐接入方式从 custom generate 开始的 per-sample 定制2.1 核心接口--custom-generate-function-path大多数 agentic RL 任务应该先从--custom-generate-function-path开始。这个参数只覆盖默认 rollout 函数slime.rollout.sglang_rollout.generate_rollout中的生成步骤外层的数据调度、训练循环完全复用 slime 默认逻辑因此不会破坏原有的 RL 训练管线。其默认值为None使用内置生成函数函数签名如下见 docs/zh/get_started/customization.mdasync def custom_generate(args, sample: Sample, sampling_params: dict) - Sample | list[Sample]这个函数负责把一次 agent 运行转换成 slime 可训练的Sample填好tokens、response_length、loss_mask、status并在需要时填好reward或交给--custom-rm-path计算。Sample类型定义在 slime/utils/types.py其中session_id: str | None None字段第 149 行正是为多轮 agent 的会话亲和路由预留的。2.2 训练目标必须是 token basedagent workflow 本身可以使用字符串、chat messages、tool calls、环境 observation 或框架自己的事件格式但训练目标仍然应该是token based尽量保留模型实际采样得到的 token ids并用loss_mask区分可训练的模型输出和 prompt、template、tool observation、环境文本。这一点在slime/agent/adapters/common.py的实现中体现得极为严格adapter 从不从 response text 重新分词恢复训练目标而是把每次 SGLang/generate调用返回的output_ids和逐 token logprobsreturn_logprobTrue原样保存见call_sglang_generate中output_token_logprobs的处理。loss_mask的规则是模型生成的 token思考、动作指令、tool call→loss_mask 1参与损失计算工具或环境返回的 tokenAPI 结果、observation、template 文本→loss_mask 0不参与损失计算loss_mask必须与response等长。2.3 一次 rollout 拆出多个训练片段fan-out 与 rollout_id如果一次 prompt rollout 只对应一个训练样本返回一个Sample即可。但在 subagent、multi-agent、context compact 等场景中一次 rollout 会自然拆成多个可训练片段主 agent 调用 subagent 后subagent 的轨迹和主 agent 的后续轨迹都需要参与训练发生 compact 后compact 前后的上下文也被切成多个 segment。此时custom_generate直接返回list[Sample]并且这些 sibling samples 必须设置相同的rollout_id这样 slime 在训练 step 切分和 loss 聚合时会把它们视作同一次 rollout而不是重复计数为多次独立 rollout。customization.md 给出的标准写法如下import copy from slime.utils.types import Sample async def custom_generate(args, sample: Sample, sampling_params: dict) - list[Sample]: segments await run_agent_and_split_segments(args, sample, sampling_params) rollout_id sample.rollout_id if sample.rollout_id is not None else sample.index samples: list[Sample] [] for segment in segments: s copy.copy(sample) s.tokens segment.tokens s.response segment.response s.response_length segment.response_length s.loss_mask segment.loss_mask s.reward segment.reward s.status Sample.Status.COMPLETED s.rollout_id rollout_id samples.append(s) return samples如果一条完整 trajectory 只有一个总奖励、但被拆成了K个训练片段常见做法是在这些片段之间分配奖励例如每个片段写入reward / K避免把同一次 rollout 的奖励重复放大。需要说明的是adapter 内部路径见下文第三节在源码层面是每个产出 sample 被赋予完整 reward、由 per-rollout 聚合器保证不重复计数的语义见 slime/agent/trajectory.py 中get_trajectory的注释两条路径都可以实现同一次 rollout 只计一次的约束自写 generate 时选择其一保持一致即可。2.4 何时才需要--rollout-function-path只有当你需要替换整个 rollout 编排时才优先考虑--rollout-function-path。典型场景包括自定义数据源调度、跨 rollout 的后台队列、完全异步生成或者默认sglang_rollout的 prompt × sample 结构已经无法表达你的 workflow。其默认值是slime.rollout.sglang_rollout.generate_rollout函数签名为def generate_rollout(args, rollout_id, data_source, evaluationFalse) - RolloutFnTrainOutput | RolloutFnEvalOutput完整实现可参考 examples/fully_async。注意覆盖整个 rollout function 意味着你要自行负责数据获取、生成、reward 计算等全链路只有 per-sample 定制确实不够用时才走这条路。2.5 与 custom rm 的配合奖励侧通过--custom-rm-path注入。单样本模式签名为async def custom_rm(args, sample: Sample) - float启用--group-rm时使用批量模式async def batched_custom_rm(args, samples: list[Sample]) - list[float]。这正好覆盖 agent 场景的三大类信号verifier reward、test-based reward环境成功判定、以及调用外部 reward 模型服务。slime 内置的--rm-type选项包括math、dapo、deepscaler、f1、gpqa、ifbench、remote_rm需要--rm-url详见 customization.md。三、Agent Runtime Adapters把现成 agent runtime 接进 slime3.1 两个开箱即用的协议 adapterslime 提供已有 agent runtime 可用的协议 adapter位于slime/agent/adapters/slime.agent.adapters.AnthropicAdapter实现 Anthropic Messages API/v1/messages、/v1/messages/count_tokens用于 Claude Code 风格 agent。源码见 slime/agent/adapters/anthropic.py。slime.agent.adapters.OpenAIAdapter实现 OpenAI Chat Completions 和 Responses API用于 OpenAI SDK / OpenAI Agents SDK 风格 client。源码见 slime/agent/adapters/openai.py。两者共享同一个BaseAdapter基类slime/agent/adapters/common.py该基类把 session 生命周期、per-sid 轮次上限、in-flight 任务记账和单轮_run_turn流水线全部继承下来子类只需填充协议相关的 wire hooks_register_routes、_session_id、_translate、_build_reply、_respond。重要定位adapter 是一个便利层不是单独的 agent framework。它的 contract 是message history in, sampled tokens outadapter 用 served 模型的 chat template 渲染当前消息历史tokenizer.apply_chat_template转成input_ids用input_ids和return_logprobTrue调 SGLang/generate把返回的 token ids / logprobs 导出为可训练的 trajectory segments不会从 response text 重新分词恢复训练目标。这个 contract 与第二节的token based 训练目标原则完全一致也是保证 RL 训练信号真实性的关键只有模型实际采样过的 token 才能作为优化目标。3.2 在自定义 generate 函数中使用 adapter原文档给出了标准用法在自定义 generate 函数里实例化对应协议的 adapter用 aiohttp 跑它的app然后通过 adapter 实例管理每次 rolloutfrom slime.agent.adapters import AnthropicAdapter adapter AnthropicAdapter( tokenizertokenizer, sglang_urlsglang_url, tool_parsertool_parser, reasoning_parserreasoning_parser, ) adapter.open_session(session_id, sampling_defaultssampling_params) # Agent client 向 adapter.app 发送请求。 segments await adapter.finish_session(session_id)结合BaseAdapter.__init__slime/agent/adapters/common.py还可以补充这些构造参数max_turns_per_sid每个 session 的轮次上限。超过上限后 adapter 会返回 429 响应来终止该 agent 运行防止失控循环。fork_threshold_tokenstrajectory fork/merge 的阈值 token 数默认 1024控制后续消息重分词漂移时是合并修正还是分叉成独立训练片段。debug_callback可选的调试回调在生产环境默认不设置。adapter 的 HTTPapp通过run_app_in_thread见 slime/agent/aiohttp_threaded.py跑在独立线程里generate.py中即以此为 Claude Code 提供 Anthropic 兼容端点。3.3 session_id 与前缀缓存亲和多轮 agent 应使用稳定的session_id。adapter 会把它作为X-SMG-Routing-Key传给 SGLang见call_sglang_generate中headers {X-SMG-Routing-Key: session_id}让同一个 session 尽量落到同一个 worker从而复用 prefix cache。session id 的解析规则是协议相关的Anthropic 侧从Authorization: Bearer或X-Api-Keyheader 读取sid_from_bearerOpenAI 侧从 body 的metadata.session_id/user字段读取sid_from_body具体见 slime/agent/adapters/common.py。3.4 TrajectoryManager把多轮会话变成可训练轨迹adapter 背后的核心数据结构是 slime/agent/trajectory.py 中的TrajectoryManager。它按session_id维护一棵 per-session 消息树每一轮record_turn把该轮的 prompt messages 沿树向下匹配挂载并挂上一个携带TurnRecordprompt/output ids、logprobs、finish_reason的 assistant 叶子节点。由于 agent 环境的字符串进、token 出特性后续轮次的 prompt 往往无法与之前保存的 token 流逐字节对上chat template 重渲染、client 重放消息等都会造成重分词漂移。_SampleBuilder.classify_token_drift把漂移分为三类源码中的DriftKindCLEAN新 prompt 精确扩展已保存 token 流直接追加尾部REALIGN漂移落在最近一次 response 区间内且较短用 prompt 覆盖该区间并标记loss_mask0继续累积FORK漂移过大或过早关闭当前 builder 新建一个——这个边界就是一次 fork对应 subagent 分派或 auto-compaction 产生的分支。get_trajectory最终把每棵树的每条 root-to-leaf 链线性化成Sample列表。其中response_trained标志保证被多个 sibling leaf 共享的生成轮次只在第一条链上参与训练其余链将其重新输出为loss_mask0的上下文避免共享前缀被重复计数。对重分词漂移的正确性守卫有专门的单测覆盖tests/test_agent/test_trajectory_manager_branching.py覆盖 matched prefixes、skipped turns、split-output drift、changed token counts、prompt-base restarts 等情形。四、Agent Serving 与性能配置agentic rollout 往往比普通单轮 generation 更依赖 serving 配置上下文更长、多轮请求更多、请求时长分布更重尾并且可能同时需要 actor、reference、reward 或工具侧模型。本节整理原文档给出的四类配置手段。4.1--sglang-*常规 SGLang server 参数透传常规 SGLang server 参数通过--sglang-*前缀传入slime 自动透传给 SGLang。例如SGLang 的--context-length在 slime 中写作--sglang-context-lengthSGLang 的--mem-fraction-static写作--sglang-mem-fraction-static其他如--sglang-log-level INFO、--sglang-kv-cache-dtype fp8_e4m3同理后者用于 long-context rollout 开启 FP8 KV cache。4.2--router-*会话亲和路由router 参数通过--router-*传入。多轮 agent 建议使用--router-policy consistent_hashingslime 为每个 sample 分配唯一session_id请求时通过X-SMG-Routing-Keyheader 传给 SGLang Model Gatewayconsistent hashing 策略会把同一session_id的多轮请求确定性地路由到同一个 worker提高 prefix cache 命中率。完整机制见 多轮 Agent 的会话亲和路由。可选的 router 策略还包括round_robin简单轮询与cache_aware缓存感知路由默认。4.3--sglang-config复杂推理拓扑更复杂的拓扑使用--sglang-configYAML 文件它可以描述 PD 分离、多模型 servingactor / ref / reward 各自独立 router、异构 server groups不同 TP 大小、不同 worker 类型以及每组不同的 SGLang overrides。典型的多轮 agent 配置是给 actor 模型配置prefilldecode两组 worker并分别用overrides设置chunked_prefill_size与mem_fraction_static。配置格式与字段参考详见 SGLang Config。4.4 PD 分离与吞吐优化多轮或 agentic RL 通常建议评估PD 分离prefill 是计算密集型处理整个 promptdecode 是内存带宽密集型逐 token 生成两者负载形态不同拆开后更容易分别扩展资源prefill 用更小 TP 提吞吐、decode 用更大 TP 降延迟。对 rollout 吞吐敏感时可以继续查看 投机采样 和 低精度训练。另外在训推一体化--colocate模式下需要调低--sglang-mem-fraction-static通常建议 0.8为 Megatron 训练预留显存详见 quick_start.md。五、参考样例从端到端 coding agent 到轻量入门5.1 coding_agent_rl最接近真实 agent RL 的端到端样例完整的 coding-agent 样例见 examples/coding_agent_rl。它展示了一个比较接近真实 agent RL 的端到端形态每条 sample 启动独立 sandboxagent 使用工具修改代码生成git diff再在干净 sandbox 里跑测试得到 reward防止 test-cheating。技术栈由三层构成generate.pyper-samplegenerate()通过--custom-generate-function-path examples.coding_agent_rl.generate.generate注册。流程为prepare_workspace→ harness 运行claude-code / codex CLI→git_diff捕获 patch →run_evaluation打分 →adapter.finish_session产出 Sample见 examples/coding_agent_rl/generate.py。slime.agent.harness与 harness 无关的 coding-agent 生命周期安装 CLI、写配置、spawn 独立进程、轮询完成标记。BaseHarness定义契约CLAUDE_CODE/CODEX是内置实现新增 harness 只需一个新文件。slime.agent.sandbox.Sandbox统一的 sandbox 契约exec/write_file/read_fileE2BSandbox是 E2B 实现。换用 Docker / Modal / 本地 VM 时只需重实现这几个方法generate.py无需改动见 examples/coding_agent_rl/README.md。该样例也演示了agent fan-out 的训练方式middleware 会把 trajectory 切成subagent、wipecompact 前被冻结的链和final等片段generate()返回list[Sample]并让这些片段共享同一个rollout_id。启动前需要配置的 SWE 相关环境变量ADAPTER_PUBLIC_HOST、E2B_API_KEY、SLIME_AGENT_SANDBOX_IMAGE_METADATA_KEY、SLIME_AGENT_NODE_TARBALL、SLIME_AGENT_CC_TARBALL等以及数据集格式prompt/label/metadatametadata 内含image、workdir、problem_statement与 grader 字段均以表格形式完整记录在 examples/coding_agent_rl/README.md 中这里不再赘述。需要注意该样例要求 SGLang server 暴露与被服务模型匹配的解析器例如 Qwen3.6 场景下SGLANG_ARGS( --sglang-tool-call-parser qwen3_coder --sglang-reasoning-parser qwen3 ... )--rollout-max-response-len是每轮传给 SGLang/generate的max_new_tokens上限--rollout-max-context-len是多轮 promptresponse 的预算仅在生成期生效每轮把max_new_tokens钳制到剩余上下文长度。5.2 轻量入门search-r1 / retool / multi_agent如果你只需要更轻量的入门例子examples/search-r1多轮工具调用的最小复现通过--custom-generate-function-path接入搜索增强的多轮生成generate_with_search.py外层仍走 slime 默认sglang_rollout。它同时演示了数据准备把session_id、tool_code等额外信息聚合进metadata字段用--metadata-key metadata映射到Sample.metadata、交互循环与 loss masking 的完整写法对应的理论说明在 quick_start.md 的 Multiturn 适配。examples/retool工具增强生成聚焦 SFT/RL 两阶段的数据处理与 tool sandbox。examples/multi_agent多 agent 模式generate_with_multi_agents通过同一接口实现 per-sample 多 agent 生成并通过MULTI_AGENT_CONFIGS配置并行数num_parallel与正误奖励权重correct_reward_weight/incorrect_reward_weight。六、接口契约测试验证你的自定义实现接入 agentic workflow 时最容易出错的是自定义函数的签名与返回结构。slime 提供了一组CPU 契约测试无需 GPU通过字符串形式的导入路径动态加载组件既能回归仓库内置 hook也能验证用户通过和训练时完全相同的 CLI 参数传入的自定义实现。测试统一放在tests/plugin_contracts/下tests/plugin_contracts/test_plugin_generate_contracts.py覆盖--custom-generate-function-pathtests/plugin_contracts/test_plugin_path_loading_contracts.py覆盖--eval-function-path、--custom-rm-path、--dynamic-sampling-filter-path、--buffer-filter-path、--data-source-path等tests/plugin_contracts/test_plugin_rollout_contracts.py覆盖--rollout-function-pathtests/plugin_contracts/test_plugin_runtime_hook_contracts.py覆盖--custom-reward-post-process-path、--custom-convert-samples-to-train-data-path等。本地运行全部契约测试python -m pytest \ tests/plugin_contracts/test_plugin_rollout_contracts.py \ tests/plugin_contracts/test_plugin_generate_contracts.py \ tests/plugin_contracts/test_plugin_path_loading_contracts.py \ tests/plugin_contracts/test_plugin_runtime_hook_contracts.py验证自定义实现时只需把插件路径替换成你的模块路径例如python tests/plugin_contracts/test_plugin_rollout_contracts.py \ --rollout-function-path my_project.custom_rollout.generate_rollout此外多轮 agent 专用的 trajectory 语义fork、merge、loss mask 重排由 tests/test_agent/test_trajectory_manager_branching.py 与 tests/test_agent/test_adapters.py 保障前者覆盖分支合并与 token 漂移的正确性后者覆盖两个协议 adapter 的翻译与回包行为。七、路线图小结把 agent workflow 接进 slime 的决策顺序可以归纳为五步选接口per-sample 定制用--custom-generate-function-path生成--custom-rm-path奖励要换整体编排才用--rollout-function-path要自定义数据调度用--data-source-path。遵守 token 语义只把模型实际采样的 token 作为训练目标loss_mask1只给模型输出环境/工具/模板文本一律loss_mask0。处理 fan-out一次 rollout 拆多个训练片段时返回list[Sample]并共享rollout_id奖励分配与聚合保持一致。复用 agent runtimeClaude Code 风格用AnthropicAdapterOpenAI SDK 风格用OpenAIAdapter稳定session_idconsistent_hashing路由提升 prefix cache 命中率。按需调 serving多轮场景评估 PD 分离与--sglang-config多模型拓扑必要时叠加投机采样与低精度训练。从 docs/zh/get_started/agent.md 出发配合 customization.md 的完整接口参考、quick_start.md 的 Multiturn 适配教程以及examples/下的四个参考样例即可把任意 agent workflow 以最小侵入方式接入 slime 的 RL 训练闭环。【免费下载链接】slimeslime is an LLM post-training framework for RL Scaling.项目地址: https://gitcode.com/GitHub_Trending/slime12/slime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

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