Agent が一つだけなら、coordination の問題はそれほど複雑ではありません。task を渡し、tool を与え、test を実行させ、最後に結果を確認すれば済みます。本当に面倒になるのは、Codex、Claude Code、Cursor、さらに automation worker まで同じ repository に触り始めたときです。

この段階で最初に壊れるのは、どの model が賢いかではありません。もっと普通の「協働」の部分です。Claude は Codex がまだ着手していないと思って同じ file を編集し、別の Agent は scheduled task が設定済みという理由だけで「もう実行された」と判断する。chat 上で request は送られたのに receiver は受け取っていない。前の Agent は古い commit を前提に分析し、次の Agent は repository が変わった後もその古い状態を引き継ぐ。

こうした問題は、orchestrator を一つ追加すれば自然に消えるわけではありません。Routing が答えるのは「次に誰へ渡すか」です。Multi-agent workflow を本当に安定させるには、もう一段必要です。今の owner は誰か、どの state が canonical か、handoff は本当に受理されたか、実行環境に必要な capability があるか、完了を誰が検証したか。

最近 GitHub で見た microcredit-agent-testbed の central message board は、この問題をかなり露骨に扱っています。Hermes、Claude Code、Codex / ChatGPT を別々の lane に分け、公開 issue と canonical world model で coordination しています。業務ドメインそのものより、そこで使われている protocol が面白い。request を送ったことと ownership を引き受けたことは別、schedule を設定したことと job が成功したことは別、configuration success と later run success も別だと明確に分けています。

この例を見て、以前の Agent Orchestration の捉え方を少し変えました。前は「どの task をどの role に渡すか」を中心に見ていましたが、今はこう考えています。routing は入口にすぎず、shared state と handoff が整って初めて orchestration は engineering になる。

Orchestration は Agent を増やすことではなく、ownership を明確にすること

OpenAI の現在の Orchestration and handoffs は、二つの pattern を分けています。一つは handoff で、specialist が次の処理を本当に引き継ぐ形。もう一つは agents-as-tools で、manager が最終責任を持ち続け、specialist は bounded task を実行して結果を返します。

この違いは重要です。結局のところ、multi-agent system が曖昧にしやすい質問に答えているからです。今の結果は誰が owner なのか。

manager が責任を持ち続けるなら specialist は function に近い。一方で handoff が起きるなら control は本当に移ります。多くの workflow が乱れるのは、code 上では delegation が起きているのに、state 上の ownership が曖昧だからです。「誰かがやっている」ことは分かっても、「今誰が責任を持っているか」は答えられない。

たとえば Coding Agent の最小構成はこう見えます。

issue
  -> triage agent
  -> implementation agent
  -> review agent

一見きれいですが、運用上の質問はすぐ出てきます。implementation agent が受け取ったあと、triage agent は同じ scope をまだ変更してよいのか。review agent は read-only なのか、それとも直接 patch してよいのか。implementation agent が DONE と言ったら task は終わりなのか。review が失敗した場合は WORKING に戻すのか、新しい request を作るのか。

こうした rule を prompt の中だけに置くと、最後は model が「だいたい理解する」ことに依存します。私は今、handoff ごとに小さな coordination contract を持たせる方が扱いやすいと思っています。最低でも request id、sender、receiver、owner、deliverable、source revision、dependencies、acceptance test、required capability、fallback、status を明示します。

これは Agent workflow を Jira 化するためではありません。chat history から推測しないと分からない曖昧な state を減らすためです。

私が最終的に使った state model はかなり小さいものです。

REQUESTED
  -> ACKNOWLEDGED
  -> WORKING
  -> DONE
  -> VERIFIED

重要なのは五つの label ではなく、意味を飛ばさないことです。

message を送ったことが証明するのは REQUESTED までです。ACKNOWLEDGED は receiver 自身が受理して初めて成立する。scheduled job を作っただけで DONE にしてはいけない。Agent が「終わった」と言えば DONE には進めますが、VERIFIED には test output、diff、log、その他の concrete evidence が必要です。

Agent が増えるほど、この保守的な分離はむしろ workflow を軽くします。新しい worker が長い会話を読み返して「たぶんこうだった」と推測する必要がなくなるからです。canonical state と最近の receipt を読めばよい。

この rule を小さな validator にして試した

protocol を文章だけで終わらせたくなかったので、Content Lab 内で第一方実験を作りました。上の third-party repository の code は一切実行せず、synthetic fixture だけで coordination rule 自体を試しています。

一つ目は coordination-contract validator です。わざと次のような壊れた state を作りました。二つの Agent が同じ scope の active owner を同時に主張する。receiver acknowledgement がないのに task が DONE になっている。handoff が stale source revision を参照している。merge capability が必要なのに read/write しかない環境へ割り当てている。完了したのに verification evidence がない。同じ external action がすでに active なのに duplicate request を作る。superseded された request がまだ active のまま残っている。

8 個の fixture はすべて期待どおり検出されました。

これは production で conflict rate が下がったことを証明するものではありません。そこまでは言えません。ただ、Agent の知能問題に見える失敗のかなりの部分は、model の外側で deterministic に検査できる coordination error であることは示せます。

capability mismatch は分かりやすい例です。「この Agent は GitHub access を持っている」と一括りにしがちですが、read、edit、push、merge、deploy、secret access、outbound messaging は全部別の capability です。interactive session が push できても、別環境の scheduled worker が同じことをできるとは限りません。

