multi-agent の設計で最初に決めるべきは、agent を何人並べるかではない。どこで handoff(担当の受け渡し)の境界を引くかだ。境界を「役割が変わる場所」ではなく「責任」——誰が承認し、何を正データとして参照し、どの操作を実行でき、失敗したとき誰が引き取るか——が変わる場所に置かないと、後から「誰が判断し、誰が実行し、誰が承認したか」を追えなくなる。
OpenAI が公開している Swarm は、この境界を Agent と handoff という2つの薄い抽象だけで表現する実験実装だ。大きな framework の機能を先に覚えるより、最小のコードで境界の引き方を確認する教材として読むほうが得るものが多い。
関連記事: 全体像から読みたい場合は AIエージェント論文おすすめ11選 も参照してください。
私は Swarm を本番採用の第一候補としては勧めない。理由は単純で、README 自身が Swarm を experimental / educational な教育用実装と位置づけており、OpenAI は本番向けの後継として Agents SDK を案内しているからだ(詳細は後述、参考リソースにもリンクがある)。
ただし、handoff の境界を最小コードで身体に入れる教材としては、今も勧める。「学習には向くが運用は別」という両論併記ではなく、prod では使わない・学習には使う、という境界つきの一つの立場をここでは言い切っておきたい。
私自身、multi-agent の設計相談を受けると、まず「何 agent を並べるか」「どの framework を使うか」という話から入りがちで、handoff の境界をどこに引くかという問いが後回しにされていると感じることが多い。Swarm のような最小限のコードは、その問いを最短で身体に入れる教材として役立つはずだと考え、この記事を書くことにした。
この記事は、Swarm を機能一覧として説明するのではなく、「境界をどこに引くべきか」という一問を軸に、README のサンプルと設計原則を読み直す。
Swarm は、OpenAI が公開している README とサンプルコードで、複数の Agent の間で handoff を回すための最小限のオーケストレーション層(agent 間の担当の切り替えを司る部分)を提供する実装だ。位置づけは実験的・教育的なもので、本番運用に必要な機能——永続化、監査、承認など——は意図的に持たない。
この前提を踏まえて、以降で使う2つの区別を先に定義しておく。
「役割」が変わることと「責任」が変わることは別の話だ。担当名を Sales から Support に変えただけでは、設計が良くなったとは言えない。handoff を置くべきなのは、次の4条件のどれかが変わる場所である。
Swarm のサンプルを読むときは、常に「この handoff は4条件のどれを切り替えているか」を確認するとよい。役割名だけが変わって4条件のどれも変わっていない handoff は、たいてい不要だ。
Swarm が担うのは、agent 間の担当の切り替え(オーケストレーション)だけだ。永続化、監査ログ、再試行、承認、秘匿情報の管理は、Swarm が意図的に持たない運用層の仕事になる。この分離線を先に引いておかないと、「Swarm でどこまでできるか」を過大評価も過小評価もしやすくなる。
Swarm が用意する部品は多くない。Agent、functions、handoff、context_variables の4つで、上で定義した責任境界(承認者・正データ・実行できる操作・失敗時の担当)を表現する一組の道具として設計されている。
Agent は「誰が何を担当するか」を表す薄いラッパーだ。name(担当の識別子)、instructions(その agent が守る判断基準)、functions(呼び出せる tool や handoff 関数)の3つを持つ。
from swarm import Agent
sales_agent = Agent(
name="Sales Agent",
instructions="製品に関する質問に答えてください。",
functions=[get_product_info, transfer_to_support],
)
この形にしておくと、「営業が持つ判断基準」と「サポートへ渡す条件」をコード上で分けて読める。
handoff は、別の Agent を返す関数として表現される。
def transfer_to_support():
return support_agent
複雑な graph DSL を書かなくても、「この条件なら担当を変える」という設計意図をそのまま関数に落とせる。ただし、この関数をどこに置くかが設計の質を決める。役割名が変わる場所ではなく、前節で定義した4条件のどれかが変わる場所に置くべきだ。
複数 agent で同じ情報を使いたいときは context_variables を渡す。
context_variables = {
"customer_id": "12345",
"booking_id": "ABC789",
"flight_date": "2024-12-15",
}
ここで重要なのは、何でも共有しないことだ。共有する状態が増えるほど、「誰の責任で何を判断したか」という境界が曖昧になる。顧客 ID、申請 ID、注文番号のような、変化しにくい識別子に絞るほうが安全に運用できる。
instructions と functions の組み合わせ(routines)は、自然言語による判断基準と関数呼び出しの接点になる。
triage_agent = Agent(
name="Triage Agent",
instructions="""
顧客の問い合わせを分析し、適切な部署に振り分けてください:
- 製品の質問 -> 営業担当
- 技術的な問題 -> サポート担当
- 返金リクエスト -> 返金担当
""",
functions=[transfer_to_sales, transfer_to_support, transfer_to_refunds],
)
この最小構成だけで、「入口で分類する agent」と「処理を実行する agent」を分けられる。
README には2つの主要なサンプルがある。同じ問い——「どこで責任が切り替わるか」——で対比すると、Swarm が何を学習材料として提供しているかがはっきりする。
Triage Agent
-> Sales Agent
-> Support Agent
-> Refunds Agent
この構成は、Triage Agent を振り分け役に徹させ、specialist agent の担当範囲を狭く保つ。返金のような取り消せない操作は、handoff 後の Refunds Agent に限定する。実際、process_refund を Refunds Agent だけに持たせれば、「返金処理を誰が実行できるか」がコードの上でそのまま可視化される。4条件のうち「実行できる操作」の境界が Agent の境界と一致している例だ。
Triage Agent
-> Flight Modification Agent
-> Lost Baggage Agent
こちらは context_variables で顧客情報や予約情報を共有しながら handoff する。customer support のサンプルとの違いは、会話の文脈だけでは引き継ぎが成立しない点にある。予約変更や紛失対応のように業務オブジェクトが絡む処理では、会話内容(ユーザーが今何を頼んでいるか)、共有状態(booking_id のような識別子)、実行権限(変更や申請を確定してよいか)を分けて考える必要がある。
2つのサンプルを並べると、Swarm の教材としての価値がはっきりする。判断すべきは常に、4条件のどれが変わる瞬間かということだ。
Swarm の設計原則をバラバラの箇条書きとして覚える必要はない。すべては「役割変更ではなく責任変更で切る」という1つの軸の系(corollary)として読める。
customer_id、ticket_id、order_id のような、変化しにくいキーを中心に持つ。3つとも、「4条件のどれかが変わる場所で境界を引く」という1つのルールの言い換えにすぎない。逆に言えば、役割名を分けたのに4条件のどれも変わっていないなら、その handoff はおそらく不要だ。
triage 相当の入口 agent に更新系の処理まで持たせる設計が危ういのは、上の4条件の系からも導ける。実行できる操作の境界と承認者が変わる境界が一致しなくなるため、例外が起きたときにどの条件が破られたのかを切り分けにくくなる。入口には分類だけを残し、実行は specialist に寄せておくと、後から見直しやすい。
Swarm が担うのは、agent 間の担当の切り替えだけだ。永続化、監査ログ、再試行、承認、秘匿情報の管理は Swarm が意図的に持たない層であり、これらが必要になった時点で、Swarm の外側に設計を足す必要がある。
運用に持ち込むとき、最初に足すことになりやすいのは state の永続化だ。handoff のたびに文脈を握り直す構造は、プロセスが再起動したり複数インスタンスで動いたりした瞬間に、それまでの判断根拠を失うリスクを抱える。これは Swarm 固有の弱点というより、in-memory な責任分割全般に共通する制約であり、Swarm の外側に運用層を設計する必要が生まれる理由でもある。
Swarm の読み方が学習だけで終わらないなら、次に確認すべきは運用層の設計だ。README 自身が Swarm を experimental / educational な実装と位置づけ、OpenAI は本番向けの後継として Agents SDK(参考リソース参照)を案内している。この運用層を設計するときは、次の4点を確認するとよい。
Swarm はこれらを解決するためのものではない。境界をどこに置くべきかを見つけるための教材として読むほうが、実務に接続しやすい。
Swarm を読むべきかどうかは、「本番でそのまま使うか」で決める必要はない。判断材料になるのは、「handoff の境界——承認者・正データ・実行できる操作・失敗時の担当——を最小コードで身体に入れる価値があるか」という一問だ。
同じ問いを、隣接する記事と並べて読み直すと、それぞれの役割がはっきりする。MetaGPT は、SOP と構造化 artifact で役割分担を重く固める設計で、Swarm の対極にある。同じスペクトルの両端として読むと、「いつ重い設計が要り、いつ最小構成で足りるか」という判断軸が得られる。ReAct の「考える→行動する→観察する」ループは、Swarm の各 Agent が内部で回している前提そのものだ。Swarm はそのループを、複数 agent 間の責任境界へ拡張したものと言える。A-MEM が持つノート化・相互リンクする永続メモリは、context_variables が意図的に持たない層の具体像でもある。
私自身は、Swarm を本番のオーケストレーション基盤として選ぶことはない。ただ、このコードで境界の引き方を一度確認しておくと、Agents SDK や他の framework を読むときの判断が速くなる。読むかどうかは、この一問に対する自分の答え次第だと思う。