更新时间:2026-09-17 GMT+08:00
分享

步骤二:配置优化方法和奖惩机制

强化学习的核心是通过奖励信号引导模型优化输出质量。本章节将围绕奖励机制配置展开,帮助您根据智能体的输出类型选择合适的训练策略。

本章节内容导航:

配置优化方法

为了降低模型的训练门槛并提升训练效果,平台预置了GRPO(群组相对策略优化)算法,与传统的强化学习算法(如PPO)相比,GRPO具有显著的工程优势:

  • 去除庞大的评论模型:传统算法需要同时运行两个大模型(一个负责生成的模型,一个负责打分的评论模型)。GRPO算法通过独特的数学设计,彻底砍掉了庞大的评论模型,让训练变得极其轻量、高效。
  • 群组对比优化:在训练过程中,模型对同一道题同时生成多个回答,并根据您配置的奖励规则对这几个回答打分排序。得分最高的回答会被强化,得分最低的回答会被抑制。通过这种“组内对比”的方式,模型逐步学会输出更高质量的回答。

配置奖惩机制

GRPO算法的核心是“通过对比学习优劣”,而奖惩机制定义了“什么是好,什么是坏”。平台为您提供三套打分标尺:

关于如何根据智能体的输出形态选择奖惩机制,请参考如何为智能体匹配最佳奖惩机制。

表1 奖罚机制类型

类型

适用场景

核心特点

规则奖励

结构化输出(JSON)、数值计算、严格意图路由等有明确标准、易于量化比对的场景。

基于规则匹配,匹配成功得分,匹配失败扣分。包含两大类原子能力:

  • 格式奖励(思维链格式校验)
  • 正确性奖励(精确匹配奖励、数学准确性奖励)

生成式奖励

客服对话、文章生成、代码生成与解释等开放式问答场景。

像人类一样理解语义与逻辑,支持0.0-1.0的精细化评分。

自适应奖励

上述两种奖励方式无法满足的复杂场景,例如需要引入外部业务逻辑、自定义计算规则或调用第三方依赖库的场景。需校验 Agent 运行的中间轨迹(如工具调用参数)、需结合外部业务逻辑进行复杂判定,或其他正则/大模型打分均无法精确覆盖的确定性场景。

基于代码开发生成奖励规则。平台将Agent运行产生的完整轨迹数据以标准格式传入用户编写的Python代码,由代码返回最终奖励分数,适合确定性奖励任务。

对于包含插件、MCP工具调用能力的单智能体:

  • 如果业务只关心最终输出是否正确,可继续使用规则奖励或生成式奖励。
  • 如果业务还需要检查是否调用了指定工具、调用顺序是否合理、参数是否正确、步骤是否执行成功,推荐使用自适应奖励,通过读取trajectory.steps中的工具调用轨迹进行打分。

规则奖励配置说明

规则奖励适用于输出有明确标准、易于量化比对的场景。在界面中,规则奖励被细分为“格式奖励”与“正确性奖励”两大类使用时,可以二选一或者均使用,共包含三种原子能力。您可以按需组合使用,平台支持通过AI自动生成正则表达式,您也可以通过正则表达式写作示例进行了解:

表2 规则奖励说明

规则奖励类型

功能说明

打分机制

界面配置要点

格式奖励(思维链格式校验)

强制要求模型的回复必须符合特定的结构规范(例如强制包含<think>思考过程标签,或回答中必须包含特定信息)。

格式匹配成功+1.0分,匹配失败给0分。

启用此项时,您必须填写正则表达式,系统将依据此正则对模型的“完整输出”进行格式校验。

权重建议:同时开启正确性奖励时,权重建议设置为0.2、0.3,作为正确性奖励的辅助格式约束项。

正确性奖励(精确匹配)

检查模型的回答是否与您数据集中的标准答案完全一致。

匹配成功给+1.0分,匹配失败给0分。

不填正则表达式:系统会将模型生成的完整回复与标准答案进行全文比对。只要模型多说了一句废话(如“好的”),就会被判为错误。

强烈建议:填写正则表达式:系统会先利用正则从模型的回复中精准提取关键信息,仅对比提取出的内容与标准答案是否一致。极大提升了校验的容错率。

