なぜ ADK Go 2.0 なのか? — エージェントオーケストレーションの新しい考え方
プロダクションで動作するエージェントアプリケーションは、単一のプロンプトで完結することはほとんどありません。ユーザーリクエストを分類(Classify)し、条件に応じて分岐(Branch)し、複数の専門エージェントに処理を分散(Fan-out)させ、結果を収集(Fan-in)する必要があります。さらに、人間の承認(Human-in-the-Loop)を必要としたり、失敗時のリトライ(Retry)やループ(Loop)も発生します。
このような複雑なオーケストレーションをアドホックな制御フローで実装すると、すぐにメンテナンスが困難になります。ADK Go 2.0 は、この問題を「グラフ(Graph)」という概念でエレガントに解決します。ノード(Node)とエッジ(Edge)でエージェントの動作フローを宣言的に記述し、スケジューラが並行実行、状態保存、一時停止・再開を処理します。
📌 コア哲学:「グラフ自体が一つのエージェントである」 — ADK 2.0 ではワークフローが
agent.Agentインターフェースを実装するため、従来のシングルエージェントを実行していたランナー、ランチャー、コンソールをそのまま流用できます。
本記事では、ADK Go 2.0 の主要機能を解説し、日本の開発現場での実践的な活用方法を考察します。
(根拠資料:Google 公式ブログ)

グラフベースのワークフロー:コードで見る核心
最も基本的な順次(sequential)ワークフローから見ていきましょう。2つの関数ノードをチェーンで接続する例です。
import "google.golang.org/adk/v2/workflow"
// ノード作成:文字列を処理する関数
upper := workflow.NewFunctionNode("upper", upperFn, cfg)
suffix := workflow.NewFunctionNode("suffix", suffixFn, cfg)
// エッジ接続:Start -> upper -> suffix
edges := workflow.Chain(workflow.Start, upper, suffix)
// ワークフローエージェント作成
wf, _ := workflowagent.New(workflowagent.Config{
Name: "simple_sequence_workflow",
Edges: edges,
})
// wf は agent.Agent インターフェースを実装 → 既存ランナーで実行可能
ルーティング(Routing)— 条件分岐
エッジにルーティング条件を追加すると、ノードの出力値に応じて次に実行するノードが決定します。
b := workflow.NewEdgeBuilder()
b.AddRoutes(router, map[string]workflow.Node{
"question": answerNode,
"statement": commentNode,
"exclamation": reactNode,
})
b.AddFanOut(planner, researchA, researchB, researchC) // 並列分岐
b.AddFanIn(join, researchA, researchB, researchC) // 結果収集
動的ノード(Dynamic Node)— ランタイムオーケストレーション
実行順序をランタイムに決定する必要がある場合は動的ノードを使用します。通常の Go コードで子ノードを直接呼び出します。
greeter := workflow.NewDynamicNode("greeter_workflow",
func(nc agent.Context, in string, emit func(*session.Event) error) (Result, error) {
// 通常の Go コードで子ノード実行
return workflow.RunNode[string](nc, greeterNode, in)
},
workflow.NodeConfig{},
)
ヒューマン・イン・ザ・ループ(HITL)— 人間の介入
event := workflow.NewRequestInputEvent(ctx, session.RequestInput{
InterruptID: "approve_refund",
Message: "返金 $200 を承認しますか? (yes/no)",
ResponseSchema: schema,
})
// イベントを発行 → ノードは 'waiting' 状態に遷移
// ユーザーが応答すると ctx.ResumedInput(...) で再開
HITL はプロセス再起動後も永続(durable)します。セッションヒストリーをスキャンして中断されたワークフローを復元できます。

主要機能比較と注意点
ADK Go 2.0 vs 1.0 の主要な変更点
| 項目 | ADK Go 1.0 | ADK Go 2.0 |
|---|---|---|
| オーケストレーション | アドホックな制御フロー | グラフベース宣言的ワークフロー |
| エージェント合成 | 限定的 | グラフ = エージェント(同一インターフェース) |
| ヒューマン・イン・ザ・ループ | なし | 組み込み、durable な一時停止/再開 |
| LLM モード | 単一モード | Chat, Task, SingleTurn |
| コンテキスト型 | InvocationContext, ToolContext, CallbackContext | 単一 agent.Context に統合 |
| リトライポリシー | なし | 指数バックオフ + ジッター内蔵 |
| 並列処理 | なし | Fan-out/Fan-in, MaxConcurrency 制御 |
⚠️ 注意点と制限
- 学習曲線: グラフベースの思考法に慣れる必要があります。単純なリクエスト-レスポンスパターンに過剰に適用すると、むしろ複雑さが増す可能性があります。
- デバッグの複雑さ: 複数のノードが同時実行されたり、状態が遷移する過程の追跡が難しい場合があります。ADK の統合テレメトリー(スパンツリー)を積極的に活用しましょう。
- セッション状態のサイズ: durable HITL のために全てのイベントがセッションに保存されます。長時間実行ワークフローの場合、セッションサイズが大きくなる可能性があるため、定期的なクリーンアップ戦略が必要です。
- Go バージョン依存: ADK 2.0 は Go 1.22 以上を推奨します。
iter.Seq2などの最新機能を使用するため、レガシープロジェクトではアップグレードが必要になる場合があります。
日本開発コミュニティでの適用コンテキスト
- 金融/Fintech: 顧客相談チャットボットで、返金やローン承認など人間の承認が必要な工程を HITL で安全に処理できます。
- ECサイト: 注文処理パイプライン(在庫確認 → 決済 → 配送)をグラフでモデリングし、各工程の失敗時リトライや例外処理を明確に設計できます。
- SI案件: 複雑な業務ロジック(例:保険請求処理)をノード単位に分割することで、各ノードを独立に開発/テストでき、保守性が大幅に向上します。
💡 実践的なヒント: 導入初期は全体をグラフ化するのではなく、最も複雑な単一業務(例:「注文キャンセルワークフロー」)からグラフにリファクタリングしてみてください。ADK 1.0 と 2.0 は同一ランタイムで動作するため、段階的な移行が可能です。

まとめ:Go エージェント開発の新しいスタンダード
ADK Go 2.0 は単なるアップデートではありません。Go エコシステムにおけるエージェントアプリケーションの構築方法そのものを変える重要なリリースです。グラフベースのワークフローは複雑なオーケストレーションを宣言的かつ保守可能にし、HITL、リトライ、並列処理といった実践的な要求をフレームワークレベルでサポートします。
特に印象的なのは「グラフ自体がエージェントである」という設計哲学です。これにより、既存のシングルエージェントコードとの完全な互換性を保ちながら、段階的な導入が可能です。Python ADK 2.0 とも割り込み(interrupt)フォーマットを共有しているため、マルチ言語環境でも一貫したワークフローを構築できます。
次のステップとしての学習方向
- 公式サンプルの実行:
go run ./examples/workflow/basic/から始めて、ルーティング、HITL、複合グラフのサンプルを順に実行してみてください。 - マイグレーションガイドの確認: ADK 1.0 ユーザーは 公式マイグレーションガイド で
InvocationContext→agent.Context変更などの主要な変更点を確認してください。 - 独自ワークフローの設計: 現在運用中のサービスで最も複雑なプロセスを一つ選び、グラフでモデリングしてみることをお勧めします。