マルチエージェントオーケストレーションにより、1つのエージェントが他のエージェントと連携して複雑な作業を完了できます。エージェントはそれぞれ独立したコンテキストを持って並列に動作できるため、出力品質の向上に役立ち、完了までの時間も短縮できます。
マルチエージェント構成が自分の問題に適しているか分からない場合は、マルチエージェントシステムを使うべきとき(使うべきでないとき)を参照してください。
Managed Agents APIリクエストにはmanaged-agents-2026-04-01ベータヘッダーが必要です。ただし、メモリストアエンドポイントは例外で、代わりにagent-memory-2026-07-22を使用します。SDKは正しいベータヘッダーを自動的に設定します。ベータヘッダーを参照してください。
すべてのエージェントは同じサンドボックス、ファイルシステム、およびボールト認証情報を共有しますが、各エージェントは独自のセッションスレッド、つまり独自の会話履歴を持つコンテキスト分離されたイベントストリーム内で実行されます。コーディネーターはプライマリスレッド(セッションレベルのイベントストリームと同じもの)でアクティビティを報告します。追加のスレッドは、コーディネーターが作業を委任するときに実行時に生成されます。
スレッドは永続的です。コーディネーターは以前に呼び出したエージェントにフォローアップを送信でき、そのエージェントは以前のターンのすべてを保持しています。
各エージェントは独自の構成(モデル、システムプロンプト、ツール、MCPサーバー、スキル)を使用します。セッションレベルのエージェント構成オーバーライドは例外で、コーディネーターとそのselfコピーに適用されます。ツール、MCPサーバー、コンテキストは共有されません。
マルチエージェント調整は、さまざまな領域にわたる作業を必要とする複雑なタスク、または複数の適切にスコープされたタスクが全体的な目標に貢献するタスクに最適です。
うまく機能するパターン:
エージェントを定義する際に、multiagentを設定して、コーディネーターが委任できるエージェントの一覧を宣言します:
ant beta:agents create <<YAML
name: Engineering Lead
model: claude-opus-4-8
system: You coordinate engineering work. Delegate code review to the reviewer agent and test writing to the test agent.
tools:
- type: agent_toolset_20260401
multiagent:
type: coordinator
agents:
- type: agent
id: $REVIEWER_AGENT_ID
- type: agent
id: $TEST_WRITER_AGENT_ID
YAMLmultiagent.agentsには以下のいずれかを指定できます:
{"type": "agent", "id": agent.id}は、以前に作成されたagentをIDで参照します。versionが指定されていない場合、参照はコーディネーター作成時点でのそのエージェントの最新バージョンに固定されます。{"type": "agent", "id": agent.id, "version": agent.version}は、特定のエージェントバージョンに固定します。{"type": "self"}は、コーディネーターが自身のコピーを生成できるようにします。セッションがエージェント構成オーバーライドを使用して作成された場合、それらのオーバーライドはこれらのコピーにも適用されます。IDで参照される一覧のエントリは影響を受けません。コーディネーターの構成(multiagent.agentsの一覧を含む)は、コーディネーターが作成または更新されたときにスナップショットされます。参照されるエージェントは、その時点で解決されたバージョンに固定されたままとなり、その定義に対する後の更新を自動的に取り込むことはありません。参照されるエージェントの新しいバージョンに委任するには、コーディネーターを更新して、その一覧がそのバージョンを参照するようにします。
コーディネーターは1レベルのエージェントにのみ委任できます。独自のmultiagent.agents一覧を持つエージェントを参照すると、作成または更新リクエストは検証エラーで失敗します。multiagent.agentsには最大20個の一意のエージェントをリストできますが、コーディネーターは各エージェントの複数のコピーを呼び出すことができます。
コーディネーターを参照するセッションを作成します。コーディネーターは必要に応じて一覧内のエージェントに委任します。
session = client.beta.sessions.create(
agent=coordinator.id,
environment_id=environment.id,
)MCPサーバーはエージェントスコープ(各エージェント定義が独自のサーバーとツールを宣言)であるのに対し、ボールト認証情報はセッションスコープ(セッション作成時に渡されるvault_idsはすべてのスレッドに適用)です。統合において2つの意味があります:
セッション作成時のエージェント構成オーバーライドは、コーディネーターとそのselfコピーのMCPサーバーを置き換えることができます。
research_agent = client.beta.agents.create(
name="researcher",
model="claude-haiku-4-5",
mcp_servers=[
{"type": "url", "name": "github", "url": "https://api.githubcopilot.com/mcp/"},
],
tools=[{"type": "mcp_toolset", "mcp_server_name": "github"}],
)
coordinator = client.beta.agents.create(
name="coordinator",
model="claude-opus-4-8",
tools=[{"type": "agent_toolset_20260401"}],
multiagent={
"type": "coordinator",
"agents": [{"type": "agent", "id": research_agent.id}],
},
)
session = client.beta.sessions.create(
agent=coordinator.id,
environment_id=environment.id,
vault_ids=[vault.id],
)
print(session.id)この例では、リサーチャーのみがGitHub MCPサーバーを宣言しているため、コーディネーターはアクセスできません。セッションのvault_idsがリサーチャーのスレッドにGitHub認証情報を提供します。
サーバーを宣言した後にエージェントのMCP呼び出しの認証が失敗する場合は、認証情報のmcp_server_urlがエージェントのmcp_servers[].urlと同じサーバーを参照していることを確認してください。両方のURLはマッチングの前に正規化されます(スキームとホストの小文字化、デフォルトポートと末尾のスラッシュの削除)。そのため、ホストの大文字小文字の違い、デフォルトポート、末尾のスラッシュはマッチを妨げませんが、異なるパス、サブドメイン、非デフォルトポートはマッチを妨げます。
セッションレベルのイベントストリーム(/v1/sessions/{session_id}/events/stream)はプライマリスレッドと見なされ、すべてのスレッドにわたるすべてのアクティビティの要約ビューを含みます。サブエージェントの完全なアクティビティは表示されませんが、作業の開始と終了、およびツール許可リクエストなどのブロッキングイベントは表示されます。
セッションスレッドは、特定のエージェントのアクティビティを詳しく調べる場所です。
セッションのstatusはすべてのエージェントアクティビティの集約です。少なくとも1つのスレッドがrunningの場合、セッション全体のステータスもrunningになります。
最大25個の同時スレッドがサポートされています。コーディネーターは一覧内の単一のエージェントの複数のコピーを呼び出すことができ、1つのagentに関連付けられた複数のスレッドを作成します。
セッションに関連付けられたすべてのスレッドを次のように一覧表示します:
for thread in client.beta.sessions.threads.list(session.id):
print(f"[{thread.agent.name}] {thread.status}")完全なリストにはプライマリスレッドが含まれます。プライマリスレッドのparent_thread_idはnullです。
これらのイベントは、/v1/sessions/{session_id}/events/streamのプライマリスレッド上でマルチエージェントアクティビティを表示します。メッセージ方向のイベントは、それらが表示されるストリームのスレッドを基準に命名されます。agent.thread_message_receivedは、このスレッドに別のスレッドからメッセージが到着したことを意味し、agent.thread_message_sentは、このスレッドがメッセージを送信したことを意味します。たとえば、コーディネーターが委任するタスクは、子自身のストリームにagent.thread_message_receivedイベントとして到着します。
| タイプ | 説明 |
|---|---|
session.thread_created | スレッドが作成されました。session_thread_idとagent_nameを含みます。 |
session.thread_status_running | スレッドがアクティビティを開始しました。 |
session.thread_status_idle | スレッドに関連付けられたエージェントが入力を待っています。エージェントが停止した理由を示すstop_reasonを含みます。 |
session.thread_status_terminated | スレッドがアーカイブされたか、終端エラーが発生しました。 |
agent.thread_message_received | プライマリスレッド上で、エージェントがコーディネーターにレポートまたは質問を送信しました。from_session_thread_id、from_agent_name、contentを含みます。 |
agent.thread_message_sent | プライマリスレッド上で、コーディネーターが別のエージェントにタスクまたはフォローアップメッセージを送信しました。to_session_thread_id、to_agent_name、contentを含みます。 |
重要なイベントはプライマリスレッドにプロキシされます。ただし、特定のエージェントの推論やツール呼び出しを調査したい場合もあります。そのためには、関連するセッションスレッドからイベントをストリーミングまたは一覧表示します。
各セッションスレッドは/v1/sessions/{session_id}/threads/{thread_id}/streamに独自のイベントストリームを持ち、セッションレベルのストリームと同じevent_deltas[]パラメータを受け付けるため、モデルが生成するサブエージェントのテキストをプレビューできます。接続は読み取っているスレッドのみをプレビューします。子スレッドのプレビューはセッションレベルのストリームには表示されないため、サブエージェントをライブで監視するには、そのスレッド自身のストリームを開きます。プレビューのオプトイン、蓄積、照合については、セッションスレッドイベントのプレビューを参照してください。
with client.beta.sessions.threads.events.stream(
thread.id,
session_id=session.id,
) as stream:
for event in stream:
match event.type:
case "agent.message":
for block in event.content:
if block.type == "text":
print(block.text, end="")
case "session.thread_status_idle":
breakサブエージェントがクライアントから何かを必要とする場合(always_askツールを実行するための許可や、カスタムツールの結果など)、そのイベントは発生元のセッションスレッドを識別するsession_thread_idとともにプライマリスレッドにクロスポストされます。
{
"type": "session.thread_status_idle",
"id": "sevt_01ABC...",
"session_thread_id": "sth_01DEF...",
"agent_name": "code-reviewer",
"stop_reason": {
"type": "requires_action",
"event_ids": ["toolu_01XYZ..."]
}
}user.tool_confirmation(tool_use_id付き)またはuser.custom_tool_result(custom_tool_use_id付き)を送信すると、サーバーは応答を正しいスレッドに自動的にルーティングします。
次の例は、ツール確認ハンドラーを拡張して応答をルーティングします。同じパターンがuser.custom_tool_resultにも適用されます。
for event_id in stop.event_ids:
client.beta.sessions.events.send(
session.id,
events=[
{
"type": "user.tool_confirmation",
"tool_use_id": event_id,
"result": "allow",
}
],
)Was this page helpful?