权重建议:如果配合格式奖励启用,权重设置建议0.7、0.8。

正确性奖励(数学准确性)

专为数学与工程计算设计。底层调用专业的符号计算引擎,检查回答在“数值上”是否与标准答案相等。它能聪明地识别0.5等于1/2,1.0等于1,并默认容忍1%的浮点数相对误差。

不倒扣分的宽容机制。正确给+1.0分,错误给0.0分。因为数学推导本身就较难,不倒扣分可以鼓励模型大胆试错探索。

不填正则表达式:系统将尝试把模型的完整回复强制解析为数字。

强烈建议:填写正则表达式:系统会利用正则从回复中“抠出”特定数值部分,再将该数值交给符号引擎进行等价性比对。

权重建议:如果配合格式奖励启用,权重设置建议0.7、0.8。

规则奖励组合选择建议:

  • 仅需校验答案正确性(标签/数字ID输出):单独使用精确匹配。
  • 仅需校验答案正确性(数值输出):单独使用数学准确性。
  • 需同时约束思考过程和答案正确性(数学/逻辑推导):思维链格式奖励 + 数学准确性。
  • 需同时约束输出格式和答案正确性(结构化输出):思维链格式奖励 + 精确匹配。

当同时配置“思维链格式奖励”与“正确性奖励”时,各项权重的总和无需严格等于1。为起辅助约束作用的“思维链格式奖励”设置较低权重(如0.2~0.3),确保模型将重点聚焦于答案本身的准确性,防止模型投机取巧凑格式而答错题。

生成式奖励配置说明

当需要对开放式问答场景的Agent进行强化学习时,需要使用生成式奖励,即由大模型作为裁判对Agent的输出结果进行理解和打分。裁判大模型最终会返回一个0.0到1.0的绝对分数。为了防止裁判“主观乱打分”,您必须在配置界面的“评分标准”输入框中,撰写一份逻辑严密的评分规则。

撰写一份评分标准,请遵循以下法则:

第一步:确立核心评分原则和权重划分

一开始就要向裁判模型讲清楚,本次评判最看重什么。是正确性、还是语气态度,或者是代码的可执行性。

参考示例:核心原则:正确性是基础(权重90%),效率和清晰度是加分项(权重10%)。

第二步:精准量化分数段

绝对不能只写“根据质量打 0-1 分”,必须明确告诉裁判模型,什么表现对应什么分数段。

参考示例:

1.0分:答案完全正确,格式完全符合预期,无废话。

0.7 - 0.9分:答案正确,但存在轻微的格式问题或语气不够自然。

0.4 - 0.6分:部分正确,缺失次要信息,但有明显的解题进展。

0.0 - 0.3分:答案错误,或完全偏离主题。

第三步:设立“一票否决”的底线红线

强化学习需要对致命错误进行严厉打击。您必须单独列出哪些情况直接判定为0分,防止模型通过其他维度的表现骗取及格分。

参考示例:

扣分情形:存在事实性错误、缺失关键信息、出现严重幻觉,请直接记为0分。

生成式奖励需要填写“API密钥凭证提供者”以获取评判模型的调用权限。裁判模型的API调用将产生费用,费用由您在MaaS平台配置的API Key对应账户承担。

自适应奖励配置说明

当规则奖励的正则匹配过于死板,而生成式奖励的大模型打分不够精准可控时,您可以使用“自适应奖励”。该模式允许您编写一段Python代码,在代码解释器中执行该代码来计算奖励得分。

与前规则奖励、生成式奖励方式相比,自适应奖励的最大优势在于:平台会将Agent运行的完整轨迹数据(Trajectory)传入您的代码,而不仅仅是最终的回复文本。这意味着您不仅能校验Agent“回答得对不对”,还能像“白盒测试”一样深入审查它的“解题过程”,了解Agent是否调用了正确的工具、工具参数是否正确、大模型的中间推理是否合理等。

适用场景:

  • 多步工具调用校验:不仅关心Agent最终回答是否正确,更要验证它是否调用了正确的工具、工具的入参是否符合预期。例如:要求Agent必须通过查询数据库工具获取考勤记录,而不是靠幻觉编造结果。
  • Agent运行轨迹合规性检查:验证Agent的中间推理步骤是否符合业务规则。例如:在审批流程中,Agent必须先调用权限校验工具,再执行审批操作。
  • 组合评分逻辑:需要同时考量多个维度(如最终答案正确性 + 工具调用正确性 + 响应时长),并用加权公式计算综合分数的场景。
  • 外部依赖验证:需要调用第三方Python库(如numpy、re等)进行结果校验的场景。

