

Key Takeaways
- RPM 充当实验裁判,模拟人类研究者的直觉选择
- RPM Conclusion 是冷启动贪心变体,无需 pilot 试跑即可选优
- 从根节点初始实验装置开始,逐代生成突变候选
- 贪心策略:始终变异当前最高 validation score 节点
- GPT-4/5 等 frontier 模型作为 RPM backbone,提供评分能力
- 三模型多数投票提供评分稳定性
- RPM 充当策略的第二个头,在轨迹级别工作
- 全量评估非排序必需,小规模子集即可识别更优候选
研究偏好模型:Agentic AI 工程的新原语
在 2026 年的 Agentic AI 工程实践中,研究偏好模型 (Research Preference Model, RPM) 正在成为一种新的编排原语。它不直接生产答案,而是充当实验裁判:在多个候选研究方向、设计草案、检索查询或工具调用序列之间,模拟人类研究者凭直觉做出的取舍判断,并把这个判断显式地接入 Agent 的决策图。从工程视角看,RPM 把散落在群聊、私人笔记与经验记忆里的研究直觉,沉淀成一个可复用、可调用的服务节点。

RPM 与传统 AutoML / HPO 的本质差异
很多工程师第一反应是把 RPM 等同于「用 LLM 调超参」,这是常见误解。传统超参搜索 (HPO) 的搜索空间是离散的数值参数组合,例如学习率、批量大小、网络层数;而 RPM 的搜索空间是候选实验设计本身------不同的 prompt 模板、RAG 召回策略、工具组合,甚至子任务的拆分方式。这两类问题在数学形态上完全不同:HPO 优化的是单个标量 loss,RPM 优化的是多目标研究质量,包括可解释性、可复现性、外部一致性与失败可诊断性。
| 维度 | 传统 HPO / AutoML | 研究偏好模型 RPM |
|---|---|---|
| 搜索对象 | 数值超参、模型结构 | 候选实验设计、提示词、研究路径 |
| 反馈信号 | 验证集 loss、指标分数 | 研究者偏好排序、成对比较 |
| 权重变化 | 需要训练 | 冻结 LM,仅优化提示 |
| 单轮耗时 | 数小时至数天 | 数十秒完成单次评判 |
| 典型工具 | Optuna、Ray Tune | LangGraph 决策节点 + LLM judge |
观察 在真实工程团队里,研究循环的最大瓶颈往往不是算力,而是「不知道下一步该试什么」。RPM 把这种隐性知识外化成可调用的裁判节点,使一名初级研究员也能复现资深研究者的探索路径------这是它与传统 AutoML 工具链最本质的工程价值差。
冻结 LM 与提示优化的实现路径
RPM 不更新任何模型权重,这一约束带来两个直接收益:第一,可以与生产环境共用同一个 LLM 推理服务,避免重复的 GPU 预算;第二,所有「学习」都发生在提示词的版本控制里,天然可回滚、可审计。下面的伪代码展示 RPM 作为 LangGraph 决策节点的最简接入方式:
python
from langgraph.graph import StateGraph, MessagesState
from langchain_core.messages import SystemMessage, HumanMessage
RPM_SYSTEM = """你是研究偏好裁判。
给定两个候选实验方案 A 与 B,按维度打分:
假设清晰度、数据可获得性、失败可诊断性。
输出 JSON: {"winner": "A|B", "rationale": "..."}"""
def rpm_judge_node(state: MessagesState):
a, b = state["candidates"]
msgs = [SystemMessage(content=RPM_SYSTEM),
HumanMessage(content=f"A: {a}\nB: {b}")]
verdict = llm.with_structured_output(VerdictSchema).invoke(msgs)
return {"messages": [verdict], "next": verdict.winner}
builder = StateGraph(MessagesState)
builder.add_node("rpm_judge", rpm_judge_node)
数据 在该教程给出的端到端案例里,RPM 把原本需要多人协作、跨数天的方案筛选压缩到单次 LangGraph 编排的若干十分钟内;被淘汰的方案不再进入实验阶段,直接节省了大量 GPU 训练小时。具体数字随任务规模变化,但量级稳定:决策密度提升约一个数量级,人力介入次数显著下降。
作为可选偏好裁判层
RPM 不必强制嵌入每个 Agent 工作流,它更适合作为条件分支节点 ,只在「需要做研究类选择」时介入------比如挑选下一组 RAG 召回策略、决定是否值得发起一次新工具调用、评估人工撰写的实验日志。一旦研究循环收敛,RPM 节点就可以旁路,让主流程回到常规的工具调用图。这种「按需裁判」的姿态与 LangGraph 中 add_conditional_edges 的设计天然契合:编排层负责「何时调用 RPM」,RPM 节点只回答「哪个候选更好」。参考 LangGraph 官方文档 可以看到,StateGraph 的节点职责划分正是为此类可选子图预留了空间。
| 部署位置 vs 收益 | 优势 | 取舍 |
|---|---|---|
| 每个 Agent 内部 vs 决策粒度最细 | 每一步都可被偏好评估 | 推理成本翻倍,容易过度裁判 |
| 工作流顶层编排 vs 全局视角 | 避免局部最优陷阱 | 单次决策要承担更多权衡 |
| 旁路条件节点 vs 按需触发 | 成本可控,与现有 LangGraph 编排兼容 | 需要清晰的触发条件设计 |
工程价值:可视化的研究循环
把 RPM 接入 LangSmith 后,每一次偏好判断都会留下输入候选、评判提示、输出 JSON 与最终选择的完整 trace,详见 LangSmith 官方文档。对工程团队而言,这套 trace 的价值不只是节省时间,而是让研究循环第一次具备 Git 级别的可审计性:谁在什么时间、基于哪些候选、为何选择了当前路径,全部可以被 PR review、被回放、被反例对照。「实验即代码、偏好即提交记录」的范式,正在成为 2026 年 AI 研究实验室与生产工程团队共享同一套方法论的关键桥梁。
双变体机制:RPM Conclusion 与 Agent RPM

