AI エージェントを何体も同時に走らせると、「誰が何をやるか」を決める係がどうしても必要になります。Claude Code のエージェントチームも、Codex のサブエージェントも、基本は 1体のリーダーが仕事を割り振る形です。
Microsoft Research が 2026年10月24日に公開した Agensh は、このリーダーをなくしました。最大 1,024体のエージェントが共有のリポジトリと掲示板を見ながら、自分で仕事を見つけ、名乗り出て、確かめて、統合する仕組みです。
この記事では、論文と公開コードを読んで仕組みを整理し、ニュースの要約では省かれがちな条件も確かめます。そのうえで、公式の共有ボードを Mac で実際に動かし、Codex CLI を 1・2・4・8体で競わせた小さな実験の結果を紹介します。
この記事の確認範囲
想定読者:Claude Code や Codex でサブエージェント・並列実行を使い始めた方、マルチエージェントの設計に興味がある方。専門用語には短い説明を添えます。

図1:左がこれまでの指揮役型、右が Agensh。指揮役の代わりに「共有の基盤」を置き、何が終わり何が残っているかを全員が読めるようにします。
30秒でわかる Agensh
先に要点をまとめます。細かい条件は後の節で説明します。
| 項目 | 内容 |
|---|---|
| 何か | 指揮役(オーケストレーター)なしで多数のエージェントを協調させる「ハーネス」(エージェントを動かす外側の仕組み) |
| 公開 | 論文 2026年9月22日(arXiv)、コード・実験スクリプト・再現手順 2026年10月24日(README の告知)、MIT License |
| 仕組み | 共有ワークスペース(Git)・連絡(チャット)・共有ボード(短いメモ)の3つと、各エージェントが回す5ステップのループ |
| 公式の結果 | 難しい5課題の平均テスト通過率が 1体 19.31% → 128体 28.78%。pandoc の作り直しで 1体 33.89% → 1,024体 55.06%(どちらも GPT-5.6-sol) |
| 注意点 | 課題によっては 8体が 1体より低い。トークン数や費用は論文に載っていない。再現手順は Linux・systemd 前提 |
| 手元の実験 | 公式の共有ボードを Mac で動かし、Codex を 1・2・4・8体で20分ずつ各2回。難しい218問の通過率は 65.8%・64.7%・79.6%・85.6%、API 換算の費用は $0.93〜$9.06 |
なぜ「指揮役なし」なのか
まず、Agensh が解こうとしている問題を整理します。
1体の AI エージェントは、1つの会話の窓(コンテキストウィンドウ)と1本の作業の流れしか持てません。大きなソフトウェアを作ると、どうしても順番待ちが長くなります。そこで複数のエージェントを同時に走らせる「マルチエージェント」が使われます。
論文によると、Codex のサブエージェント、Claude Code のサブエージェントとエージェントチーム、GitHub Copilot の fleet、Kimi Agent Swarm など、既存の仕組みの多くは 指揮役と作業役(orchestrator-worker) の形をとっています。指揮役が計画を立て、仕事を分けて配り、結果を受け取って統合します。
この形は分かりやすい反面、体数を増やすと指揮役が詰まります。何十体もの進み具合を1体が把握し、衝突を調整し、成果をまとめるのは大変です。論文は「システム全体の拡張性が、指揮役の管理能力で頭打ちになる」と指摘しています。
Agensh の答えは、人間の開発チームと同じように、全員が同じ立場で自分から動くことです。ただし「勝手に動け」と言うだけでは重複や衝突が起きます。そこで、全員が読み書きできる基盤を用意し、そこで状況を共有させます。
仕組み①:各エージェントが回す5ステップのループ
Agensh の中心は、エージェントごとに回る「協調ループ」です。全員が同じループを、ほかの人を待たずに(非同期に)くり返します。