选择“自适应奖励”后,需要完成以下两项配置:

1. 选择代码解释器

代码解释器是运行自适应奖励代码的沙箱环境。您需要提前在平台中创建并初始化代码解释器(包括安装所需的pip依赖、上传自定义Python文件等),完成后在此处选择对应的代码解释器。

代码解释器创建方法请参考创建代码解释器。

2. 编写执行函数

在代码输入框中,填写用于计算奖励的Python代码片段。编写要求如下,payload完整字段说明请参考附录:自适应奖励payload数据格式说明。

  • 必须包含{{payload}}占位符:训练时平台会将Agent运行产生的完整轨迹数据(JSON字符串)替换到{{payload}}的位置,您在代码中通过json.loads()进行解析后使用。
  • 必须通过print()输出一个数值作为奖励分数:平台读取代码标准输出的数值作为本次的奖励得分,建议返回范围在0.0 ~ 1.0之间。

代码示例:

平台已为您预置了一段默认代码,您可以直接在此基础上修改。

import json

def cal_reward(payload_str):
    # 1. 解析系统传入的 payload 数据
    data = json.loads(payload_str)

    # 2. 获取标准答案与 Agent 的实际最终输出
    reference_output = data.get("reference_output")
    actual_output = data.get("trajectory", {}).get("root", {}).get("output")

    # 3. 编写您的自定义校验逻辑
    return 1 if reference_output == actual_output else 0

# {{payload}} 为必要引用变量,系统会将其替换为真实的 JSON 字符串
print(cal_reward({{payload}}))
  • {{payload}}是平台的数据注入占位符。训练时,平台会把本次 Agent 运行产生的轨迹数据(JSON字符串)替换到这里,传给cal_reward函数。
  • data = json.loads(payload)把平台传入的JSON字符串解析成Python字典,方便后续读取字段。
  • reference_output = data.get("reference_output")从payload中取出数据集里的标准答案,也就是您在准备数据集时填写的reference_output字段。

    例如您的数据集中有这样一条数据:

    {"input": "我家宽带断了", "reference_output": "故障报修"}

    那么这里取到的reference_output就是 "故障报修"。

  • actual_output = data.get("trajectory").get("root").get("output")从轨迹数据中取出Agent本次运行的最终回复。可以把这个路径理解为:
    • trajectory:本次Agent运行的完整轨迹数据。
    • root:本次运行的整体汇总,记录了Agent从收到用户问题到给出最终回复的结果。
    • output:Agent最终返回给用户的回复文本。
  • return 1 if reference_output == actual_output else 0把标准答案和 Agent 实际输出做对比:相同则返回 1(满分,模型回答正确);不同则返回 0(零分,模型回答错误)。

默认代码说明

默认代码做的是完整字符串精确匹配:只要Agent的输出和标准答案有任何一个字符不同,就给0分。

这在某些场景下会过于严格,例如:

  • Agent 输出 "故障报修\n",标准答案是 "故障报修",因末尾多了换行符导致匹配失败。
  • Agent 输出 " 故障报修 ",标准答案是 "故障报修",因首尾有空格导致匹配失败。

另外,默认代码只校验最终答案,无法检查Agent的执行过程,例如是否调用了正确的工具、工具参数是否正确。

当遇到上述情况时,可以在默认代码的基础上进行扩展。

