エージェントがより野心的なタスクを引き受けるにつれて、以下の点が課題となっています。
- 大規模な作業を確実に完了すること
- 自身のコンテキストを管理すること
これらの課題にどう対処するか、私たちは 動的サブエージェント という形で実験を進めてきました。これは、汎用的なツール呼び出しでサブエージェントのタスクを発行する代わりに、エージェントがサブエージェントの実行を制御する短いスクリプトを記述するというものです。これにより、モデルは得意とするコードパターン(ループ、分岐、並行処理など)を活用して、タスクに適したオーケストレーションロジックを記述できます。
なぜ動的サブエージェントなのか?
Deep Agents は既に サブエージェント をサポートしています。これらはコンテキストを分離し、メインエージェントが作業単位を委任できるようにし、中間結果をメインのコンテキストウィンドウから隔離します。では、なぜ動的サブエージェントが必要なのでしょうか?
通常のサブエージェントでは、メインモデルが直接呼び出すことで、一度に一つずつ実行されます。これは小規模では機能しますが、数百ものサブエージェントを生成する必要がある場合や、オーケストレーションロジックに条件分岐や複数のフェーズが必要な場合には、機能しなくなります。
動的サブエージェントは、プログラムによるオーケストレーション でこれを解決します。エージェントはツールコールを順番に行う代わりに、サブエージェントをオーケストレーションして呼び出す短いスクリプトを記述し、軽量なインタプリタで実行します。
典型的な例は、300 ページのドキュメントの各ページに 1 つのサブエージェントを割り当てるケースです。エージェントはサブエージェントツールを 300 回呼び出す代わりに、ループを記述します。
1const results = await Promise.all(pages.map(page =>2 task({ description: `Summarize page ${page.number}`, subagentType: "summarizer" })3));
これにより、ツールコールベースのオーケストレーションでは確実に実現できない、以下の 2 つのことが可能になります。
大規模な処理における確定的なカバレッジ。 構造がない場合、エージェントは範囲を判断して判断を下し、500 件中 75 件をスクリーニングして終了とみなす可能性があります。ディスパッチループではそうはなりません。カバレッジは、プロンプトエンジニアリングの問題ではなく、構造的な保証になります。
信頼性の高い複雑なオーケストレーション。 オーケストレーションをコードとして記述することは、モデルがそれを一連のツールコールとして再現するよりも信頼性が高くなります。特に、ファンアウトと合成、マルチフェーズパイプライン、条件分岐などで顕著です。
これは、Claude Code のワークフロー や Recursive Language Models (RLMs) と同じ考え方です。つまり、モデルがコードを記述し、そのコードがさらに多くのエージェントをディスパッチするというものです。
クイックスタート
動的サブエージェントを使用するには、2 つのものが必要です。作業をディスパッチするための サブエージェント と、コードインタプリタ(モデルがオーケストレーションコードを記述して実行する、セキュアで軽量なランタイム)です。Deep Agents には、QuickJS ベースのオプションのコードインタプリタが含まれています。これを使用するには、QuickJS ミドルウェアパッケージをインストールし、create_deep_agent の middleware 引数で CodeInterpreterMiddleware を渡します。
1pip install -U "deepagents[quickjs]"
1from deepagents import create_deep_agent2from langchain_quickjs import CodeInterpreterMiddleware34agent = create_deep_agent(5 model="openai:gpt-5.5",6 middleware=[CodeInterpreterMiddleware()],7)
Deep Agents には汎用の サブエージェント が組み込まれているため、ワークフローで使用できる汎用的なサブエージェントプロファイルが既に 1 つ用意されています。専門的なワークフローの場合は、独自の名前、説明、システムプロンプトを持つ カスタムサブエージェント を設定します。名前と説明によって、エージェントはどのロールを使用すべきかを認識します。
動的サブエージェントをトリガーするには、次のようにエージェントに "workflow" という単語を含むプロンプトを与えます。
1result = await agent.ainvoke({2 "messages": [{"role": "user", "content": "Run a workflow that reviews every file in src/routes/ and summarizes the top risks."}]3})
コーディングエージェントと併用する
動的サブエージェントを最も簡単に試す方法は、Deep Agent を使用して構築されたターミナルコーディングエージェントである dcode を使用することです。これにはコードインタプリタが有効になった状態で同梱されているため、配線する必要は何もなく、動的サブエージェントがすぐに使用できます。
インストール
1curl -LsSf https://langch.in/dcode | bash
実行
1dcode
動的サブエージェントをトリガーするには、"ワークフロー" を依頼するだけです。エージェントは作業をこなす代わりに、組み込みの task() グローバル関数を呼び出すオーケストレーションスクリプトを記述し、コードインタプリタで実行します。例えば、"src/ 内のすべてのファイルを SQL インジェクションについてレビューする ワークフロー を実行してください" と依頼します。
サブエージェントが生成されると、dcode はそれらを動的サブエージェントパネルに、ディスパッチごとにフェーズにグループ化してライブ表示します。

