7月26日、Dazbo (Darren Lester)が「Building a Multi-Agent FinOps Solution with Google ADK, Levering Tools, MCP and Google-Managed Assis」と題した記事を公開した。Google ADK・MCP・BigQueryを組み合わせたマルチエージェント構成のFinOpsプラットフォーム「FinSavant」の実装詳細を掘り下げた内容で、本記事はFinSavantシリーズの第3回に相当する(第1回・第2回はそれぞれリンク先を参照)。
「モノリシックエージェント」を避ける設計判断
クラウドコスト管理(FinOps)のようなタスクは多岐にわたる。コスト分析、リソース監査、推奨事項の取得、ナレッジQ&A——これらをひとつの巨大エージェントに詰め込む設計はアンチパターンだと著者は明言する。
理由は明確だ:
- プロンプトが肥大化し、管理不能になる
- エージェントがルールを守りにくくなる
- すべてのツールにアクセスできるため、適切なツールを選びにくくなる
- 一貫性と信頼性が下がる
そこでFinSavantは5つの専門サブエージェント+1つのルートエージェントという構成を採用する。ルートエージェントが意図を解釈し、適切なサブエージェントに委譲する、いわゆるオーケストレーターパターンだ。コード全体はGitHubリポジトリ(smart-gcp-finops)で公開されている。
FinSavantのエージェント構成
各サブエージェントの役割は以下のとおり:
| エージェント名 | 役割 |
|---|---|
BillingExplorer |
BigQueryを使ったコストトレンド・SKU価格分析 |
InfrastructureAuditor |
使われていないIPや未アタッチディスクなどゾンビリソース検出 |
CloudAdvisor |
GCPのライトサイジング・最適化推奨 |
KnowledgeAssistant |
GCPアーキテクチャのベストプラクティスQ&A |
RootCauseAnalyst |
コストスパイクの根本原因分析(BigQuery+Cloud Asset Inventory) |
ルートエージェント(FinOpsCoordinator)はツールを一切持たない。その役割はルーティングのみだ。
ルートエージェントの実装:選択的ルーティングが肝
最も重要な設計ポイントは、ルートエージェントのプロンプトに書かれた選択的委譲ルールだ。
AGENT_INSTRUCTION = """
CRITICAL SELECTIVE ROUTING AND A2UI PRESERVATION RULES:
1. You MUST only delegate tasks to the specific subagent(s) directly relevant
to the user's request.
- If the user only asks about costs, spend trends, SKU prices, or budgets,
ONLY invoke BillingExplorer.
Do NOT invoke CloudAdvisor or InfrastructureAuditor.
...
2. Do NOT run a full multi-agent audit unless the user explicitly requests
a "full audit", "comprehensive review", or asks a multi-faceted question.
Keep simple queries fast and single-scoped!
"""
「コストを見せて」という問いに対して、CloudAdvisorやInfrastructureAuditorまで呼び出してしまう——そういった不必要なマルチエージェントスイープを明示的に禁止している。シンプルな問いにはシンプルな単一エージェント呼び出しで応じる設計だ。
ルートエージェントのモデルには**gemini-3.5-flash-lite**(原文記載のモデル名)を使う。ルーティング判断に重い推論は不要なため、高速・低コストなモデルで十分という判断だ。
コンテキストキャッシュで入力トークンコストを75〜90%削減
マルチターンの会話では、毎ターンごとに同一の大きなシステムプロンプトとサブエージェント定義を再パース・再トークナイズするコストがかかる。FinSavantはGeminiのネイティブコンテキストキャッシングを有効化することでこれを回避する。
app = App(
root_agent=root_agent,
name="finops_agent",
context_cache_config=ContextCacheConfig(
min_tokens=2048, # この閾値を超えるとキャッシュが発動
ttl_seconds=600, # 10分間キャッシュを保持
cache_intervals=10, # 10ターンごとに更新
),
...
)
記事によると、これにより入力トークンコストを最大75〜90%削減し、TTFT(Time to First Token)レイテンシも大幅に改善できるとしている。
コールバックとプラグインによるクロスカッティング処理
ADKにはエージェントレベルのコールバックとアプリレベルのプラグインという2種類のライフサイクルフックがある。
エージェントレベルコールバック:特定のエージェントに紐づく。たとえば
before_agent_discover_projectsはルートエージェントの実行前にCloud Billing APIを呼び出し、リンクされたGCPプロジェクト一覧をsession.state['allowed_projects']に格納する。サブエージェントはこのセッション状態を読むだけでよく、API呼び出しは重複しない。アプリレベルプラグイン(
BasePlugin):全エージェントにグローバルに適用される。FinSavantではDefensiveToolErrorPlugin(ツールエラーの防御的ハンドリング)とFinOpsTelemetryPlugin(テレメトリ収集)を登録している。
この分離設計により、セッション管理・認証・キャッシュ・エラーハンドリングといった横断的関心事を、各サブエージェントのコードから切り離して管理できる。
MCP経由のツール統合
MCP(Model Context Protocol)は、AIエージェントが外部ツールやデータソースと標準化されたインターフェースで接続するためのオープンプロトコルだ。各エージェントが個別にAPIクライアントを実装する代わりに、MCPサーバーを介してツールを宣言的に公開・利用できるため、エージェント側のコードとツール実装を疎結合に保てる。
FinSavantではmcp_config.pyでリモートMCPツールセットとOAuth2認証プロバイダーを一元管理し、BigQueryやCloud Asset Inventoryへのアクセスをエージェントロジックから抽象化している。新たなデータソースを追加する際もMCPサーバー側の定義を変更するだけでよく、各サブエージェントのコードに手を加える必要がない。
FastAPI BFFとの接続
エージェントの外側にはFastAPI製のBFF(Backend for Frontend)が置かれ、React UIとADKエージェントランタイムの間を仲介する。BFFとは、特定のフロントエンドに最適化されたAPIゲートウェイ層のことで、UIが必要とするデータ形式への変換やセッション管理をバックエンド側で集約する設計パターンだ(参考:BFF pattern)。
フロントエンドはA2UIと呼ばれるコンポーネント機構を使い、エージェントが返す構造化JSONブロック(```json+a2ui ```)を動的なダッシュボードUIとしてレンダリングする。このため、ルートエージェントのプロンプトには「サブエージェントが返したA2UIブロックを改変せずそのまま転送せよ」という指示が明示的に含まれている。BFF層がこの転送を中継することで、エージェントの出力とUIレンダリングの間に余分な変換処理が挟まらない設計になっている。
シリーズはUI構築、デプロイ、CI/CD、エージェント評価・チューニングへと続く予定だ。
詳細はBuilding a Multi-Agent FinOps Solution with Google ADK, Levering Tools, MCP and Google-Managed Assisを参照していただきたい。