金曜の障害調査で、ワーカーは足りているのに待たされる
たとえば、金曜の夜。本番の遅いAPIを切り分けるために、エージェントを並列で走らせます。ログ担当、メトリクス担当、最近のデプロイ差分担当——それぞれ別スレッドです。
子はそこそこ速く動いています。なのに全体が伸びる。理由は単純で、全部の結果が親スレッドに戻り、親が次の指示を出すまで子が止まったままだからです。
「エージェントを増やしたのに速くならない」は、モデルの賢さだけの話ではありません。集め方の話でもあります。Carnegie Mellon University の Xuecheng Liu氏・Daman Arora氏らのチームは、この集約ボトルネックを外す枠組みとして Message Passing Language Models(MPLMs) を提案しました。論文は Message Passing Enables Efficient Reasoning です。プロジェクトページは MPLM: Message Passing Language Models、実装は Zanette-Labs/mplm に公開されています。
本稿では、研究の細部をなぞるより先に、並列エージェントのハーネスで何が変わるかを現場の言葉に落とします。
なぜ「forkしてjoinする」だけでは足りないか
テスト時に計算を増やして推論を強くする流れは、すでに一般的です。1本の長い Chain-of-Thought(思考の連鎖)で進めるやり方と、タスクを分けて並列に進めるやり方があります。
後者の代表が fork-join です。親が子スレッドを起動し、子が終わり次第、親が結果を集めて次の手を決めます。レイテンシは下がります。ただし、次の制約が残ります。
子同士は基本的に直接話せません。情報は親経由です。子のコンテキストは短命で、一度返したら消える設計が多いです。親は集約・再プロンプト・ツール呼び出しで忙しくなり、結果として暗黙の直列化が起きます。
モデル以外の制御層をハーネスと呼ぶ整理は、ハーネスエンジニアリングとは?——AIエージェントを「手綱」で導く設計思想 でも扱っています。MPLMは、そのハーネス側に 点対点のメモ渡し を足す提案だと読めます。
タスクを分解して多数のサブエージェントに振る製品側の流れは、Claude CodeのDynamic Workflows:数百のサブエージェントで大規模開発を進める時代へ で追っています。計画・実装・レビューを分ける Agent Teams の話は、Claude Opus 4.6は「副操縦士」じゃない——エンジニアの隣に立つ“自律する同僚”の中身 と並べて読むと整理しやすいです。どちらも「親が束ねる」構図が強いので、本稿の問い——子同士がメモを渡してよいか——と対比しやすいです。
MPLMが足した4つの指令
MPLMでは、モデル自身が特殊タグ付きの文字列を生成し、推論エンジン上の軽いコントローラがそれを解釈します。指令は次の4つです。
spawn
新しいスレッドを起動し、IDとプロンプトを渡します。forkに近い操作です。
send
指定したIDのスレッドへ、短いメッセージを送ります。
recv
指定したスレッドからのメッセージを待ちます。到着するまでそのスレッドはブロックされます。
stop
そのスレッドの実行を終了します。
古典的な並列計算の Message Passing Interface(MPI) に近い発想を、LLMスレッド向けに持ち込みました。スレッドは短命な使い捨てではなく、状態を持ち続け、必要な相手とだけやり取りする想定です。
概念だけ抜き出すと、次のようなプロトコルになります。動く本番コードではなく、会話の型を示すためのものです。
# 親: セルごとのワーカーを起動する(Sudokuのイメージ)
<spawn[1,2,...,81]> initial grid state
# セル12のワーカー: まだ候補が複数なら、行・列・箱の隣人を待つ
<recv[neighbors...]>
# 候補が1つに決まったら、親と隣人へ通知して終了
<send[0, neighbors...]> cell=(1,3) value=7
<stop>
コントローラは vLLM のような batched inference の上に載り、実行可能なスレッドをまとめてデコードします。recv 中のスレッドは待機し、send でメッセージが届くと再開します。論文では wait-for-all / wait-for-any、早期打ち切り(preemption)、要約付きの再spawnなども議論されています。
Sudokuと3-SATで見えた、2種類の効き方
著者らは構造の分かりやすい問題で、効率の差を測りました。訓練データは Python でシミュレーションしたトレースです。それを使って Qwen3-0.6B-Base を教師ありファインチューニング(SFT)しています。比較対象は、1本の Serial CoT と、親が集約する Fork-Join(FJ)です。
局所通信が効く場合(Sudoku)
各マスに1スレッドを割り当てます。マスは、同じ行・列・箱の隣人から数字を受け取り、候補を削ります。候補が1つになったら(いわゆる naked singles)、親と隣人へ数字を送り、自分は止まります。全部止まると親が盤面をまとめます。
論文 Table 1 では、たとえば 9×9 で MPLM が約 14.9秒・正解率100%、FJ が約 59.6秒・93% です。16×16 や 25×25 では、FJ と Serial は著者の置いたコンテキスト/計算の制約で訓練自体が成立せず、MPLM は 25×25 で 72% まで解けました。ツールなしの一部フロンティア推論モデルでも、大きい盤では苦戦する、という比較も示されています。
ポイントは「小さいモデルが強い」ことだけではありません。隣人だけと話す設計にした結果、1スレッドあたりのコンテキスト増加が抑えられた、という構造の話です。
早期打ち切りが効く場合(3-SAT)
ブール式が満たせるかを探索する問題では、ある枝が解を見つけた瞬間、他の枝を続ける必要がなくなります。MPLMでは、解を見つけた子が親へ送り、親が他の枝を止められます。FJでは、親は子が揃うまで待ちやすいので、木が偏っていると「最後の葉」までレイテンシが引きずられます。
精度は FJ と同程度(変数数ごとの表ではおおよそ90%前後)で、平均レイテンシは MPLM が速い、という結果です。偏った木では、サマリーで触れられるように 数倍速い例も出ます。
並列化で呼び出しが増えると経済性が崩れやすい点は、AIエージェントが変えるビジネスの未来:エージェント・ワークフローの実践ガイド でも触れています。MPLMが示すのは、「呼び出しを増やすなら、無駄な枝を早く切れ」という打ち消し側の設計です。
長文脈QAでは、プロンプトだけでも効いた
SudokuとSATは専用トレースで学習した話です。一方、LongBench-v2 では、タスク用の追加学習なしで、大きめのモデルにMPLMの手順をプロンプト指示しています。比較は fork-join 寄りの RLM(Recursive Language Models)です。
論文 Table 2 の平均では、次のようになります。
- Qwen3-30B-A3B: 正解率 29.7%→37.8%、平均レイテンシ 105.7秒→61.3秒(およそ1.7倍速い)
- Qwen3.6-35B-A3B: 正解率はほぼ同等(46.7%対46.5%)、平均レイテンシ 223.5秒→102.2秒(およそ2.2倍速い)
やり方の骨格はこうです。長い文脈をチャンクに分け、各ワーカーが要約を親へ送る。親は要約を見て、必要なら特定のワーカーだけに追加質問する。ワーカーは状態を残すので、同じ区間を再度読み込むコストを抑えやすい、という説明です。
長い文脈を一度に載せず分割して扱う発想は、長いチャットほど答えが雑になる——Context Rotを防ぐMemory・Projects・Skillsの使い分け ともつながります。MPLMは、その分割を「親への一括返却」ではなく、「必要なら同じワーカーへ聞き直す」形にしています。
現場のハーネスに落とすとき、見る3点
研究をそのまま本番に載せる必要はありません。設計レビューでは、次の3点をチェックすると使いやすいです。
通信の相手は、事前に言えるか
Sudokuの「行・列・箱」、長文の「チャンクID」、マイクロサービスの「依存するAPI境界」のように、誰が誰の結果を必要とするかが先に書ける仕事ほど、点対点は効きやすいです。オープンエンドな調査や、途中で依存関係が変わる仕事では、親が束ねる方が安全なことも多いです。著者自身も、オープンエンドではプロンプトや追加学習が要る、と限界を書いています。
集約点は、何を集める役に限定できているか
親が「全ログを読んで再推論する」役まで抱えると、fork-joinの弱点が再発します。親はルーティングと最終報告、局所の詳細はワーカー間、と役割を分ける発想が近いです。
早期停止の条件はあるか
探索や複数仮説の比較では、「1つ見つかったら他を止める」「矛盾が出たら枝を捨てる」が書けるかが効きます。止められない並列は、コストだけ増えます。
小さな設計メモとして、自チームのワークフローを次の表に当てはめてみるのも有効です。
# レビュー用のチェックリスト(概念)。本番のオーケストレータではない。
workflows = [
{
"name": "障害の一次切り分け",
"edges_known": True, # ログ/メトリクス/差分の依存が言えるか
"need_peer_notes": True, # 担当同士が直接メモを渡す価値があるか
"early_stop": True, # 根因候補が立ったら他調査を止めてよいか
},
{
"name": "仕様が曖昧な機能設計",
"edges_known": False,
"need_peer_notes": False,
"early_stop": False,
},
]
for w in workflows:
if w["edges_known"] and w["need_peer_notes"]:
style = "点対点メッセージを検討"
else:
style = "親集約(fork-join)を維持"
print(f"{w['name']}: {style}")
動かす条件は Python 3 のローカル実行で足ります。出力は設計メモのたたき台であり、採用判断そのものではありません。
誤解しやすい点
「並列=常にメッセージパッシングが強い」
そうではありません。通信パターンが不明な仕事では、親が状況を見て振り直す方が失敗が安いです。MPLMの強みは、既知の疎な依存と早期打ち切りが同時に欲しい場面です。
「Sudokuで解けた=任意の推論がスケールする」
著者は Sudoku を naked singles(消去だけで進む盤)に限定しています。推測と検証を深くまたぐ手筋は、この実験では求めていません。一般化の証拠は LongBench-v2 側の方が近いですが、こちらもプロンプト設計に依存します。
「小さいモデルのSFT結果を、そのままフロンティア製品に当てはめる」
Sudoku/SATは 0.6B の学習結果、LongBenchは数十B級のプロンプト結果です。数字の意味するレイヤーが違います。自社では、同じタスクを「親集約」と「隣接通知+早期停止」の2ハーネスで、正解率・レイテンシ・トークン合計を並べる方が実務的です。
次の一歩は、通信図を1枚書くこと
MPLMが示しているのは、新しいモデル名というより、エージェント並列の通信設計です。スレッドを増やす前に、「誰が誰に何を渡すか」「親は何だけ集めるか」「いつ止めるか」を図にすると、ボトルネックの位置が見えやすくなります。
金曜の調査でも、月曜の設計レビューでも、最初の一歩は同じです。既存のオーケストレーション図に、矢印が全部親へ向かっていないかを一度見直す。矢印の一部をワーカー間に移せるなら、メッセージパッシングの発想が使えます。移せないなら、親集約のまま、親の仕事を減らす方が先です。
万能のハーネスはありません。それでも、「増やしたのに待たされる」違和感の正体を、モデル以外の層で説明できるようになるだけでも、次の試作は進めやすくなります。
作成日: 2026-09-25