記事一覧へ
数週間前、私たちが公開した「5つのエージェントスキル設計パターン」に関する記事がバイラルになりました。Tool Wrapper・Generator・Reviewer・Inversion・Pipeline というパターンは、開発者がエージェントスキルを設計するための構造的な語彙を提供しました。しかし、どれほど巧みに設計されたシングルスキルも、問題の一部しか解決しません。
より難しい問いはこうです——プロダクション環境で、複数のエージェントにまたがる複数のスキルをいかにオーケストレーションするか? Agent A の出力を Agent B の入力に適した形式にするにはどうすればよいか? 特定のステップが必ず特定の順序で実行されることを保証しながら、各ステップ内の AI の柔軟性は残すにはどうすればよいか? 異なるチームが異なる言語で書いたエージェントをどう連携させるか?
Google Cloud Next 26 で、私たちは **Agent Development Kit(ADK)2.0** をリリースしました。この3つの主要な追加機能——グラフベースワークフロー、協調エージェント、そして正式化された Skills フレームワーク——がこれらの問いに答えます。以下に、エージェントアーキテクチャを次のレベルに引き上げる5つのオーケストレーションパターンを紹介します。
by @addyosmani and @Saboo_Shubham_
---
## Pattern 1: The Hybrid Graph(ハイブリッドグラフ)
エージェントシステムで最も多く見られるプロダクション障害は、オーケストレーションの失敗です。エージェントは各ステップ単体では正しく推論するのに、順序を誤って実行したり、必須ステップをスキップしたり、人間のレビュアーが想定していなかった経路を取ったりします。
これが起きる原因は、多くのエージェントアーキテクチャがワークフローロジックをシステムプロンプト内にエンコードしているからです。LLM は最初の数ターンは忠実に指示に従います。しかし7ターン目あたりからショートカットを取り始め、12ターン目にはステップを完全にスキップし始めます。これは手続き的なワークフローを定義するのに自然言語の指示を使うことの根本的な限界です。LLM はオプティマイザーです。効率よく役に立つ出力を生成するよう訓練されています。モデルが5ステップのワークフローを見ると、ステップをまとめたり並べ替えたりすることでより役立つ応答が生成できると判断しがちです。
ADK 2.0 のグラフベースワークフローはこれを構造的に解決します。エージェントロジックをノードがアクション・エッジが条件ロジック付きの遷移である有向グラフとして定義します。重要な革新は、決定論的ノード(ハードコードされたビジネスルール)と AI 駆動ノード(LLM 推論)を同じグラフ内に混在させられる点です。
具体例として、ローン申請処理エージェントを考えます。一部のステップは決定論的でなければなりません(規制コンプライアンスチェック、信用スコアのしきい値、書類要件)。他のステップは AI の柔軟性が活きます(書類品質の評価、財務プロファイルの要約、推薦文の生成)。
```python
from google.adk import Agent, Workflow, Event
from pydantic import BaseModel
# --- ノード間で共有するスキーマ ---
class LoanApp(BaseModel):
documents: dict
credit_score: int
class DocStatus(BaseModel):
status: str
missing: list[str] = []
class CreditResult(BaseModel):
tier: str
auto_approve: bool
flag: bool = False
# --- 決定論的ノード: 必要書類を検証する ---
def validate_documents(node_input: LoanApp):
required = ["id_proof", "income_proof", "address_proof", "bank_statements"]
missing = [doc for doc in required if doc not in node_input.documents]
if missing:
return Event(
route="incomplete",
message=DocStatus(status="incomplete", missing=missing),
)
return Event(route="complete", message=DocStatus(status="complete"))
# --- AI 駆動ノード: 書類品質を評価する ---
assess_quality = Agent(
name="assess_quality",
model="gemini-flash-latest",
instruction=(
"Evaluate the quality and authenticity of the provided documents. "
"Flag concerns about readability, completeness, or inconsistencies. "
"Return a short structured assessment."
),
output_schema=str,
)
# --- 決定論的ノード: 信用スコアチェック ---
def check_credit_score(node_input: LoanApp):
score = node_input.credit_score
if score >= 750:
return CreditResult(tier="prime", auto_approve=True)
if score >= 650:
return CreditResult(tier="standard", auto_approve=False)
return CreditResult(tier="subprime", auto_approve=False, flag=True)
# --- AI 駆動ノード: 推薦文を生成する ---
recommendation = Agent(
name="recommendation",
model="gemini-flash-latest",
instruction=(
"Given the document assessment and credit result in context, "
"produce a loan recommendation with risk factors and suggested terms."
),
output_schema=str,
)
# --- 決定論的ノード: コンプライアンスチェック(ルーティング付き)---
MAX_LEGAL_APR = 36.0
MAX_TERM = 84
def compliance_check(node_input):
violations = []
# 実装例: 推薦フィールドをパースしてルールを検証する
# if recommendation.apr > MAX_LEGAL_APR: violations.append(...)
# if recommendation.term_months > MAX_TERM: violations.append(...)
if violations:
return Event(route="non_compliant", message={"violations": violations})
return Event(route="compliant", message={"violations": []})
def human_review(node_input):
return Event(message="Escalated to human reviewer.")
def auto_approve(node_input):
return Event(message="Auto-approved.")
def request_missing_docs(node_input: DocStatus):
return Event(message=f"Missing documents: {node_input.missing}")
# --- ワークフローを組み立てる ---
loan_processor = Workflow(
name="loan_processor",
edges=[
("START", validate_documents),
(validate_documents, {
"complete": assess_quality,
"incomplete": request_missing_docs,
}),
(assess_quality, check_credit_score, recommendation, compliance_check),
(compliance_check, {
"compliant": auto_approve,
"non_compliant": human_review,
}),
],
)
```
プロンプトベースのオーケストレーションとの決定的な違いは、必須構造がフレームワークによって強制される点です。LLM は各ノード内では柔軟性を持ちますが、ノードをスキップしたりグラフを並べ替えたりすることはできません。決定論的ノードは標準的なテストフレームワークでユニットテスト可能です。AI 駆動ノードは Agent Simulation を使って個別に評価できます。そしてグラフ構造自体が検査可能なため、コンプライアンス担当者はワークフローをレビューし、必須ステップが含まれ適切に順序付けられていることを、LLM プロンプトを一切読まずに確認できます。
---
## Pattern 2: The Coordinator-Specialist(コーディネーター+スペシャリスト)
「God エージェント」はプロダクションエージェントシステムで最も多く見られるアンチパターンです。1つのエージェントがすべてをこなそうとします——カスタマーサポート、データ分析、ドキュメント生成、API 連携。システムプロンプトは何千トークンにも膨れ上がり、ツールセットは膨大となり、LLM が何十もの可能なアクションから常に選択しているため挙動が予測不能になります。
機能を追加するにつれて問題は悪化します。5番目の主要機能追加あたりで、システムは信頼できなくなります。エージェントがタスクに不適切なツールを使います。データ分析をしているのにカスタマーサポートのトーンを使います。プロジェクトのタイムラインについて簡単な質問に答えるときに財務コンプライアンスルールを適用します。指示がモデルの注意を奪い合い、モデルは開発者が想定しなかったトレードオフを始めます。
ADK 2.0 の協調エージェントはコーディネーター+スペシャリストパターンをネイティブでサポートします。コーディネーターエージェントはタスクのルーティングとワークフロー管理を担当します。スペシャリストエージェントは焦点の絞られたコンテキストとツールで、ドメイン固有の作業を担当します。
```python
from google.adk import Agent
# 責務を絞ったスペシャリスト
data_analyst = Agent(
name="data_analyst",
model="gemini-flash-latest",
mode="task", # 完了時に自動的にコントロールを返す
instruction=(
"You are a data analysis specialist. You run SQL queries, produce "
"visualizations, and generate statistical summaries. Stay inside "
"data analysis. Call complete_task when the analysis is done."
),
tools=[bigquery_tool, visualization_tool, statistics_tool],
)
document_writer = Agent(
name="document_writer",
model="gemini-flash-latest",
mode="task",
instruction=(
"You are a technical document specialist. You produce reports, "
"summaries, and documentation in structured formats. You do not "
"access databases. Call complete_task when the document is ready."
),
tools=[markdown_tool, template_tool, format_tool],
)
customer_expert = Agent(
name="customer_expert",
model="gemini-flash-latest",
mode="task",
instruction=(
"You are a customer context specialist. You pull from CRM data, "
"support tickets, and communication logs to provide customer "
"insights. Call complete_task once insights are assembled."
),
tools=[salesforce_tool, zendesk_tool, email_search_tool],
)
# コーディネーター: sub_agents を持つ通常の Agent。
# ADK が自動で request_task_<subagent_name> ヘルパーを注入する。
coordinator = Agent(
name="project_coordinator",
model="gemini-flash-latest",
sub_agents=[data_analyst, document_writer, customer_expert],
instruction=(
"You coordinate specialists. For a single-domain request, delegate "
"to the matching specialist. For cross-domain requests, sequence the "
"specialists: gather customer context first, then data, then the "
"final report. Each subagent returns control when its task is done."
),
)
```
サブエージェントの `mode` はコントロールがコーディネーターに戻る方法を定義します。`task` モードでは、スペシャリストが作業を完了するまで動き続け、自動的にコーディネーターにコントロールを戻します。コーディネーターは関連する出力を次のスペシャリストのコンテキストとして渡します。document writer はデータベースを再クエリする必要がありません。data analyst の出力をコンテキストとして受け取ります。
各スペシャリストは独自のアイデンティティ(Agent Identity 経由)、独自のツール権限(Agent Gateway で管理)、独自のメモリコンテキストを持ちます。data analyst は CRM データにアクセスできません。customer expert は SQL クエリを実行できません。単一エージェントの誤作動による被害範囲はそのドメインに封じ込められます。
このパターンはテストとイテレーションも簡略化します。data analyst の出力品質が劣化したら、そのスペシャリスト1つを評価して修正すればよいのです。モノリシックなエージェントを再トレーニングしたり再プロンプトしたりする必要はありません。新しい機能(例えば競合インテリジェンス・スペシャリスト)を追加するときは、コーディネーターに登録すれば即座に利用可能になります。
---
## Pattern 3: Skill Composition(スキル合成)
前回の記事では5つのスキル設計パターン——Tool Wrapper、Generator、Reviewer、Inversion、Pipeline——を紹介しました。ADK 2.0 はこれらを、スキルをマルチエージェントワークフローにおけるファーストクラスの市民にする宣言的 Skills フレームワークで正式化します。
重要な追加機能は `SkillToolset` です。これにより、エージェントはスキルをツールとしてロードし使用できます。エージェントはスキルの内部実装を知る必要はありません。スキルの名前・説明・インターフェースを知るだけです。これにより、元のスキル作成者が想定していなかった形でエージェントをまたいでスキルを連鎖させる合成が可能になります。
実際の動作を考えます。3つの異なるチームが構築した3つの既存スキルがあるとします:
```
skills/
├── data-extractor/
│ └── SKILL.md # Pattern: Tool Wrapper(API からデータ抽出)
├── trend-analyzer/
│ └── SKILL.md # Pattern: Pipeline(多段階トレンド分析)
└── executive-summary/
└── SKILL.md # Pattern: Generator(フォーマット済みサマリーを生成)
```
コーディネーターエージェントはこれらのスキルを、いずれのスキルも個別には設計されていなかったワークフローに合成できます:
```python
import pathlib
from google.adk import Agent
from google.adk.skills import load_skill_from_dir
from google.adk.tools import skill_toolset
# SKILL.md ベースの各スキルをディレクトリからロード
skills_root = pathlib.Path(__file__).parent / "skills"
data_extractor = load_skill_from_dir(skills_root / "data-extractor")
trend_analyzer = load_skill_from_dir(skills_root / "trend-analyzer")
executive_summary = load_skill_from_dir(skills_root / "executive-summary")
market_skills = skill_toolset.SkillToolset(
skills=[data_extractor, trend_analyzer, executive_summary],
)
market_intelligence = Agent(
name="market_intelligence",
model="gemini-flash-latest",
instruction=(
"You are a market intelligence agent. For a market analysis request: "
"1) use data-extractor to pull market data, "
"2) pass data to trend-analyzer for pattern identification, "
"3) use executive-summary to format findings for leadership."
),
tools=[market_skills],
)
```
プログレッシブ・ディスクロージャーのおかげで、エージェントはスキルを実際に呼び出すときにのみ、そのスキルの完全なコンテキストをロードします。ユーザーがトレンド分析を必要としない簡単な質問をした場合、trend-analyzer スキルの指示・参照・アセットはコンテキストウィンドウにロードされません。これにより、エージェントが数十のスキルにアクセスできる場合でも、コンテキストのトークン使用量を効率的に保てます。
これは npm・pip・Maven を成功させたのと同じ洞察です——小さく、焦点が絞られ、明確なインターフェースを持つ合成可能なパッケージは、大きくモノリシックなライブラリよりも価値があります。個別のチームが自分たちのドメインのスキルを構築します(データエンジニアリングチームが抽出スキルを、分析チームが分析スキルを、コミュニケーションチームがフォーマットスキルを)。プラットフォームチームが組み立てたコーディネーターエージェントは、それらのチームが直接調整する必要なく、組織の境界をまたいだワークフローにこれらを合成できます。
---
## Pattern 4: The Cross-Language Pipeline(クロス言語パイプライン)
ADK は現在、Python・TypeScript・Go・Java の4つの言語で利用可能です。各 SDK は A2A(Agent-to-Agent)プロトコルをネイティブでサポートしています。つまり、Python で書かれたエージェントが Go で書かれたエージェントにシームレスに委任でき、そのエージェントが Java で書かれたエージェントに委任できます。
これは、異なるチームが異なる言語を使っている組織で重要です。ML チームは Python を書きます。プラットフォームチームは Go を書きます。エンタープライズインテグレーションチームは Java を書きます。フロントエンドチームは TypeScript を書きます。以前は、これらのチームをまたいだマルチエージェントワークフローを構築するために、カスタム API 統合・プロトコルネゴシエーション・データ形式の変換が必要でした。A2A はこれらすべてを標準化します。
クロス言語パイプラインが実際にどのように見えるかを示します:
各エージェントは `/.well-known/agent-card.json` でその機能を Agent Card として公開します。他のエージェントはこれらの機能を自動的に発見します。A2A プロトコルはタスク管理・ステータス更新・結果のストリーミングを処理します。各エージェントの観点からは、異なる言語のリモートエージェントへの委任はローカル関数を呼び出すのと同じように感じられます。
各 SDK もパイプラインに言語固有の強みをもたらします。ADK Go 1.0 は、マルチエージェントパイプラインにわたる分散トレーシングのための OpenTelemetry 統合・プラグイン経由のセルフヒーリングロジック・Kubernetes マニフェストや Terraform リソースを管理するのと同じ方法でエージェントを宣言的に管理できる YAML ベースのエージェント定義を追加しました。Java SDK は長い会話履歴を管理するためのイベント圧縮と、エンタープライズガバナンスに不可欠な人間の承認ワークフローのための ToolConfirmation を追加します。
---
## Pattern 5: The Sandboxed Executor(サンドボックス実行)
最後のパターンは、ワークフローの一部としてコードを実行する必要があるエージェントという一般的な要件に対応します。データ分析エージェントは pandas 操作を実行する必要があります。コードレビューエージェントはテストを実行する必要があります。ドキュメント処理エージェントは変換スクリプトを実行する必要があります。
実行環境が分離されていない場合、エージェント内で任意のコードを実行することはセキュリティリスクです。ADK は、プロセスレベルの分離を備えたホスト環境で AI 生成コードを実行するマネージドサンドボックス実行環境を提供し、変数・インポートされたモジュール・ファイル状態をセッション内のツール呼び出しをまたいで維持するため、エージェントは毎回状態をリロードせずに多段階のコーディングタスクに取り組めます。
この例は Agent Runtime サンドボックスを使用します。まず Agent Engine Code Execution クイックスタートでサンドボックスを作成し、そのリソース名を以下に渡します。
```python
from google.adk import Agent
from google.adk.code_executors import AgentEngineSandboxCodeExecutor
code_analyst = Agent(
name="code_analyst",
model="gemini-flash-latest",
code_executor=AgentEngineSandboxCodeExecutor(
sandbox_resource_name="SANDBOX_RESOURCE_NAME",
),
instruction="""You are a code analysis specialist. When reviewing code, you can:
1. Install dependencies and import libraries as needed
2. Run test snippets and static checks across multiple steps
3. Keep variables and file state across calls without reloading
4. Report findings backed by actual execution results
Your code runs in an isolated sandbox environment. You cannot
reach the host filesystem, your internal systems, or network
resources outside this environment."""
)
```
サンドボックスの境界が重要なセキュリティ特性です。エージェントは多くのステップにわたって任意の Python を実行できますが、そのコードはマネージドサンドボックス内にとどまります。ホストのファイルシステムに触れることも、内部システムへの接続を開くことも、権限を昇格させることもできません。無限ループや過剰なメモリ使用など実行が暴走した場合、ランタイムは何かが漏れ出る前にハードリミットを強制します。
このパターンは前回の記事の Pipeline スキルパターンと組み合わせると特に強力です。ソースコードを解析してドキュメント文字列を生成し最終ドキュメントを組み立てる必要があるドキュメンテーションパイプラインは、コード構造について LLM に推論させる代わりに、解析ステップを上記のようなコード実行エージェントに渡すことができます。実際の Python で Python の AST を解析するほうが正確であり、エグゼキューターを独立したエージェントに保つことは、ADK がコード実行を他のツールと合成することを期待する方法と一致しています。
---
## 適切なオーケストレーションパターンを選ぶ
これらのパターンは、前回の記事のスキルパターンと同様に合成できます:
- Hybrid Graph は個別のノードで Coordinator-Specialist を使用できます——グラフが全体的なワークフローを定義し、スペシャリストエージェントがドメイン固有のノードを処理します
- Coordinator-Specialist セットアップは各スペシャリスト内で Skill Composition を使用できます——各スペシャリストはそのドメインに関連するスキルのみをロードします
- Cross-Language Pipeline はあらゆる段階で Sandboxed Executors を使用できます——Python エージェントがサンドボックスで ML モデルを実行し、Go エージェントがサンドボックス化されたテストデータでコンプライアンスチェックを実行します
- どのパターンも、個別のスキルレベルで前回の記事の5つのスキルパターン(Tool Wrapper・Generator・Reviewer・Inversion・Pipeline)を組み込めます
---
## Getting Started
ADK 2.0 は現在利用可能です。`pip install google-adk --pre`(Python 3.11+)でインストールできます。既存の ADK 1.x エージェントは後方互換性がありますが、高度な実装ではマイグレーションのテストが必要な場合があります。
ADK サンプルリポジトリ(github.com/google/adk-samples)には、Python・TypeScript・Go・Java にわたる 30 以上のサンプルエージェントが含まれており、シンプルな Tool Wrapper から複雑なマルチエージェントワークフローまでのパターンをカバーしています。
ドキュメント: adk.dev
GitHub リポジトリ: ADK Python | ADK Java | ADK Go | ADK TypeScript
---
## エージェントスキルからシステムへ:Google for Startups AI Agents Challenge
デモを超えて進むために、スタートアップが Gemini Enterprise Agent Platform 上で自律エージェントを構築・最適化・リファクタリングするグローバル6週間チャレンジに参加してください。
$500 のクラウドクレジット、完全なプラットフォームアクセス、そして $90,000 のプライズプールへの挑戦権が手に入ります。ADK 2.0 のオーケストレーションパターンを実践し、プロダクション対応のエージェントシステムを構築しましょう。
今すぐサインアップして構築を始めましょう!

