「マルチエージェントシステムとは何か」を調べると、たいてい「役割の違うエージェントを複数立てて協調させる構成」という説明に行き着く。それは正しいが、その先が空白のまま終わることが多い。誰が次に動くかは何が決めるのか、各エージェントは他人の作業結果をどこまで見ているのか、いつ止まるのか。この3つに答えられないと、マルチエージェントは「なんとなく複数いる」だけの構成になる。
その空白を埋める教材として、Victor Dibia の victordibia/designing-multiagent-systems は少し変わった立ち位置にいる。これは解説書『Designing Multi-Agent Systems: Principles, Patterns, and Implementation for AI Agents』の公式コードリポジトリで、中身は PicoAgents という「教えるためだけにゼロから書かれたマルチエージェントフレームワーク」だ。この記事では、書籍本体(有料)ではなく Apache-2.0 で公開されているコードのほうを読み、協調戦略の違いが実際には何の違いなのかを確認していく。
- ・正体:有料書籍『Designing Multi-Agent Systems』の公式コードリポジトリ。中身は自作フレームワーク PicoAgents(Apache-2.0・742★・188フォーク)
- ・何ができる:エージェントの推論ループから協調戦略・停止条件・評価・Web UI までを、依存フレームワークなしの実装で読める
- ・核心:協調戦略の違いは
BaseOrchestratorの抽象メソッド3つの差でしかない。実際 RoundRobin 版と AI 版はうち1つしか違わない - ・何を代替できる:本番フレームワークの代替ではない。LangGraph や CrewAI を選ぶ前に「何を選んでいるのか」を理解するための教材
- ・注意:書籍本体は有料。またドキュメントが実装より先を書いている箇所がある(後述)
マルチエージェント以前の前提として、エージェント単体の仕組み(計画・記憶・ツール実行のループ)を整理したい場合は AIエージェントとは?仕組み・種類・代表的OSSフレームワークを初心者向けに解説【2026年版】 が下地になる。また、この記事は特定フレームワークの選定そのものは扱わないので、9種を実コードで比較した AIエージェントフレームワーク比較2026|LangGraph・CrewAI・Dify等9種をStar数・実コードで検証 を選定の入口として併読してほしい。
マルチエージェントシステムとは何か——「1体では足りない」の境界線
マルチエージェントシステムとは、役割やツールの異なる複数のエージェントが、共有された文脈をやり取りしながら1つのタスクを進める構成を指す。単一エージェントとの本質的な違いは、エージェントの数ではなく、「次に誰が動くか」を決める判断がエージェントの外側に出てくることにある。
単一エージェントの場合、この判断は存在しない。エージェントは自分の推論ループの中でツールを呼び、結果を見て、また考える。動くのは常に自分だけだ。ところが2体以上になると、「詩を書く担当」と「批評する担当」のどちらのターンなのかを誰かが決めなければならない。この決定を担う層が、いわゆるオーケストレーションである。PicoAgents ではこの層が orchestration/ という独立したディレクトリになっていて、そこが記事の後半で読み解く中心になる。
では、いつ複数にすべきなのか。リポジトリの構成から読み取れる考え方は素直だ。第1部の冒頭で扱われるのは詩人と批評家の例で、これは「生成」と「評価」という性質の異なる判断を分けたほうが質が上がるタイプの分割にあたる。同じ役割のエージェントを2体並べても得るものは少ないが、生成と批評、あるいは調査と要約のように、求められる態度が違う作業は分けたほうが噛み合う。
やらせてみる"] --> B{"うまくいかない
原因はどれか?"} B -- "手順が多くて
途中で見失う" --> C["ワークフロー型
手順を固定して分割"] B -- "生成と評価で
求める態度が違う" --> D["自律協調型
役割を分けて対話させる"] B -- "ツールが多すぎて
選択を誤る" --> E["役割ごとに
ツールを絞って分割"] B -- "単にコンテキストが
足りていない" --> F["分割しない
文脈設計を直す"] C --> G["次に誰が動くかを
決める層が必要になる"] D --> G E --> G G --> H["オーケストレーション
=この記事の主題"]
注意したいのは、右下の分岐だ。エージェントを増やせば解決する問題は意外に少ない。コンテキストの渡し方が悪いだけなら、分割しても改善しないどころか、渡し忘れの箇所が増えて悪化する。マルチエージェント化は「1体でやってみて、何が足りなかったか」を言語化できてから選ぶ手段であり、この順序を飛ばすと、動いているように見えて何が効いているか分からない構成になりやすい。
① 何ができる:複数エージェントの協調・停止・評価までを、外部フレームワークに依存しない実装で読み通せる。② 何を解決する:「マルチエージェントは役割分担」で止まっていた理解を、「次に誰が動くかを決める3つの接合部」という具体に落とす。③ 何を代替できる:本番フレームワークの代替にはならない。代替するのは断片的な入門記事の読み漁りのほうである。
designing-multiagent-systems の正体——有料書籍とApache-2.0のコード
このリポジトリを扱うときは、最初に書籍とコードの線引きをはっきりさせておく必要がある。両者はライセンスも入手方法も別だ。
書籍『Designing Multi-Agent Systems: Principles, Patterns, and Implementation for AI Agents』は Victor Dibia の著書で、有料である。電子版が公式販売ページで、ペーパーバックとハードカバーが Amazon で提供されている。一方、victordibia/designing-multiagent-systems のコードは Apache-2.0 で公開されており、クローンして読むぶんには費用がかからない。つまり「書籍の理論・設計上のトレードオフ・本番運用上の考慮」は有料側にあり、「その理論を実装した完全なコード」は無料側にある、という構造だ。
この記事が扱うのは後者に限られる。書籍を読んでいない状態で書籍の主張を代弁することはできないので、以下はすべて公開リポジトリの README とソースコードから確認できた内容だけで構成している。
examples/ 配下の .py を数えると73本あった(2026-07-25 時点の main ブランチをファイル一覧から集計)規模感としては、単独著者による教材リポジトリとしては厚い。examples/ 配下の .py ファイルは73本、picoagents/tests/ にテストが34ファイルある。README が「50以上」と控えめに書いているサンプル数は、実測では73本だった。こうした「READMEの申告より実物が多い」方向のずれは読者に不利益がないが、逆方向のずれもあるので後半で扱う。
そして中核が PicoAgents だ。README はこれを「マルチエージェントシステムの仕組みを教えるという唯一の目的のために、完全にゼロから作られたフル機能のマルチエージェントフレームワーク」と位置づけている。この「教えるためだけに」という限定が重要で、PicoAgents は LangGraph や CrewAI の競合として名乗り出ているわけではない。
「ゼロから」の範囲は広い。エージェント本体(推論ループ・ツール実行・ストリーミング・middleware)はもちろんだが、停止条件・評価フレームワーク・モデルクライアント・Web UI までが自前だ。モデルクライアントは OpenAI・Azure OpenAI・Anthropic の3実装があり、いずれも OpenAI 互換エンドポイントを指せるので Ollama や LM Studio のようなローカル環境にも向けられる。モデル側の選択肢そのものを整理したい場合は LLMとは?仕組み・主要モデル比較・ローカル実行・量子化を一気にまとめる2026年版 が対応する。
導入は Python パッケージとして素直だ。リポジトリを取得して picoagents/ に入り、編集可能インストールを行う。
git clone https://github.com/victordibia/designing-multiagent-systems.git
cd designing-multiagent-systems/picoagents
python -m venv venv && source venv/bin/activate
pip install -e ".[all]" # web UI・computer use・examples を含む一括導入
export OPENAI_API_KEY="your-api-key-here"
冒頭の画面(Web UI)を立ち上げる場合は、エージェント定義のあるディレクトリを指定するだけでよい。自動ディスカバリが走り、そのディレクトリ内のエージェント・オーケストレータ・ワークフローが一覧に並ぶ。
picoagents ui --dir ./examples
協調戦略の違いは「3つのメソッド」でしかない
ここが、このリポジトリを読む最大の見返りだ。picoagents/src/picoagents/orchestration/_base.py にある BaseOrchestrator を開くと、抽象メソッド(@abstractmethod)はたった3つしか宣言されていない。
run / run_stream)は BaseOrchestrator 側が共有している(orchestration/_base.py の実装を読んで確認)この3つは、マルチエージェントを動かすうえで避けて通れない問いにそのまま対応している。
| 抽象メソッド | 答えている問い | 設計上の意味 |
|---|---|---|
select_next_agent() |
次に動くのは誰か | 協調戦略の本体。固定順・LLM判断・計画駆動がここで分かれる |
prepare_context_for_agent() |
そのエージェントに何を見せるか | 共有履歴の渡し方。全部見せるか、要約するか、絞るか |
update_shared_state() |
実行結果の何を残すか | 共有文脈の育て方。全発言か、成果物だけか |
そして実装を読むと、驚くほど素朴な事実に行き当たる。固定順(ラウンドロビン)とLLM判断の違いは、このうち1つ目だけなのだ。
RoundRobinOrchestrator の select_next_agent() は、インデックスを1つ進めて配列長で割った余りを返すだけである。AIOrchestrator のほうは、各エージェントの名前・説明・保有ツールから能力一覧を組み立て、直近の会話とあわせて「次はどのエージェントが答えるべきか」を尋ねるプロンプトを作り、構造化出力で選ばせる。返ってくるのは選ばれたエージェント名・理由・確信度の3点セットだ。
ところが、残りの2メソッド——prepare_context_for_agent() と update_shared_state() ——は、この2つのオーケストレータで実装が一致している。どちらも共有履歴を素朴に文字列連結し、末尾に「今があなたのターンです」に相当する一文を足して渡す。そして結果からは先頭の1件(自分が送った文脈メッセージ)を除いて履歴に積む。つまり「LLMに次の話者を選ばせる高度な協調」と「順番に回すだけの単純な協調」の差は、コード上は1メソッドの中身に閉じている。
この見方が手に入ると、既存フレームワークの読み方が変わる。LangGraph の条件付きエッジも、CrewAI の Process 指定も、結局は「次に誰が動くか」をどう記述させるかの語彙の違いとして整理できる。逆に、prepare_context_for_agent() に相当する部分——各エージェントに何を見せるか——は、どのフレームワークでも同じくらい素朴なままになりがちで、ここが実運用でトークン消費と品質の両方を左右する勘所になる。PicoAgents の実装が全履歴の単純連結であることは、教材としての正直さでもあり、同時に「本番ではここを設計し直す必要がある」という宿題の提示にもなっている。
マルチエージェントシステムを動かし、止める——3つの協調戦略と9つの停止条件
2026年7月時点の main ブランチで、orchestration/__init__.py が公開している協調戦略は3つだ。
| 戦略 | クラス | 次の話者の決め方 | 向く場面 |
|---|---|---|---|
| 固定順 | RoundRobinOrchestrator |
配列の順に巡回するだけ | 役割と順序が最初から決まっている議論・レビュー |
| LLM判断 | AIOrchestrator |
能力一覧と会話履歴からLLMが構造化出力で選ぶ | 次に必要な作業が状況で変わる調査・分析 |
| 計画駆動 | PlanBasedOrchestrator |
先に計画を立て、それに沿って割り当てる | 手順の見通しが立つ多段タスク |
README は計画駆動について Magentic One 系のパターンを参照している。3つのうちどれが優れているという話ではなく、タスクの不確実性をどこで吸収するかの違いと捉えるのが実装に即している。固定順は人間が事前に順序を決め、LLM判断は実行時に毎回決め、計画駆動は最初に一度まとめて決める。
AIOrchestrator の実装で目を引くのは、失敗したときの落ち方が3段構えになっている点だ。構造化出力が期待どおり返れば確信度をそのまま採用する。型が違ったり構造化出力が得られなかった場合は、応答テキストからエージェント名を拾う経路に落ちる。LLM呼び出し自体が例外を投げた場合は、警告を出しつつ既定のエージェントに落とす。いずれの経路でも、選択の理由と確信度は selection_history に記録され続ける。
この「壊れても止まらないが、壊れた痕跡は残す」設計は、マルチエージェントを実運用に載せるときに繰り返し必要になる型だ。次の話者を選ぶ判断は毎ターン発生するため、ここで例外を投げて全体を落とすと、長時間走るタスクが1回のAPI不調で消える。かといって黙って既定値に落ちるだけでは、後から「なぜこの順番で動いたのか」を追えない。確信度つきの選択履歴は、その両方を成立させるための最小限の仕掛けになっている。
止め方も同様に作り込まれている。termination/ には停止条件が9種類あり、最大メッセージ数・特定文字列の検出・トークン使用量・経過時間・外部からの停止指示・キャンセル・ハンドオフ検出・関数呼び出し検出、そしてそれらを組み合わせる複合条件が揃う。オーケストレータ側には max_iterations の既定値50も置かれている。
自律協調型のマルチエージェントは、放置すると互いに相槌を打ち続ける状態に入りうる。トークン量と経過時間の上限を最初から入れておくのが安全側で、9種類の停止条件が独立モジュールとして切り出されているのは、それが後付けではなく設計要素であることの表明と読める。
止め方と並んで、長く走らせたときに問題になるのが共有履歴の膨張である。前節で見たとおり、PicoAgents の共有文脈の受け渡しは全履歴の単純連結だ。ターンを重ねれば、この文字列はそのまま伸び続ける。リポジトリにはこの点に対応する題材も用意されていて、examples/contextengineering/ にはコンテキスト圧縮(compaction)を扱うノートブックが置かれている。コミット履歴では、hooks・compaction・コンテキスト系ツール・ベンチマークをまとめて追加した v0.4.0 が 2026-02-11 に入っている。
実行結果を残す側の仕組みも別モジュールとして用意されている。store/ は SQLModel と非同期 SQLAlchemy を使ったデータベース永続化層で、エージェントの実行記録・評価結果・データセット・評価対象の設定を保存する。既定は SQLite だが、接続文字列を差し替えれば PostgreSQL も指せる構成になっている。こちらは v0.4.0 ではなく、その約1か月後(2026-03-06)の永続ストア追加コミットで入ったものだ。なお skills/ に置かれているのは Python ではなく、code-review と debug の2つの SKILL.md である。
つまりこのリポジトリは、「協調戦略を差し替える」段階の教材で終わらず、協調させたあとに必ず来る文脈管理と記録の問題まで射程に入れている。マルチエージェント化でトークン消費が想定を超える原因の多くは、モデルの選択ではなく、各ターンで全履歴を配り直す実装にある。3つの抽象メソッドのうち prepare_context_for_agent() と update_shared_state() が、まさにその蛇口にあたることを思い出しておきたい。
同じ課題を4フレームワークで書き比べる
このリポジトリで、日本語の解説記事がまだ拾っていない資産が examples/frameworks/ である。ここには同じ課題を複数のフレームワークで実装した等価コードが置かれている。
examples/frameworks/README.md とディレクトリ構成より作成)各フレームワークのディレクトリは agents/ workflows/ orchestration/ という同じ形に揃えられており、agents/ の下には basic_agent.py memory.py middleware.py structured_output.py が並ぶ。つまり同じ5つの課題を、4通りの書き方で読み比べられる。ここでひとつ実物を確認しておくと、README の比較表に挙がっているのは Microsoft Agent Framework・Google ADK・LangGraph の3つだが、実際のディレクトリには claude-agent-sdk/ が4つ目として存在する。表の更新が追いついていないだけで、コードは置かれている。
リポジトリが提示している対応表は、フレームワーク間の語彙の違いを一覧にしたものだ。主要な行を抜き出すと次のようになる。
| パターン | PicoAgents | MS Agent Framework | Google ADK | LangGraph |
|---|---|---|---|---|
| ツールを使う基本エージェント | Agent + 関数 |
ChatAgent + @ai_function |
Agent + 関数 |
create_react_agent + @tool |
| 記憶・文脈 | ListMemory |
ContextProvider |
ToolContext.state |
MemorySaver チェックポインタ |
| 逐次ワークフロー | Workflow.chain() |
SequentialBuilder |
SequentialAgent |
StateGraph + エッジ |
| 巡回オーケストレーション | RoundRobinOrchestrator |
WorkflowBuilder(循環) |
LoopAgent |
StateGraph + 条件付きエッジ |
| 並列オーケストレーション | 手書きの asyncio | ConcurrentBuilder |
ParallelAgent |
手書きの asyncio |
| 構造化出力 | output_format=Model |
response_format=Model |
response_schema=Model |
with_structured_output |
この表の価値は、埋まっていないマスも正直に書いてあることにある。並列オーケストレーションの列を見ると、PicoAgents と LangGraph は「手書きの asyncio」で、専用の抽象を持たない。ハンドオフの行では PicoAgents 側が手動扱いになっている。フレームワーク比較の記事は往々にして全項目に丸を付けたがるが、ここでは「クリーンに対応が取れないフレームワーク固有機能は意図的に複製しない」と方針が明記されている。
読み比べの実利は、フレームワークを乗り換えるときに現れる。LoopAgent と RoundRobinOrchestrator と「StateGraph + 条件付きエッジ」が同じことを指していると分かっていれば、移植は語彙の変換作業に落ちる。逆にこの対応関係を知らないまま片方の入門記事だけを読むと、そのフレームワーク固有の命名を一般概念だと思い込むことになる。
個別フレームワークの側から入りたい場合は、グラフとして状態遷移を書く流儀を LangGraph入門|マルチエージェント・ステートマシン構築の基本と他フレームワークとの違い で、役割定義から組み立てる流儀を CrewAI入門|マルチエージェント協調フレームワークの基本とLangGraph/AutoGenとの違い で確認できる。本記事の3メソッドの見方を持ってから読むと、それぞれが「次の話者をどう書かせているか」の違いとして整理しやすい。
教材コードを読むときの3つの注意点
ここまで肯定的に紹介してきたが、この種の教材リポジトリを読むときに踏みやすい箇所が3つある。いずれも実装を確認して分かったことだ。
1つ目は、ドキュメントが実装より先を書いている箇所があること。 前掲の対応表には「Supervisor オーケストレーション」の行に SupervisorOrchestrator というクラス名が載っているが、orchestration/__init__.py のエクスポート一覧にこの名前はなく、リポジトリ内に該当する実装ファイルも見つからない(supervisor.py は LangGraph 側の比較実装として存在するだけだ)。またハンドオフ型については orchestration/_handoff.py というファイルが存在するものの、中身は11行で、「このモジュールは将来 HandoffOrchestrator を提供する」という説明とTODOコメントだけが書かれた未実装のスタブである。
教材リポジトリでは、書籍の構想が先に文書化され、実装が後から追いつく順序になりうる。ファイルの存在は実装の存在を意味しない。
__init__.py の __all__ に載っているかどうかが、実際に使える機能かどうかの目安になる。
2つ目は、章番号を頼りにしないこと。 README の章一覧では、ワークフローとオーケストレーションと事例研究にそれぞれ章番号が振られているが、同じ README 内のディレクトリ説明やサンプル実行例では、同じモジュールに別の章番号が書かれている箇所がある。第1部から第4部の構成でも、章番号は連続していない。書籍を持っていない状態で章番号を根拠に何かを主張すると誤りやすいので、この記事では章番号ではなくディレクトリ構成を軸に説明してきた。
3つ目は、READMEに載っている効果の数値が著者自身の事例に基づく申告であること。 「2段階フィルタリングによるLLMコスト90%削減」「Think ツールによる54%の性能向上」といった数字が Key Features に並ぶが、これらは著者自身のケーススタディについての記述とされるもので、第三者による再現結果ではない。手法の方向性を掴む材料としては有用でも、自分の環境で同じ削減率が出る保証とは別物として扱うのが妥当だ。
あわせて、リポジトリの活動状況も把握しておきたい。最終コミットは 2026-03-12 の README 更新で、コミットは実質的に単独著者によるものだ。これを「停滞」と読むのは適切ではなく、書籍に追随する教材リポジトリという性質上、書籍の版が動かなければコードも動かないのが自然である。ただし、依存ライブラリ側のAPI変更に追随する速度は、活発な本番フレームワークほどは期待できない。サンプルが動かない場合は、まず各フレームワークのバージョンを疑うことになる。
まとめ——どこから読み始めるか
マルチエージェントシステムを理解するうえで、このリポジトリが提供している一番の価値は、フレームワークでも書籍でもなく、「協調戦略の違いは3つのメソッドの差でしかない」という見通しだと考える。この見通しがあると、乱立するフレームワークの機能表を、共通のパターンに引き戻して読めるようになる。
読み始める順序としては、いきなり picoagents/ の本体に入るより、code_along/ から入るほうが負荷が低い。ここには最小のエージェントを4段階で組み上げる流れが置かれていて、コアの推論ループ、ツール呼び出し、記憶、ストリーミングの順に1ファイルずつ進む。PicoAgents 本体はこれを production 相当まで広げたものだと README も説明している。基礎ができたら orchestration/_base.py で3つの抽象メソッドを確認し、_round_robin.py と _ai.py を並べて読む。この2つの差分を自分の目で見ることが、この記事で述べたことの検証になる。
`victordibia/designing-multiagent-systems` は、本番投入するフレームワークを探している人向けではない。LangGraph や CrewAI を選ぶ前に、自分が何を選ぼうとしているのかを理解したい人のための教材である。書籍は有料だが、コードは Apache-2.0 で読める。まず
code_along/ の4ファイルと orchestration/ の3実装を読むだけでも、マルチエージェントの議論を「役割分担」より一段具体的な言葉で扱えるようになる。
参照ソース
・victordibia/designing-multiagent-systems(公式リポジトリ・README) — PicoAgents の位置づけ、モジュール構成、書籍との関係、Key Features の数値
・examples/frameworks/README.md(フレームワーク横断の Pattern Mapping) — 4フレームワークの対応表と比較方針
・picoagents/src/picoagents/orchestration/_base.py — BaseOrchestrator の抽象メソッド3つ
・picoagents/src/picoagents/orchestration/_ai.py — LLMによる話者選択と3段構えのフォールバック
・picoagents/src/picoagents/orchestration/_round_robin.py — 固定順の実装と共有履歴の渡し方