そのため私は、曖昧な has-access flag よりも、task 側が必要な capability を宣言し、runtime 側が本当に持っている capability を返す形を好みます。

Claude Code の現在の subagents documentation も近い方向です。subagent ごとに context を分離し、tool や permission を制限でき、repository change を isolating したい場合は worktree も使えます。また、大量の independent exploration や tool isolation には subagent が向く一方、複数 phase が密接な shared context を必要とし、頻繁に行き来するなら main session の方が向くとも説明されています。Multi-agent は多ければよいわけではありません。境界が本当に違う仕事だけを分ける方が自然です。

二つ目の実験は receipt replay です。

append-only event log を REQUESTED から VERIFIED まで進め、その途中で invalid transition を入れました。REQUESTED -> WORKING は reject されます。「request を送った」ことから「receiver が受理した」を推測できないからです。REQUESTED -> DONE も reject されます。schedule や trigger は execution proof ではないからです。receiver 以外が ACKNOWLEDGED を書くことも reject。VERIFIED に evidence がない場合も reject されます。

7 個の replay check はすべて通過し、さらに derived state を消した後でも event log から最終 VERIFIED state を再構築できました。

long-running agent workflow ではここが重要です。state が一つの chat にしか存在しなければ、context compression、新しい session、別の machine に移った瞬間、次の Agent は summary を信じるしかありません。request、acknowledgement、done、verification の receipt が durable なら、summary を信頼する必要はなく、fact を読めばよい。

GitHub は control plane には向くが runtime database ではない

ここまで試すと、個人開発者や小さな team にとって GitHub はこの layer の control plane としてかなり使いやすいと感じます。

GitHub が orchestration platform だからではありません。state が versioned で、変更には author と timestamp があり、commit を revision として使え、issue / PR に evidence を残せ、repository file は Codex や Claude Code が直接読める。専用 orchestration backend を最初から導入しなくても、canonical state を repository に固定するだけで cross-session problem の多くを減らせます。

私の Content Lab も同じ方向です。active topic、active Dossier、previous command、next command、lifecycle state を persist し、Dossier history は DISCOVERED、SCORED、RESEARCHING、READY_FOR_TEST と append されます。一つの chat が「どこまでやったか」を覚えていることに依存しません。今回の experiment でも、active pointer、explicit next command、append-only state history を同じ GitHub-backed workflow で扱えることを確認できました。

ただし、runtime state を全部 Git に置くのは勧めません。high-frequency lock、millisecond lease、message queue、temporary token、sensitive credential は Git の役割ではありません。GitHub に向いているのは、session をまたいで残り、後から audit できる durable facts です。

私は二層で考えます。

runtime state
  -> lock, stream, short-lived message, transient execution state

canonical coordination state
  -> owner, revision, handoff, receipt, evidence, final decision

前者は database、queue、SDK session に置ける。後者は数日後に別の Agent が見ても「何が起きたか」が分かる必要があります。

OpenAI の現在の Running agents も、state continuation を明示的な design choice として扱っています。自分で history を持つ、session を使う、server-managed continuation を使う、interrupted run を resume する、といった方法です。Agents SDK の observability guidance では model call、tool call、handoff、guardrail なども trace されます。つまり、execution state と auditable state はどちらも設計対象であり、prompt だけに依存してはいけないということです。

最初に補うべきなのは「誰が何をしたか」の evidence chain

以前の記事で書いた原則は今も変わりません。一つの Agent で安定して終えられるなら、architecture を立派に見せるためだけに五つへ分解しない方がよい。OpenAI の guidance も、可能なら one agent から始め、capability isolation、policy isolation、prompt clarity、trace legibility に本当に必要になった段階で specialist を追加する方向です。

ただし、複数 Agent を使い始めたら、私は以前より早く shared state を入れるようになりました。

複雑な supervisor を先に作るのではありません。planner と reviewer を増やすことが目的でもない。まず ambiguity を残さないことです。同じ scope の owner は誰か。receiver は本当に acknowledge したか。task はどの revision を前提にしているか。execution environment は何ができるか。DONE を支える evidence は何か。後から receipt だけで実際の順序を再構築できるか。

この layer は派手ではありません。demo で「賢く見える」わけでもない。でも長く運用すると、Agent をもう一つ増やすより重要になります。

Multi-agent system で怖いのは、一つの model が間違うことだけではありません。すべての local decision が個別には合理的なのに、global state がすでに false になっていることです。一つの Agent は「まだ誰も着手していない」と思い、別の Agent は「もう完了した」と思い、automation は「schedule が実行済み」と思い、reviewer は古い revision を検証する。全部それらしくても、workflow 全体は壊れています。

だから今 Agent Orchestration とは何かと聞かれたら、「複数 Agent を分担させること」だけでは足りないと答えます。

私ならこう言います。task、state、permission、evidence を、推測に依存しない workflow に組み立てること。

Routing は次に誰へ渡すかを決める。Ownership は今誰が責任を持つかを決める。Handoff は context と boundary を引き渡す。Receipt は receiver が本当に受けたことを証明する。Capability boundary は実行できない環境へ task を渡すのを防ぐ。Trace と evidence は、後から「なぜこの state になったのか」を説明できるようにします。

Coding Agent を real project に深く入れていくなら、関連する CLAUDE.md が長くなったときに AGENTS.md、Skills、CI の境界をどう分けたか は、その一つ前の layer を扱っています。あちらが「rule をどこへ置くか」なら、この文章が扱うのは次です。複数 Agent が同時に動き始めたとき、どうすれば一つの信頼できる現実を共有できるか。