代码常用写法与脚本示例

  • 示例一:去除首尾空格,避免误判

    适用场景:意图分类、标签输出、状态码输出。

    在默认代码基础上加 .strip(),去除首尾的空格和换行符:
    import json
    
    def cal_reward(payload):
        data = json.loads(payload)
        reference_output = data.get("reference_output", "").strip()
        actual_output = data.get("trajectory").get("root").get("output", "").strip()
    
        return 1 if reference_output == actual_output else 0
    
    print(cal_reward({{payload}}))
  • 示例二:加入异常保护

    适用场景:所有生产环境中的脚本。

    建议在所有脚本中加入 try-except,避免因为单条样本数据异常导致训练中断:
    import json
    
    def cal_reward(payload):
        try:
            data = json.loads(payload)
            reference_output = data.get("reference_output", "").strip()
            actual_output = data.get("trajectory").get("root").get("output", "").strip()
    
            return 1 if reference_output == actual_output else 0
        except Exception:
            return 0
    
    print(cal_reward({{payload}}))
  • 示例三:必须调用指定工具才给分

    适用场景:防止模型跳过工具调用、直接编造答案。

    如果只校验最终答案,模型可能靠猜测得到正确结果,而没有真正调用工具。这时可以检查trajectory.steps,验证Agent在执行过程中是否真的调用了指定工具。

    trajectory.steps是Agent运行过程中所有执行步骤的列表,按执行顺序排列,每个步骤包含以下常用字段:
    表3 参数说明

    字段

    说明

    type

    步骤类型,llm为大模型调用,tool为工具调用。

    name

    步骤名称,工具步骤中可用于识别调用的是哪个工具。

    input

    步骤输入内容,工具步骤中可用于检查传入的参数。

    output

    步骤输出结果。

    status

    执行状态,success为成功,failed为失败。

    import json
    
    def cal_reward(payload):
        try:
            data = json.loads(payload)
            steps = data.get("trajectory").get("steps", [])
    
            for step in steps:
                if step.get("type") == "tool" and step.get("name") == "query_attendance_db":
                    return 1
            return 0
        except Exception:
            return 0
    
    print(cal_reward({{payload}}))
  • 示例四:工具调用正确,参数也提取正确

    适用场景:工具参数提取、工号/订单号/设备号等关键参数校验。

    工具名对了,但参数填错了,同样应该扣分。step.input通常是一个JSON字符串,需要先用json.loads()解析成字典,再读取具体参数字段。

    在此类场景中,reference_output可以用作校验基准值而非最终回复文本。数据集可以这样构造:
    表4 数据集示例

    input

    reference_output

    帮我查一下张三(工号1001)上个月的考勤记录

    1001

    查一下李四(工号2058)上周的考勤情况

    2058

    import json
    
    def cal_reward(payload):
        try:
            data = json.loads(payload)
            expected_emp_id = data.get("reference_output", "")
            steps = data.get("trajectory").get("steps", [])
    
            for step in steps:
                if step.get("type") == "tool" and step.get("name") == "query_attendance_db":
                    try:
                        tool_params = json.loads(step.get("input", "{}"))
                    except Exception:
                        tool_params = {}
                    if tool_params.get("emp_id") == expected_emp_id:
                        return 1
    
            return 0
        except Exception:
            return 0
    
    print(cal_reward({{payload}}))

    step.input是JSON字符串而不是字典,需要先解析再读取字段。直接做字符串包含判断虽然也能工作,但在参数值存在嵌套或特殊字符时容易误判,建议优先使用解析后读取字段的方式。

  • 示例五:结果与过程都纳入评分
    适用场景:既要最终答案正确,也要执行过程正确。
    import json
    
    def cal_reward(payload):
        try:
            data = json.loads(payload)
            reference_output = data.get("reference_output", "").strip()
            actual_output = data.get("trajectory").get("root").get("output", "").strip()
            steps = data.get("trajectory").get("steps", [])
    
            # 维度1:最终答案是否正确(权重 0.7)
            answer_score = 1 if reference_output == actual_output else 0
    
            # 维度2:是否调用了指定工具(权重 0.3)
            tool_score = 0
            for step in steps:
                if step.get("type") == "tool" and step.get("name") == "query_attendance_db":
                    tool_score = 1
                    break
    
            return 0.7 * answer_score + 0.3 * tool_score
        except Exception:
            return 0
    
    print(cal_reward({{payload}}))