図2:協調ループ。1→5 を終えたら 1 に戻り、次の仕事を探します。
各ステップの中身は次のとおりです。
- 状況を集める:目標、main ブランチの現状、仲間の進捗やメッセージ、共有ボードのメモを読み、残っている仕事を探します。
- 仕事を名乗る:自分が担当する範囲を
CLAIMとして共有ボードに書きます。ほかの人と重なったら、直接メッセージ(DM)で話し合います。 - 手を動かす:自分の作業場所(ブランチ)で実装します。途中で分かったことは共有ボードに書きます。
- 確かめる:受け入れ条件を満たすか自分で検証し、満たさなければやり方を直します。
- 統合する:main にマージし、何を変えたか・なぜか・どう確かめたかを
PATCH_SUMMARYとして書きます。衝突したら最新の main を取り込んで解決し、もう一度マージします。
面白いのは、このループが実行基盤のプログラムではなく、プロンプトに書かれている点です。論文の付録には実際のプロンプトが全文載っていて、1,024体すべてが「番号以外まったく同じ」プロンプトで動きました。そのため、下で動く単体のエージェント(論文の実験では GitHub Copilot CLI)を、Claude Code などに差し替えられる設計になっています(ただし公開版に入っているのは Copilot 用の接続部分だけです)。
仕組み②:全員で共有する3つの基盤
ループを支えるのが、論文で「組織の基盤(organization infrastructure)」と呼ばれる3つの部品です。
| 基盤 | 役割 | 公式の実装 |
|---|---|---|
| 共有ワークスペース | 進行中・統合済みの成果を置く。変更履歴とマージの衝突を検出する | Gitea(自前で立てる Git サービス)。PR は承認0件でマージ可、main への直接 push は禁止 |
| 連絡(メッセージ) | チーム全体への告知と、急ぎの1対1の連絡 | Mattermost(自前で立てるチャット)。チャンネルは次のターンの頭、DM は作業の途中に届く |
| 共有コンテキスト(共有ボード) | 再利用できる発見と「いま誰が何をしているか」を残す | board-service(FastAPI+MySQL)。考え方は DeLM という先行研究から |
3つ目の共有ボードが、Agensh を特徴づける部品です。ここには長い文章ではなく、種類付きの短いメモだけを書きます。
| 種類 | 意味 | 文字数の上限 |
|---|---|---|
OBSERVED | 参照プログラムで気づいた挙動 | 100 |
FACT | 確かめた事実 | 100 |
FAIL | 試してダメだった仮説(プロンプトでは「最も価値が高い」と強調) | 100 |
CLAIM | いま担当している作業(既定で1時間たつと一覧から消える) | 100 |
PATCH_SUMMARY | 終えた変更を files=・idea=・evidence= の3項目で | 300 |
長い内容は detail に入れておき、読みたい人だけが board_unfold で広げます。PATCH_SUMMARY の証拠欄が「tbd」「pending」「unverified」のような仮の言葉だと、サーバーが受け付けません。ただし書かれたテストを実際に走らせて確かめるわけではなく、文字列で判定しているだけです。
仲間のメモは「作業の途中」に届く
もう1つの工夫が、メモの届け方です。普通のチャットのように「次に話しかけられたとき」に届くだけだと、仲間がすでに失敗した方法を、何分も試し続けてしまいます。

図3:公式の notice shim は、B がボードや連絡のツールを呼んだ瞬間に、未読の DM と新着メモを結果の末尾へ付け足します。
公式の mcp-notice-shim.cjs は、エージェントが使う MCP サーバー(ツールを提供する小さなサーバー)を包む中継役です。ツールの結果を返す前に共有ボードへ「この人宛ての未読はあるか」を問い合わせ、あれば末尾に付け足します。プロンプトには、届いたメモへの反応も決めてあります。
FAIL:自分が同じことをしているならやめるFACT・OBSERVED:そのまま使う- 自分の作業と重なる
CLAIM:DM で当人と話をつける - それ以外の
CLAIM:気にせず自分の作業を続ける
なお、これは「次にツールを呼んだとき」に届く仕組みです。走っているコマンドに割り込むわけではありません。
1体ごとに付く「配達係」
公式の構成では、エージェント1体ごとに TypeScript 製の小さな配達係(mini-router)が付きます。Gitea と Mattermost の出来事を受け取ってデータベースの待ち行列に入れ、エージェントのターンが終わったら、まとめて次のプロンプトとして渡します。
このとき、まだ読んでいない共有ボードのメモを ==== SHARED CONTEXT ==== という見出しで添えます。10分間何もしていないエージェントには「仕事はいつでもある」と催促し、ボードに何も書かずにターンを終えたエージェントには「共有すべき発見はないか」と促します。
公式の実験:何を、どの条件で測ったか
Agensh の評価に使われたのは ProgramBench というベンチマークです。コンパイル済みの参照プログラム(中身は読めない実行ファイル)だけを渡され、それと同じ動きをするプログラムをゼロから作り直す課題です。インターネットは使えず、時間は6時間です。採点は隠しテストの通過率で行います。
全200課題のうち、最先端モデルの平均通過率が最も低い5課題が選ばれました。
| 課題 | 何をするソフトか | 元のファイル数 | 元の行数 |
|---|---|---|---|
| FFmpeg | 動画・音声の変換 | 10,090 | 約155万 |
| gromacs | 分子シミュレーション | 8,982 | 約82万 |
| pandoc | 文書形式の変換(Markdown→HTML など) | 2,767 | 約10万 |
| PHP-src | PHP 言語の処理系 | 26,266 | 約281万 |
| ctags | ソースコードの索引づくり | 7,313 | 約25万 |
条件をそろえるため、モデルは全条件で GPT-5.6-sol(推論の深さ high)、各エージェントの中身は GitHub Copilot CLI です。起動時の取り合いを減らすため、最初の1時間は30秒に1体ずつ、その後は3秒に1体ずつエージェントを起動しました。締め切りの45分前と5分前には「新しい機能は始めず、マージを済ませよ」という声かけを送ります。1,024体の実験は16台のノードに64体ずつ載せています。
1体だけの比較対象(ベースライン)は、共有の基盤を使わない単独構成です。1体だと6時間もたずに「終わりました」と止まりがちなので、止まるたびに「仕事はいつでもある」と続けさせる仕組みを付けています。
公式の結果を読む