これは dcode で最も簡単に試せますが、ACP を介してお好みのツール(Zed など)でも使用できます。
仕組み
エージェントには eval ツール が与えられます。エージェントは、インタプリタ内で安全に実行される JavaScript を記述します。サブエージェント が設定されている場合、インタプリタはコードからそれらをディスパッチする組み込みの task() グローバル関数を公開します。手元のタスクに基づいて、モデルは異なるコード(ループ、分岐、Promise.all など)を記述し、インタプリタはそれを決定論的に実行します。

task() は、description、subagentType、およびオプションの responseSchema を受け取ります。responseSchema が指定された場合、結果は既に型付けされたオブジェクトとして返され、フィルタリングや次のステップへの引き渡しが容易になります。
1const result = await task({2 description: "Review src/auth/login.ts for security issues.",3 subagentType: "reviewer",4 responseSchema: {5 type: "object",6 properties: {7 severity: { type: "string", enum: ["high", "medium", "low"] },8 issues: { type: "array", items: { type: "string" } },9 },10 },11});1213const critical = result.severity === "high" ? result.issues : [];14critical; // model sees the last line
詳細については、ドキュメントの プログラムによるサブエージェント および インタプリタ を参照してください。
一般的なオーケストレーションパターン
Anthropic の 動的ワークフロー は、並列エージェント作業のための一連のオーケストレーションパターンを広めました。これらは有効にする機能ではありません。作業から自然に生まれる形状であり、タスクが変わるとエージェントは別の形状に落ち着きます。以下の表は、各形状とそれが適した作業の種類をマッピングしたものです。

以下では、各パターンが Deep Agents でどのように機能するかを、ライブトレースとともに詳しく説明します。また、これら 6 つのパターンを説明する動画も用意していますので、こちら でご覧いただけます。
分類して実行
アイテムを最初に分類し、その分類に基づいて各アイテムを専門のサブエージェントが処理します。これにより、異なるタイプのアイテムが混在する入力に対して、それぞれに異なる専門知識が必要な場合に処理できます。

使用例: サポートチケット、エラーログ、ユーザーフィードバックのトリアージ、またはタイプに応じて異なる処理が必要なバッチアイテム全般。
例: サポートチケットのバックログをトリアージします。エージェントはチケットを読み取り、それぞれをバグ、機能リクエスト、質問に分類します。バグはバグ調査エージェントへ、機能リクエストは機能分析エージェントへ、質問はサポート応答エージェントへ振り分けます。結果はカテゴリごとにグループ化されたサマリーになります。
トレースは こちら でご覧ください。
ファンアウトと合成
エージェントは同じ種類の作業を多数のアイテムに対して並行してディスパッチし、その結果を結合します。

使用例: ディレクトリ全体のコードレビュー、ドキュメントバッチの分析、ログファイルの処理、複数のサービスにわたる同一チェックの実行。
例: ソースツリー全体のファイル単位のセキュリティレビュー。エージェントは src/ 以下のすべての TypeScript ファイルを検出し、ファイルごとに 1 つのセキュリティレビューアーエージェントを並行してディスパッチします。その後、結果を単一の優先順位付きレポートに統合し、重要度評価と変更が必要な行を提示します。
トレースは こちら でご覧ください。
敵対的検証
2 パスパターンです。最初のパスで調査結果を生成します。2 番目のパスでは、各調査結果を独立した検証エージェントに送信し、合意が得られた調査結果のみが保持されます。これにより、スピードよりも確実性が重要な場合に、誤検出を減らすことができます。