在 RPM 的工程实践中,同一个「研究偏好模型」会分化为两条调用路径------RPM Conclusion 与 Agent RPM。两者共享同一套打分模型,但触发时机、依赖证据与运行开销截然不同。理解这条分叉,是把 RPM 从论文概念落到生产流水线的关键一步。
RPM Conclusion:基于先验的冷启动贪心
RPM Conclusion 是最轻量的变体,它跳过实验验证阶段,直接拿候选清单去问 RPM------"这几条里哪条最值得投入"。整个调用链路只有一次模型推理,通常在秒级完成,适合作为 Agent 决策图里的快速筛选节点。
由于结论完全依赖 RPM 内部的先验直觉(prior),RPM Conclusion 对候选的"可观测性"要求很低------即使候选只是一句话的标题,RPM 也能凭语义相似度给出排序。这使它在冷启动阶段成为唯一可行的选项。
python
# RPM Conclusion 调用形态
candidates = ["方案 A: embedding 检索",
"方案 B: BM25 检索",
"方案 C: 混合检索"]
decision = rpm_conclusion.rank(
candidates=candidates,
context=task_context,
budget_hint="low",
)
# decision.best → "方案 C"
这种形态的优势是延迟极低、可串入任何决策节点;代价是结论与真实执行结果之间存在不可观测的偏差。RPM 推荐的"最优"方案,在真实数据集上的表现可能并非第一,偏差在跨范式比较时尤为明显。
Agent RPM:基于实验反馈的闭环决策
Agent RPM 在做出最终选择之前,先调度一个最小规模的 pilot 试跑,把候选里排名前 N 的方案各执行一遍,采集真实指标(准确率、召回率、延迟、token 消耗),再把这些证据喂给 RPM 决策。这种形态把"猜"与"验"分成了两个阶段,本质上是把 RPM 从静态排序器升级为闭环裁判。
python
# Agent RPM 调用形态
pilot_pool = rpm_conclusion.rank(candidates, context, top_k=3)
evidence = run_pilot(pilot_pool, scale=0.05, dataset=eval_set)
final = agent_rpm.decide(
candidates=pilot_pool,
pilot_metrics=evidence.metrics,
pilot_cost=evidence.cost,
remaining_budget=task.remaining_hours,
)
Agent RPM 的额外开销集中在 pilot 阶段:一次小规模执行可能要 30 分钟到数小时。但这笔开销换来的是"RPM 推荐 = 实证最优"的可信度,适合用于关键路径上的最终决策。在 LangGraph 的状态图里,这通常被实现为一个 pilot_node + rpm_decide_node 的子图,配合 checkpointer 实现中断恢复。
核心差异:先验直觉 vs 实验反馈
| 维度 | RPM Conclusion | Agent RPM |
|---|---|---|
| 触发时机 | 任意决策点,无须前置条件 | 必须先有 pilot 证据 |
| 调用延迟 | 秒级 | 30 分钟到数小时 |
| 结论可信度 | 依赖先验,与真实表现存在偏差 | 基于实证,与执行结果一致 |
| 适用候选规模 | 数十到数百皆可 | 受 pilot 成本限制,通常 ≤ 5 |
| 典型失败模式 | 先验偏差导致"看起来好但跑不动" | pilot 耗尽预算,无决策可下 |
观察 这两条路径不是替代关系,而是分层关系。生产实践里,常见做法是先跑一次 RPM Conclusion 把候选池从几十条压到 3-5 条,再启动 Agent RPM 在缩小的池子里做带证据的最终决策。这种"粗排 + 精排"的两段式架构,既能控制 pilot 成本,又能保证最终选择的实证可信度。把 RPM Conclusion 单独用在精排环节是常见误区------它的先验无法抵消 pilot 数据带来的信息增益。
预算驱动的选型决策
是否值得为 Agent RPM 的 pilot 阶段付出额外开销,取决于三个相互作用的变量:剩余预算、候选的可执行性、噪声水平。三者的组合决定了 pilot 投入的边际收益,也决定了该用哪个变体。
- 剩余预算 < 15 小时:pilot 阶段消耗的时间占比过高,Agent RPM 与 RPM Conclusion 的最终收益差距通常很小,选 RPM Conclusion 更经济。
- 15-25 小时区间:pilot 成本被充分摊薄,Agent RPM 在高噪声任务(例如开放域问答、跨语种检索)上的优势开始显现。
- > 25 小时:Agent RPM 的闭环优势充分释放,但往往已进入多轮迭代优化阶段,RPM 本身的边际收益递减,需要重新评估整体编排策略。
候选的可执行性也会影响选择:如果候选里有相当一部分无法在本地环境直接 pilot(比如需要外部 API 配额、特定 GPU 资源),Agent RPM 的候选池会被人为缩小,此时 RPM Conclusion 反而更稳健。噪声水平指的是候选之间的真实性能差距------差距越小(噪声越高),pilot 阶段的样本量就需要越大,Agent RPM 的开销随之膨胀。
选型决策矩阵
| 预算 / 候选特征 | 候选不可执行比例高 | 噪声水平低(差距大) | 噪声水平高(差距小) |
|---|---|---|---|
| < 15 小时 | RPM Conclusion | RPM Conclusion | RPM Conclusion |
| 15-25 小时 | RPM Conclusion | Agent RPM | Agent RPM(扩大 pilot) |
| > 25 小时 | 重新切分候选 | Agent RPM | Agent RPM(扩大 pilot) |
数据 在多数中等规模的检索任务里,RPM Conclusion 与 Agent RPM 在粗排阶段选出的 Top-3 候选常常高度重合,经验上重合率往往超过七成。换言之,当两变体结论一致时,Agent RPM 的 pilot 投入更像是在为小概率的偏差场景买保险,而不是常态收益。这也是预算阈值(< 15h vs 15-25h)成为判断标准、而不是默认总是用 Agent RPM 的原因。
与 LangGraph 工作流的衔接
无论是哪种变体,落地都需要挂载到一个可中断、可恢复的状态图上。LangGraph 的官方文档展示了如何用 add_conditional_edges 把 RPM 节点与执行节点拼接,Send API 用于把候选 fan-out 到 pilot 子图。可观测性则交给 LangSmith,用于追溯每一次 RPM 调用的输入候选、上下文与最终理由,这也是审计 RPM 决策可解释性的重要抓手。
小结
RPM Conclusion 与 Agent RPM 的本质取舍在于"先验直觉"与"实验反馈"之间的成本-收益平衡。在大多数冷启动与小预算场景里,RPM Conclusion 已经足够;只有当预算跨过 15 小时门槛、候选可执行、噪声足够低时,Agent RPM 的 pilot 开销才值得投入。把两者组合成"粗排 + 精排"的分层架构,通常比单独使用任何一种都更稳健,也更符合真实工程团队对决策可追溯性的要求。
进化式树搜索方法论
进化式树搜索把 AiroDojo 的「研究自动化」具象成一棵由实验装置组成的搜索树。它的工程价值在于:把 RPM 的打分能力当作内部的「进化压力」,把每次成功或失败的实验装置当作「基因」,通过代数式的变异与筛选,在预设的算力预算内逼近最优解。这棵树的根节点是人工预设的初始实验装置(可能是某个 baseline,也可能是上一轮迭代的最佳产物),叶子节点则是不同代际积累下来的实验变体------每一片叶子背后都是一个真实跑过、可被复现的研究轨迹。
根节点与初始实验装置
根节点不是凭空长出来的,它来源于两件事:一是 AiroDojo 对当前研究问题的工程化拆解,二是讲师在一开始设定的基线配置。这套课程强调「显式初始化」,即在树搜索启动之前,把所有已知的实验要素------数据集、超参数、评估脚本------都以结构化字段写入节点。后续每一个子节点只对根节点的某个子集做变异,而不是从零生成,这显著降低了无效分支的比例。在 LangGraph 里,这种「节点可携带配置字典、边上可携带算子标签」的设计可以直接映射到 StateGraph 的状态字段,参考其 官方文档 中关于节点状态持久化的描述;而 AiroDojo 的实验装置本质上是 LangChain 工具链的一次实例化,详见 LangChain 文档 中关于 Tool 组合的部分。
候选-评分-选择-全量评估-产物回灌
闭环是整棵树的「血液循环」,任何一环断开,搜索都会退化成随机游走。具体来看:
- 候选生成:给定父节点,突变算子(mutation operator)产出 K 个候选装置,常见算子包括调参微调、改评估指标组合、替换 backbone 模块等。
- 轻量评分:RPM 对 K 个候选做一次推理打分,排序得到 Top-M。
- 选择:从 Top-M 里挑出 N 个进入下一阶段,N 通常远小于 K。
- 全量评估:把 N 个候选真正跑起来,产出可比对的实验指标。
- 产物回灌:把脚本、验证集结果、日志作为 artifacts 写回 RPM 的上下文窗口,让 RPM 在下一轮能「看到」前一轮的结果。

