コンテンツにスキップ

ファイルベースIPCメッセージバス

Append-only JSONLによる、TaskSpecワークフローを備えた構造化エージェント間デリゲーション。


ほとんどのマルチエージェントシステムは、メッセージブローカー(Redis、RabbitMQ、Kafka)のインストールと運用を要求します。これは小さなオフィスにも企業メールサーバー、IT部門、SLAを求めるようなものです。

DuDuClawは異なるアプローチを取ります:掲示板方式

廊下の共有掲示板を想像してください:

  • エージェントAがタスクの付箋を掲示板に貼る(ファイルに1行追記)
  • オフィスマネージャーが定期的に巡回し、新しい付箋を読む(ディスパッチャーがファイルをポーリング)
  • オフィスマネージャーがその付箋をエージェントBに渡す(サブプロセスを起動)
  • エージェントBが結果を掲示板に貼り戻す

メールサーバー不要。IT部門不要。SLA不要。掲示板と画鋲、そして信頼できるオフィスマネージャーだけです。


各メッセージはbus_queue.jsonlに追記される1行のJSONです:

{"from": "agent-a", "to": "agent-b", "task": "summarize-report", "payload": {...}, "ts": "2026-04-07T10:30:00Z"}
{"from": "agent-b", "to": "agent-a", "task": "summary-result", "payload": {...}, "ts": "2026-04-07T10:30:15Z"}

1行 = 1メッセージ。ファイルはappend-onlyログのように時間とともに成長します。

HeartbeatSchedulerが起動(定期間隔)
|
v
AgentDispatcherがbus_queue.jsonlを読み取り
|
v
管理下のエージェント宛の新メッセージはあるか?
|
+--+--+
| |
あり なし
| |
| v
| 次のハートビートまでスリープ
|
v
保留中の各メッセージについて:
|
v
max_concurrent_runsセマフォを確認
|
+---> 空きあり?--> Claude CLIサブプロセスを起動してタスク実行
|
+---> 全スロット満?--> 次のサイクルにメッセージを持ち越し

JSONL(JSON Lines)にはこのユースケースに最適な特性があります:

Append-onlyは本質的に並行安全。 複数のプロセスが同じファイルに同時に追記しても、互いのデータを破損しません。各append操作は完全な1行を書き込みます——インターリーブのリスクはありません。

ファイルは本質的に永続的。 操作中にシステムがクラッシュしても、クラッシュ前に書き込まれたすべてのものは保存されます。メッセージの消失なし、リカバリプロトコル不要。

人間が読める。 tail -f bus_queue.jsonlでメッセージ履歴全体をデバッグできます。特別なツール、管理コンソール、プロトコルデコーダー不要。

外部依存ゼロ。 ブローカーのインストール、設定、監視、パッチ、トラブルシューティングは一切不要。ファイルシステムがブローカーです。

各エージェントのハートビート設定にmax_concurrent_runsがあります。メッセージの洪水によるシステム過負荷を防止します:

エージェント"agnes"の設定:
max_concurrent_runs = 3
現在の状態:
実行中:タスク2件
保留中:メッセージ5件
ディスパッチャーの判断:
- あと1タスク開始(上限3に到達)
- 残り4メッセージは次のサイクルに持ち越し

シンプルなカウンティングセマフォです——複雑なキュー管理も優先スケジューリングもありません。タスクが完了すると、そのスロットが次の保留メッセージに開放されます。


ディスパッチャーは連続実行されません——HeartbeatSchedulerによって駆動され、各エージェントに統一されたタイミングメカニズムを提供します:

HeartbeatScheduler(エージェントごと)
|
+---> bus_queue.jsonlの新タスクをポーリング
|
+---> GVUサイレンスブレーカーをチェック
| (エージェントが最近進化していなければ、
| プロアクティブなリフレクションをトリガー)
|
+---> 期限到来のcronタスクを起動

インターバルはエージェントごとに設定可能。高トラフィックのカスタマーサポートエージェントは5秒ごとにポーリング、バックグラウンドの分析エージェントは5分ごとにポーリングといった具合です。


すべての外部依存は潜在的な障害点です。Redisはメモリ管理、監視、バックアップが必要。KafkaはZooKeeper(またはKRaft)、トピック管理、コンシューマーグループの調整が必要。JSONLファイルに必要なのは…ファイルシステムだけ。

