先に要点
- オーケストレーター は、複数の AIエージェント やツールの役割分担を調整する司令塔のような役目で、本質は 分類 → 委任 → 統合 のループです。
- マルチエージェント 構成では、調査・実装・レビューなどを分けて動かすために、誰に何を任せるかを決める中心が必要になります。
- 最大の失敗は coordinator が太りすぎること。委任せず自分で実行し始めると、トークン消費とレイテンシが膨らみ、結局1つの巨大な単体エージェントに退化します。
- 太りすぎは
System promptの行数、保持するツール数、1ターンあたりの平均トークン数という3つの数値で検知できます。本文に切り分け手順を載せます。
AI エージェントの話を追っていると、オーケストレーター という言葉が出てきます。
特に Anthropic の Multiagent sessions や、OpenAI の Agents SDK のように複数エージェントを組み合わせる話になると頻度が上がります。
ただ、用語だけ先に入ってくると 結局何をしている役なのか が見えにくいです。
この記事では Anthropic と OpenAI の公式ドキュメントをもとに、AI エージェント設計におけるオーケストレーターの基本を整理します。
単なる用語説明ではなく、どこまで任せるべきか、handoff と何が違うのか、どこで太って失敗するのか までつなげて、実装判断に使える形で見ていきます。
オーケストレーターとは何か
オーケストレーターとは、複数のエージェントやツールがある構成で、全体の流れを調整する役目です。
たとえば、ユーザーから「このリポジトリの不具合を直して」と依頼されたとします。 そのとき、
- 調査担当がコードを読む
- 実装担当が修正する
- テスト担当が確認する
- レビュー担当が抜け漏れを見る
という分業にしたいことがあります。
このとき、最初に誰へ振るか、どこで別の担当に渡すか、最後にどうまとめるか を決めるのがオーケストレーターです。
自分で全部を解く専門家というより、交通整理と進行管理をする中心 と考えると分かりやすいです。
そして、その交通整理の中身を分解すると、ほとんどのオーケストレーターは次の3ステップのループに落ち着きます。
オーケストレーターの本質は「分類 → 委任 → 統合」ループ
ライブラリや実装が違っても、オーケストレーターの中身はほぼ同じ形です。 来た要求を 分類 し、適切な担当に 委任 し、返ってきた結果を 統合 する。このループを停止条件に達するまで回します。
擬似コードで書くと、骨格は次のようになります。言語非依存で、要点はコメントに寄せています。
def orchestrate(user_request):
context = [] # 統合用のメモ。長い生ログは入れない
pending = [user_request] # まだ片付いていない仕事
steps = 0
MAX_STEPS = 8 # 暴走防止の停止条件(数値はあとで調整)
while pending and steps < MAX_STEPS:
steps += 1
task = pending.pop(0)
# 1) 分類: この仕事は誰の領分か
kind = classify(task) # "research" / "implement" / "review" ...
if kind == "needs_human": # 危険な操作は人間へエスカレーション
return ask_human(task)
# 2) 委任: 担当だけに必要な文脈を渡して実行させる
agent = route(kind) # 専門エージェントを選ぶ
sub_context = slice_context(context, kind) # 全部は渡さない
result = agent.run(task, sub_context) # 別文脈で実行
# 3) 統合: 結果を要約してメモに足す。新しい仕事が出たら積む
context.append(summarize(result))
pending += result.followups # 例: レビューが指摘した修正タスク
return compose_final_answer(context) # 最後に1つの回答へまとめる
ここで効いているのは route()、slice_context()、compose_final_answer() の3つです。
route() が分類結果に応じて担当を選び、slice_context() が「その担当に必要な分だけ」を切り出して渡し、compose_final_answer() が散らばった結果を1つの責任ある回答に束ねます。
OpenAI Agents SDK ではこの委任を Agent.as_tool() で表現します。manager 役のエージェントが specialist を tool として呼び、会話の主導権は manager が持ち続けます。上の擬似コードの agent.run(task, sub_context) が、ちょうど tool 呼び出しに対応するイメージです。
分類 (classify)
来た仕事の種類を判定する。ここを LLM に任せるか if/else にするかで、後述する太りやすさが変わります。
委任 (delegate)
担当に「必要な文脈だけ」を渡して実行させる。全文脈を渡すと、せっかく分けた意味が消えます。
統合 (integrate)
結果を要約してまとめ、必要なら次の仕事を積む。停止条件に達したら1つの回答へ束ねます。
このループのうち、route() と compose_final_answer() だけがオーケストレーターの本来の仕事です。
逆に言えば、それ以外をオーケストレーター本体に書き始めた瞬間に「太りすぎ」が始まります。
なぜオーケストレーターが必要になるのか
1. 役割分担を明確にしやすい
単体の AI エージェントに全部を任せると、調査・判断・実装・レビューが1本の会話に詰め込まれます。 小さな仕事なら成立しますが、長い作業では役割が混ざりやすいです。
オーケストレーターがいると、調査は調査だけ、実装は実装だけ、レビューはレビューだけ、と切り分けやすくなります。
OpenAI Agents SDK でも、manager が specialist agents を as_tool() で呼ぶ「agents as tools」パターンが代表例として紹介されています。
2. コンテキストを分けやすい
マルチエージェントの利点は、並列化できることだけではありません。 担当ごとに持たせる情報を分けやすいことも大きいです。
Anthropic の Multiagent sessions でも、coordinator が別スレッドの agent に仕事を振り、各 agent は分離された文脈で動く形が説明されています。
擬似コードの slice_context() がこれに当たり、全員が同じ長い会話を丸ごと抱える必要はありません。
これは実務的にも効きます。レビュー担当に、実装時の細かい試行錯誤ログまで全部持たせる必要はないことが多いからです。
3. 並列化しやすい
複数の調査を同時に進めたいとき、オーケストレーターがいると分岐しやすくなります。
A担当は公式仕様、B担当は既存コード、C担当はテスト観点、のように分けて、あとで結果だけ集める設計にできます。OpenAI のドキュメントでも asyncio.gather で独立タスクを並列実行する例が「コードによるオーケストレーション」として挙げられています。
ただし、並列化はそれだけで正義ではありません。 小さい作業を無理に分割すると、呼び出し回数と統合作業ばかり増えて逆に遅くなります。
オーケストレーターと handoff の違い
ここは混同されやすいところです。 OpenAI のドキュメントでは、orchestration を大きく「LLM に任せる」と「コードで決める」に分け、LLM 側で次の2つの構成を挙げています。
- manager / orchestrator が specialist を
as_tool()で呼ぶ構成 - handoff で別エージェントに会話の主導権を渡す構成
違いをかなり雑にまとめると、こうです。
| 観点 | オーケストレーター型 | handoff型 |
|---|---|---|
| 主導権 | 中心のエージェントが持ち続ける | 別の担当へ渡し、相手がそのターンを引き継ぐ |
| SDK での表現 | Agent.as_tool() で specialist を tool 化 |
handoffs=[...] に渡す相手を列挙 |
| 向く場面 | 全体管理、統合、最終回答を1つにまとめたい | 問い合わせの種類ごとに担当そのものが変わる |
| 強み | ガードレールや出力形式を一元化しやすい | 専門担当に会話を集中させやすい |
| 弱み | 司令塔が太りやすい | 引き継ぎ設計が雑だと情報が抜けやすい |
誰かがずっと全体を見ている構成 が欲しいならオーケストレーター型、問い合わせ内容に応じて担当そのものを入れ替える構成 なら handoff 型、と考えると整理しやすいです。
ケーススタディ: coordinator が太りすぎる実例と切り分け
ここが今回の本題です。オーケストレーター設計で一番ありがちな事故は「coordinator が太りすぎる」こと。具体的な例で、現象から回避までを追います。
状況: 社内向けの「リポジトリの不具合修正エージェント」を、coordinator + 調査・実装・レビューの3 specialist で組んだ。最初は快適だったが、運用2週間で遅くなり、コストが当初見積もりの3倍に膨らんだ。
現象 → 原因 → 確認手順 → 回避
太りすぎを数値で検知する3つの目安
感覚ではなく数値で見るのが大事です。次の3つを定期的に測ると、太り始めを早めに捕まえられます。あくまで実務での当たりを付けるための目安で、絶対的なしきい値ではありません。
| 指標 | 健全な目安 | 太りすぎのサイン |
|---|---|---|
| coordinator の system prompt 行数 | 分類・委任・統合の規則が中心で、数十行に収まる | specialist の仕事内容まで書き込まれ、肥大化していく |
| coordinator が直接持つツール数 | 分類・統合用と委任口(specialist 呼び出し)が中心 | 実行系ツール(コード編集・外部API実行など)まで本体に付いている |
| 1ターンの中身(委任か自前実行か) | 大半が specialist への委任ターン | 自前で長文生成・コード生成するターンが増えている |
切り分けの原則はシンプルです。誰に渡すかを決める役 と 実際に深く作業する役 を、コードと権限の両方で物理的に分けること。
coordinator が実行系ツールを「持っていない」状態にしておけば、太ろうにも太れません。これは設計でいちばん効く予防策です。
AIエージェント設計でよくあるオーケストレーターの仕事
依頼の分類
来た仕事が何なのかを分類します。設計相談なのか、実装なのか、調査なのかで回す相手が変わるからです。擬似コードの classify() がこれです。
担当の選択
どの specialist agent やどの tool を使うかを決めます。重要なのは 全部使う ではなく 必要なものだけ使う ことです。
停止条件の管理
どこまでやれば完了とみなすかを決めます。これが曖昧だと、調査だけ延々と続いたり、レビューが再調査を始めたりします。擬似コードで MAX_STEPS を置いたのは、この暴走を止めるためです。
結果の統合
複数の担当から返ってきた結果をまとめて、最終的に人が読める形へ整えます。 この最後の整形や優先順位付けこそ、オーケストレーターが手放してはいけない役目です。
どんなときにオーケストレーター型が向いているか
向いているのは、分業したいが、最後は1つの責任ある回答にまとめたい 場面です。
- 複数の情報源を調べてから結論を返したい
- コード修正・テスト・レビューを分けて動かしたい
- 出力フォーマットや安全確認を中央で統一したい
- 途中の担当は入れ替えても、最後の窓口は一つにしたい
逆に、FAQ のように質問カテゴリごとに担当を切り替えれば十分なケースでは、handoff の方が素直なこともあります。
よくある失敗
1. オーケストレーターが何でもやり始める
前章のケーススタディそのものです。
司令塔なのに自分で調査し、実装し、レビューし、さらにまとめまでやると、結局は巨大な単体エージェントに戻ります。誰に渡すかを決める役 と 実際に深く作業する役 は、意識して分けた方が安定します。
2. 担当の境界が曖昧
調査担当が設計提案まで始める、レビュー担当が修正を始める、といった状態です。 責任の境界がぼやけて、あとから見直しにくくなります。
3. 分割しすぎる
エージェントを増やせば高度になるわけではありません。 小さな仕事を無理に5役へ分けると、受け渡しコストの方が目立ちます。
4. 人間の確認点がない
重要な設計判断、費用がかかる操作、本番影響がある変更まで全部自動で流すと危険です。
擬似コードの needs_human 分岐のように、どこで人間が止めるかを最初に決める方が安全です。
実務で先に決めたい設計項目
オーケストレーターを入れる前に、少なくとも次を決めておくと崩れにくいです。
- どの条件でどの担当へ渡すか(
route()の規則) - どの情報を共有し、どの情報を分離するか(
slice_context()の範囲) - specialist に許す権限はどこまでか(実行系ツールは specialist 側に置く)
- どこで人間承認を挟むか(
needs_humanの条件) - 最終回答をまとめる責任を誰が持つか(
compose_final_answer()の担当)
このあたりを決めずに始めると、とりあえず coordinator を置いたが、結局ぐちゃぐちゃ になりやすいです。
オーケストレーターに関するよくある質問
Q. オーケストレーターは特別なツールが必要ですか?
A. 専用フレームワーク(LangGraph、CrewAI、AutoGen、OpenAI Agents SDK)がありますが、自前で LLM 呼び出しのループを書いても実装できます。本文の擬似コードのとおり、分類 → 委任 → 統合 のループが本質です。
Q. coordinator が太っているかどうかは、どう判断しますか?
A. 本文の3指標、つまり system prompt の行数、coordinator が直接持つツール数、1ターンが委任か自前実行か、を測ります。トレースを1リクエスト分開き、委任ターンより自前生成ターンが多ければ太りすぎのサインです。
Q. オーケストレーターと普通のメインエージェントは違いますか?
A. 名称の違いで本質は近いです。複数のサブを呼び分ける管理役 という観点で オーケストレーター と呼ぶことが多いだけです。
Q. 階層構造はどこまで深くできますか?
A. 技術的には何階層でも可能ですが、深くするほどデバッグが難しくなりコストも増えます。まずは 2階層(オーケストレーター + サブ) で組み、必要が出てから増やすのが現実的です。
Q. オーケストレーターには何モデルを使いますか?
A. 全体管理は上位モデル、個別タスクは軽量モデル、と使い分けるとコスト効率が良いです。分類だけなら軽量モデルやルールで十分なことも多く、上位モデルは統合と最終回答に絞ると費用を抑えられます。
Q. ルールベースとAIベース、どちらでオーケストレーションしますか?
A. 単純な分岐はルールベース(if/else)、判断が必要な分岐は AI ベース、を組み合わせます。classify() を AI に任せると柔軟だが曖昧、ルールにすると確実だが硬い、というトレードオフがあります。OpenAI も「コードによるオーケストレーション」を予測可能性が要る場面で推奨しています。
Q. 失敗時のリトライはどう設計しますか?
A. 指数バックオフ、最大リトライ回数、部分成功からの再開、人間エスカレーションを設計します。サブが失敗したら、オーケストレーターが代替の担当や手段を選ぶこともできます。
Q. オーケストレーター無しの単体エージェントとどちらが良いですか?
A. 単純なタスクなら単体が圧勝です。複数の独立タスクを並列実行したい、役割を明確に分けたい、結果の整合性を取りたい 場面でオーケストレーターが価値を発揮します。
まとめ
オーケストレーターとは、複数の AI エージェントやツールの役割分担を調整し、全体の流れを束ねる役 です。
その中身は 分類 → 委任 → 統合 のループで、AI エージェント設計ではかなり重要ですが、一番賢い親玉 という理解で入れると太って失敗します。
大事なのは、
- 何を分業するのか
- 誰がどこまで担当するのか(実行系ツールは specialist 側へ)
- どこで統合するのか
を先に決め、coordinator が太っていないかを数値で見張ることです。 マルチエージェント全体の入り口から見たい場合は、マルチエージェントとは?複数のAIエージェントを分けて使う意味と注意点を整理 もあわせて読むと流れがつかみやすいです。
参考リンク
- Anthropic Docs: Multiagent sessions
- Anthropic Docs: Observability
- OpenAI Agents SDK: Agents
- OpenAI Agents SDK: Agent orchestration
- OpenAI Agents SDK (JS): Agents guide