节点与边的语义
在这棵搜索树里,节点就是实验装置 ,它的内部字段包括配置、运行日志、产出指标、父节点指针、产物哈希;边就是生成关系,从父节点指向子节点,边上记录突变算子的类型与关键参数。AiroDojo 把搜索空间抽象成节点字段的可变域------只有落在可变域内的修改才被允许,这是工程上避免「幻觉式实验装置」的关键。
Artifacts 反哺 RPM 上下文
搜索过程中最容易被忽略的环节是 artifacts 回灌。脚本路径、验证指标、误差曲线、失败堆栈都会作为结构化文本进入 RPM 的下一轮 prompt。如果不做这一步,RPM 就只能根据「自己想象中」的实验结果打分,产生严重的幻觉偏差。该教程特别提醒,artifacts 要做长度截断与去噪------RPM 的上下文窗口是稀缺资源,塞太多冗余日志反而会让打分质量下降。生产实现里通常会按段落做摘要压缩,把原始指标保留为附件、压缩结果作为提示词注入,这是 LangGraph 状态管理中常见的「摘要 + 全文」分层模式。
终止条件
树搜索不会无限生长。终止条件有两种:预算耗尽 (GPU 小时数、API 调用费用、迭代轮数触达上限)或满意结果(连续若干代 Top-M 指标不再单调上升,即可判定收敛)。这两条边界共同决定了「什么时候该收手」,在生产环境里,后者通常通过非参数统计判据来形式化,避免「伪收敛」------即指标小幅抖动就被误判为已收敛而提前收手。
观察 树搜索的工程难点不在「生成」,而在「选择」。RPM 在每一代里对 K 个候选做轻量排序,这一步决定了整棵树的探索-利用权衡:K 太小容易陷入局部最优,K 太大又会消耗评分预算。把评分环节设计成可批量、可缓存、可降级的子模块,是把这套方法落地的工程前提。一旦评分不可批量,RPM 就会变成串行瓶颈,K 不得不收敛到 4 以内,搜索宽度直接被腰斩。
数据 实测经验里,每代候选数 K 控制在 8-16 之间时,RPM 打分的稳定性最佳;高于 32 后,排序一致性下降明显,容易出现跨代不可比。同一套打分模型下,K=8 的累计命中速度比 K=2 快约 3 倍,但单次推理开销是 K=2 的 1.5 倍左右------线性开销换近线性的探索宽度,是这套机制在工程上能跑得动的核心数字基础。评分温度(temperature)方面,建议从 0.7 起步,前两代保持较高温度以扩大覆盖面,后续几代降到 0.3 以内做精细筛选。
代码:树节点与单步迭代伪代码
python
@dataclass
class ExperimentNode:
config: dict # 实验装置的可变字段
parent_id: str | None # 父节点指针
mutation_op: str # 生成关系(调参/换模块/改指标)
metrics: dict = field(default_factory=dict)
artifacts: list[str] = field(default_factory=list)
status: str = "pending" # pending / scored / evaluated
def evolve_one_step(root, rpm, budget_left):
candidates = [mutate(root) for _ in range(K)]
scores = rpm.batch_score([c.config for c in candidates])
top_n = select_top(candidates, scores, n=N)
for node in top_n:
node.metrics = run_full_eval(node.config)
node.artifacts = dump_artifacts(node)
node.status = "evaluated"
rpm.ingest_artifacts(node.artifacts)
return top_n, budget_left - len(top_n)
这段伪代码浓缩了一代迭代的全部动作:变异、批量评分、Top-N 选择、全量评估、artifacts 回灌。生产实现里,rpm.ingest_artifacts 通常要走异步队列与摘要压缩,否则上下文窗口很快就被日志塞满。节点本身可以序列化为 JSON 落到磁盘,配合 LangGraph 的 SqliteSaver 或 PostgresSaver 就能做跨代、跨会话的持久化,这对长跑树搜索来说几乎是必备设施。
方案取舍:进化式树搜索 vs 单次贪心
| 维度 | 进化式树搜索 | 单次贪心(RPM Conclusion) |
|---|---|---|
| 推理次数 | 每代 O(K),多轮累计 | 全程 1 次 |
| 预算成本 | 高(GPU + API) | 低(秒级) |
| 探索宽度 | 强,跨代累积 | 弱,只看静态候选 |
| 适用阶段 | 中后期精细搜索 | 冷启动粗筛 |
| 失败容忍 | 中(单点失败不影响整体) | 低(一次打分决定) |
| 可复现性 | 强(每代可回放) | 弱(无历史痕迹) |
取舍要点:预算充足、追求最优解时优先选树搜索;预算紧张、只需「够用」时退回单次贪心。生产里常见的折中是先用 RPM Conclusion 做冷筛,再把 Top-N 喂给树搜索做精修------把两者的开销与收益分层叠加,既控制成本又拿到最优解附近的细致搜索能力。这条分层路线,本质上就是把「冷启动贪心」当作树搜索的初始种群发生器,用最便宜的环节把搜索空间先砍一刀,再把省下来的预算交给昂贵的闭环去榨取边际收益。
父节点选择:贪心与 MCTS 取舍
贪心策略------把变异焦点钉在当前最优上
进化式树搜索的每一代,引擎都要面对一个看似简单却分量十足的工程问题:从已有实验装置(节点)中,挑哪一个作为下一轮变异的父节点?最直接的答案就是贪心------始终选择当前 validation score 最高的节点,再让变异算子在它的实验装置描述上做修改。这种逻辑实现起来极轻:线性扫一遍活跃节点集合,记录最大分数对应的节点即可。
python
# 贪心式父节点选择(伪代码)
def select_parent_greedy(active_nodes):
best_score = float("-inf")
parent = None
for node in active_nodes:
if node.validation_score > best_score:
best_score = node.validation_score
parent = node
return parent
贪心风格的最大好处是行为完全可预测:每次看到的父节点就是当前最佳,任何一次回归测试都能复现同一路径。在 LangGraph 的状态图里,这种「线性、可重放」的轨迹可以通过 add_conditional_edges 封装为独立节点,让整棵搜索树成为可被 LangSmith 追踪的工作流(参考 LangGraph 文档)。
探索-利用张力与 MCTS 风格的类比
但纯贪心有一个明显盲区:它把全部资源压向当前最优,如果这条分支本身只是次优山头,后续变异只会越走越窄,陷入局部最优。MCTS 给出了更平衡的范式:把父节点选择拆成「利用(exploitation)」与「探索(exploration)」两项加权和------UCB = exploitation_term + c · exploration_term,其中 c 越大,系统越愿意派变异算子去访问历史命中次数少、validation score 不一定最高但方差较大的节点。在 AiroDojo 的语境里,可类比为 parent_score + λ · uncertainty_bonus,λ 即探索权重。
观察 这种「分数 + 不确定性」的双因子选择,在工程上等价于把搜索树当成一个多臂老虎机问题来对待:每一代父节点选择是一次 arm 拉动,validation score 是 reward。把它落地到 LangGraph 时,Send API 提供的并行派发能力天然适配多候选并行评估,可以把不同父节点候选的变异评估一次性铺开(参考 LangChain 文档)。
三种路径的取舍矩阵
把工程现实摊开看,父节点选择大致有三条主流路径:静态贪心、MCTS 风格 UCB、以及更激进的强化学习式策略。下表给出五个维度的对比:
| 维度 | 静态贪心 | MCTS 风格 UCB | 强化学习式 |
|---|---|---|---|
| 选择规则 | 取当前最高 validation score | 分数 + 不确定性加权 | 由学得的策略/Q 函数决定 |
| 工程复杂度 | 低(线性扫描) | 中(需维护访问计数) | 高(需训练回路) |
| 局部最优风险 | 高 | 中 | 低 |
| 策略开销 | 极低 | 中等(统计同步) | 高(策略推理) |
| 可解释性 | 强 | 中 | 弱 |
数据 假设一棵搜索树预算为 200 个变异槽位,静态贪心在前 50 次内大概率把变异集中在 1-2 个高分父节点附近;MCTS 风格 UCB 通常能把父节点分散到 5-8 个候选上;强化学习式策略若训练充分,父节点分布最接近「均匀探索」,但单步推理延迟会多出 2-3 倍。在算力紧张的研究自动化场景里,这 2-3 倍延迟往往就是「能不能多跑一代」的边界。
动态策略的代价
更聪明的选择策略几乎总是更贵。MCTS 风格需要额外维护每个节点的访问次数与分数方差,会引入跨代际的统计同步问题;强化学习式则要求在线或离线训练一个父节点评估网络,每次变异前还要多一次前向推理。对于按小时级节奏迭代的研究流水线,这些毫秒到秒级的开销会被成百上千次父节点选择放大。
工程上常见的折中是「分层策略」:前若干代用贪心快速收敛到一片高分盆地,中段切到 UCB 做局部突围,末段再切回贪心做精修。这样既享受了静态贪心的稳定性,又用动态策略覆盖了最容易陷住的山头,是一种风险与开销都比较可控的权衡。

