プロダクト発表・小互による解説

Prime Intellectが公開したマルチエージェントRL訓練フレームワーク:「1体のAgentを鍛える」から「複数Agentが作用し合う集団を鍛える」へ

追加された中核はわずか2つのクラス。既製の4環境はリポジトリですぐ動作します
60秒で要点
  • Agentの訓練は長らく2つの問題に阻まれてきました。決め打ちのテストが正しい解答を0点にするケース、静的で数ラウンドでモデルに学習され尽くす問題集。
  • 今回の解決策は、AgentにAgentを評価させること。評価者はサンドボックスに入りコードを実際に実行してから判定し、出題者は難易度を「ちょうど半分が解ける」水準に調整します。
  • 既製の4環境はすべてオープンソースですが、「スコアを誰と比較するか」という問題だけで、2つの新しいアルゴリズムが生まれました。
⚑ これはPrime Intellect自身による発表内容の解説です。示されているのはメカニズムとコードのみで、訓練結果の数値は一切ありません。また、4つの環境と2つの新アルゴリズムに関する効果の比較もありません。
はじめに

1つのAgentから、複数のAgentへ

強化学習で1つのAgentを訓練する光景は、長らくこうでした。1つのモデルが固定の問題集に取り組み、答えは決め打ちのテストが採点します。すると3つの問題が発生します。テストのアサーションはしばしば実装の詳細に依存し、正しい解答でも期待された書き方でなければ0点になる。問題集は静的で、モデルは数ラウンドで内容を学習し尽くす。そして対話する相手が存在しないため、交渉や駆け引きを学ぶことができません。

Prime Intellectが本日公開したのは、まさにこれらの問題に取り組むものです。トレーニングスタックを「1つのAgentを鍛える」から「複数のAgentが相互に作用する集団を鍛える」へと拡張し、Agent間の任意の相互作用を調整したり、学習に参加させる役割を指定したり、相互作用全体に功績を分配したりできます。コードはverifiers v0.3.0 と prime-rl v0.8.0 にあり、8月7日に公開されました。

まず区別すべき点があります。マルチエージェントアプリケーションオーケストレーションフレームワークは、複数のAgentが協力して作業を完了させることに焦点を当てています。一方、今回のツールキットが焦点を当てるのは、作業が完了した後、その相互作用の中で誰が学習すべきか、各役割の功績をどう計算するかです。後述しますが、「スコアを誰と比較するか」という問題だけでも、2つの新しいアルゴリズムが必要になりました。

メカニズム

追加された2つのクラス:AgentとEnv

verifiersの以前のバージョンでは、シングルエージェントの実行に必要な部品はすでに分解されていました。Taskset(実行するタスク)、Harnessモデルがその中で実行されるプログラム。どのツールを呼び出せるか、結果をどう読み取るか、どうステップを進めるかを決定します。モデルをエンジンとするなら、ハーネスは車全体です。同じエンジンでも、レーシングカーに載せるかトラックに載せるかで、できる仕事はまったく異なります。(モデルを駆動するプログラム)、Runtime(このプログラムをどのマシンで実行するか)です。今回の変更は非常にシンプルです。これら3つを1つにまとめたものをAgentと名付けました。

Harness骨格 モデル Runtime環境 Agent 再利用可能な部品 run(task) Trace トレース この実行での行動記録
Agentは「どの骨格 × どのモデル × どこで実行するか」を1つの部品にまとめ、外部にはrunという1つのアクションだけを公開します。本サイトによる図解。

タスクを与えると、Trace1つのAgentが1回の実行を完了するまでの完全な記録:発言、ツール呼び出し、取得スコア、消費トークン数など。各車両のドライブレコーダーのようなものです。相互作用内の全Agentの記録をまとめたものがEpisodeです。(トレース)が返ってきます。この実行中に何を言い、どのツールを呼び、どれだけのスコアを取り、どれだけのトークンを消費したかがすべて含まれています。サンドボックスの起動、ツールサービスのインストール、タイムアウト再試行などの面倒な処理はすべて、この1つのアクションに隠蔽されています。したがって、任意の骨格、任意のモデル、任意の実行環境を自由に組み合わせて、通常のコードで制御できます。

