【免费下载链接】labs-molt
A scalable, agentic-first, and HuggingFace-native RL framework for research (9k lines).
Molt 是一个 agentic-first 的强化学习(RL)训练框架,用约 9.2K 行 Python 代码打通了 vLLM 推理、Ray 异步队列和 PyTorch/FSDP2 训练。在 Molt 里,"奖励函数"不需要任何特殊接口——它就是你在 Python 里写的任意一段逻辑:规则打分器、LLM-as-Judge 大模型评委、多轮工具调用环境,都统一收敛为一个Result(reward=...)返回值。本文带你用最少代码掌握 Molt 自定义奖励函数、打分器与多轮工具的实战写法。
一、为什么 Molt 的奖励函数这么自由?
传统 RL 框架通常要求你把奖励模型注册成独立组件,而 Molt 的设计是"Agent 即程序,Trainer 只是一个 Actor":
- 你的环境/代理继承
Env或ChatAgent,在step()/run()里执行任意 Python 代码; - 返回
Result(reward=...)后,框架自动完成 token 对齐、轨迹累积、优势估计等所有脏活; - 甚至可以让评委模型回调正在 rollout 的同一组 vLLM 引擎做 LLM-as-Judge,不用额外部署推理服务。
整条契约定义在 molt/agents/base.py 中,Result类(molt/agents/base.py#L105-L114)只强制一个字段:reward必须是标量,其余全是可选增强。
二、单轮打分器:一个 step() 函数即可
最简单的奖励函数是"规则打分器"。Molt 内置的数学环境 examples/python/agents/math.py 只有 20 行有效代码:
class MathEnv(Env): async def step(self, state) -> Result: prompt, action, label = state.get("observation_text", ""), state["action_text"], state.get("label") or "" result = await asyncio.to_thread(_GRADER.score_response, prompt + action, prompt, label) reward = torch.tensor(float(result.get("reward", 0.0)), dtype=torch.float32) return Result(reward=reward, info={"math_exact": reward})关键点:
state字典由框架喂给你:observation_text(对话上下文)、action_text(模型本轮生成)、label(数据集里的标准答案);- 打分逻辑放在线程里(
asyncio.to_thread),避免阻塞 rollout 的 asyncio 事件循环; info里的数值会自动变成监控指标,比如math_exact准确率、missing_answer缺失率,训练时直接可见。
配套的打分器 examples/python/utils/math_grader.py 采用两级答案等价判断:先做字符串归一化 + 精确匹配,再走 sympy 符号等价,所以\frac{1}{2}和0.5都能被正确判分,且sympy缺失时优雅降级。
💡自定义你的打分器:复制 math.py 改两处即可——
step()里换成你自己的判分逻辑(正则、执行代码、比对结构),再把启动参数--train.agent_path指向你的文件。
三、LLM-as-Judge:把大模型当评委
当任务没有标准答案(开放式问答、代码评审、对话质量)时,规则打分器失效,需要 LLM-as-Judge。Molt 对此有两层支持:
3.1 通过 ChatAgent 调用同一组 vLLM 引擎
ChatAgent路径(molt/agents/chat_agent.py)会在会话地址下自动拉起一个 OpenAI/Anthropic 兼容的 FastAPI 服务。你在代理里用标准的AsyncOpenAI客户端发起第二次请求,把"模型回答 + 评分提示词"发给它,让模型自己打分:
class JudgeAgent(ChatAgent): async def run(self, ctx: ChatContext) -> Result: client = AsyncOpenAI(base_url=ctx.base_url, api_key=ctx.api_key) resp = await client.chat.completions.create(model=ctx.model_name, messages=list(ctx.messages), ...) judge = await judge_with_same_engine(client, resp.choices[0].message.content) return Result(reward=judge_score, info={"judge": judge_score})因为评委调用走的是 rollout 用的同一批 vLLM 引擎,零额外 GPU 成本;参考最小实现见 examples/python/agents/chat_minimal.py。
3.2 把打分信号交给score做动态过滤
Result还有一个score字段(默认等于reward)。训练时开启:
--algo.dynamic_filtering_enable --algo.dynamic_filtering_range 0.0 1.0框架会按代理的 score 过滤低质量样本再进梯度计算。让评委模型的score输出 0/1 的"是否通过"判断,配合reward输出细粒度分数,是 LLM-as-Judge 场景的常见组合。
四、多轮工具调用实战:Python 沙箱执行器
最有代表性的示例是 geo3k 视觉数学环境 examples/python/agents/geo3k.py:模型可以反复调用python_executor工具验算,最终在<answer>中提交答案才结算奖励。
奖励设计的三个要点:
- 过程不奖励,终点才结算:工具轮返回
Result(reward=0.0, observation=工具输出, terminated=False),只有模型给出最终答案或轮数耗尽时(geo3k.py#L169-L219)才调用_final_reward()对整条轨迹判分; - 提交答案即终止:防止"答完又反复验算"的刷长度行为(length-hacking),代码注释中明确标注了这一失败模式;
- 沙箱安全:工具执行器 examples/python/tools/python_executor.py 用一次性临时目录 + 硬超时(默认 10 秒)+ 内存上限(默认 1GB)运行用户代码,跑飞了也不会卡死 rollout。
多轮奖励天然支持过程奖励 + 结果奖励:你可以在每一轮step()里给小分(比如格式正确 +0.1),最后一轮给大头(答案正确 +1.0),框架会自动累加为trajectory.reward。
五、奖励整形参数速查
代理返回的原始 reward 在进入损失函数前,还可被框架统一整形(定义见 molt/cli/train_rl_ray.py):
| 参数 | 作用 | 典型用法 |
|---|---|---|
--reward.clip_range | 奖励裁剪范围,默认(-10, 10) | 防止评委模型输出异常大分数 |
--reward.overlong_buffer_len+--reward.overlong_penalty_factor | DAPO 式超长惩罚:在max_len最后 B 个 token 内线性升压 | 抑制模型用废话填满上下文 |
--reward.stop_properly_penalty_coef | 截断轨迹的奖励乘系数 C∈[0,1](负值直接替换为 C) | 惩罚答到一半被截断的样本 |
两个长度惩罚互斥(CLI 会直接拒绝同时开启),且都以 rollout 的峰值 segment 计算,不会因多轮上下文压缩而失真。
六、一键跑起来:启动命令与参考脚本
以 4B 文本数学 RL 为例(完整脚本:examples/scripts/quick_start/rl_qwen3_4b.sh):
python3 -m molt.cli.train_rl_ray \ --actor.model_name_or_path /path/to/Qwen3-4B \ --data.prompt_dataset /path/to/prompts.jsonl \ --train.agent_path examples/python/agents/math.py \ --vllm.num_engines 2 --vllm.tensor_parallel_size 2 \ --rollout.batch_size 128 --train.batch_size 128 \ --algo.advantage.estimator reinforce \ --algo.kl.init_coef 0只需把--train.agent_path换成你自己的奖励函数文件,框架会导入其中的AgentRunner类(校验逻辑见 molt/agents/base.py#L281-L297)。仓库提供了四套可直接参考的代理:
| 代理 | 路径 | 演示内容 |
|---|---|---|
| 单轮规则打分 | examples/python/agents/math.py | \boxed{}判分,最小模板 |
| VLM 多轮 + 工具 | examples/python/agents/geo3k.py | Python 沙箱工具调用 |
| ChatAgent 最小示例 | examples/python/agents/chat_minimal.py | OpenAI SDK 黑盒 rollout |
| ChatAgent 多轮工具 | examples/python/agents/chat_geo3k.py | 自管理轮次上限 |
七、总结:三步写出你的自定义奖励函数
- 选路径:简单单轮/框架管循环 → 继承
Env;自己管多轮对话/外部 SDK → 继承ChatAgent; - 写判分:在
step()/run()里用任意 Python(正则、执行器、LLM-as-Judge 回调)计算分数; - 返回 Result:
reward必填,info加诊断指标、score加过滤信号,--train.agent_path指向文件即可训练。
Molt 把"奖励函数"从框架组件降级成了普通 Python 代码,这正是它 ~9.2K 行还能支撑 1T 级 MoE agentic RL 的原因——你能在 Python 里算出来的,都是合法的奖励。
【免费下载链接】labs-molt
A scalable, agentic-first, and HuggingFace-native RL framework for research (9k lines).
相关推荐
openjiuwen.agent_evolving.agent_rl.online.judge 模块解析:LLM-as-a-Judge 多维奖励评分器与延迟判分流水线
openjiuwen.agent_evolving.agent_rl.online.judge 模块解析:LLM as a Judge 多维奖励评分器与延迟判分
人工智能AI AgentAgent 框架大模型工具调用RAG提示工程强化学习TensorTrade 奖励函数设计实战:从 PBR 到自定义 Reward Scheme 的完整指南
TensorTrade 奖励函数设计实战:从 PBR 到自定义 Reward Scheme 的完整指南 导读 奖励函数(Reward Scheme)是 Tens
人工智能金融科技机器学习OpenRLHF 自定义奖励函数与 Agent RLHF 实战:从 RFT 单步打分到多步环境交互
OpenRLHF 自定义奖励函数与 Agent RLHF 实战:从 RFT 单步打分到多步环境交互 导读 本篇技术指南聚焦 OpenRLHF 训练框架中最灵活的
AI 技能人工智能大模型深度学习
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考