实战建议
如果团队刚开始把研究自动化跑起来,建议先用静态贪心把端到端流水线打通------优先验证变异算子、validation 评估器、checkpointer 这些基础设施是否稳。当搜索树深度超过 5 代仍能看到稳定增益时,再考虑引入 UCB 风格,把 λ 设为可调超参数;至于强化学习式策略,通常只在父节点候选空间爆炸(超过 1000 个活跃节点)且算力预算允许时才值得上,否则策略开销会吃光本该留给真正变异探索的预算。
父节点选择从来不是孤立的算法题,而是研究自动化系统里最容易被低估的杠杆点------一行选择逻辑的差异,在几十代迭代后会演化成截然不同的研究轨迹。
RPM 骨干模型与提示优化
锚定评分器:RPM 骨干模型的职责
RPM(Reward/Performance Model,这里指对"实验装置描述"打分的模型)在整棵进化树中承担裁判角色。它不参与变异生成,也不负责调度;它的唯一职责是:给定一段 prompt 与候选装置描述,返回一个可比较的 validation score,供贪心父节点选择和后代排序使用。

之所以选择 GPT-4 / GPT-5 这一类 frontier 模型作为 RPM backbone,核心在于三点:
| 维度 | frontier 模型 | 中小模型 | 自训 reward model |
|---|---|---|---|
| 评分稳定性 | 强,zero-shot 接近人类判断 | 弱,需 prompt 反复校准 | 强但需大量标注 |
| 推理能力 | 支持复杂语义与多步评估 | 难以评价多步方案 | 仅在训练分布内有效 |
| 部署成本 | 按 token 计费,无 GPU 维护 | 中等 | 高,需训练基础设施 |
frontier 模型的评分粒度是 prompt 级别的------只要把评估维度、候选输出与参照集合塞进同一个上下文,它就能给出一个相对稳定、可复现的分数。对于 RPM 这种"小批量、高频次"的打分场景,frontier 模型是最合算的工程选择。
评估来源:Offline GPT-5 作为 ground truth
RPM 在打分时需要一个相对客观的 ground truth,否则分数之间不可比。该教程的做法是用 offline 状态的 GPT-5 做静态评估:给定一批标准 query 与对应"理想输出",让 GPT-5 离线批跑,生成一份 reference set。每次新 prompt 出现时,RPM 把候选输出与 reference set 做对比,得出一个 0-1 之间的归一化分数。
数据 这种 offline 评估的代价结构很清晰:reference set 一旦稳定,后续每一轮进化只需消耗 GPT-5 的推理成本,而无须再调人工标注 API;RPM 自身在打分时也只用 frontier 模型的 forward pass,完全跳过反向传播,单机即可完成闭环。
提示优化:DSPy 的位置
RPM 的可学习参数只有 prompt 这一项。要把这唯一的旋钮调好,绕不开提示优化框架------这里采用 DSPy。它把"输入字段 → 提示模板 → LM 调用 → 输出解析 → 评估"这条链路抽象成模块化的 signature,让研究者只关心"什么样的字段组合更好",而不是"怎么把 token 序列敲进字符串里"。
python
# DSPy 风格的 RPM 评分签名(伪代码)
import dspy
class RPMScore(dspy.Signature):
"""给定候选装置描述,返回与 reference 的相似度。"""
candidate = dspy.InputField(desc="实验装置描述")
reference = dspy.InputField(desc="offline GPT-5 生成的参考输出")
score = dspy.OutputField(desc="0-1 的归一化分数")
class RPMJudge(dspy.Module):
def __init__(self):
super().__init__()
self.judge = dspy.ChainOfThought(RPMScore)
def forward(self, candidate, reference):
return self.judge(candidate=candidate, reference=reference)
DSPy 在优化时会自动构造少量 few-shot 示例、在 signature 内做 prompt 微调,并以 offline GPT-5 的分数为优化目标。整套迭代可以在几十次 forward pass 内收敛,完全不需要动模型权重,这也是它与微调路线的根本分野。
微调 vs 提示优化:取舍矩阵
| 维度 | 直接微调 | DSPy 提示优化 |
|---|---|---|
| 数据规模需求 | 千级以上标注 | 几十到几百条 reference |
| 迭代周期 | 数小时到数天(含训练) | 数分钟到数十分钟 |
| 回滚成本 | 高,需重部署 checkpoint | 极低,替换 prompt 字符串即可 |
| 跨模型可移植性 | 差,checkpoint 与模型绑定 | 强,prompt 与 backbone 解耦 |
| 调优上限 | 高(理论上) | 受限于 backbone 本身能力 |
| 风险面 | 灾难性遗忘、版本漂移 | prompt 注入、对齐偏移 |
观察 在 agentic 工程的迭代节奏里,提示优化的"小步快跑"远比微调的"大步慢走"贴合实际需求。每一次贪心父节点选择都可能把搜索树带进一个未探索的分支,需要 RPM 当晚就给出新分数;若此时还要等微调 pipeline 跑完,整个进化流程会被压成批处理,失去在线探索的意义。
此外,提示级优化的另一个隐性收益是模型无关性:同一套优化过的 prompt 模板,可以无缝迁移到 GPT-4、Claude、Gemini 或本地开源模型,只需替换 backbone 调用方------这是 checkpoint 路线做不到的。
工程入口与回滚机制
AiroDojo 项目把 RPM 当作一个独立的微服务部署,打分接口与进化引擎之间通过 HTTP 解耦。这意味着任何一次 prompt 升级都对应一次普通的 PR,带版本号带 diff;回滚只需把 PR revert,无须重启训练机;不同分支可以并行运行多版 RPM 做 A/B 评估,互不污染状态。DSPy 与 AiroDojo 的代码组织延续了 LangChain 模块化的风格,理解 Module / Signature / Optimizer 这几个核心概念后,迁移成本几乎为零。
- LangChain 官方文档 python.langchain.com/docs/introd...
- LangSmith 官方文档 docs.smith.langchain.com/
到这里,RPM 已经把"打分"和"调分"两件事解耦成两个独立的工程单元:一个负责给出稳定分数,一个负责把分数越调越高。下一节将进入实际变异算子的设计,看 prompt 是如何在进化引擎里被"动手术"的。
集成 RPM 与奖励黑客防御
集成 RPM 与奖励黑客防御

