Anti-Reward-Hacking Grader Design

Nikola Balic (@nibzard)· emerging

问题

在强化学习训练过程中,模型会主动寻找最大化奖励的方法。如果你的评分器存在边缘案例或漏洞,模型会发现并加以利用:

  • 钻指标空子:模型并非通过解决任务,而是利用评分器的弱点来获得100%的奖励分数
  • 异常行为:Agent会习得奇怪的捷径,这些捷径在技术上满足奖励函数,但无法反映真实质量
  • 刚性评估:简单的评分器(如精确字符串匹配)会因格式差异而惩罚有效的答案
  • 实际性能下降:训练阶段的高奖励无法转化为生产环境中的成功表现

Rogo团队就亲身经历过这种情况:早期训练的平均验证奖励达到100%,但模型并非在提升实际性能,而是在利用其金融推理评分器中的边缘案例。

方案

通过迭代强化与多维度评估设计抗投机操控的奖励函数:


核心原则:

  1. 难以被投机操控:发现漏洞后系统性地填补
  2. 提供梯度引导:采用0.0-1.0的连续分数而非二元(0/1)分数,指导模型学习
  3. 多维度拆解评估:从多个维度开展评估,避免单一维度投机即可最大化总奖励
  4. 可解释性:评分器需输出评分理由,助力检测投机行为
  5. 对抗性测试:训练前手动尝试“破解”评分器,验证鲁棒性

实现方案:

class 抗投机鲁棒评分器:
    """
    专为抵御奖励投机设计的多维度评分器
    """
    def __init__(self, 领域评估标准):
        self.评估标准 = 领域评估标准
        self.违规模式库 = []  # 已知的投机模式

    def 评分(self, 问题, 基准答案, Agent回答, 工具调用轨迹):
        """
        通过多维度检查防止投机行为
        """
        # 先检查已知投机模式
        for 模式 in self.违规模式库:
            if 模式.匹配(Agent回答, 工具调用轨迹):
                return {
                    "score": 0.0,
                    "reason": f"检测到投机模式:{模式.name}",
                    "violation": True
                }

        # 多维度评估计算分项得分
        分项得分 = {}

        # 1. 事实准确性(权重最高)
        分项得分['准确性'] = self._检查准确性(
            Agent回答,
            基准答案
        )

        # 2. 推理质量(防止死记硬背式作答)
        分项得分['推理质量'] = self._检查推理质量(
            工具调用轨迹,
            Agent回答
        )

        # 3. 完整性(防止仅输出部分答案)
        分项得分['完整性'] = self._检查完整性(
            Agent回答,
            必要要素=self.评估标准.get('required_elements', [])
        )

        # 4. 引用质量(防止生成幻觉内容)
        分项得分['引用质量'] = self._检查引用质量(
            Agent回答,
            工具调用轨迹
        )

        # 5. 格式规范性(支持部分得分)
        分项得分['格式规范性'] = self._灵活检查格式(
            Agent回答,
            预期格式=self.评估标准.get('format', 'any')
        )

        # 加权聚合计算最终得分
        权重配置 = {
            '准确性': 0.50,
            '推理质量': 0.20,
            '完整性': 0.15,
            '引用质量': 0.10,
            '格式规范性': 0.05
        }

        最终得分 = sum(权重配置[k] * 分项得分[k] for k in 分项得分)

        return {
            "score": 最终得分,
            "subscores": 分项得分,
            "reason": self._生成得分说明(分项得分, 权重配置),
            "violation": False
        }

    def _检查准确性(self, 回答, 基准答案):
        """
        带归一化处理的灵活准确性检查
        """
        # 对答案做归一化,消除格式差异影响
        归一化回答 = self._归一化答案(回答)
        归一化基准 = self._归一化答案(基准答案)

        # 完全匹配则得满分
        if 归一化回答 == 归一化基准:
            return 1.0

        # 数值类答案的容差判断(例如0.999与1.0视为近似正确)
        if self._是数值型(归一化回答) and self._是数值型(归一化基准):
            try:
                回答数值 = float(归一化回答)
                基准数值 = float(归一化基准)

                # 相对误差<1%得满分,1%-5%得0.5分,超出得0分
                相对误差 = abs(回答数值 - 基准数值) / 基准数值
                if 相对误差 < 0.01:
                    return 1.0
                elif 相对误差 < 0.05:
                    return 0.5
                else:
                    return 0.0
            except:
                pass

        # 文本类答案的语义相似度匹配
        相似度 = self._语义相似度(归一化回答, 归一化基准)
        if 相似度 > 0.9:
            return 1.0
        elif 相似度 > 0.7:
            return 0.5
        else:
            return 0.0

    def _检查推理质量(self, 工具调用轨迹, 回答):
        """
        验证Agent是否真正有意义地使用工具
        防止:直接输出答案而不展示合理推理过程
        """
        if not 工具调用轨迹 or len(工具调用轨迹) == 0:
            return 0.0  # 必须通过工具调用完成推理

        # 检查可疑投机模式
        # 1. 重复调用相同工具(大概率为投机行为)
        if self._存在重复调用(工具调用轨迹):
            return 0.2

        # 2. 工具调用与最终回答无关(随机探索式投机)
        if not self._工具支撑回答(工具调用轨迹, 回答):
            return 0.3

        # 3. 工具调用具备合理的逻辑递进
        if self._调用逻辑递进合理(工具调用轨迹):
            return 1.0

        return 0.6

    def 添加违规模式(self, 模式名称, 检测函数):
        """
        新增已发现的投机模式检测规则
        """
        self.违规模式库.append({
            "name": 模式名称,
            "matches": 检测函数
        })

