字数 6210,阅读大约需 29 分钟
强化学习的核心原理很简单:一个系统执行动作,环境给予奖励,智能体更新其行为以随时间最大化该奖励。
上述交互以离散步骤进行。在每一步中,按顺序发生三件事:
1. 智能体观察环境的当前状态(S)。状态是对智能体所处情境的描述,足以决定下一步该做什么。例如,在国际象棋中,状态是棋盘位置;在对话模型中,状态是迄今为止的对话历史。 2. 智能体根据其所见选择动作(A)。动作是智能体的输出,是它影响环境的唯一方式。例如,在国际象棋中,动作是合法走棋;对于LLM,动作是生成的回复。 3. 环境随后做两件事:它转换到新状态(S'),并发出奖励(R),这是一个评估该动作的标量数值。下一步开始,循环继续。
将这些步骤串联起来就形成了一条轨迹:
S₀ → A₀ → R₀, S₁ → A₁ → R₁, S₂ → A₂ → R₂, ...从左到右阅读,这是智能体与环境交互的完整历史。每个(S, A, R, S')四元组是一次转换,而强化学习的大部分工作就是从这些转换中学习。
将RL应用于LLM
当RL首次应用于LLM时,环境是人类的偏好。
OpenAI的InstructGPT(2022年)引入了RLHF(从人类反馈中进行强化学习),其流程是:
• 人类对模型输出进行排名 • 这些排名用于训练奖励模型 • PPO(近端策略优化)使用该奖励模型对LLM进行微调
ChatGPT就是基于这个精确的流程构建的。
但人类无法坐在训练循环中实时对每个输出进行评分。如果模型对每个提示生成16个回复,跨越数千个训练步骤,那就是数十万个评估。
OpenAI通过将过程分为两个阶段来解决这个问题:

第一阶段:离线阶段。在这里,人类对相对较小的模型输出集进行排名,并生成成对比较。这是昂贵的人力劳动部分,但这是一次性成本。
第二阶段:他们用这些排名训练奖励模型,这是一个单独的LLM,学习预测人类会偏好什么。现在你有了一个神经网络,可以立即对任何输出进行评分,无需等待人类。奖励模型是人类判断的压缩近似值,快到足以放入训练循环中。
有了奖励模型,PPO可以以GPU速度运行实际的RL训练。模型生成回复,奖励模型对其进行评分,PPO更新权重,无需大量人力。
然而,代价是PPO需要同时在内存中保留四个完整大小的模型:

1. 策略(正在训练的LLM) 2. 参考策略(原始模型的冻结副本,用于通过KL散度惩罚防止训练偏离太远) 3. 奖励模型(上述讨论的人类偏好近似器,用于对每个输出进行评分) 4. 以及评论家,也称为价值模型(详见下文)
评论家的存在是为了回答一个问题:
这个奖励相对于我们通常对该提示的预期是好还是坏?
我们需要这个,因为原始奖励0.7单独来看毫无意义。例如,在一个简单的事实问题中,大多数回复得分为0.9,那么0.7就低于平均水平。但如果在一个复杂的开放式问题中,大多数回复得分为0.4,那么0.7就是优秀的。

评论家通过在训练期间观察数千个(提示,奖励)对来学习这个基准。
PPO的实际训练信号是优势,估算为奖励减去评论家预测的基准。这使得信号在不同难度提示之间保持稳定。但代价是评论家本身就是一个完整大小的LLM,又增加了一个模型的内存占用。对于一个70亿参数的LLM,这意味着大约需要280亿参数同时驻留在内存中。
DeepSeek R1突破:使用可验证奖励
2025年1月,DeepSeek发布了R1,采用了一种根本不同的奖励信号方法。
他们没有从人类偏好中训练奖励模型(RLHF流程的第1和第2阶段),而是使用了RLVR(使用可验证奖励的强化学习)。
这是一种简单的、基于规则的验证,环境本身提供信号。例如:

• 对于数学问题,验证器检查模型的答案是否与已知解匹配 • 对于代码,编译器运行输出并返回通过或失败。二进制奖励:正确得1分,错误得0分
由于ground truth是可用的(或可推断的)用作奖励,因此不需要人类排名或显式奖励模型。
RL优化器是GRPO(群体相对策略优化),它剥离了PPO的大部分基础设施。它完全移除了评论家模型。
GRPO不是训练单独的模型来预测每个提示的预期奖励,而是对同一提示生成多个回复(通常16个),并在每个组内对奖励进行归一化。

如果16个回复中有4个正确解答了数学问题,这4个获得正向优势,另外12个获得负向优势。
这一步骤从内存中削减了整个完整大小的模型。
GRPO还移除了对学习奖励模型的需求,因为RLVR的验证器直接处理评分。
因此,四个模型的PPO设置(策略+参考+评论家+奖励模型)缩减到仅两个,即正在训练策略和用于KL正则化的参考副本。
事实上,在实践中,一些实现将参考合并到策略检查点中,接近于单模型设置。
凭借这个设置,DeepSeek R1-Zero,仅使用GRPO和可验证奖励进行训练(完全没有监督微调),在AIME 2024数学问题上的成绩从15.6%提升到77.9%。使用多数投票,达到了86.7%,与OpenAI的o1持平。
该模型自己开发了自我验证、反思和链式思维推理能力,完全来自二进制正确/错误的信号,没有人教它逐步推理。RL训练循环发现推理能改善奖励,所以模型学会了推理。
RLVR与GRPO成为2025年训练推理模型的主导方法。每个主要实验室都遵循这个方法发布了推理变体。
问题
GRPO本身是通用的。它不关心奖励来自数学验证器、代码编译器、人类还是Python脚本。它只需要每个回复一个数字,然后对每个组内的奖励进行归一化以产生训练信号。

但这里一个明显的瓶颈是这些奖励来自哪里。
对于数学和代码来说,这没问题,因为环境提供了确定性信号。但是,与真实世界工具和数据交互的智能体产生的输出无法用字符串匹配与正确答案进行比较。
RAG智能体检索上下文并生成回复。没有单一的正确答案可以比较。客服智能体起草回复。没有编译器可以运行它。摘要智能体将20页文档压缩。有许多有效的摘要,没有字符串匹配验证器能够区分好的和一般的。

在这些情况下,环境不会像数学问题那样给你奖励信号。
当然,一些智能体任务确实有可验证的结果,对于这些,RLVR工作得很好,即使涉及多步工具使用。可验证性取决于任务的结果,而不是模型是否作为智能体行事。但对于大多数智能体工作流,结果是主观的或多维的。
直观地说,GRPO仍然是正确的选择,因为采取多个步骤、调用工具和组合回复的智能体将从探索中受益,尝试不同方法,并因有效的方法而得到强化。所以,虽然RL框架是正确的选择,但缺失的部分是评分函数。
一种解决方案是编写自定义奖励函数,用Python代码根据手定义的规则对每个输出进行评分。例如:

• RAG奖励函数可能检查回复是否使用了检索到的上下文(忠实度),惩罚不在上下文中的内容(幻觉),奖励完整性,并处理上下文本身模糊的情况 • 工具使用奖励函数可能对多步任务的阶段性进展进行评分,惩罚不必要的API调用,并测量智能体是否达到正确的最终状态
每个标准返回一个部分分数,然后求和或加权得到最终奖励。
这有效,但它引入了自己的问题。编写一个好的奖励函数需要数天的迭代。研究人员需要预见边缘情况,校准不同标准之间的权重,并测试函数是否真正奖励了你想要的行为。
一个过度权重格式合规而低估忠实度的奖励函数会训练出一个产生格式精美但充满幻觉的智能体。
奖励函数也很脆弱。如果你改变检索管道、添加新工具或修改系统提示,奖励函数需要重写。
调试也很成问题。当智能体在训练过程中学会不良行为时,原因可能是奖励函数、训练超参数、数据或其他东西。但由于奖励函数是自定义代码,你通常无法判断函数是否在测量你认为是测量的东西,直到你已经用它训练了一个模型并评估了输出。
这就是RL在可验证任务(数学、代码、逻辑)中被广泛采用,但在智能体工作流(RAG、客服、工具使用、摘要)中没有被广泛采用的主要原因。
RLVR为推理模型提供了一个通用的、自动化的奖励信号,它们可以检查答案并返回0或1。对于大多数智能体工作流,没有这样的等价物。
区别不在于模型。同一个Qwen 2.5 14B可以扮演两种角色。区别在于任务。我们能否验证智能体是否产生了可以自动检查的输出?
AI实验室如何解决这个问题?
这不是只有开源实践者才注意到的问题。主要AI实验室一直在从不同方向趋同于同一个问题。
Anthropic证明你根本不需要人类在RL循环中。他们的Constitutional AI工作表明,如果你写下一组原则("宪法"),AI可以根据这些原则评估输出,并生成用于RL训练的人类偏好数据。AI根据书面原则评判自己的输出,并使用这些判断作为RL信号。这是一个重要的概念转变,一份规则文档取代了人类评估员大军。

OpenAI一直在内部开发类似的东西。他们正在开发"通用验证器",这是一种将RL扩展到数学和代码之外的领域(如生物学、医学和通用知识)的技术,这些领域的答案无法用简单的字符串匹配来检查。细节没有公开,但方向很明确:我们需要跨任何领域工作的通用奖励信号,而不仅仅是具有确定性验证器的领域。
RULER
如果你想看实际应用,RULER内置于OpenPipe的ART框架中(开源,9k+星),是一个通用奖励函数,用单个函数调用替换了所有那些自定义评分代码。

它使用LLM-as-judge对多个轨迹进行排名,它利用了使GRPO强大的相同属性——只有相对排名才重要。
以下是它逐步工作的方式:

对于每个训练步骤,你为同一场景生成N个轨迹(通常4到8个)。
RULER将所有N个发送给裁判LLM(如o3、o4-mini,甚至本地Qwen3 32B)。
裁判读取智能体的系统提示以了解智能体应该做什么,然后相对于其他轨迹对每个轨迹进行0到1的评分。
两个属性使这成为可能:
1)相对评分比绝对评分更容易。
LLM在绝对评分方面表现挣扎,因为没有共同的校准。但问"这4个回复中哪个最好遵循了系统提示的指令"是一个比较任务,LLM在这类任务上表现一致。RULER利用这一点,将所有轨迹一起呈现,要求裁判相互排名。
2)GRPO无论如何都会在每个组内进行归一化。
最好的轨迹在绝对值中是0.9还是0.3并不重要。GRPO取组内的分数,计算均值和标准差,然后归一化。训练信号来自相对排序,理解哪些轨迹高于平均,哪些低于平均。RULER的相对排名直接映射到GRPO期望的内容。
一个粗略的演练
在跳入代码之前,让我们概念性地追踪发生了什么。假设你正在训练一个RAG智能体。在每个训练步骤,GRPO为同一查询生成多个回复:

在传统设置中,你会编写奖励函数对每个进行评分:

每个辅助函数(uses_context、has_hallucination、is_complete、is_concise)都是自己的工程项目。你需要精确定义"使用上下文"的含义,决定阈值,处理边缘情况,并测试一切。
使用RULER,你用以下代码替换所有这些:

裁判LLM读取系统提示("仅使用检索到的上下文回答。不要添加不在上下文中的信息。"),读取所有四个回复并评分。系统提示已经隐式定义了忠实度、幻觉和完整性。裁判应用这些标准,无需在Python中实现它们。
轨迹和轨迹组
ART将每个智能体回复表示为轨迹(Trajectory),这是一系列消息(系统、用户、助手),打包了GRPO训练所需的元数据。同一场景的多个轨迹形成一个轨迹组(TrajectoryGroup)。这是RULER评分和GRPO训练的单位。

reward=0.0 的初始化是一个占位符。
在 ruler_score_group 返回后,每个轨迹的 reward 字段会用裁判的评分进行更新。
Choice 和 ChatCompletionMessage 对象是 OpenAI 的标准类型,所以如果你已经在使用 OpenAI SDK 进行推理,这些就是你已经在使用的相同对象。
两个具体示例
RULER有两个级别的API。
1)低级ruler函数
低级ruler函数处理普通消息字典,因此不需要ART特定的对象。这是了解RULER实际做什么的最快方式。
让我们看一个最小示例,对同一RAG查询有三个轨迹。
下面,我们定义了三个消息列表:一个忠实的,一个产生幻觉的,一个完全忽略上下文的。
接下来,我们运行评分:

这产生以下输出:

注意,我们从未编写忠实度检查器或编码幻觉检测器。系统提示提到"使用检索到的上下文准确回答用户查询",裁判应用该标准作为评估标准。
幻觉回复得0.45分(不是零),因为它部分使用了上下文。30天退款部分是正确的。裁判给了部分分数奖励正确的部分,并惩罚了编造的部分。这是一个微妙的区别,在基于规则的奖励函数中需要大量工程才能编码。
而且,分数分布在0-1范围内:0.97、0.45、0.05,不像二元通过/失败。RULER产生反映相对质量的梯度。GRPO可以使用这个梯度来应用比例更新,强力强化忠实行为,轻度抑制幻觉模式(因为它部分正确),并强力抑制忽略上下文的行为。
2)高级ruler_score_group函数
上面的ruler函数适合理解和实验,但ART的训练循环在轨迹和轨迹组对象上操作。这些携带GRPO读取的奖励字段、用于检查的调试日志,以及model.train()期望的结构。
之后,高级ruler_score_group函数处理转换。
下面,让我们看同一个RAG场景,结构化为在真实训练管道中使用的方式,现在有4个轨迹而不是3个。

现在我们有4个轨迹而不是3个。第四个是冗长但准确的回复,只使用检索到的上下文,但用不必要的填充词/句子包装。
我们定义轨迹和轨迹组:

最后,我们运行评分:

这是原始推理:

如果你仔细注意...
• 简洁忠实回复(0.98)仅比冗长准确回复(0.96)高一点。两者都只使用检索到的上下文,都是正确的,但系统提示说"仅使用检索到的上下文回答",而简洁版本更直接地做到了这一点。裁判认识到冗长是轻微的质量问题,而不是正确性问题。这是一个微妙的区别,很难在评分函数中编码,因为你如何写出一条规则说"技术正确但不必要的冗长,扣0.02分"? • 幻觉回复从第一次实验的0.45下降到这里的0.20。区别在于系统提示。第一次实验说"使用检索到的上下文准确回答"。这次说"不要添加不在上下文中的信息"。更严格的指令产生了更严格的评分。裁判自动适应了。如果你收紧系统提示,RULER会自动收紧其评估以匹配,而你无需更改任何评分代码。 • 忽略上下文的回复在两个实验中都得0.05分。当答案就在检索到的上下文中,而智能体说"我不确定"时,无论系统提示如何措辞,都没有歧义。
这些评分的轨迹正是model.train()期望的,所以让我们看看。
完整训练循环
要实际使用这些分数进行训练,你用真实的模型推理替换硬编码回复。
ART的gather_trajectory_groups处理编排。本质上,对于每个场景,它使用模型的当前权重生成一组轨迹,用RULER对其进行评分,并收集GRPO的结果:

在每一步中,模型使用当前权重为每个场景生成4个回复,RULER相对排名,GRPO强化高分行为同时抑制低分行为。
智能体在每次迭代中都会更好地遵循系统提示的指令。经过多步,模型学会得分高的模式(忠实度、简洁性、基于上下文),并忘掉得分低的模式(幻觉、忽略上下文、冗长)。
注意,在这段代码中任何地方都没有定义奖励函数。
应用于不可验证任务
RULER是通用的。它适用于任何任务,而不仅仅是自定义奖励痛苦的形式自由任务。
实际问题是什么时候RULER比更简单的替代方案增加价值。
对于纯确定性任务(SQL查询返回正确的行了吗?),二进制验证器更便宜,给出更清晰的信号。对于纯主观任务(摘要好吗?),RULER是唯一的自动选项。对于介于两者之间的任务(智能体找到正确答案并很好地解释了吗?),你可以结合两者:

RULER在你分配的任何 rollout奖励下保留为单独指标,因此你可以在确定性验证之上叠加LLM-judge评分,而不会丢失任何信号。
实践细节
以下是我们基于使用RULER收集的一些实践见解:
• 你不需要最贵的模型作为裁判。更便宜的模型如Qwen3 32B通常效果很好。你也可以使用Claude、通过Ollama的本地模型,或任何LiteLLM支持的模型。这是成本-质量权衡,而不是硬性要求。 • 每组4到8个轨迹是推荐范围。少于4个给裁判的比较参照太少。多于8个可能混淆裁判,增加成本而没有相应好处。 • 当组中的所有轨迹共享相同的系统提示和用户消息时(通常如此),RULER自动去重公共前缀。裁判只看到一次共享上下文,然后是不同的回复。这对长系统提示或多轮对话大幅削减token使用量。 • RULER将裁判响应缓存到磁盘。如果你重新运行相同的轨迹,它不会再次调用API。这在调试时很重要,因为你要迭代系统提示或评分标准。
结论
将RL应用于智能体的瓶颈从来不是优化算法。GRPO很好地处理了这一点。它一直是奖励信号。
RLVR通过让环境直接对输出评分来解决可验证任务的这个问题。RULER通过让LLM裁判相对地对输出评分来解决所有任务(可验证或不可验证)的这个问题。
完整实现在ART仓库中,还有Colab笔记本带你逐步完成端到端训练循环。
仓库:https://github.com/OpenPipe/ART
夜雨聆风