図4:課題ごとの最終テスト通過率。数値はプロジェクトページの図から読み取りました。どの条件も1回ずつの実行です。
数字を表にまとめます。
| 課題 | 1体 | 8体 | 32体 | 128体 |
|---|---|---|---|---|
| 5課題の平均 | 19.31% | 20.68% | 26.52% | 28.78% |
| pandoc | 33.89% | 41.75% | 43.11% | 50.94% |
| ctags | 25.82% | 18.47% | 44.69% | 45.62% |
| gromacs | 19.69% | 19.37% | 19.37% | 22.12% |
| FFmpeg | 6.54% | 11.97% | 13.22% | 12.89% |
| PHP-src | 10.63% | 11.86% | 12.23% | 12.35% |
pandoc だけは 1,024体まで試されていて、55.06% でした。1体の 33.89% より 21.17 ポイント高く、128体の 50.94% よりも 4.12 ポイント高い数字です。
ここから読み取れることは3つあります。
- 平均では、体数を増やすほど上がる傾向がある:1体→128体で 9.47 ポイント、相対で約49%の向上です。
- ただし少人数では差が小さく、逆転もある:1体→8体の平均は +1.37 ポイントだけです。ctags では 8体が 1体を 7ポイント以上下回り、gromacs は 32体まで横ばいでした。
- 早く到達する効果もある:最初の2時間の推移を見ると、pandoc で通過率 30% を超えたのは 128体が30分、32体が60分、8体が90分の時点でした。1体は2時間たっても届いていません。

図5:公式リポジトリの図(microsoft/Agensh、MIT License)。紫の線は README とプロジェクトページで追加された GPT-6.1-sol の結果です。
最新の GPT-6.1-sol では、pandoc の通過率が 1体 56.19% → 8体 71.38% → 32体 79.59% と伸びています。この結果は論文本文にはなく、README とプロジェクトページで追加されたものです。モデルが変わると1体だけでも 56% に届く点は、押さえておきたいところです。
規模ごとに「協調の形」が変わった
論文で興味深いのは、記録(軌跡)から読み取れた振る舞いの変化です。全員が同じプロンプトなのに、規模が大きくなるほど、新しい協調の形が自然に現れました。

図6:論文 3.2 節で紹介された規模ごとの振る舞い。事例の紹介で、頻度は数えられていません。
たとえば 128体の pandoc では、2体が「作者がブランチを更新してテスト→コミットのハッシュを渡す→相手が検証してマージ」という統合の手順を決め、ほかのエージェントもその手順を使い始めました。1,024体では統合役が複数生まれ、候補の何人かに声をかけて最初に応じた人を選び、残りの依頼を取り消すといった動きまで見られたそうです。
ニュースの要約で省かれがちな条件
Agensh を紹介するニュースや要約では、数字だけが短く切り出されることがあります。一次情報と照らし合わせて、補っておきたい点を表にしました。
| よく見る説明 | 一次情報で確認できること |
|---|---|
| 10月24日に OSS 公開 | README の告知は 10月24日。ただしリポジトリのコミットは1件だけで、日付は 10月21日(米国時間)、GitHub への push は 10月23日(UTC)。論文は 9月22日に arXiv で公開済み |
| pandoc の再実装で 1体 33.89% → 1,024体 55.06% | 数字は正しい。モデルは GPT-5.6-sol(high)。課題は「実行ファイルの動きだけを手がかりに、ネットなし・6時間で作り直す」ProgramBench の形式 |
| GPT-6.1 Sol を32体使う構成で 79.59% | 正しいが、同じモデルの1体でも 56.19%。論文本文にはなく README の追加結果 |
| 1,024体が中央管理者なしで協調 | 1,024体の実験は16ノード×64体。公開された手順は1台用(既定は8体)で、複数ノードの構成は含まれていない |
| Docker Compose で再現できる | Linux・systemd・cgroup v2・パスワードなしの sudo が前提。起動スクリプトはモデルを gpt-5.6-sol(high)に固定し、ProgramBench 本体も別に必要 |
| 成功率・トークン・費用を比べたい | 論文が報告しているのは通過率と時間だけ。トークン数、API 料金、マージ衝突の回数は載っていない |
最後の点は特に大事です。体数を増やして通過率が上がっても、その分だけトークンを何倍も使っているなら、実務では割に合わないかもしれません。そこで手元の実験では、通過率と一緒にトークン数と費用、衝突や重複の回数も数えることにしました。
公式の再現手順は何を必要とするか
公開されたリポジトリには、1台のマシンでチームを動かす Docker Compose の構成と、1体だけで動かす比較用の起動スクリプトが入っています。再現手順(REPRODUCE.md)から、主な前提を抜き出します。
- OS:Linux。Docker Engine、Compose v2、systemd、cgroup v2 が必要です。メモリの上限を決める systemd の設定(slice)と、再起動時に実験を止める見張り役(reboot guard)を先に入れます。
- 権限:Docker とコンテナのデータ操作に、パスワードなしの
sudoを使います。 - ベンチマーク:ProgramBench v1.2.5 を指定のコミットで入れ、課題ごとの公式イメージを取り込みます。
- モデル:Responses API を話せる LLM のゲートウェイが必要です。起動スクリプトは gpt-5.6-sol(high)以外を受け付けません。
- 資源:エージェント1体あたりのメモリ上限は 64GiB、配達係は 8GiB です(上限であり、確保量ではありません)。
つまり Mac にそのまま入れて make up すれば動く、というものではありません。論文の6時間・数十体の実験を再現するには、Linux のサーバーとそれなりの API 予算が要ります。
そこで今回は方針を変えて、公式の部品のうち、Agensh らしさの中心である共有ボードと途中配信(notice shim)をそのまま取り出し、残りを軽い代役に置き換えて Mac で動かしました。
Mac で小さな Agensh を組む
ここからは手元の実験です。目的は、論文の数字を再現することではなく、少人数(2〜8体)で動かしたとき、通過率・費用・衝突がどう変わるかを自分の目で見ることです。
構成:公式の部品と代役