操作步骤

  1. 步骤一:配置优化对象与模型配置完成后,单击“下一步”。进入配置优化方法和奖罚机制页面。
  2. 平台默认使用强化学习和GRPO(群组相对策略优化)算法对智能体中的模型进行优化。优化方法为默认配置,不可修改。

    图1 配置优化方法

  3. 参考配置奖惩机制、规则奖励配置说明、生成式奖励配置说明、正则表达式写作示例、自适应奖励配置说明选择合适的奖罚机制,并进行配置。

    当同时配置“思维链格式奖励”与“正确性奖励”时,各项权重的总和无需严格等于1,为起辅助约束作用的“思维链格式奖励”设置较低权重(如0.2~0.3),以此确保模型在规范输出结构的同时,将重点聚焦于答案本身的准确性,防止模型投机取巧“凑格式而答错题”。

    注意,生成式奖励需要填写“API密钥凭证提供者”。填写该参数后可以获取评判模型的调用权限。在页面单击“前往创建”,配置如下:

    • 身份名称:可自定义。
    • 认证类型:选择“API Key”。
    • API Key值:需登录MaaS模型即服务平台,在API Key管理页面创建,创建时权限范围选择全部即可。
    • 标签:可选,用于分类标记配置信息。
    图2 配置API密钥凭证提供者
    图3 创建出站身份

  4. 奖罚机制配置完成后,参考步骤三:配置超参数配置模型训练超参数。

    奖惩机制配置是训练成功的关键。如果训练后奖励值异常,请优先检查正则表达式和评分标准是否正确,详见常见问题。

正则表达式写作示例

在配置规则奖励时,正则表达式的作用就是切除模型输出的废话,只提取核心答案交给系统进行打分。

您可以通过下方的示例了解正则表达式的构造方法:

示例一:JSON数字提取(适用于输出为状态码、数字ID场景)

假设您的Agent需要输出{"status": 200},而您数据集的答案字段填的是200。

  • 正则写法:\{\s*"status"\s*:\s*(\d+)\s*\}
  • 正则解释:
    • \{ 和 \}:匹配 JSON 的左右大括号。
    • \s*:极其重要!包容大模型生成时随机加入的多余空格或换行。
    • "status":您定义的 JSON 键名(根据业务自行替换)。
    • (\d+):进行数字提取。括号 () 代表提取内容,\d+ 代表精准提取纯数字。系统最终只会拿括号里的数字去和标准答案比对。

示例二:JSON文字标签提取(适用于意图分类场景)

假设您的 Agent 需要输出具体的意图标签,如 {"intent": "故障报修"},而您数据集的答案字段填的是故障报修。

  • 正则写法:\{\s*"intent"\s*:\s*"(.*?)"\s*\}
  • 正则解释:
    • 由于输出的是中文字符串,通常被双引号包裹。因此写成 "(.*?)"。
    • (.*?):进行文本提取。它会提取双引号内部的任何字符(包含中文、英文、符号),直到遇到下一个双引号为止。系统只会拿提取出的文字去和标准答案比对。

示例三:思维链格式校验(适用于强制推理场景)

在使用“思维链格式奖励”时,我们需要验证模型的“完整回复”是否严格按照“先思考,后输出”的结构进行。

假设您在 Prompt 中规定:“请必须先以‘分析过程:’开头进行推理,最后以‘最终答案:’给出结果。”

  • 正则写法:^分析过程:[\s\S]+?最终答案:\s*[\s\S]+$
  • 正则解释:
    • ^分析过程::^ 代表必须以其后的内容开头。强制模型一上来必须进入分析状态,绝不允许在前面输出任何废话(防止模型“脱口而出”错误答案,破坏思维链)。
    • [\s\S]+?:万能匹配符,包容分析过程中的所有推理文字和换行符(使用 +? 确保思考过程不能为空)。
    • 最终答案::匹配思考结束、答案开始的边界词。
    • \s*[\s\S]+$:代表在“最终答案:”之后,必须有实质性的内容输出。$ 代表文本到此结束。

示例四:特性锚点的数值提取(适用于数学推导)

假设在数学计算中,要求模型最终以ANSWER: 113.04格式输出最终的计算结果。

  • 正则写法:ANSWER:\s*(\d+\.?\d*)
  • 正则解释:
    • ANSWER:\s*:检索“ANSWER:”关键字,并自动忽略冒号后多余的空格。
    • (\d+\.?\d*):匹配并提取紧跟“ANSWER:”后面的整数或浮点数(如将提取113.04)。

如果配置正则表达式后训练奖励值始终为0,可能是正则写错,请参考常见问题。

相关文档