Envはマルチエージェントの本拠地であり、シグネチャも同様に一言で表せます。Env.run(task, agents)。初期タスクと、準備済みのAgentグループが与えられ、残りの制御フローは自分でコーディングします。各Agentの実行が完了すると、そのトレースは自動的にEpisode(つまり相互作用全体の記録)に統合されます。

verifiers v1 のシングルエージェントとマルチエージェントの構造比較
左が従来のシングルエージェント:タスクセットを1つの骨格に与えます。右が現在:Env内に複数の明示的なAgentが存在し、実行後は各役割の個別トレースを含む1つのEpisodeに統合されます。図:Prime Intellect

Env.run は通常のasync Pythonです。順次実行したい場合はawaitを2回、並行実行したい場合はTaskGroupを開始し、対話をさせたい場合はwhileループを書きます。DSLも、グラフオーケストレーションも、ステートマシン設定ファイルもありません。以前のシングルエージェントは新しいフレームワークでは1行に縮小され、この抽象化レイヤーは何も追加しません。

シングルエージェント環境の全実装
class SingleAgentEnv(Env[SingleAgentEnvConfig]):
    async def run(self, task: Task, agents: Agents) -> None:
        await agents.agent.run(task)
クラス全体がたったの1文:唯一のAgentにタスクを実行させるだけです。

もう1つの便利な設計として、Agentの名前は設定フィールド名から自動的に生成されます。設定クラスに solverjudge という2つのフィールドを書くと、コード内で agents.solveragents.judge として利用でき、追加の登録は不要です。

サイト内関連記事 Prime Agent 自己改善が可能なAgentフレームワーク:Opus 5を置き換えたところ、ARC-AGI-3スコアが30.2%から95.5%に急上昇 同じ会社が2日前に公開した骨格プログラム。上記のharnessは、この種のものを指します。
シナリオ1

Agentを評価者としてテストを覆す

実装済みの4つのマルチエージェント環境:評価者、模擬ユーザー、出題と解答、ターン制ゲーム
実装済みの4つの環境。以下で順に解説します。図:Prime Intellect

まず、これがどれほど一般的な問題かを説明します。ソフトウェアエンジニアリングの訓練タスクでは、正誤はテストケースによって判定されますが、そのテストケースはしばしば特定の実装詳細を検証しています。変数名、関数がリストを返すのかジェネレーターを返すのかなどです。美しく機能する解答でも、テストが期待する書き方でなければ0点になります。このシグナルが訓練にフィードバックされると、モデルが学ぶスキルは歪みます。つまり、テストが何を求めているかを推測することを学び、タスクを正しく実行することを学ばなくなるのです。

大きなモデルに一回で採点させればいいのでしょうか?一度の呼び出しで正確な判定を下すのは非現実的です。コードベースを見ることも、テストを実行することも、何かを検証することもできず、テキストの断片を見て推測するしかありません。

評価者をAgentにすると状況は変わります。独自のサンドボックスを持ち、コードを調べたり、どのテストがどの行で失敗しているかを確認したり、自分で実行してみたり、そして決め打ちのテストの結論を覆すことができます。

一回呼び出しの大規模モデル採点 テキストを見て推測するだけ テキスト の断片 ? 評価者もAgent サンドボックスに入り コードを実際に実行、テストの結論を覆せる 評価者のサンドボックス コードを調べる 失敗テストを確認 自分で実行 判定 項目別に採点
同じ解法でも、上の経路は推測するしかなく、下の経路は検証できます。本サイトによる図解。
評価者環境の制御フロー(ブログ掲載の簡略例)
class AgenticJudgeEnv(vf.Env[AgenticJudgeEnvConfig]):
    async def run(self, task, agents) -> None:
        solution = await agents.solver.run(task)
        if not solution.ok:
            raise
        await agents.judge.run(JudgeTask.from_trace(solution))
解答者が先に実行し、失敗すれば全体が無効になります。成功すれば、そのトレースを判定タスクに変換して評価者へ渡します。

