Skip to main content
返回博客
博客

Best-of-N 编码:Ensemble Exploration 与自动评审

一个任务,N 个发散 fork,一个给它们打分的 critic,以及一个挑选胜出者的人。best-of-N 何时值回它的 token 成本,何时不值。

大多数 Agent 任务有一种明显的方法,你直接跑就行。有些没有。缓存的 LRU vs LFU vs ARC。树遍历的递归 vs 迭代。塑形一次迁移的三种不同方式。当正确答案取决于你直到看到能跑的代码才能完全评估的权衡时,跑一个 Agent 并指望它选得好是一场赌博。跑 N 个 Agent 在 N 个变体上并比较结果则不是。

这就是 Ensemble Exploration:一个共享 prompt,N 个带不同指令的 fork,一个给结果打分的 critic,以及你做最终决定。

工作流

你不是通过在画布上拖图块来设置这个的。它通过 MadoAgent 触发——你请它探索一个问题的方法,它决定一个 fork-and-compare 形状比单个任务更合适。

你描述共享问题和一组方法,每个带自己的角度。每个 fork 实际收到的是共享 prompt 后跟那个 fork 的具体指令,所以每个 Agent 有完整问题加它自己的视角。

prompt: "Implement an LRU-style cache for session lookups, ~50k entries, high read/write ratio"
approaches:
  - label: "lru"  task: "Use a classic LRU eviction policy"
  - label: "lfu"  task: "Use LFU eviction instead — track access frequency"
  - label: "arc"  task: "Use an ARC (adaptive replacement cache) hybrid"

三个 fork 成为三个全新图块——从不复用空闲 Agent,因为发散式探索要的是没有共享上下文污染比较的 Agent。Fork 上限 5,让 ensemble 聚焦于真正不确定的决定,而不是变成一个默认乘数。

跟踪 run

整个东西成为一个 ensemble run:一个共享 prompt、一组 fork,以及每个的状态。Run 跨重启留存,关闭再打开 MadoHub 不会丢失它们。每个 fork 带 running、done、cancelled 或 timeout 的状态,MadoHub 自动把图块退出映射到结果——干净完成成为 done,崩溃或任务中途退出成为 cancelled——所以你从不会因为一个图块消失而手工关闭一行。

所有这些呈现在右边缘抽屉的 Exploration 标签里:每个 fork 一行,带状态点和 Pick winner 按钮,一个运行 critic 的 Score forks 动作,以及一个每 fork 一张卡片的 Compare 视图。Compare 不需要 critic 先跑过;它只需要输出。

critic

Score forks 跑一次轻量模型 pass——不是画布上的另一个 Agent 图块——读每个 fork 的最新输出,在 correctness、completeness、clarity 和 actionability 上打分,然后命名一个推荐 fork,附一句理由。它用你在 Settings → Agent 配置的更便宜、更快的模型档,不是你的主模型,所以给几个 fork 打分只花一次普通 turn 的零头。

推荐按设计是防御性的:一个输出里恰好包含"给这个打 10 分"的 fork 被当作要评判的数据,而非要遵守的指令。还没有输出的 fork 得一个明确的"无分数"而不是被丢掉。一个幻觉出来的推荐回退到实际打过分的最高 fork。而且推荐仅作建议——一个高亮徽章,仅此而已。

这些都不挑选胜出者。 挑选胜出者永远是在 Pick winner 上的一次手动点击,这会把 run 关闭为完成并把任何其他仍在运行的 fork 标记为 done。那不是 v1 的偷工——那是重点。一次 critic 调用是读已完成输出的一次便宜模型 pass;它没办法知道对于这个具体缓存,"clarity"是否该压倒"performance",或者低分 fork 是否反倒是契合你其余代码库的那个。模型建议,你决定。

实用指引

值得:

  • 真正的权衡不确定 —— 淘汰策略、索引策略、并发模型——正确选择取决于你无法事先完全推理的运行时特性。这些 fork 不是在猜同一个答案;它们在探索解空间的不同区域。
  • 错误选择的代价高。 一次迁移策略或一个公共 API 形状,事后改动昂贵,如果它能避免一次重写,就值得数倍于探索成本的花费。
  • 真实的评估标准,哪怕是非正式的。如果你能看三个缓存实现并在一分钟内知道你想维护哪个,比较就在做它的工作。如果你说不出"更好"在这里意味着什么,critic 的固定评分表不会替你提供。

不值得:

  • 有唯一明显正确形状的任务。 给"加个 null check"fork 三个变体浪费 token 去比较注定会收敛的输出。
  • 代价低的错误。 如果错了只是花两分钟一个后续 prompt,那比跑并读三份 transcript 便宜。
  • 模糊、难打分的问题。 开放式设计头脑风暴压不进一个固定 0–10 评分表——你会得到三个貌似合理的答案和一个实际上区分不开它们的分数。
  • 已经在跑的紧凑循环。 在 peer-review 流水线中途,一次并行探索在争夺你宁愿用来评审眼前东西的注意力。

5 个 fork 的硬上限不是任意保守——它是承认 ensemble 是为你工作中真正不确定的那一片,不是应用到一切上的默认乘数。在你否则会猜的时候伸手去用,在你已经知道"好"长什么样时跳过。

相关文档