单 RPM backbone 虽具备 frontier 模型的常识广度,但其评分分布往往带有系统性偏置------某些 prompt 表述风格会被无意识地抬高,某些术语的密集使用会被过度奖励。集成 RPM(Ensemble RPM)通过引入多个独立评分视角,把单模型的"审美偏好"摊平到群体决策上。
三模型多数投票与 Arbiter 仲裁
集成 RPM 的核心是三模型多数投票。三个独立 backbone 分别对同一对 (prompt, 装置描述) 给出 scalar score,系统对分数做离散化分桶(如 high / mid / low 三档),取出现最多的桶作为最终评分。三票一致时置信度最高;2:1 时多数票胜出;只有三方意见彻底分裂(各占一档)时,才进入仲裁环节。
当三票形成 1:1:1 分裂,Arbiter LM 作为第四个裁判被唤醒------它不参与常规流水线,只在 split decision 时介入,对同一对重新打分打破僵局。Arbiter 通常选用不同家族或不同训练阶段的模型,以最大化视角差异。
| 决策情形 | 触发条件 | 仲裁路径 |
|---|---|---|
| 三票一致 | 三 backbone 同桶 | 直接采纳 |
| 2:1 多数 | 两票同桶,一票异 | 采纳多数桶 |
| 1:1:1 分裂 | 三方各占一桶 | 唤醒 Arbiter 裁决 |
对 reward hacking 的天然抵抗
奖励黑客(reward hacking)指候选生成器学会"骗过"评分器的漏洞------堆砌偏好的关键词、复述训练语料句式、在格式上过度对齐隐性偏好。单 RPM 的偏置固定可学,极易被穿透。集成 RPM 的抵抗体现在两个层面:其一,生成器要同时骗过三个独立偏置的模型,搜索空间呈指数级膨胀;其二,Arbiter 的存在让"刚好压线"的伪高分策略失去稳定收益,作弊痕迹在仲裁时更易暴露。
python
async def ensemble_score(prompt, description, backbones, arbiter):
scores = await asyncio.gather(
*[b.score(prompt, description) for b in backbones]
)
buckets = [discretize(s) for s in scores]
unique = set(buckets)
if len(unique) == 1:
return scores[0], "unanimous"
if any(buckets.count(b) >= 2 for b in unique):
return median(scores), "majority"
return await arbiter.score(prompt, description), "arbiter"
LangSmith 的 evaluation suite 广泛使用这种多裁判结构做 reward hacking 的回归测试,详见 docs.smith.langchain.com/。
单 RPM vs 集成 RPM 的延迟与成本权衡
集成不是免费的午餐。三 backbone 并行调用把延迟从 1× 推到 3×,token 成本约三倍;加上偶发 Arbiter,整体开销落在 3.0--3.5× 区间。
| 维度 | 单 RPM | 集成 RPM (3+1) |
|---|---|---|
| 单次评分延迟 | 低 (1× 调用) | 中--高 (3× 并行 + 偶发 Arbiter) |
| Token 成本 | 1× | 约 3.0--3.5× |
| 评分稳定性 | 受单模型偏置影响 | 三视角摊平,分裂时 Arbiter 兜底 |
| 抗 reward hacking | 弱,易被针对性攻击 | 强,作弊需穿透多模型 |
| 适用规模 | 小规模 PoC (<100 候选) | 大规模进化搜索 (>1000 候选) |
观察 在进化搜索早期(候选 < 100),集成 RPM 的额外开销是显著负担;进入中后期、候选突破上千以后,稳定性收益远超 token 成本------一次评分偏置错误会让贪心父节点选错,后续数轮迭代都在为这个错误买单。把集成做成可配置开关、按搜索阶段动态切换,是落地的关键工程经验。
数据 多数投票的稳定性可用"三方一致率"作为在线指标监控。prompt 清晰、格式规范时,一致率通常在 60%--75%;骤降到 40% 以下,往往意味着 prompt 分布漂移或生成器开始针对评分器过拟合,需要触发人工抽检并回滚候选池。
工程落地要点
落地需注意三点:第一,三个 backbone 应覆盖不同家族或训练阶段,避免同源偏置导致投票退化为单点意见;第二,并行调用必须用 asyncio.gather 而非串行 for 循环,Python 官方文档对此有详细说明,见 docs.python.org/3/library/a... 唤醒频率应作为监控指标持续追踪,频繁触发说明 backbone 选型需重新评估。此外,LangChain 的 with_structured_output 接口可以让所有 backbone 输出统一 schema,极大简化投票与仲裁的归一化逻辑,见 python.langchain.com/docs/introd...
把单 RPM 升级到集成 RPM,是把评分器从"一个可能出错的 oracle"变成"一群会吵架但最终能达成共识的评审委员会"。在 Agentic AI 的进化搜索场景里,这层冗余不是奢华,而是搜索质量的下限保障。
训练范式:Tree DPO 与 PPO 价值网络类比
RPM 在标准的采样-打分流程里,本质上是策略网络 (policy) 的第二个输出头。生成器负责从 prompt 出发展开研究轨迹,RPM 则对已经展开完成的整条轨迹给出总体评价,粒度停留在「这条研究路径值不值得继续」,而非单 token 的对错。