評価者に与えられるプロンプトは明確に書かれています。

トレースからこのAgentが何をしたかを再構築し、自分のサンドボックスでの実際の実行を通じて検証してください。自分で検証できる結果については、トレース内の記述を決して鵜呑みにしないでください。

verifiersリポジトリ内の評価者用採点プロンプト

判定をスコアに変換する方法:評価者は事前に定義された複数の基準に従って項目ごとに採点し、結果をJSONとしてサンドボックス内の指定されたファイルに書き込みます。フレームワークは厳密に検証し、各判定を解答者のトレース上の指標として記録し、加重平均を取って judge と呼ばれる報酬にします。デフォルトでは評価者のスコアのみを採用し、タスクセット自身の報酬重みは0です。両方を使用したい場合は、重みを1に調整するだけです。

ブログにはない3つの設計

評価者が作業するサンドボックスは選択式です。共有版では、評価者は解答者が使用したサンドボックスに直接入り、ワークスペースはそのまま保持され、変更履歴も見えます。分離版では、評価者に新しいサンドボックスを与え、解答者が正式に提出した成果物のみを復元します。どの環境IDを選ぶかでセキュリティ境界が決まるため、実際の動作と矛盾する可能性のあるスイッチを残すことはありません。

評価者の骨格はコードを実行できなければなりません。この点は環境構築時にチェックされ、チャットのみのツールなし骨格を接続するとエラーになります。実行なしで下せる判定は、プラグイン式採点器であり、Agent評価者ではありません。

作業開始前に環境をクリーンアップします。解答者が先にサンドボックスを使用するため、評価者が作業を開始する前に、フレームワークは判定ファイルとトレースファイルを削除します。これは2つの事態を防ぐためです。解答者が事前に判定ファイルを埋め込んで評価者の結果を偽装すること、またはアップロードパスにシンボリックリンクを仕掛けて評価者の書き込み操作を任意のファイルにリダイレクトすることです。

もう1つ一貫した原則があります。評価者のトークンは訓練データに決して入りません。評価者は測定のための物差しであり、物差し自体が最適化の対象になるべきではありません。

シナリオ2

出題するAgentと解答するAgent

強化学習が有用な学習シグナルを得るには、問題の難易度がモデルの現在のレベルに近い必要があります。簡単すぎる問題は情報がなく、難しすぎる問題も情報がありません。静的データセットはこれを提供できません。モデルが強くなっても、自動的に難しくなるわけではないからです。

その方法は、モデル自身に問題を生成させることです。1つのAgentが出題者となり、シードトピックから新しい問題を構築します。別のAgentグループが解答者となり、それぞれが問題を解きます。解答者が正解するとスコアを得ます。これは理解しやすいでしょう。出題者のスコアは問題自体の出来映えではなく、その問題が解答者グループに何をもたらしたかだけを見ます。

全員が正解すれば、簡単すぎることを意味します。全員が間違えれば、難しすぎるか、問題自体に欠陥があることを意味します(例えば、出題者自身が計算した答えが間違っている場合)。半分の人が解けたとき、その問題がトレーニングに与える情報が最も多くなります。この量はlearnability(学習価値)と呼ばれます。式で表すと 4p(1−p) であり、pは解答率で、p=0.5のとき正確に1になります。

1.0 0.5 0 0% 25% 50% 75% 100% 解答者の解答率 学習価値 半数が解ければ価値最大 全員不正解:難しすぎ、または問題に欠陥 全員正解:簡単すぎる
出題者の報酬曲線4p(1−p)。両端は0で、中央が盛り上がります。高得点を目指すには「ちょうど半分が解ける」難易度に近づけるしかありません。本サイトが公式に基づき作成。

この曲線が自動カリキュラムのすべての秘密です。モデルが強くなれば、生成する問題も自動的に難しくなります。人間が難易度を調整する必要はありません。このアイデアはAbsolute Zero(Zhaoら、2025)に由来します。