使用例: 誤検出のコストが高いセキュリティ監査、コンプライアンスチェック、調査結果に高い信頼性が必要なあらゆるレビュー。
例: 誤検出が許容されないセキュリティ監査。監査エージェントが潜在的な脆弱性に対して広く網をかけ、各調査結果は独立した検証エージェントに渡されます。検証エージェントはコードを新たに読み、CONFIRMED または REFUTED の判定を返します。確認された調査結果のみが最終レポートに残ります。
トレースは こちら でご覧ください。
生成とフィルタリング
複数のサブエージェントが同じ問題に対して独立した解決策を生成します。エージェントは結果をコード内で比較、スコアリング、フィルタリングし、最良のものだけを保持します。

使用例: アーキテクチャ提案、リファクタリング戦略、コンテンツバリエーション、コミットする前に複数のオプションを検討することでより良い結果が得られるあらゆるタスク。
例: 競合するレートリミッターの再設計案をランク付けします。エージェントはアーキテクトに rate-limiter.ts の複数の独立した再設計案を生成させます。各案は上書きを防ぐために別々のファイルに書き込まれます。その後、バースト時の正確性、マルチインスタンスサポート、複雑さに基づいてスコアリングされます。最も優れた案が、その理由とともに選ばれます。
トレースは こちら でご覧ください。
トーナメント
バリエーションが審査エージェントによって直接比較され、勝者がトーナメント形式で勝ち進みます。

使用例: 主観的な基準に基づく最適化、スタイルの選択、競合する実装間での選択。
例: 複雑な createOrder ハンドラーのリライトをペアワイズブラケット方式で比較します。複数のライターがそれぞれ異なる優先順位でリライト候補を生成し、審査エージェントがそれらを直接比較して、ラウンドごとに勝者を決定します。最終的に 1 つのチャンピオンが選ばれ、審査エージェントの判断根拠とともに返されます。
トレースは こちら でご覧ください。
完了するまでループ
エージェントは発見ループを実行し、既に見つけたものと重複排除しながら、新しい結果がなくなるまで続けます。作業の範囲が事前にわからない場合に役立ちます。

使用例: 網羅的な検索、デッドコードの検出、依存関係の監査、固定された結果数ではなく完全性を求めるあらゆるスイープ。
例: パスベースのセキュリティスイープ。エージェントはスキャンパスを実行し、コード内で見つけたものを検査し、前回のパスで新しい問題が見つかった場合にのみ次のパスを開始します。パスで新しい問題が見つからなくなった時点で停止します。統合された調査結果と、実行にかかったパス数を報告します。
トレースは こちら でご覧ください。
結論
動的サブエージェントは、エージェントにより多くの自律性と信頼性の向上をもたらす方法です。コードがカバレッジと中間コンテキストを処理し、モデルは依然として判断を要する重い作業を行います。上記のパターンは出発点に過ぎません。実際には、エージェントはタスクの要求に基づいてこれらを構成し、組み合わせます。
これは、Recursive Language Model のアイデアを最もシンプルな形で実現したものです。エージェントがコードを記述し、そのコードがさらに多くのエージェントをディスパッチします。これはエージェントが自身を再帰的に呼び出すことであり、コンテキストウィンドウによって制限されたり、固定されたワークフローに閉じ込められたりすることはありません。エージェントは問題を必要なだけ細分化し、その断片を任意の形状で再構成できます。上記で強調したオーケストレーションパターンは、可能性の初期の一端に過ぎませんが、モデルがコードを書く能力を向上させるにつれて、その上限は上がり続けるでしょう。
動的サブエージェント は、Deep Agents がこれを今日、皆さんの手に届ける方法です。エージェントにコードインタプリタを追加するか、動的サブエージェントがすぐに使える dcode を手に取って始めてください。
謝辞
@colifran_ と @huntlovell による共著。レビューを提供してくれた @hwchase17、@masondrxy、@chester_curme に感謝します。