図7:手元の構成。緑の共有ボードは公式の部品をそのまま動かし、Git とチャットは軽い代役にしました。
| 役割 | 公式の Agensh | 今回の Mac 版 |
|---|---|---|
| 各エージェント | GitHub Copilot CLI 1.0.70(ACP 経由) | Codex CLI 0.159.2(codex exec、標準サンドボックス、ネット遮断) |
| モデル | GPT-5.6-sol(high) | GPT-6.1 Sol(high) |
| 共有ワークスペース | Gitea。PR 経由でマージ | ローカルの bare リポジトリ。main へ直接 push(拒否されたら取り込んで再 push) |
| 連絡 | Mattermost | 自作の小さな MCP サーバー(チャンネル投稿・DM)。DM は公式と同じ表に入れ、公式 shim で途中配信 |
| 共有ボード | board-service+mcp.cjs+notice shim | 公式のまま(MySQL 8.4 は Docker で起動) |
| 配達係 | mini-router(1体に1つ) | 自作の駆動役 run_team.py(ターンの頭にボードの未読とチャンネル投稿を渡す。公式の文面を移植) |
| 時間 | 6時間、締切45分前・5分前に声かけ、10分無反応で催促 | 20分、締切3分前・1分前に声かけ(比率よりやや早め)、33秒無反応で催促(6時間→20分と同じ比率) |
| 起動の間隔 | 最初の1時間は30秒に1体 | 20秒に1体 |
| 1体の比較対象 | 単独構成+止まったら継続を促す | 同じく単独構成+止まったらすぐ継続(公式の文面を移植) |
課題:pandoc の Markdown→HTML 変換を作り直す
論文の目玉が pandoc だったので、課題もそれに寄せました。参照プログラムは Homebrew の pandoc 3.12.1 で、Markdown を受け取って HTML の断片を返す部分(pandoc -f markdown -t html --wrap=none)だけを対象にします。
エージェントには次のルールを渡しました。
- 参照プログラムは実行して挙動を観察してよい。中身の解析や、実装からの呼び出しは禁止
- Python 3.12 の標準ライブラリだけで作る。ネットは使えない
- リポジトリの直下に
compile.shを置き、./executableを作る(ProgramBench と同じ約束) - 対象の書式は14種類(見出し、段落と改行、強調、インラインコードとエスケープ、リンク、画像、引用、箇条書き、番号付きリスト、コードブロック、水平線、表、脚注、引用符やダッシュの自動変換)
採点には、エージェントに見せない隠しテストを使います。最初に用意したのは150問(14種類×10問+混在した文書10問)で、後から、書式を組み合わせた難しい300問を足しました(理由は結果の節で説明します)。出力を pandoc と1文字単位で比べ、末尾の空白だけは無視します。採点時は sandbox-exec で pandoc と参照プログラムの実行を禁止し、ずるができないようにしました。
隠しテストは実験と並行して作り、すべての実行が終わるまで実験フォルダの外に置きました。後で Codex の記録を検索し、エージェントがその場所を読んでいないことも確認しています。
共有ボードを Mac で起動する
公式の board-service は Python(FastAPI)製で、Mac でもそのまま動きます。必要なのは MySQL と、いくつかの環境変数です。
# 1. MySQL 8.4 を Docker で起動する(127.0.0.1 だけで待ち受ける)
docker run -d --name agensh-lab-mysql \
-e MYSQL_ROOT_PASSWORD=<ROOT_PASSWORD> -e MYSQL_DATABASE=<DB_NAME> \
-e MYSQL_USER=agensh -e MYSQL_PASSWORD=<DB_PASSWORD> \
-p 127.0.0.1:13306:3306 mysql:8.4 --max-connections=1000
# 2. 公式リポジトリを取得し、board-service 用の Python 環境を作る
git clone https://github.com/microsoft/Agensh.git
uv venv --python 3.12 board-venv
uv pip install --python board-venv/bin/python -r Agensh/board-service/requirements.txt
MySQL が起動したら、公式の初期テーブル(mini-router/sql/ の 01-events-schema.sql と 03-board-schema.sql)を流し込みます。
for f in 01-events-schema.sql 03-board-schema.sql; do
docker exec -i agensh-lab-mysql mysql -uagensh -p<DB_PASSWORD> <DB_NAME> < Agensh/mini-router/sql/$f
done
board-service を起動するときは、外から接続されないように --host 127.0.0.1 を付けます。公式の main.py をそのまま実行すると 0.0.0.0(すべてのネットワーク)で待ち受けるためです。
cd Agensh/board-service
MYSQL_DSN='mysql://agensh:<DB_PASSWORD>@127.0.0.1:13306/<DB_NAME>' \
BOARD_MEMBERS_JSON='{"pbench": ["pbench-w1", "pbench-w2", "harness"]}' \
BOARD_LIFECYCLE_DIR=/tmp/agensh-lifecycle \
../../board-venv/bin/python -m uvicorn main:app --host 127.0.0.1 --port 8660
起動したら、curl で読み書きを試せます。w1 として FAIL を書き、w2 宛ての未読を確かめる例です。
# w1 が FAIL を書く(受け付けられると G1 などのラベルが返る)
curl -s -X POST localhost:8660/board/pbench/note -H 'Content-Type: application/json' \
-d '{"thread_id":"pbench-w1","type":"FAIL","content":"Heading ids keep punctuation? No: # Hello, World! -> id=hello-world"}'
# => {"status":"admitted","reason":null,"gist_id":1,"label":"G1"}
# 証拠欄が仮の言葉(tbd)の PATCH_SUMMARY は受け付けられない
curl -s -X POST localhost:8660/board/pbench/note -H 'Content-Type: application/json' \
-d '{"thread_id":"pbench-w1","type":"PATCH_SUMMARY","content":"files=mdhtml.py | idea=heading ids | evidence=tbd"}'
# => {"status":"rejected","reason":"ok:0/1,ps_invalid_ev=1",...}
# w2 宛ての未読(notice shim が作業の途中に付け足す中身)
curl -s localhost:8660/pending/pbench-w2
# => {"agent":"pbench-w2","notices":[{"id":"g1","text":"[tpbench-w1/FAIL +0.0m] Heading ids keep ..."}],...}
Codex から共有ボードを使う
Codex には、公式の mcp.cjs(ボードの4つのツール)を、公式の mcp-notice-shim.cjs で包んで登録します。エージェントごとに名前(AGENT_NAME)だけを変えます。
# $CODEX_HOME/config.toml の一部(エージェントごとに AGENT_NAME を変える)
[mcp_servers.board]
command = "node"
args = ["<AGENSH>/mini-router/mcp-notice-shim.cjs", "--",
"node", "<AGENSH>/board-service/mcp.cjs"]
env = { BOARD_SERVICE_URL = "http://127.0.0.1:8660", AGENT_NAME = "pbench-w1", BOARD_IDS = "pbench" }
# codex exec は承認を求められないため、明示的に許可しないと MCP の呼び出しが拒否される
default_tools_approval_mode = "approve"
enabled_tools = ["board_read", "board_write", "board_grep", "board_unfold"]
実際の実験では、本人の普段の Codex 設定・メモリー・グローバルな AGENTS.md が混ざらないよう、CODEX_HOME を実験用のフォルダに分けました。認証ファイルだけをシンボリックリンクでつないでいます。上の設定は、駆動役が codex exec -c ... で毎回渡しています。
各エージェントの作業フォルダには、公式の prompts/agents.txt を移植した AGENTS.md を置きました。Gitea と Mattermost の説明を、ローカルの Git と msg ツールの説明に書き換えた以外は、協調ループの文面をそのまま使っています。
結果:体数を増やすと何が変わったか
各条件を2回ずつ、合計8回走らせました。1回目は 1→2→4→8体、2回目は時間帯の影響を打ち消すため 8→4→2→1体の順です。
基本の150問は、1体でもほぼ満点だった
最初に用意した隠しテスト150問は、易しすぎました。8回とも 96.0〜100.0% で、1回目の1体は、開始から3分で150問中134問を通しています。GPT-6.1 Sol にとって、pandoc の Markdown→HTML の基本部分は、20分あれば1体で作り切れる大きさでした。
これでは体数の差が測れません。そこで、提出物がどこで失敗したかは見ずに、14種類の書式を入れ子にしたり混ぜたりした文書を乱数で300問作り(固定シード)、追加のテストにしました。入れ子のリストの中の引用、脚注の中の強調、表のセルの中のリンク、といった組み合わせです。
ところが採点してみると、この300問のうち82問(27%)に、生成器が "A "quoted" title" のような内側に引用符を含むリンクのタイトルを入れていました。後で説明するとおり、この1つの書き方が結果を大きく揺らしたので、以下では 300問全体 と、その82問を除いた218問 の両方を示します。
通過率は上がったが、費用はほぼ体数に比例した