出題-解答環境の制御フロー(ブログ掲載の簡略例)
async def run(self, task: vf.Task, agents: vf.Agents) -> None:
    proposed = await agents.proposer.run(task)
    solve_task = SolveTask.from_trace(proposed)
    async with asyncio.TaskGroup() as tg:
        for _ in range(self.config.n):
            tg.create_task(agents.solver.run(solve_task))
出題者が先に実行し、提出された問題を新しいタスクに変換してから、n人の解答者に並行して解かせます。

リポジトリ内の実装は、この例よりもかなり具体的です。シードトピックは6つあります:比率混合、数論、組合せ、幾何、確率、剰余算術。出題者はまずコードを書いて数字を構築し、答えをエンドツーエンドで検証してから、最後にJSONを1行出力する必要があります。答えは整数でなければならず、ごまかしの余地を与えません。デフォルトでは4人の解答者が同じ問題を解きます。

2つの座席はまったく異なる設定が可能で、これは非常に実用的です:

座席骨格実行場所この設定の理由
出題者codex本物のサンドボックス問題構築と答えの検証のためにコードを書く必要があるため
解答者 ×4null(ツールなし)不要解答のみで操作はしないため、モデル呼び出しのコストのみ

どちらを学習させるかもスイッチで選択できます。両方学習させることも、出題者のみ、または解答者のみを学習させることも可能です。

シナリオ3

2つのモデルがポーカーで対戦、相手は自分自身

クーン・ポーカーはゲーム理論の教科書に出てくる玩具モデルで、その小ささは一言で説明できます。合計3枚のカードJ、Q、K(Kが最大)、各プレイヤーは1チップのアンティを賭け、それぞれ1枚のカードを伏せて受け取ります。先手は「チェック」か「1チップのベット」を選び、1、2アクションでゲームは終了し、勝敗は±1または±2チップです。

これを選んだのは、小ささゆえです。数万ハンドを繰り返して戦略がどこに収束するかを見ることができ、ゲーム自体の複雑さに予算を費やす必要がありません。

プレイヤー0 先手 チェック ベット プレイヤー1 プレイヤー1 チェック→ 開示 ±1 再ベット → プレイヤー0へ フォールド → ポット獲得 +1 コール → 開示 ±2 数字はプレイヤー0の純チップ数。両者は常に相反する
1ハンドは最大2アクションで精算され、5つの終局があります。本サイトが環境ルールに基づき作成。

環境は3つのことを管理します:誰がどの伏せカードを持っているか、現在の公開状況、この手番での有効なアクション。すべてホスト側で判定されます。モデルは応答に角括弧付きのアクションを含めるだけでよく、例えば [check] のようにします。2つ以上含めた場合や間違えた場合は、もう一度尋ねられ、それでもダメなら棄権と判定されます。タスクセットは無限で、各ハンドにランダムシードがあり、好きなだけハンドを実行できます。

2つの座席はデフォルトで同じモデルにバインドされており、これが自己対局です。戦略が強くなると、相手も一緒に強くなり、カリキュラムが自動的に難易度を上げていきます。別途対戦相手サービスを用意する必要はありません。

アルゴリズム

功績をどう異なる役割に分配するか

前述の2つの自己対局の例は、どちらも同じ問題を提起します:今回得たスコアは、何と比較すべきか。

パフォーマンスを評価するには、「通常のレベル」と比較して初めて良し悪しが決まります。この通常のレベルをベースラインと呼びます。期末試験で80点が良いか悪いかは、クラスの平均点によって決まります。ベースラインはその平均点です。GRPOのアプローチはまさにこれです:同じ問題に対して一連の答えを生成し、そのグループの平均点より高いものを強化します。

しかし、クラスの半分が別の問題用紙を受けていたら、平均点は意味を持ちません。マルチロールトレーニングではこの問題に直面します。しかも、2つの異なる形で発生します。

ある人の失敗を、別の人のせいにしない

出題-解答の相互作用では、解答者の成績は「同じ問題への他の試行」とのみ比較されるべきです。問題をまたいで比較すると、難しい問題での失敗を使って、正常に機能している解答者を罰することになります。出題者の成績は「同じシードトピックから生成された他の問題」とのみ比較されるべきです。クラシックなGRPOはこの階層を表現できません。一連のロールアウトをフラットにして平均を計算するため、難易度の異なる問題と異なる役割がすべて混ざってしまいます。