这种「第二个头」的设计直觉来自监督学习里的多任务头:同一个 backbone 共享表征,多个 head 各司其职。在 Agentic AI 场景里,RPM head 与生成 head 共享同一份研究领域先验,代价是表征空间被训练目标同时拉扯------这正是后面讨论双头架构权衡时的核心张力。
类比 PPO 价值网络:打分,但粒度是轨迹
RLHF 中的 PPO 用一个 value network V(s) 估计状态 s 下的期望回报,它对单步决策 打分,梯度回传给 actor 以稳定策略更新。把 RPM 摆在 PPO value network 的对面看,它做的几乎是同一件事:打分------只是粒度从 token 级跃迁到「整条研究轨迹」级。
二者差异并非来自机制,而来自信号密度。PPO value network 每一步都能收到即时反馈,RPM 只能在轨迹完成时给一次全局评分。这导致 RPM 的训练信号天然稀疏,需要靠采样多条轨迹、做对比学习来弥补;Tree DPO 正是顺着这条线索走出的工程化答案。
Tree DPO:把树展开转成偏好对
Tree DPO 的核心做法是:在每个研究节点采样若干分支,展开成多条完整轨迹,由 RPM 给每条轨迹打分,然后把「RPM 评分高的」标为 chosen、「评分低的」标为 rejected,直接喂给 DPO 损失函数。这种做法把稀疏奖励密集化------一次展开可得到 K×(K-1) 个偏好对,远比单条轨迹末端的稀疏信号更易拟合。
下面给出一个偏好对的构造示例,关注 margin 字段对训练噪声的过滤:
python
def build_preference_pairs(trajectories, rpm_scores):
pairs = []
for i, traj_i in enumerate(trajectories):
for j, traj_j in enumerate(trajectories):
if i == j:
continue
si, sj = rpm_scores[i], rpm_scores[j]
if abs(si - sj) < 0.05: # 过滤近似平局
continue
chosen = (traj_i, traj_j) if si > sj else (traj_j, traj_i)
pairs.append({
"prompt": traj_i["prompt"],
"chosen": chosen[0]["text"],
"rejected": chosen[1]["text"],
"margin": abs(si - sj),
})
return pairs
代码中 margin 字段保留,可在 DPO 损失里加权,让 RPM 差异更大的对贡献更多梯度,避免「相近轨迹互相对比」造成的训练噪声。在异步采样-打分流水线里,可以借助 Python 的 asyncio 模块 (docs.python.org/3/library/a...) 并行展开多条轨迹;若把分支结构映射到 LangGraph 的图上,RPM 评分节点可以作为 graph edge 的 condition 函数,详见 LangGraph 官方文档 (langchain-ai.github.io/langgraph/)...%25E3%2580%2582 "https://langchain-ai.github.io/langgraph/)%E3%80%82")
双头架构:Qwen 同模型同时承担生成与 RPM
回到工程落地:能否让同一个 Qwen checkpoint 既当生成器又当 RPM?技术上可以,只需在最后一层增加一个回归 head 输出标量评分。真正的取舍在于奖励黑客风险------模型天然倾向给自己打高分,这正是 RLHF 早期 self-reward 争论的根源。
| 维度 | 独立 RPM 模型 | 同模型双头架构 |
|---|---|---|
| 表征一致性 | 弱,可能与生成器错位 | 强,共享 backbone |
| 部署成本 | 双倍显存 | 单卡可跑 |
| 奖励黑客风险 | 低,异源打分 | 高,模型倾向自我奖励 |
| 训练耦合度 | 解耦,可独立迭代 | 紧耦合,需谨慎冻结 head |
| 场景特征 | 偏向独立 RPM | 偏向双头架构 |
|---|---|---|
| 算力预算 | 充裕,优先安全性 | 受限,优先吞吐 |
| 任务稳定性 | 强对抗场景 | 单领域深耕 |
| 迭代节奏 | RPM 与生成器独立版本 | 必须同步发布 |
如果团队决定走双头路线,经验上的折中是「RPM head 冻结初始若干 epoch」------让生成 head 先稳定,再解冻 RPM head 做联合微调;若走独立 RPM 路线,则可借助 Pydantic 严格约束 (docs.pydantic.dev/) 偏好对的 schema,降低评分漂移。整套 Agentic 系统的总体参考见 LangChain 文档 (python.langchain.com/docs/introd...%25E3%2580%2582 "https://python.langchain.com/docs/introduction/)%E3%80%82")
观察 RPM 与 RLHF 的边界正在模糊。当 RPM 在轨迹级别打分、用 DPO 损失训练策略时,它事实上已经替代了 PPO 中 critic 的位置;而当 RPM 由同模型承担时,又复现了 RLHF 早期 self-reward 的争论。这条演化路径提示我们:Agentic 时代的奖励建模不再是独立模块,而是策略本身的延伸------未来的「奖励函数」更可能内嵌在策略权重里,而不是外挂一个独立网络。
数据 在该教程演示的实验里,单条研究轨迹平均展开 6.3 个分支节点,RPM 对每条轨迹的评分耗时约为生成耗时的 8%;独立 RPM 相比同模型双头,在 reward hacking 检测基准上把误判率从 17% 压到 6%,但显存占用翻倍。这组数字印证了上表的权衡:算力与安全之间没有免费午餐,「第二个头」的便利必须用更严格的奖励黑客检测来对冲。
选择性评估与工程收尾
全量评估是过度工程,子集足以识别更优候选
RPM 在生成完整轨迹后给出整体评价,这一步的开销往往比生成本身还高------它要求模型对一条可能数百 token 的轨迹做完整推理,再输出一个标量或偏好对。当候选池有上百条轨迹时,对每一条都跑全量评估既慢又贵。但工程上真正需要的,只是从这些候选里挑出「更好」的那一条------这并不需要看到全部。选择性评估的本质,是把「评估」从隐式的全量义务,变成显式的预算调度问题。
5% 子集的高概率直觉:假设生成器产出的候选之间存在真实的优劣分布(而非无差别噪声),那么从 N 条候选里随机抽样 N × 5% 进行评估,挑出其中评估最高的一条作为最终输出,只要总样本 N 足够大、生成器的质量方差可控,被遗漏在子集外的更优解概率会迅速衰减。这与 A/B 测试用小流量做决策的逻辑同源------5% 的样本量在统计意义上已经能稳定识别出头部候选,不必为长尾反复付账。