図8:体数別の通過率と費用。棒は2回の平均、白丸は各回の値です。
| 体数 | 追加218問 平均(1回目 / 2回目) | 追加300問 平均(1回目 / 2回目) | 基本150問(1回目 / 2回目) | 入力トークン(平均) | 出力トークン(平均) | API 換算の費用(平均) |
|---|---|---|---|---|---|---|
| 1体 | 65.8%(59.6% / 72.0%) | 60.7%(53.7% / 67.7%) | 96.0% / 98.7% | 2.7M | 41k | $0.93 |
| 2体 | 64.7%(69.3% / 60.1%) | 54.3%(57.7% / 51.0%) | 99.3% / 96.7% | 9.0M | 72k | $1.91 |
| 4体 | 79.6%(79.8% / 79.4%) | 63.2%(68.7% / 57.7%) | 98.7% / 100.0% | 20.2M | 141k | $4.27 |
| 8体 | 85.6%(90.4% / 80.7%) | 84.2%(88.3% / 80.0%) | 99.3% / 99.3% | 45.3M | 242k | $9.06 |
218問で見ると、1体の 65.8% と2体の 64.7% はほぼ同じで、4体で 79.6%、8体で 85.6% まで上がりました。1体→2体では成果が増えず、費用だけが約2倍になっています。4体・8体では +14〜20 ポイント伸びましたが、費用は1体の約4.6倍・9.8倍です。
回ごとのばらつきも大きく、同じ1体でも 59.6% と 72.0%、同じ8体でも 90.4% と 80.7% と、10ポイント前後の差が出ました。2回ずつの実験なので、「1体のほうが2体より良い」とまでは言えません。言えるのは、少人数では差がはっきりせず、費用はほぼ体数に比例して増えること、4〜8体では細かい書式の組み合わせまで再現できたことです。
チームが細かい書式に強かった理由の1つは、自作テストの量だと考えられます。1回目の最終コードを比べると、1体は JSON の固定テストを持たず、2体は158件、4体は728件、8体は1,780件の「参照の出力」をテストとして保存していました。8体の1回目では、最後に起動した w8 が最初に「差分テストの仕組みと題材づくり」を名乗っています(その後、コードブロックの担当に移りました)。
費用はあくまで API の単価で換算した目安です。今回は Codex Pro の定額枠で動かしたので、追加の支払いはありません。Codex の週の利用枠の表示は、実験の前後で 1% から 5% に増えました(同じ時間に動いていた別の作業の分も含みます)。入力トークンの 93〜98% はキャッシュ(前回と同じ部分の読み直し)で、単価は通常の20分の1です。
自作テストは全部通っていたのに、40問以上が落ちた
体数を増やしても、良いことばかりではありませんでした。4体の回は2回とも、途中で通過率が大きく下がり、最後まで戻りませんでした。

