はじめに
3-shakeの荒木です。今回はLLM基盤向けのAPIゲートウェイソリューションである「agentgateway」を紹介します。agentgatewayはKubernetes Gateway API実装である「kgateway」と組み合わせて使用され、Kubernetes環境におけるAIエージェントやツール向けのトラフィック管理を提供します。
Kubernetesと
LLMエージェントを取り巻く現状
LLMエージェントのエンタープライズ導入において、従来のマイクロサービスアーキテクチャとは異なる課題に直面しています。エージェント間の長寿命なステートフル通信、複数のLLMプロバイダーへの動的ルーティング、MCPやA2Aといった新しいプロトコルのサポートなど、既存のAPI GatewayやService Meshでは十分に対応できないユースケースが増えています。
同時に、KubernetesエコシステムではGateway APIの標準化が進み、従来のIngressの制約を解消する新しいトラフィック管理の仕組みが確立されました。さらに、AI/MLワークロードに特化した拡張(Gateway API Inference Extension)も進展しており、Kubernetes上でAIインフラを構築する土台が整いつつあります。
このような背景から、Kubernetes Gateway APIの実装であるkgatewayと、AIエージェント専用データプレーンであるagentgatewayを組み合わせることで、Kubernetes環境におけるLLMエージェントのトラフィック管理を実現するソリューションが登場しました。
agentgatewayの概要
agentgatewayは、AIエージェント向けに一から構築された専用データプレーンです。2025年8月にLinux Foundationに寄贈されました。
オープンソースで高可用性・高スケーラビリティを備えたエンタープライズグレードのデータプレーンであり、あらゆる環境においてエージェントやツール向けのAI接続を提供します。kgatewayをコントロールプレーンとして使用することで、Kubernetes環境においてagentgatewayプロキシを迅速に起動・管理し、そのライフサイクルを制御できます。制御プレーンは、Kubernetes Gateway APIおよびkgatewayカスタムリソースをagentgatewayデータプレーン向けのプロキシ設定に変換します。
以下のような多様なエージェント接続のユースケースをサポートしています:
- エージェント間通信(A2A)
- モデルコンテキストプロトコル(MCP)
- エージェントネイティブツールとしてのREST API
- クラウド環境およびローカル環境の大規模言語モデル(LLM)呼び出しのルーティング
- Gateway API Inference Extensionへの対応
Gateway API(kgateway+agentgateway)を利用することで、Kubernetes環境におけるAIエージェントやMCPなどの新しいプロトコルをサポート可能となります。
agentgatewayのユースケース例
1. 複数LLMプロバイダーへのルーティング
OpenAI、Anthropic、ローカルLLMなど複数のLLMプロバイダーを統合し、リクエストに応じて適切なプロバイダーにルーティングする場合:
- 使用リソース: リスナー、ルーティングルール(HTTPRoute)、バックエンド
- 設定例:
/api/openai/*へのリクエストはOpenAI APIへ、/api/anthropic/*はAnthropic APIへルーティング - ポリシー: バックエンド認証(APIキーの付与)、レート制限、タイムアウト設定
2. MCPサーバーの公開と管理
社内ツール(データベース検索、ファイル操作など)をMCPサーバーとして公開し、エージェントからアクセス可能にする場合:
- 使用リソース: リスナー、バックエンド(MCPタイプ)、ターゲット
- 設定例: 複数のMCPサーバーを単一のエンドポイントで集約し、ツール一覧を統合提供
- ポリシー: CORS設定、認証(JWTトークン検証)、リクエストヘッダー修飾
3. エージェント間通信(A2A)
複数のAIエージェントが協調してタスクを実行するマルチエージェントシステムを構築する場合:
- 使用リソース: リスナー、ルーティングルール、バックエンド、ポリシー(A2A有効化)
- 設定例: ルートエージェントが専門エージェント(調査、分析、レポート作成)にタスクを委譲
- ポリシー: A2A機能の有効化、リクエストミラーリング(監査用)、リトライ設定
本記事の例では、このA2Aをプロキシする例を示します。
Kubernetes Gateway APIとkgatewayの違い
AIエージェントゲートウェイを理解するためには、これら2つの関係性を把握することが重要です。
Kubernetes Gateway API
「Kubernetes Gateway API」は、Kubernetes SIGが策定した標準仕様です。従来のIngress APIの制約を解消し、より表現力豊かで拡張性の高いトラフィック管理を実現します。
特徴:- Kubernetesネイティブな標準API仕様
- GatewayClass、Gateway、HTTPRouteなどのリソースを定義
- ベンダー非依存で複数の実装が共存可能
- ロールベースの設定分離(インフラ管理者 vs アプリ開発者)
Gateway APIはIngressまたはAPI Gatewayをプログラムするために使用できるAPIであり、仕様にすぎません。実際のプロキシ機能は各実装(kgateway、Envoy Gateway、Kong、Istioなど)が提供します。
kgateway
kgatewayは、あらゆるクラウド環境でのAPI接続を実現するコントロールプレーンとKubernetes Gateway APIを統合した、EnvoyベースのKubernetesネイティブなAPIゲートウェイです。2025年3月4日より、CNCFのSandboxプロジェクトに認定されています。
特徴:- Gateway APIの完全実装
- Envoy(マイクロサービス向け)とagentgateway(AI向け)の両方をサポート
- Ingress、API Gateway、サービスメッシュ、AI Gatewayを統合
- Istio ambient/sidecarモードとの相互運用
kgatewayには、もう1つ「AI Gateway」という、Envoyベースのゲートウェイプロキシを用いたLLM基盤向けGateway API実装も含まれていました。しかし、この機能は非推奨となり、v2.2で削除される予定とのことです(【参考】v2.1時点でのドキュメントページに記載)。使い分けの指針:
- kgateway+Envoy: 従来のHTTP/gRPCルーティング、API管理、WAF、サービスメッシュ統合
- ●kgateway+agentgateway: AIエージェント、MCPサーバー、LLMプロバイダー統合、A2A通信
「ADK」と「A2A」
「ADK(Agent Development Kit)」は、AIエージェントの開発とデプロイを行うための柔軟でモジュール式のフレームワークです。GeminiとGoogleエコシステムに最適化されていますが、モデルに依存しない設計でSequential、Parallel、Loopなどのワークフローエージェントによる柔軟なオーケストレーションと、マルチエージェント構造をサポートします。
「A2A(Agent2Agentプロトコル」は、異なるフレームワークやベンダーで構築されたAIエージェント間のシームレスな通信と協調を可能にするオープン標準です。内部のメモリやツール、ロジックを共有せずに安全なエージェント間連携を実現できます。
Agent Cardという、Agentの能力を記述した統一フォーマットを通信開始時に提示することで、異なるエージェントフレームワーク間での相互運用性を確保します。/.well-known/agent-card.jsonというエンドポイントで共通して提供されます。
A2Aプロトコルの特殊性
A2Aプロトコルは、RESTとは根本的に異なるタスク中心のパラダイムを採用しています:
- ステートフルなタスクライフサイクル: タスクがsubmitted → working → completed/failedなどの状態遷移を行い、
contextIdで文脈を維持 - Server-Sent Eventsによるストリーミング:
message/streamメソッドが長時間接続でタスクの進捗を逐次配信 - Agent Card検出: エージェントの能力・認証方式・ストリーミング対応を
/.well-known/agent-card.jsonというエンドポイントでJSONメタデータとして公開
すべてのリクエストが単一エンドポイントに送信され、メソッド名(message/send等)はJSONボディ内で指定されます。これはURLパスでリソースを識別するRESTとは本質的に異なります。
agentgatewayに期待される機能実装
️ kgateway v2.1のagentgateway統合では、A2Aプロトコル向けの機能がまだ限定的です。
そのため、実環境で利用する際には、導入時点での状況を確認することをおすすめします。
将来実装が期待される機能
以下の機能は、agentgatewayのスタンドアロン版では利用可能ですが、kgateway統合版ではまだ実装されていません。
- A2A固有のテレメトリフィールド
A2Aプロトコル固有のメソッド名(a2a.method=message/streamなど)を自動抽出してログに記録する機能。現在はCEL式で手動設定が必要です。 - Agent Card URLの動的書き換え
ロードバランサーの背後にエージェントが配置されている場合、Agent Card内のurlフィールドを実際の公開アドレスに自動的に書き換える機能。
agentgatewayの主要リソース
kgatewayでagentgatewayを設定する際、以下のリソースを組み合わせてAIエージェント向けのトラフィック管理を実現します:
- Bind: ゲートウェイリスナーと特定のネットワークポートを関連付けるポートバインディングのセット
- Port: 特定のネットワークアドレスでリッスン。各ポートは複数のリスナーとルートを含む
- Listener: プロトコル(HTTP、HTTPS、TCP、TLS)のサポート、ホスト名マッチング、TLS設定を備えた受信リクエスト処理
- Route: 受信リクエストを適切なバックエンドに振り分けるルーティングルール(HTTPRoute、GRPCRouteなど)
- Backend: トラフィックの転送先(LLMプロバイダー、MCPサーバー、静的ホストなど)
- Policy: ヘッダー操作、リダイレクト、CORS、認証、タイムアウト、リトライなどの設定
各リソースの詳細な設定方法については、kgateway公式ドキュメントを参照してください。
kgatewayの利用方法
インストール方法はこちら(Helm)を参考にしてください。本記事の検証時点ではv2.1.1のHelm Chartでインストールを行なっています。
デプロイしたA2Aエージェントへのルーティング管理の例
ADK+A2Aエージェントをデプロイして、kgatewa+agentgatewayでルーティング管理する例を示します。
【Agent EngineのA2A対応記念】A2AリモートエージェントをAgent Engineにデプロイする
こちらは、Google CloudのAI Solutions Architectの方が公開しているA2Aに関しての記事です。ここで登場する実装例をベースにしたエージェントを利用しています。
agent_theme: 調査レポートの調査項目を選定するagent_report: 選定した項目に基づいて調査レポートを作成するagent_writer: 記事を作成するagent_reviewer: 記事をレビューする
これら4つのエージェントをGKE上にデプロイします。そのうちの1つagent_themeのコード例を示します。
from google.adk.agents.llm_agent import LlmAgent
from google.adk.a2a.utils.agent_to_a2a import to_a2a
from a2a.types import AgentCard
import os
import vertexai
project = os.getenv("GOOGLE_CLOUD_PROJECT")
location = os.getenv("GOOGLE_CLOUD_LOCATION")
staging_bucket = os.getenv("STAGING_BUCKET")
agent_url = os.getenv("APP_URL")
port = os.getenv("PORT", "8080")
vertexai.init(
project=project,
location=location,
staging_bucket=staging_bucket,
)
name = 'report_contents_agent'
instruction = '''
あなたの役割は、記事の執筆に必要な情報を収集して調査レポートにまとめる事です。
前段のエージェントは、5項目程度の調査対象トピックを指定します。
* 出力形式
日本語で出力。
調査レポートは、トピックごとに客観的情報をまとめます。各トピックについて、5文以上の長さで記述すること。
'''
description = '記事の執筆に必要な情報を収集してレポートにまとめるエージェント(レポート作成'
agent = LlmAgent(
name=name,
model='gemini-2.5-flash',
description=description,
instruction=instruction,
)
if agent_url is None:
a2a_app = to_a2a(agent, port=port)
else:
final_agent_card = AgentCard(
name=name,
url=agent_url,
description=description,
version="0.0.1",
capabilities={},
skills=[{
"description": f"{description} ¥n{instruction}",
"id": name,
"name": "model",
"tags": ["llm"]
}],
default_input_modes=["text/plain"],
default_output_modes=["text/plain"],
supports_authenticated_extended_card=False,
preferred_transport="JSONRPC",
protocol_version="0.3.0"
)
a2a_app = to_a2a(agent, agent_card=final_agent_card)A2Aエージェントのエージェントカードに記載されるurlを環境変数APP_URLで指定しています。
後述する、スタンドアロンのagentgatewayではAgentCardのURLを実際の公開エンドポイントのホスト名に書き換えてしまう機能があるため、このPythonコードの例で示すAgentCardの書き換えロジックは不要になります。
️ 今回の検証はv2.1で行なっていますが、このバージョンではurlの書き換え機能は確認できませんでした。今後のアップデートに期待しています。
具体的なADKエージェントのDockerfileとArtifact Registryへのプッシュは省略しますが、ADKはuvicornで立ち上げるfastapiサーバーとして実装されます。そのため、DockerfileのEntrypointは以下のようになります。
uvicorn main:a2a_app --host 0.0.0.0 --port $PORT以下のようなKubernetesマニフェストでデプロイできるので、これを「agents-k8s.yaml」というファイル名で保存します。
apiVersion: v1
kind: ServiceAccount
metadata:
name: adk-vertexai-user
---
# Agent Theme Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: agent-theme
labels:
app: agent-theme
spec:
replicas: 1
selector:
matchLabels:
app: agent-theme
template:
metadata:
labels:
app: agent-theme
spec:
serviceAccountName: adk-vertexai-user
containers:
- name: agent-theme
image: us-central1-docker.pkg.dev/your-project-id/a2a/agent-theme:latest
imagePullPolicy: Always
ports:
- containerPort: 8080
name: http
env:
- name: PORT
value: "8080"
- name: APP_URL
value: "http://GATEWAY_IP:8080/theme" # 外部IPが払い出されたのちに修正
- name: GOOGLE_CLOUD_PROJECT
value: "your-project-id"
- name: GOOGLE_CLOUD_LOCATION
value: "us-central1"
- name: STAGING_BUCKET
value: "gs://your-staging-bucket"
- name: GOOGLE_GENAI_USE_VERTEXAI
value: "TRUE"
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "250m"
livenessProbe:
httpGet:
path: /.well-known/agent-card.json
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
readinessProbe:
httpGet:
path: /.well-known/agent-card.json
port: 8080
initialDelaySeconds: 30
periodSeconds: 5
---
# Agent Theme Service
apiVersion: v1
kind: Service
metadata:
name: agent-theme
labels:
app: agent-theme
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
appProtocol: kgateway.dev/a2a
selector:
app: agent-theme
---
# 同様に残り3つのエージェントのDeploymentとServiceを作成1点、注意点として、ServiceのappProtocolにkgateway.dev/a2aを指定する必要があります。これにより、kgatewayとagentgatewayがA2Aプロトコルとして認識するようになります。
ADKエージェントはgeminiを利用するため、adk-vertexai-userというKubernetesサービスアカウントを作成し、適切な権限を付与します。
Workload Identity Federation for GKEを有効にしたクラスタであればKubernetesサービスアカウントに直接IAMロールをバインドすることができます。詳細はこちら。
export GOOGLE_CLOUD_PROJECT=your-project-id
export GOOGLE_CLOUD_PROJECT_NUMBER=$(gcloud projects describe ${GOOGLE_CLOUD_PROJECT} --format="value(projectNumber)")
gcloud projects add-iam-policy-binding projects/${GOOGLE_CLOUD_PROJECT} ¥
--role=roles/aiplatform.user ¥
--member=principal://iam.googleapis.com/projects/${GOOGLE_CLOUD_PROJECT_NUMBER}/locations/global/workloadIdentityPools/${GOOGLE_CLOUD_PROJECT}.svc.id.goog/subject/ns/default/sa/adk-vertexai-user ¥
--condition=None次に、GatewayClassを使用するGatewayリソースを作成します。
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: agentgateway
spec:
gatewayClassName: agentgateway
listeners:
- protocol: HTTP
port: 8080
name: http
allowedRoutes:
namespaces:
from: All最後に、HTTPRouteリソースを作成します。
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: agent-routes
spec:
parentRefs:
- name: agentgateway
namespace: default
rules:
- matches:
- path:
type: PathPrefix
value: /theme
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /
backendRefs:
- name: agent-theme
port: 80
# ...省略各エージェントを識別するためのプレフィックス(/theme、/reportなど)でルーティングを振り分けつつ、実際のバックエンドサービスにはプレフィックスを除いて送信するようにURLRewriteフィルタを使用しています。
例えば、http://<kgateway-external-ip>:8080/themeにアクセスするとagent-themeエージェントにリクエストがルーティングされます。この段階で外部IPが払い出されていることを確認して、agents-k8s.yamlのAPP_URL環境変数を修正し、設定を反映します。
kubectl apply -f agents-k8s.yamlエージェントカードを取得してみます。
export INGRESS_GW_ADDRESS=$(kubectl get gateway agentgateway -o=jsonpath="{.status.addresses[0].value}")
curl http://$INGRESS_GW_ADDRESS:8080/theme/.well-known/agent-card.jsonこのエージェントを利用してみます。検証にはa2a-inspectorを利用しました。下図のように応答が取得できます。
スタンドアロンagentgateway
kgatewayと連携することなく、主要機能をローカルで試す目的でもagentgatewayを利用できます(同一名称)。こちらを参考にインストールします。
curl https://raw.githubusercontent.com/agentgateway/agentgateway/refs/heads/main/common/scripts/get-agentgateway | bash
...
# agentgateway installed into /usr/local/bin/agentgateway
# localhost:8000で立ち上げたADKのA2Aエージェントをlocalhost:3000でバインディングしている例
cat config.yaml << EOF
config:
logging:
format: json
fields:
add:
backend: backend
binds:
- port: 3000
listeners:
- routes:
- policies:
cors:
allowOrigins:
- "*"
allowHeaders:
- "*"
a2a: {}
backends:
- host: localhost:8000
EOF
agentgateway -f config.yamlhttp://localhost:15000/uiにアクセスします。
このUIでそのままメッセージを送って検証が行えます。
kgateway+agentgatewayの同様の機能を気軽に試すことができ、Kubernetes環境にデプロイする前の設定の検証に便利です。
まとめ
本記事では、LLMエージェント向けのAPIゲートウェイソリューションであるagentgatewayと、その制御プレーンとなるkgatewayを紹介しました。v2.1時点では、kgateway+agentgateway統合の機能は限定的です。A2A/MCP固有のプロトコルレベル機能(テレメトリ自動抽出、Agent Card URL書き換えなど)は未実装であり、現時点で積極的に採用する動機は低いと言えます。
一方、スタンドアロン版のagentgatewayはこれらの機能を提供しており、ローカル開発や設定検証には有用です。GUIツールを使った迅速なプロトタイピングが可能です。
プロジェクトは活発に開発が進んでおり、以下の点で注目に値します:
- アーキテクチャの先進性: Envoy(マイクロサービス向け)とagentgateway(AIエージェント向け)を単一のKubernetes Gateway APIで統合管理
- 標準化への貢献: CNCFおよびLinux Foundation傘下でのオープンな開発
今後のバージョンアップで機能が充実すれば、エンタープライズでのLLMエージェント導入において有力な選択肢となる可能性があります。技術選定においては、プロジェクトの動向を追うことをお勧めします。
【参考】