開発者のマシン上で単一バイナリとして実行されるよう設計されたシステムにとって、このシンプルさは妥協ではなく機能です。

ファイルに書き込まれたメッセージは、プロセス再起動、システムリブート、クラッシュに耐えます。失われる可能性のある「処理中」の状態はありません——行が追記されれば、それは永続的です。

メッセージブローカーで問題が発生すると、不透明な内部状態をデバッグすることになります。JSONLファイルで問題が発生すると、テキストエディタで開くだけです。すべてのエージェント間通信の完全な履歴が、時系列順に、プレーンテキストで存在します。

このアプローチには自然な上限があります:数十のエージェントが1日数百のメッセージを交換する規模ではうまく機能します。毎秒数百万メッセージにはスケールしません。しかしそれはDuDuClawのユースケースにとって正確に正しいトレードオフです——少数の専門エージェントを実行する個人開発者や小規模チーム向けです。


DelegationEnvelope:構造化されたハンドオフ

Section titled “DelegationEnvelope:構造化されたハンドオフ”

生のJSONLメッセージは単純なタスクには十分ですが、複雑なマルチエージェントワークフローには構造が必要です。DelegationEnvelope は標準化されたハンドオフプロトコルを提供します:

DelegationEnvelope:
context: 受信者が必要とする背景情報
constraints: 境界と要件
task_chain: 誰が誰に何を委任したかの履歴
expected_output: 送信者が期待する成果物
delegation_depth: 現在のホップ数(上限5)

エンベロープはメッセージと一緒にバス上を移動します。それを処理する各エージェントは task_chain に追記し、追跡可能な委任経路の監査証跡を作ります:

エージェントA → エージェントB → エージェントC
| | |
v v v
depth=1 depth=2 depth=3

システムは無限委任ループを防ぐため、最大委任深度(5ホップ)を強制します。エンベロープ形式は後方互換性があり、エンベロープを理解しないエージェントも生のペイロードをそのまま処理できます。


TaskSpec:マルチステップワークフローの計画

Section titled “TaskSpec:マルチステップワークフローの計画”

依存関係を持つ複数ステップにまたがるタスクには、TaskSpec システムが構造化されたワークフロー計画を提供します:

TaskSpec:
steps:
- id: "step-1"
action: "research"
dependencies: []
status: completed
- id: "step-2"
action: "draft"
dependencies: ["step-1"]
status: in_progress
- id: "step-3"
action: "review"
dependencies: ["step-2"]
status: pending

ワークフローエンジンが扱うもの:

  • 依存関係を考慮したスケジューリング:ステップは依存関係が完了した時にのみ実行
  • 自動リトライ:失敗したステップは最大3回、バックオフ付きで再試行
  • 自動リプラン:リトライを使い切ると、システムは調整したステップで再計画(最大2回)
  • 永続化:TaskSpecの状態は tasks/ ディレクトリに保存され、プロセス再起動を生き延びる
ステップが失敗
|
v
リトライ(最大3回)
|
+--+--+
| |
成功 まだ失敗
| |
v v
続行 リプラン(最大2回)
|
v
調整したステップを生成し
そこから再試行

  • HeartbeatScheduler:各エージェントのポーリングリズムを駆動。
  • Agent Registry:ディスパッチャーがどのエージェントが存在し、並行制限がいくつかを認識。
  • コンテナサンドボックス:タスクが隔離を必要とする場合、ディスパッチャーはホスト上ではなくコンテナ内でサブプロセスを起動。
  • DelegationEnvelope:複雑なマルチエージェントハンドオフに構造化されたコンテキストを提供。
  • TaskSpec:依存関係を考慮したマルチステップワークフローを、リトライとリプラン付きで実現。
  • Multi-Runtime:ディスパッチャーは各エージェントのランタイム設定に基づき、適切なCLIバックエンド(Claude/Codex/Gemini)を起動。
  • 監査ログ:ディスパッチされたすべてのタスクがJSONL監査証跡に記録。

機能する最もシンプルなソリューションは、通常最良のソリューションです。DuDuClawの規模でのエージェント間通信において、JSONLファイルはメッセージブローカーが提供するすべて——永続性、並行安全性、可観測性——を、運用オーバーヘッドなしで提供します。そしてタスクが複雑になったときは、DelegationEnvelopeとTaskSpecが、基盤となる転送方式のシンプルさを犠牲にすることなく構造を追加します。