図9:4体の2回分の推移(追加300問)。1分ごとに「この時点の main」を採点しました。
原因をコミット単位で採点して探すと、どちらもインライン担当(w2)の変更でした。
- 1回目(13.9分):自分で見つけた
[foo](u "t" "more")というケースに合わせて、「リンクのタイトルの中に同じ引用符があれば無効」という規則を1行足した。247問 → 198問 - 2回目(8.5分):Unicode の URL や参照定義のタイトルに対応するため、タイトルの解釈を書き換え、最初の閉じ引用符で打ち切るようにした。212問 → 167問
どちらも、pandoc なら受け付ける "A "quoted" title" のようなタイトルを弾くようになりました。それでも、チームの自作テスト(最終728件と786件)はすべて通っていました。各自が自分の担当範囲のテストで「確かめる」ステップを済ませてから統合しても、別の書き方の入力を壊す変更は素通りしたわけです。
この落ち幅は、追加テストの作り方にも左右されます。生成器が使うタイトル4種類のうち1つが内側に引用符を含むため、影響が大きく出ました。そこで82問を除いた218問でも比べると、4体は2回とも約80%(79.8% と 79.4%)で、ほぼ同じ値になります。
協調の手間と費用は、体数以上に増えた

図10:協調にかかった手間(左が1回目、右が2回目)。1体は単独構成なので、ボードと連絡は使っていません。
まず、1体あたりの入力トークンも増えました。単独の1体は 2.1M・3.3M でしたが、チームでは1体あたり 3.8〜5.8M です。チームのエージェントは、ボードや連絡のツールを頻繁に呼び、仲間の変更を取り込むたびに短いターンをくり返します。ツールを呼ぶたびに会話全体を読み直すので、その分だけ入力が膨らみます。8体の1回目は、合計でコマンド670回、ボード151回、連絡ツール304回を呼んでいました(1体の1回目はコマンド40回だけ)。
一方で、統合そのものは思ったより滑らかでした。push の拒否(先に誰かが push していた)は1回あたり0〜14回ありましたが、マージの衝突(CONFLICT)の表示は、チームの6回を合わせて4回だけです。最初の数分でファイル単位に担当を分けたので、同じ行を同時に書き換えることがほとんどありませんでした。締切3分前・1分前の声かけも効き、締切の時点で main に入っていないコミットは、どの回も0件でした。
ログから見えた3つの場面
数字だけでは分からない動きを、記録から3つ紹介します。
① 最初に起動した1体が、分担案まで書いた:エージェントは20秒おきに1体ずつ起動します。チームのどの回でも、最初に起動した w1 が開始1分以内に分担案を出し(6回中4回は最初の CLAIM に「自分は本体と compile.sh、仲間はインライン・リスト・表と脚注を」と書き、残る2回は DM とチャンネルへの投稿)、後から起動した仲間はほぼその通りに名乗りました。8体の2回目は、8体の担当が課題文書(SCOPE.md)に並べた書式の一覧とほぼ1対1で対応しています。指揮役はいなくても、最初に動いた1体が実質的な計画役になり、課題文書の箇条書きがそのまま仕事の分け方になりました。
② 担当の衝突は、数秒の DM で片づいた(8体):1回目の8体では、w3 と w4 がほぼ同時(開始0.9分と1.3分)に「links.py(リンク・画像)を担当」と名乗りました。1.5分の時点で w3 が「先に名乗っていて、30件ほど調べ、API も w2 と決めた」と DM を送り、w4 は「表を担当する」と CLAIM を書き直しました。本体担当の w1 からも、w4 へ別の担当を勧める DM が届いています。論文の8体の例(FFmpeg で重なりを話し合い、片方が範囲を変えた)とよく似た動きです。
③ 統合の窓口に DM が集まった:8体の回では、本体と統合を名乗った w1 が、DM の約半分に関わっていました(1回目は128通中61通、2回目は124通中66通)。「モジュールをつなぐ場所」を持つ1体に、関数の形の相談や、統合で見つけたバグの報告が集まります。4体の2回目でも、DM 17通のうち13通が w1 との間でした。
共有ボードの使われ方