Hierarchical GRPOが行うのはグループ化です。これを(役割、相互作用)ごとにグループ化し、各グループが独自のベースラインを計算します。コードは驚くほど短く、グループ化、グループ平均の減算、それだけです。

ゼロサムゲームでは、平均スコアは常に0

ポーカーでは別の形で機能不全に陥ります。ゼロサムゲームでは、一連の対局の報酬平均は常にほぼ0です。一方が勝てば他方が負けるため、戦略の良し悪しに関係なく一定です。これをベースラインとして使用することは、ベースラインがないことと同じです。

さらに厄介なのは、2つの座席の報酬スケールが逆であることです。混ぜて計算すると、先手の構造的な優位性がこの役割の永続的な功績として読み取られてしまいます。先手は単に良いポジションに座っているだけなのに、常に報酬を受け取っていることになるのです。

RAEの解決策は、各役割に独自の移動平均線を維持することです。この役割が通常どれだけのスコアを得るかをローリングで記憶し、功績は今回のスコアから自分の通常レベルを引いたものに等しくなります。シングルエージェント環境でこれを使用すると、自動的に移動平均ベースラインを持つREINFORCEに退化します。

クラシックGRPO:ひとまとめの平均点 難しい問題も簡単な問題も、出題者も解答者も、すべて1つの線で比較 共通ベースライン
すべてのスコアが同じ線上で比較されます。本サイトによる図解。
Hierarchical GRPO:グループごとに独自のベースライン 解答者は同じ問題への他の試行とのみ比較、出題者は同じシードの他の問題とのみ比較 同じ問題への4回の試行 同じシードから生成された複数の問題
2つのグループはそれぞれ独自のベースラインを持ち、互いに干渉しません。本サイトによる図解。
RAE:各役割が独自の移動平均を持つ ゼロサム対局ではグループ平均が常に0になるため、役割自身の履歴を物差しにする プレイヤー0の通常レベル プレイヤー1の通常レベル 自分の通常レベルを上回る = 功績あり
2つの線は独立して動き、先手の構造的優位性は功績として扱われません。本サイトによる図解。

両アルゴリズムはprime-rl内にあり、それぞれ数十行です。RAEはSPIRALの論文(arXiv:2506.24119)に由来します。

シナリオ4

ユーザーもAgentにする

アシスタントタイプのタスクには共通点があります。「1つのプロンプトと1つの応答」では表現できないことです。実際の人間は、あなたには見えない背景を持っており、情報は少しずつ明かされ、あなたの応答に反応し、いつ完了とみなすかを決めるのは人間側です。

そこで、ユーザーもAgentにします。1つの相互作用は、ユーザーとアシスタントの間の往復対話であり、両方のトレースがこの相互作用の記録に残ります。模擬ユーザーはデフォルトで凍結されトレーニングされません。評価者と同じで、環境の一部だからです。アシスタントのトレースは元のタスクに基づいて採点され、トレーニングに使用されます。

情報は次のように分配されます。タスクセット内の1行のデータは、ユーザー側の世界として解釈されます。そのプロンプトはユーザーのシステムプロンプト内の「あなたの状況」になり、アシスタントは同じタスクを受け取りますが、プロンプトは空にされます。したがって、アシスタントは最初は何をすべきか分からず、対話を通じて見つけ出すしかありません。

ユーザー側:完全な状況を把握 アシスタント側:最初は空白 ユーザーAgent 聞かれなければ言わない、短く話す アシスタントAgent 何ラウンドも聞き出すしかない 「こんにちは、何かお手伝いしましょうか」 ユーザーはここで初めて要望を伝える 満足したか、達成不可能と判断したら、ユーザーが終了マークを送る
挨拶はユーザー側にのみ存在します。アシスタントが先に「電話に出て」、ユーザーが話し始めます。本サイトによる図解。