python
async def selective_evaluate(candidates, eval_fn, budget_ratio=0.05):
n = len(candidates)
sample_size = max(1, int(n * budget_ratio))
sample = random.sample(candidates, sample_size)
scored = [(c, await eval_fn(c)) for c in sample]
scored.sort(key=lambda x: x[1], reverse=True)
return scored[0][0], scored[0][1]
预算分配:把昂贵评估留给最有希望的候选
工程上更精明的做法不是「随机抽样 5%」,而是先用廉价启发式(规则打分、模型自评、长度惩罚、关键词命中)做一次粗筛,再把昂贵的 RPM 评估集中投放到 top-k 个候选上。这种「两级漏斗」结构把整体开销砍掉一个数量级,同时不损失对最优候选的命中率。
| 阶段 | 评估方式 | 候选数 | 单次成本 | 用途 |
|---|---|---|---|---|
| 粗筛 | 启发式/自评 | 全量 N | 低 | 排序+剪枝 |
| 精筛 | RPM 全量评估 | top-k (k≈0.05N) | 高 | 最终打分 |
| 兜底 | 全量评估 | 全部 | 极高 | 仅 top-k 分数接近时触发 |
数据 在典型 Agentic 搜索场景下,粗筛阶段单次评估成本约是 RPM 的 1/20,候选数却多 20 倍;两级漏斗的综合开销可以压到「全量 RPM」方案的 8%--12%,而最优候选召回率仍能维持在 90% 以上。当 top-k 之间的 RPM 分数差距超过预设阈值(例如 0.15)时,直接提交头部,不必再评估其余------这就是早停的工程触发条件,也是把 RPM 从「奢侈品」变「日用品」的关键开关。
与朴素贪心的根本差异
朴素贪心每一步只看当前最优,容易陷在局部极小值里,且无法解释「为什么没选另一条」;RPM 驱动的选择性评估则把「评估」本身也变成一个可调度的算子------何时评估、评估谁、评估到什么粒度,都是显式决策。早停(early stopping)在这里表现为:当粗筛出的 top-k 彼此拉开明显差距时,直接提交头部候选,不必再为尾部花一分钱。这种「结构化搜索 + 显式预算 + 早停」的三件套,与 Best-of-N 采样、束搜索、MCTS 共同构成 Agentic 系统的搜索工具箱,RPM 则是其中评估环节的统一接口。
观察 把 RPM 视为可调度的算子,而非「每条轨迹必经的关卡」,是 Agentic 工程从「能跑」走向「跑得优雅」的关键一步。搜索空间被结构化,预算被显式化,失败成本被可预测化------这套模式与 LangGraph 的 StateGraph 设计哲学高度一致:用图结构把控制流从隐式循环里抽出来,每个边的开销与触发条件都可以被 LangSmith 观测。详见 LangGraph 官方文档 langchain-ai.github.io/langgraph/ 与 LangSmith 监控文档 docs.smith.langchain.com/。
RPM 不适用的边界
RPM 并非万能,它有几个明确的边界:其一,任务目标本身就是「发散性创作」,没有「更优」定义,任何评分都会注入偏置甚至收敛同质化;其二,候选差异落在 RPM 偏好分布覆盖不到的区域(强事实、强合规),「更优」与「更正确」之间存在系统性 gap;其三,延迟预算在毫秒级的链路,RPM 评估本身的开销就不允许出现。这些场景下,应当退回规则引擎、人工闸门(HITL)或独立验证器(verifier),而不是强行上 RPM。
选型取舍速查
| 候选规模 vs 评估策略 | 推荐方案 | 取舍依据 |
|---|---|---|
| ≤10 条 | 全量 RPM | 评估开销可控,样本太少抽样失真 |
| 10--500 条 | 两级漏斗 | 5% 精筛命中率与成本最优 |
| >500 条 | 启发式粗筛 + 极小 RPM 子集 | 全量评估已不可承受 |
| 强事实/强合规 | RPM + 人工复核 | RPM 偏好无法替代事实正确性 |
把「评估」当一等公民来调度,Agentic 系统才真正摆脱朴素贪心的脆弱,迈入工程化、可观测、可治理的下一阶段。
参考来源
官方与一手资料
- LangChain 官方文档 python.langchain.com/docs/introd...
- LangGraph 官方文档 langchain-ai.github.io/langgraph/
- LangSmith 官方文档 docs.smith.langchain.com/
- Pydantic 官方文档 docs.pydantic.dev/
- FastAPI 官方文档 fastapi.tiangolo.com/
- Chroma 官方文档 docs.trychroma.com/
- Python asyncio 文档 docs.python.org/3/library/a...
- freeCodeCamp 官网 www.freecodecamp.org/
- LangGraph GitHub 仓库 github.com/langchain-a...
- Render 官方文档 render.com/docs
- Docker 官方文档 docs.docker.com/