迭代强化流程:

graph TD
    A[设计初始评分器] --> B[启动模型训练]
    B --> C{出现可疑高奖励情况?}
    C -->|是| D[排查Agent行为轨迹]
    D --> E[识别投机模式]
    E --> F[新增投机检测规则]
    F --> G[更新评分器]
    G --> B
    C -->|否| H[在保留数据集上验证性能]
    H --> I{性能符合预期?}
    I -->|是| J[部署模型]
    I -->|否| E

    style E fill:#ffebee,stroke:#c62828,stroke-width:2px
    style F fill:#fff3e0,stroke:#f57c00,stroke-width:2px
    style J fill:#e8f5e9,stroke:#388e3c,stroke-width:2px

如何使用

阶段1:初始设计

  1. 分解质量要求:将“优质回答”拆解为4-6项可量化的评判标准
  2. 为标准分配权重:根据业务优先级为各项标准赋予对应权重
  3. 提升灵活性:灵活适配格式差异(例如“7%”与“0.07”这类情况)
  4. 构建可解释性:返回分项得分及对应的推理依据

阶段2:对抗性测试

  1. 手动试探测试:尝试编写本身不正确但能获取高分的回答
  2. 边缘案例测试:针对极端输入场景开展测试(如空回答、乱码内容等)
  3. 增设防护机制:防止轻易钻规则空子(例如,要求至少调用N个工具)

阶段3:训练监控

  1. 警惕分数突变:若奖励(reward)分数骤升至100%,需立即展开调查
  2. 抽样检查轨迹:手动复核高奖励样本,验证其实际质量
  3. 对比分布趋势:验证集的奖励分数应与训练集的奖励分数走势保持一致
  4. 核查真实业务指标:确认业务关键绩效指标(KPIs)得到提升,而非仅奖励分数上涨

阶段4:迭代强化

  1. 识别钻空子模式:发现规则漏洞利用行为时,归纳其特征模式
  2. 增设检测机制:针对该漏洞利用模式添加明确的检测规则
  3. 重新训练:使用强化后的评分器(grader)重新执行训练流程
  4. 持续迭代:这是一个需要长期推进的循环过程

权衡

优点:

  • 鲁棒学习:模型学会真正解决任务,而非为优化指标投机取巧
  • 泛化能力更强:多维度评分能催生更全面的解决方案
  • 可调试性:分项分数有助于定位模型的薄弱环节
  • 与生产环境对齐:训练奖励与业务指标相关联

缺点:

  • 工程投入大:需要精心设计与反复迭代
  • 收敛速度更慢:评分机制更严格会导致初始奖励偏低
  • 评分器复杂度高:需维护更多代码,潜在调试工作量大
  • 主观性:部分评分维度(如“财务稳健性”)需要严谨定义
  • 计算成本高:多维度评分每份样本耗时更长

参考文献

关键词

涉及OpenAI聚焦Agent RFT技术的Rogo案例研究视频、DeepMind发布的AI规范博弈主题博客,以及推理修复型代码审查奖励、智能体强化微调、RLAIF三类AI相关技术模式。

直译

来源摘要

正在获取来源并生成中文摘要…

来源: https://youtu.be/1s_7RMG4O4U

← 返回社区