図11:4体の1回目に共有ボードへ書かれたメモの抜粋(原文は英語、下の行は筆者の訳)。
ボードに書かれたメモの大半は PATCH_SUMMARY(変更の報告)と FACT(確かめた事実)でした。プロンプトで「最も価値が高い」とされる FAIL(ダメだった仮説)は、6回のチームの回を合わせても 3 件しか書かれていません。
PATCH_SUMMARY の証拠欄には「705/705 fixtures pass」のように自作テストの通過数が並びましたが、図9のとおり、それは参照プログラムとの一致を保証しませんでした。エージェントが「失敗」をあまり書かないのは、20分という短さのせいかもしれません。論文の6時間・数百体の規模では、他人の失敗を避ける効果がもっと効いてくる可能性があります。
この実験の限界
結果を読むときの注意点もまとめておきます。
- 各条件2回だけで、ばらつきの大きさは十分には分かりません。8体の2回でも、218問で 90.4% と 80.7% の差がありました
- 課題は pandoc の一部分(Markdown→HTML)で、論文の課題よりずっと小さいものです。追加テストは筆者の生成器で作ったため、どの書式の組み合わせが多いかは生成器の作りに依存します
- 時間を20分に縮め、Gitea・Mattermost・配達係を代役にしました。公式の構成と同じ結果になるとは限りません
- 使ったのは Codex CLI と GPT-6.1 Sol です。論文の Copilot CLI・GPT-5.6-sol とは違います
自分の開発で試すなら
最後に、手元の実験から分かった「小さく試すときの進め方」をまとめます。

