audieleon/goodhart
GitHub: audieleon/goodhart
对强化学习奖励函数进行静态分析的工具,在训练前检测退化解、激励错位和可利用的奖励结构。
Stars: 0 | Forks: 0
# goodhart
[](https://github.com/audieleon/goodhart/actions/workflows/ci.yml)
[](https://www.python.org/downloads/)
[](LICENSE)
**论文:** [在训练前捕获古德哈特定律:具有形式化保证的静态奖励分析](https://github.com/audieleon/goodhart/blob/main/CITATION.cff) (Sheridan, 2026)
**在训练前捕获奖励陷阱。** Goodhart 在您的 RL 奖励配置上运行 44 条可组合的分析规则,并在您消耗算力之前报告退化均衡、不良激励和可利用的奖励结构。24 条规则由机器验证的 LEAN 4 证明作为支撑(零个 sorry),包括对 Ng 1999 和 Skalse 2022 的形式化。
## 安装
```
pip install goodhart
# 或从源码安装
pip install git+https://github.com/audieleon/goodhart.git
# 可选:可视化与 Gymnasium 自动检测
pip install goodhart[all]
```
## 快速开始
```
# 检查 sparse reward 配置
goodhart --goal 1.0 --penalty -0.01 --steps 500
# -> 关键:death 以 9.6x 击败 survival
# 尝试已发表论文中的示例
goodhart --example coast_runners
# -> 关键:循环 EV (+800) 击败 goal (+100)
# 列出所有可用示例
goodhart --examples
# 交互模式(提出问题)
goodhart
```
## 使用
### CLI
```
# 使用 training params 快速检查
goodhart --goal 1.0 --penalty -0.001 --steps 400 --gamma 0.999 \
--actors 64 --budget 10000000 --lr 1e-4 --specialists 3 --floor 0.10
# 从配置文件(YAML、JSON 或 TOML)
goodhart --config my_experiment.yaml
# 从带有注释的 Python reward function
goodhart --check my_env.py:compute_reward
# 附带教育性解释
goodhart --example humanoid_idle --verbose
# 深入探讨特定规则
goodhart --explain idle_exploit
# 诊断并建议修复方案
goodhart --doctor --goal 1.0 --penalty -0.01 --steps 500
# Machine-readable doctor 输出
goodhart --doctor --goal 1.0 --penalty -0.01 --steps 500 -j
# Field 参考
goodhart --fields # list all fields
goodhart --field intentional # explain one field
# CI 集成
goodhart -q --config experiment.yaml # exit 1 on criticals
goodhart -sq --config experiment.yaml # exit 1 on warnings too
goodhart -sq --ignore idle_exploit --config e.yaml # suppress known-OK warnings
# Grep 友好的输出
goodhart --format compact --config experiment.yaml | grep CRITICAL
# 从 stdin 读取配置
cat reward.yaml | goodhart --config - -j | jq '.criticals'
```
### Python API
```
# 快速检查(打印报告,返回 bool)
from goodhart import check
passed = check(goal=1.0, penalty=-0.01, max_steps=500) # False if criticals
# Programmatic 分析(无打印,返回 typed Result)
from goodhart import analyze
result = analyze(goal=1.0, penalty=-0.01, max_steps=500, gamma=0.999)
print(result.passed) # True/False
print(result.criticals) # list of Verdict objects
print(result.to_dict()) # JSON-serializable dict
```
### 装饰器(注解 Python 奖励函数)
```
from goodhart import reward_function, RewardSource, RewardType
ALIVE_BONUS = 1.0
VELOCITY_SCALE = 0.5
CTRL_COST = -0.001
@reward_function(
max_steps=1000, gamma=0.99, n_actions=8, action_type="continuous",
sources=[
RewardSource("alive", RewardType.PER_STEP, ALIVE_BONUS,
requires_action=False, intentional=True),
RewardSource("velocity", RewardType.PER_STEP, VELOCITY_SCALE,
intentional=True, state_dependent=True),
RewardSource("ctrl", RewardType.PER_STEP, CTRL_COST,
requires_action=True),
],
)
def compute_reward(obs, action, info):
return ALIVE_BONUS + obs["velocity"] * VELOCITY_SCALE + CTRL_COST * sum(a**2 for a in action)
# 函数正常工作并携带分析元数据
compute_reward(obs, action, info) # returns reward
compute_reward.goodhart_check() # prints full report
assert compute_reward.goodhart_passed() # CI gate
```
常量只需定义一次,并在装饰器和函数体之间共享——没有重复,不会产生偏差。
### AI 助手 (Claude Code, Cursor)
如果您使用 AI 编码助手,goodhart 可以在您讨论奖励设计时自动运行。将其添加到您的 MCP 配置中(一次性设置):
```
{
"mcpServers": {
"goodhart": {
"command": "python",
"args": ["-m", "goodhart.mcp_server"]
}
}
}
```
**Claude Code:** 添加到 `~/.claude/settings.json`
**Cursor:** 添加到 `.cursor/mcp.json`
然后只需在对话中描述您的奖励——助手会自动调用 `goodhart_check` 并解释发现的问题。可用工具:check、doctor、explain rules 和 browse examples。
### YAML 配置
```
# my_experiment.yaml
environment:
name: "MiniHack-Navigation"
max_steps: 500
gamma: 0.999
reward_sources:
- name: goal
type: terminal
value: 1.0
discovery_probability: 0.05
- name: step penalty
type: per_step
value: -0.001
training:
algorithm: APPO
lr: 0.0002
entropy_coeff: 0.0001
num_envs: 256
total_steps: 10000000
```
## 示例
来自已发表论文的 66 个内置示例,以及来自奖励失败数据集的 146 个评估条目:
```
goodhart --examples # list all examples
goodhart --example coast_runners # run CoastRunners (loop exploit)
goodhart --example humanoid_idle # run Humanoid (idle exploit)
goodhart --fields # explain RewardSource fields
```
## 规则
分为四类的 44 条可组合规则:
```
goodhart --rules # list all with descriptions
goodhart --explain X # deep-dive on rule X
```
- **19 条奖励规则**:惩罚主导、死亡激励、空闲利用、探索阈值、重生利用、死亡重置、塑造循环、塑造安全性 (Ng 1999)、代理可黑客性 (Skalse 2022)、内在充分性、预算充分性、复合陷阱、阶段性平台、奖励主导、指数饱和、内在主导、折扣视野不匹配、仅负奖励、奖励延迟视野
- **13 条训练规则**:学习率机制(所有算法)、critic LR 比率、熵机制、clip 分数风险 (PPO)、专家崩溃、批次大小交互、并行效应、内存容量、经验回放缓冲区比率(离线策略)、目标网络更新 (DQN)、epsilon 调度 (DQN)、软更新率 (SAC/DDPG/TD3)、SAC alpha
- **4 条架构规则**:嵌入容量、路由下限必要性、循环类型、参与者数量效应
- **8 条盲点建议**:关于静态分析无法检测到的失败模式的基于模式的提示(物理引擎漏洞、目标错误泛化、信用分配深度、约束 RL、非平稳性、学习型奖励、缺失约束、聚合陷阱)
奖励结构规则(19 条)与算法无关——它们分析 MDP 奖励,而不受限于训练算法。训练规则(13 条)涵盖 PPO、APPO、DQN、SAC、DDPG、TD3、IMPALA 和 A2C,并提供针对特定算法的阈值和检查。
## 它能捕获什么与它不能捕获什么
**能捕获**(仅从配置中):
- 退化均衡(静止不动、快速死亡)
- 重生奖励循环(CoastRunners、YouTube 观看时长)
- 死亡即重置漏洞(Road Runner 关卡重放)
- 塑造奖励循环与基于势函数的塑造对比 (Ng 1999)
- 奖励荒漠(无梯度信号,例如 Mountain Car)
- 代理奖励可黑客性 (Skalse 2022)
- 专家崩溃、熵问题、预算不充分
**不能捕获**(在配置模式匹配时发出建议提示):
- 物理引擎漏洞(box surfing、leg hooking)
- 目标错误泛化(CoinRun “向右走”)
- 学习型奖励模型博弈(RLHF 过度优化)
- 缺失奖励项(tokamak 线圈平衡)
- 自博弈中的非平稳性
- Episode 级别聚合陷阱(Sharpe 比率)
## 示例
来自已发表论文(1983-2025)的 66 个内置示例,以及包含来自 133 篇论文的 212 个条目的[奖励失败数据集](https://huggingface.co/datasets/audieleon/reward-failure-dataset):
```
goodhart --examples # list all
goodhart --example coast_runners # run one
```
示例包括文档化的失败案例(CoastRunners、Humanoid、Mountain Car)、积极的设计模式(Pendulum、CartPole、Breakout)、工业应用(YouTube、数据中心冷却、tokamak 等离子体、脓毒症治疗),以及展示静态分析无法检测到内容的真实局限性案例。
## 形式化证明
24 条规则链接到机器验证的 LEAN 4 定理(103 个定理,零个 sorry)。每个链接都有一个强度级别:
- **VERIFIED**(13 条规则):Python 检查是该定理的直接实例。
- **GROUNDED**(7 条规则):该定理证明了核心内容。Python 通过折扣和阈值进行了扩展。
- **MOTIVATED**(4 条规则):该定理证明了问题为何重要。Python 检查的是结构启发式方法。
核心形式化:
- **Ng 1999 定理 1**:基于势函数的奖励塑造保持了 V*(充分性、必要性、通用策略版本、无折扣扩展)。完整的 MDP,其 Bellman 收缩通过巴拿赫不动点定理实现。
- **Skalse 2022 定理 1-3**:开集上的不可黑客性不可能定理、不可黑客对的存在性、简化表征。包括一个机器验证的证明,即定理 2 的非平凡见证构造需要 |Pi| >= 3;对于 |Pi| = 2,只存在平凡见证(已记录的边缘情况,参见 proofs/GoodhartProofs/Skalse.lean)。
```
cd proofs
lake build # requires LEAN 4 + Mathlib
# 应完成且零 sorry,零错误
```
## 自动检测
从 Gymnasium 环境中自动检测奖励结构:
```
pip install goodhart[detect]
goodhart --detect CartPole-v1
goodhart --detect MountainCar-v0
```
## 许可证
Apache 2.0
标签:AI安全, AI安全工具, Chat Copilot, Gymnasium, LEAN 4, Python, Python安全, RL, 云安全监控, 代码分析, 凭证管理, 古德哈特定律, 奖励函数分析, 奖励陷阱, 奖励黑客, 对齐, 强化学习, 形式化验证, 无后门, 机器学习开发工具, 机器学习验证, 退化均衡, 逆向工具, 逆向激励, 静态分析