ユーザーのペルソナにはいくつかのルールが書かれています。自分の言葉で話す、短く話す、ペルソナを維持する、作業はアシスタントが行う(ツール呼び出し、回答、形式はすべてアシスタントが行い、代わりに行わない)、詳細は尋ねられたら話す。目標が達成されたか、アシスタントには達成不可能だと確信した場合は、終了マークを返して締めくくります。デフォルトでは最大8ラウンドで、対話が発散するのを防ぎます。

模擬ユーザー環境の制御フロー(ブログ掲載の簡略例)
async with (
    agents.user.interaction(user_task) as user,
    agents.assistant.interaction(assistant_task) as assistant,
):
    ask = await user.turn("Hello! How can I help you today?")
    while True:
        answer = await assistant.turn(ask.last_reply)
        if answer.terminated:
            break
        ask = await user.turn(answer.last_reply)
        if ask.terminated:
            break
両側に「切断しない」対話を開き、環境が間に立って転送し、どちらかが終了を宣言したら回線を切ります。

これにより、異なるユーザーグループ、ペルソナ、非表示の目標、相互作用戦略を同じインターフェースに挿入でき、アシスタント側も個別に設定できます。これは前述の3つの環境と同じ部品の異なる組み合わせであり、別の評価パイプラインではありません。

導入

現在入手できるもの

リポジトリには既製の骨格が13個あり、Claude Code、Codex、Kimi Codeなどの実際のプログラミングAgentが含まれており、モデルに直接組み合わせて使用できます。

  • claude_code
  • codex
  • kimi_code
  • bash
  • browser_use
  • mini_swe_agent
  • hermes_agent
  • openclaw
  • terminus_2
  • rlm
  • pi
  • pool
  • null

実行環境は4種類:ローカルプロセス、Docker、Modal、そして自社のクラウドサンドボックスです。前述の4つの環境に加えて、リポジトリには BestOfNEnv も含まれています。同じタスクをn回独立して試行し、最良のものと、しきい値を超えた試行があったかどうかを示します。拒否サンプリングやpass@k評価に役立ちます。

サイト内関連記事 RLM(再帰言語モデル):ツールを呼び出すのではなく、モデル自身を呼び出すコードを書かせる 上記リストのrlmは、この考え方を骨格にしたものです。

同じAgent抽象化は、自社でも合成データ生成とフィルタリングのパイプラインに使用されています。各トレースの形式は統一され、監査可能であり、それ自体がデータ成果物です。ブログの最後の例はわずか10数行で、PoolsideのLaguna-S2.1モデルが pool 骨格で実行され、PyPIでverifiersの最新リリースバージョンを確認するというものです。前述のトレーニングと同じAgentを使用しています。

🧰 スタートアップカード · verifiers
価格オープンソースで無料。モデルAPIとサンドボックス計算リソースは別途
ハードルPythonができてモデルAPIキーがあれば、シングルマシンで評価を実行可能。トレーニングにはprime-rlの接続が必要。マルチエージェント環境では評価者側をコンテナ(Dockerまたは自社クラウドサンドボックス)で実行する必要があります。マルチエージェント機能はverifiers v0.3.0とprime-rl v0.8.0に含まれ、いずれも2026-08-07リリース。旧バージョンには含まれません
出典
Multi-Agent Systems in PRIME-RLKonstantin Dunas、Mika Senghaas、Eli Gottlieb と Prime Intellect チームPrime Intellect ブログ2026-08
本サイトの注記
2枚の構造図は原文からの引用。コードブロックはブログ掲載の簡略例です(原文ではIllustrative exampleと明記)。メカニズムの詳細は verifiers リポジトリの main ブランチの実装に基づいて説明しています。共有/分離の評価者、評価者の骨格がコード実行可能であること、作業開始前の判定ファイルのクリーンアップ、6つのシードトピック、2つの座席の異種構成、ユーザーAgentの8ラウンド上限などはブログでは詳述されていません。バージョン番号とリリース日はGitHub Releasesより取得。曲線図は 4p(1−p) に基づき作成。その他は本サイトによる図解です。