図12:指揮役なしの複数体を試すかどうかの判断(筆者の整理)。
手順1:1体の基準を測る
まず、同じ課題・同じ時間で1体を走らせ、通過率とトークンを記録します。今回の実験でも、基本の150問では1体がほぼ満点でした。1体で十分な大きさの仕事なら、複数体にしても費用が増えるだけです。
手順2:2体、4体と増やしながら5つを測る
体数を増やしたら、通過率だけでなく次の5つを並べて見ます。今回は2体では1体と差が出ず、4体から伸びました。2体だけ試して「効果なし」と決めないほうがよさそうです。
| 指標 | 何が分かるか | 今回の測り方 |
|---|---|---|
| 通過率 | 成果が増えたか | 締切の main を取り出して隠しテストで採点 |
| 総トークン・費用 | いくら払ったか | Codex の記録($CODEX_HOME/sessions/ の rollout)の token_count を合計 |
| 担当の重複 | 同じ仕事を2人がしていないか | 共有ボードの CLAIM を時刻つきで並べる |
| push の拒否・衝突 | 統合でどれだけ手間取ったか | ツールの出力から [rejected]・CONFLICT ( を数える |
| 締切で入らなかった作業 | 書いたのに捨てられた分 | 各作業フォルダで git rev-list <提出>..HEAD を数える |
main への反映の記録は、共有リポジトリ(bare リポジトリ)に post-receive フックを置くだけで取れます。
#!/bin/sh
# origin.git/hooks/post-receive:main などへの反映を時刻・作者つきで記録する
while read old new ref; do
t=$(perl -MTime::HiRes=time -e 'printf "%.3f", time')
a=$(git log -1 --format='%an%x09%s' "$new" 2>/dev/null)
printf '%s\t%s\t%s\t%s\t%s\n' "$t" "$old" "$new" "$ref" "$a" >> "$GIT_DIR/pushes.log"
done
この記録があると、「何分の時点の main を採点したら何点だったか」を後から再現でき、図9のような推移や、4体で起きた回帰の原因を突き止められます。
手順3:今回の失敗から入れておきたい工夫
実験で見えた弱点には、Agensh のプロンプトや運用で手当てできるものもあります。ここは筆者の提案で、まだ試していません。
- main に入れる前に、全員分のテストを回す:各エージェントは自分の担当のテストだけで「確かめる」を済ませがちです。リポジトリに共通のテスト置き場を決め、統合の前に全体を流すよう、プロンプトの手順4に書き足します。
- 統合の窓口を最初から決めておく:指揮役は置かなくても、本体の担当に DM が集まります。誰が統合の窓口かを最初の CLAIM で宣言させると、集中を見越した動き方ができます。
FAILを書く場面を具体的にする:「仮説が外れたら書く」だけでは、ほとんど書かれませんでした。「参照と出力が食い違って、原因が自分の思い込みだったとき」のように例を足すと増えるかもしれません。- 費用の上限を先に決める:今回は1体あたりのトークンも体数とともに増えました(連絡やマージのたびに会話全体を読み直すため)。体数×時間で予算を見積もり、上限を超えたら止める仕組みを用意します。
つまずいたところと対処
Mac で組むときに実際にはまった点を、確認する順番にまとめます。

図13:つまずいた順の対処表。上から確認すると早く切り分けられます。
| 症状 | 原因 | 対処 |
|---|---|---|
codex exec が「Reading additional input from stdin…」のまま止まる | スクリプトから呼ぶと標準入力を待つ | < /dev/null を付ける(駆動役では stdin=DEVNULL) |
| ボードのツールが「requires approval, but approval policy is never」で拒否される | codex exec は承認を求められないので、MCP の呼び出しが既定で拒否される | default_tools_approval_mode = "approve" と enabled_tools をサーバーごとに書く |
git commit が失敗し、エージェントが .git を /tmp にコピーして回避し始めた | Codex の標準サンドボックスは、書き込み可能なフォルダの中でも .git だけは読み取り専用にする | git clone --separate-git-dir=<外の場所> で管理フォルダを作業フォルダの外に置き、その場所を writable_roots に足す |
| 普段の Codex 設定・メモリー・グローバルな AGENTS.md が実験に混ざる | ~/.codex をそのまま使っている | CODEX_HOME を実験用に分け、認証ファイルだけリンクする |
| board-service が LAN から見える | 公式の main.py は 0.0.0.0 で待ち受ける | python -m uvicorn main:app --host 127.0.0.1 で起動する |
公式の launch_single_node.sh や make up が動かない | Linux・systemd・cgroup v2・sudo が前提 | Mac では部品(board-service・shim・prompts)を取り出して使う。本格的な再現は Linux のサーバーで |
エージェントが /tmp を検索し、作業と関係ないファイル名まで一覧した | 標準サンドボックスは書き込みを絞るが、読み取りはディスク全体に開いている | 見られて困るものがあるマシンでは、公式と同じくコンテナに入れて動かす |
.git の件は、知らないと気づきにくい点です。エージェントは、書き込めないと分かると .git を一時フォルダにコピーし、GIT_DIR を差し替えて commit と push を続けました。動くことは動きますが、作業フォルダの .git には commit が残らず、本当の履歴がどこにあるのか分かりにくくなります。試運転の段階で気づけたので、本番では外に置く方式に直しました。
最後の項目は、2回目の8体の回で見つけました。仲間の一時ファイルを探そうとした1体が rg --files /tmp を実行し、同じ Mac で動いていた別の作業のファイル名まで一覧していました。ネットは遮断していたので外へは出ていませんし、隠しテストの場所にも触れていません(記録を検索して確認)。それでも、公式の Agensh が各エージェントをコンテナに入れ、参照プログラムを「実行はできるが読めない」権限で置いている理由がよく分かります。
このほか、codex exec は GPT-6.1 Sol が混み合うと「Selected model is at capacity」で落ちることがあります。駆動役では、会話が始まる前に落ちたら10秒待って最初からやり直し、会話が始まっていれば codex exec resume で続きから再開するようにしました。
まとめ
Agensh は、「指揮役が仕事を配る」という多くのマルチエージェントの前提を外し、共有ワークスペース・連絡・共有ボードの3つと、全員が同じプロンプトで回す5ステップのループで協調させる仕組みです。公式の実験では、難しい5課題の平均通過率が 1体 19.31% → 128体 28.78%、pandoc では 1,024体で 55.06% まで伸びました。ただし少人数では差が小さい課題や逆転もあり、トークン数や費用は報告されていません。
手元の Mac で公式の共有ボードと途中配信を動かし、Codex を 1〜8体で競わせた結果は、次のとおりです。
- 基本の150問は、1体でも 96.0〜98.7%。課題が小さいうちは、体数を増やす意味がほとんどなかった
- 書式を組み合わせた難しい問題(218問)では、1体 65.8%・2体 64.7%・4体 79.6%・8体 85.6%。伸びたのは4体以上で、2体では差が出なかった
- API 換算の費用は $0.93 → $1.91 → $4.27 → $9.06 と、ほぼ体数に比例した。1体あたりのトークンも、連絡と統合のぶん増えた
- 指揮役はいなくても、最初に起動した1体が分担案を書き、本体担当に DM が集まった。似た役割は自然に生まれる
- 4体は2回とも、自作テストを全部通したまま、1つの変更で40問以上を失った。統合の前に全体を確かめる仕組みが要る
「数を増やせば賢くなる」というより、決まった時間の中で成果を増やすために、トークンを払い、統合の手間とリスクを引き受ける仕組みだと考えると、使いどころが見えてきます。テストで合否を判定でき、部品に分けられ、締め切りが厳しい仕事なら、1体の基準と比べながら小さく試す価値があります。
次の一歩としては、公式の prompts/agents.txt を読み、自分のエージェントの AGENTS.md や CLAUDE.md に協調ループを移植してみるのが手軽です。共有ボードが欲しくなったら、今回のように board-service と notice shim だけを取り出して動かせます。
参考リソース
- microsoft/Agensh(GitHub):ハーネス本体、実験スクリプト、再現手順(REPRODUCE.md)、プロンプト(prompts/)。MIT License
- Agensh: Scaling Organizational Intelligence to 1,024 Agents(arXiv:2609.26781):技術レポート。付録 A に全エージェント共通のプロンプト、付録 B に配達の仕組み
- Agensh プロジェクトページ:結果の図と、1,024体の作業を再生するデモ
- ProgramBench(facebookresearch/ProgramBench):評価に使われたベンチマーク
- DeLM(yuzhenmao/DeLM):共有ボードの考え方の元になった研究
- pandoc:今回の手元の実験で正解役に使った文書変換ツール