ADKmulti-agentorchestrationagent-ops
スキルからシステムへ:ADK 2.0が実装する5つのマルチエージェント・オーケストレーションパターン
♥ 448↻ 57
原文を表示 / Show original
Google Cloud Tech
@GoogleCloudTech
From Skills to Systems: 5 Multi-Agent Orchestration Patterns in ADK 2.0
3
60
448
59K
A few weeks ago, our article on 5 Agent Skill design patterns went viral. The patterns (Tool Wrapper, Generator, Reviewer, Inversion, Pipeline) gave developers a structural vocabulary for designing agent skills. But a single skill, no matter how well-designed, only solves part of the problem.
The harder question is: how do you orchestrate multiple skills across multiple agents in a production system? How do you ensure that Agent A's output is the right format for Agent B's input? How do you enforce that certain steps always happen in a certain order while still allowing AI flexibility within each step? How do you coordinate agents written in different languages by different teams?
At Google Cloud Next 26, we launched Agent Development Kit (ADK) 2.0 that answers these questions with three core additions: graph-based workflows, collaborative agents, and a formalized Skills framework. Here are five orchestration patterns that will take you to the next level of agent architecture.
By @addyosmani and @Saboo_Shubham_
Pattern 1: The Hybrid Graph
The most common production failure in agent systems is an orchestration failure. The agent reasons correctly about each individual step but executes them in the wrong order, skips a mandatory step, or takes a path that no human reviewer anticipated.
This happens because most agent architectures encode workflow logic inside system prompts. The LLM follows the instructions faithfully for the first few turns. By turn seven, it starts taking shortcuts. By turn twelve, it's skipping steps entirely. This is a fundamental limitation of using natural language instructions to define procedural workflows. LLMs are optimizers. They're trained to produce helpful outputs efficiently. When the model looks at a five-step workflow, it often decides it can produce a more helpful response by combining steps or reordering them.
ADK 2.0's graph-based workflows solve this structurally. You define agent logic as a directed graph where nodes are actions and edges are transitions with conditional logic. The critical innovation is that you can mix deterministic nodes (hard-coded business rules) with AI-driven nodes (LLM reasoning) in the same graph.
Here's a concrete example: a loan application processing agent. Some steps must be deterministic (regulatory compliance checks, credit score thresholds, documentation requirements). Other steps benefit from AI flexibility (assessing document quality, summarizing financial profiles, generating recommendations).
python
from google.adk import Agent, Workflow, Event
from pydantic import BaseModel
# --- Schemas shared between nodes ---
class LoanApp(BaseModel):
documents: dict
credit_score: int
class DocStatus(BaseModel):
status: str
missing: list[str] = []
class CreditResult(BaseModel):
tier: str
auto_approve: bool
flag: bool = False
# --- Deterministic node: validate required documents ---
def validate_documents(node_input: LoanApp):
required = ["id_proof", "income_proof", "address_proof", "bank_statements"]
missing = [doc for doc in required if doc not in node_input.documents]
if missing:
return Event(
route="incomplete",
message=DocStatus(status="incomplete", missing=missing),
)
return Event(route="complete", message=DocStatus(status="complete"))
# --- AI-driven node: assess document quality ---
assess_quality = Agent(
name="assess_quality",
model="gemini-flash-latest",
instruction=(
"Evaluate the quality and authenticity of the provided documents. "
"Flag concerns about readability, completeness, or inconsistencies. "
"Return a short structured assessment."
),
output_schema=str,
)
# --- Deterministic node: credit score check ---
def check_credit_score(node_input: LoanApp):
score = node_input.credit_score
if score >= 750:
return CreditResult(tier="prime", auto_approve=True)
if score >= 650:
return CreditResult(tier="standard", auto_approve=False)
return CreditResult(tier="subprime", auto_approve=False, flag=True)
# --- AI-driven node: generate recommendation ---
recommendation = Agent(
name="recommendation",
model="gemini-flash-latest",
instruction=(
"Given the document assessment and credit result in context, "
"produce a loan recommendation with risk factors and suggested terms."
),
output_schema=str,
)
# --- Deterministic node: compliance check, with routing ---
MAX_LEGAL_APR = 36.0
MAX_TERM = 84
def compliance_check(node_input):
# node_input here is the recommendation text or structured object.
# In a real implementation you would parse it or pass structured data.
violations = []
# Example rule checks; wire these to your parsed recommendation fields.
# if recommendation.apr > MAX_LEGAL_APR: violations.append(...)
# if recommendation.term_months > MAX_TERM: violations.append(...)
if violations:
return Event(route="non_compliant", message={"violations": violations})
return Event(route="compliant", message={"violations": []})
def human_review(node_input):
return Event(message="Escalated to human reviewer.")
def auto_approve(node_input):
return Event(message="Auto-approved.")
def request_missing_docs(node_input: DocStatus):
return Event(message=f"Missing documents: {node_input.missing}")
# --- Assemble the workflow ---
loan_processor = Workflow(
name="loan_processor",
edges=[
("START", validate_documents),
(validate_documents, {
"complete": assess_quality,
"incomplete": request_missing_docs,
}),
(assess_quality, check_credit_score, recommendation, compliance_check),
(compliance_check, {
"compliant": auto_approve,
"non_compliant": human_review,
}),
],
)
The key difference from prompt-based orchestration: the mandatory structure is enforced by the framework. The LLM has flexibility within each node but cannot skip nodes or reorder the graph. The deterministic nodes are unit-testable with standard testing frameworks. The AI-driven nodes can be evaluated separately using Agent Simulation. And the graph structure itself is inspectable, so a compliance officer can review the workflow and verify that every required step is included and properly ordered without reading any LLM prompts.
Pattern 2: The Coordinator-Specialist
The "God agent" is the most common anti-pattern in production agent systems. One agent tries to do everything: customer support, data analysis, document generation, API integration. Its system prompt is thousands of tokens long, its tool set is enormous, and its behavior is unpredictable because the LLM is constantly deciding between dozens of possible actions.
The problem gets worse as you add capabilities. Around the fifth major addition, the system becomes unreliable. The agent uses the wrong tool for the task. It applies the customer support tone when doing data analysis. It follows financial compliance rules when answering a simple question about project timelines. The instructions compete for the model's attention, and the model starts making tradeoffs you didn't anticipate.
ADK 2.0's collaborative agents provide native support for the coordinator-specialist pattern. A coordinator agent handles task routing and workflow management. Specialist agents handle domain-specific work with focused context and tools.
python
from google.adk import Agent
# Specialists with focused responsibilities
data_analyst = Agent(
name="data_analyst",
model="gemini-flash-latest",
mode="task", # returns control automatically when done
instruction=(
"You are a data analysis specialist. You run SQL queries, produce "
"visualizations, and generate statistical summaries. Stay inside "
"data analysis. Call complete_task when the analysis is done."
),
tools=[bigquery_tool, visualization_tool, statistics_tool],
)
document_writer = Agent(
name="document_writer",
model="gemini-flash-latest",
mode="task",
instruction=(
"You are a technical document specialist. You produce reports, "
"summaries, and documentation in structured formats. You do not "
"access databases. Call complete_task when the document is ready."
),
tools=[markdown_tool, template_tool, format_tool],
)
customer_expert = Agent(
name="customer_expert",
model="gemini-flash-latest",
mode="task",
instruction=(
"You are a customer context specialist. You pull from CRM data, "
"support tickets, and communication logs to provide customer "
"insights. Call complete_task once insights are assembled."
),
tools=[salesforce_tool, zendesk_tool, email_search_tool],
)
# Coordinator: a regular Agent with sub_agents.
# ADK auto-injects request_task_<subagent_name> helpers.
coordinator = Agent(
name="project_coordinator",
model="gemini-flash-latest",
sub_agents=[data_analyst, document_writer, customer_expert],
instruction=(
"You coordinate specialists. For a single-domain request, delegate "
"to the matching specialist. For cross-domain requests, sequence the "
"specialists: gather customer context first, then data, then the "
"final report. Each subagent returns control when its task is done."
),
)
The subagent mode defines how control flows back to the coordinator. Task mode means the specialist runs until it completes its work, then automatically returns control to the coordinator, which passes the relevant output forward as context for the next specialist. The document writer does not need to re-query the database. It receives the data analyst's output as context.
Each specialist has its own identity (via Agent Identity), its own tool permissions (governed by Agent Gateway), and its own memory context. The data analyst cannot access CRM data. The customer expert cannot run SQL queries. The blast radius of any single agent's malfunction is contained to its domain.
This pattern also simplifies testing and iteration. When the data analyst's output quality degrades, you evaluate and fix that one specialist. You don’t need to retrain or re-prompt a monolithic agent. When you add a new capability (say, a competitive intelligence specialist), you register it with the coordinator and it is available immediately.
Pattern 3: Skill Composition
In our previous article, we covered five skill design patterns: Tool Wrapper, Generator, Reviewer, Inversion, and Pipeline. ADK 2.0 formalizes these with a declarative Skills framework that makes skills first-class citizens in multi-agent workflows.
The key addition is 𝚂𝚔𝚒𝚕𝚕𝚃𝚘𝚘𝚕𝚜𝚎𝚝, which lets agents load and use skills as tools. An agent does not need to know the internal implementation of a skill. It knows the skill's name, its description, and its interface. This enables composition - chaining skills together across agents in ways the original skill authors did not anticipate.
Here’s how this works in practice. Imagine you have three existing skills built by three different teams:
skills/
├── data-extractor/
│ └── SKILL.md # Pattern: Tool Wrapper (extracts data from APIs)
├── trend-analyzer/
│ └── SKILL.md # Pattern: Pipeline (multi-step trend analysis)
└── executive-summary/
└── SKILL.md # Pattern: Generator (produces formatted summaries)
A coordinator agent can compose these skills into a workflow that none of them was individually designed for:
python
import pathlib
from google.adk import Agent
from google.adk.skills import load_skill_from_dir
from google.adk.tools import skill_toolset
# Load each SKILL.md-backed skill from its directory
skills_root = pathlib.Path(__file__).parent / "skills"
data_extractor = load_skill_from_dir(skills_root / "data-extractor")
trend_analyzer = load_skill_from_dir(skills_root / "trend-analyzer")
executive_summary = load_skill_from_dir(skills_root / "executive-summary")
market_skills = skill_toolset.SkillToolset(
skills=[data_extractor, trend_analyzer, executive_summary],
)
market_intelligence = Agent(
name="market_intelligence",
model="gemini-flash-latest",
instruction=(
"You are a market intelligence agent. For a market analysis request: "
"1) use data-extractor to pull market data, "
"2) pass data to trend-analyzer for pattern identification, "
"3) use executive-summary to format findings for leadership."
),
tools=[market_skills],
)
Thanks to progressive disclosure, the agent only loads a skill's full context when it actually invokes that skill. If a user asks a simple question that does not require trend analysis, the trend-analyzer skill's instructions, references, and assets are never loaded into the context window. This keeps context token usage efficient even when an agent has access to dozens of skills.
This is the same insight that made npm, pip, and Maven successful: small, focused, composable packages with clear interfaces are more valuable than large, monolithic libraries. Individual teams build skills for their domain (data engineering builds extraction skills, analytics builds analysis skills, communications builds formatting skills). A coordinator agent assembled by the platform team can compose these into workflows that cross organizational boundaries without any of those teams needing to coordinate directly.
Pattern 4: The Cross-Language Pipeline
ADK is now available in four different languages: Python, TypeScript, Go, and Java. Each SDK has native support for the A2A (Agent-to-Agent) protocol. This means an agent written in Python can seamlessly delegate to an agent written in Go, which can delegate to an agent written in Java.
This matters in organizations where different teams use different languages. The ML team writes Python. The platform team writes Go. The enterprise integration team writes Java. The frontend team writes TypeScript. Previously, building a multi-agent workflow across these teams required custom API integrations, protocol negotiation, and data format translation. A2A standardizes all of that.
Here's what a cross-language pipeline looks like in practice:
Each agent publishes its capabilities via an Agent Card at /.𝚠𝚎𝚕𝚕-𝚔𝚗𝚘𝚠𝚗/𝚊𝚐𝚎𝚗𝚝-𝚌𝚊𝚛𝚍.𝚓𝚜𝚘𝚗. Other agents discover these capabilities automatically. The A2A protocol handles task management, status updates, and result streaming. From each agent's perspective, delegating to a remote agent in a different language feels like calling a local function.
Each SDK also brings language-specific strengths to the pipeline. ADK Go 1.0 added OpenTelemetry integration for distributed tracing across multi-agent pipelines, self-healing logic via plugins, and YAML-based agent definitions that let you manage agents declaratively (the same way you manage Kubernetes manifests or Terraform resources). The Java SDK adds event compaction for managing long conversation histories and ToolConfirmation for human-approval workflows that are critical for enterprise governance.
Pattern 5: The Sandboxed Executor
The final pattern addresses a common requirement: agents that need to execute code as part of their workflow. A data analysis agent needs to run pandas operations. A code review agent needs to execute tests. A document processing agent needs to run transformation scripts.
Running arbitrary code inside an agent is a security risk if the execution environment isn't isolated. ADK provides a managed sandbox executor that runs AI-generated code in a hosted environment with process-level isolation, and keeps variables, imported modules, and file state alive across tool calls within a session so agents can work through multi-step coding tasks without reloading state each time.
This example uses an Agent Runtime sandbox. Create one first via the Agent Engine Code Execution quickstart, then pass its resource name below.
python
from google.adk import Agent
from google.adk.code_executors import AgentEngineSandboxCodeExecutor
code_analyst = Agent(
name="code_analyst",
model="gemini-flash-latest",
code_executor=AgentEngineSandboxCodeExecutor(
sandbox_resource_name="SANDBOX_RESOURCE_NAME",
),
instruction="""You are a code analysis specialist. When reviewing code, you can:
1. Install dependencies and import libraries as needed
2. Run test snippets and static checks across multiple steps
3. Keep variables and file state across calls without reloading
4. Report findings backed by actual execution results
Your code runs in an isolated sandbox environment. You cannot
reach the host filesystem, your internal systems, or network
resources outside this environment."""
)
The sandbox boundary is the critical security property. The agent can run arbitrary Python across many steps, but that code stays inside the managed sandbox. It cannot touch your host filesystem, open connections into your internal systems, or escalate privileges. If execution goes haywire, such as an infinite loop or excessive memory use, the runtime enforces hard limits before anything leaks back to you.
This pattern is particularly powerful combined with the Pipeline skill pattern from our previous article. A documentation pipeline that needs to parse source code, generate docstrings, and assemble a final document can hand off the parsing step to a code-executing agent like the one above, rather than asking an LLM to reason about code structure. Parsing Python ASTs with actual Python is more accurate, and keeping the executor in its own agent matches how ADK expects you to compose code execution with other tools.
Choosing the right orchestration pattern
These patterns compose, just like the skill patterns from our previous article:
A Hybrid Graph can use Coordinator-Specialist at individual nodes - the graph defines the overall workflow, and specialist agents handle domain-specific nodes
A Coordinator-Specialist setup can use Skill Composition within each specialist - each specialist loads only the skills relevant to its domain
A Cross-Language Pipeline can use Sandboxed Executors at any stage - the Python agent runs ML models in a sandbox, the Go agent runs compliance checks with sandboxed test data
Any pattern can incorporate the five skill patterns (Tool Wrapper, Generator, Reviewer, Inversion, Pipeline) from our previous article at the individual skill level
Getting Started
ADK 2.0 is available now. Install with pip install google-adk --pre (Python 3.11+). Your existing ADK 1.x agents are backward compatible, though advanced implementations may need migration testing.
The ADK samples repository (github.com/google/adk-samples) includes 30+ sample agents across Python, TypeScript, Go, and Java, covering patterns from simple tool wrappers to complex multi-agent workflows.
Documentation: adk.dev
GitHub Repos: ADK Python | ADK Java | ADK Go | ADK TypeScript
🚢 From Agent Skills to Systems: Google for Startups AI Agents Challenge
Move beyond the demos by joining our 6-week global challenge for startups to build, optimize, or refactor autonomous agents on the Gemini Enterprise Agent Platform.
You'll get $500 in cloud credits, full platform access, and a shot at the $90,000 prize pool. Put these ADK 2.0 orchestration patterns into practice and build production-ready agent systems.
Sign up today to start building!
Want to publish your own Article?
Upgrade to Premium
2:28 AM · Apr 24, 2026
·
59.6K
Views
3
60
448
762