powered by TechFeed
表示モード
ハウツー

AIエージェントの品質劣化をPRの段階で自動検知 — GitHub ActionsとAmazon Bedrockで作る評価CI/CDパイプライン

9月9日、AWSが「Automated agent evaluation with Amazon Bedrock AgentCore and GitHub Actions」と題した記事を公開した。この記事では、Amazon Bedrock AgentCoreとGitHub ActionsでAIエージェントの評価を自動化し、品質低下をPRの段階で検知するCI/CDパイプラインの構築方法について詳しく紹介されている。以下に、その内容を紹介する。

9月9日、AWSが「Automated agent evaluation with Amazon Bedrock AgentCore and GitHub Actions」と題した記事を公開した。この記事では、Amazon Bedrock AgentCoreとGitHub ActionsでAIエージェントの評価を自動化し、品質低下をPRの段階で検知するCI/CDパイプラインの構築方法について詳しく紹介されている。以下に、その内容を紹介する。


「AIエージェントが劣化したことに誰も気づかない」問題

システムプロンプトを変更する。モデルを入れ替える。ツールの設定を更新する。こうした変更のたびにAIエージェントの品質が手動テストに委ねられているなら、問題が発覚するのはユーザーからのクレームが届いてからになりがちだ。

この記事が提案するのは、そのサイクルを断ち切るCI/CDの品質ゲートだ。PRをマージする前に、エージェントの評価スコアが閾値(例: 1.0点満点中0.8点)を下回れば自動的にブロックするという仕組みを、GitHub ActionsとAmazon Bedrock AgentCoreで実現する。


パイプラインの全体像

パイプラインは以下の流れで動く。

  1. CDKでエージェント+MCPサーバーをAgentCoreランタイムにデプロイ
  2. CognitoからM2M(machine-to-machine)トークンを取得してAPIを認証
  3. 評価用プロンプトセットでエージェントを呼び出し
  4. CloudWatchに記録されたOpenTelemetryトレースをAgentCore Evaluate APIでスコアリング
  5. スコアが閾値を満たさなければPRをブロック

AgentCoreランタイムは、AWSが「エージェント向けのAWS Lambda」と表現する管理型ホスティング基盤で、スケーリングやセッション分離をプラットフォーム側が担う。エージェントコード(Python、任意のフレームワーク)をデプロイするだけで動作する。


最大の難所:OAuth保護されたMCPサーバーをCIから呼ぶ方法

記事の核心はここだ。MCPサーバーにOAuth認証とロールベースアクセス制御(RBAC)がかかっている場合、ヘッドレスのCI実行環境はインタラクティブなOAuthフローを完了できない。この問題への対処として、記事では3つのアプローチを提示している。

アプローチA:保存済みトレースを評価する

ステージング環境でエージェントを動かしてトレースをJSONとして保存し、PR時のCIはその保存データを評価する。ライブ呼び出しもOAuth解決も不要で、最も素早く品質ゲートを立ち上げられる。ただし、現在のPRのコードではなくステージング環境の挙動を評価することになる。

アプローチB:サービスアカウント+保存済みリフレッシュトークン

テスト専用ユーザーを一度手動でOAuth認証させ、リフレッシュトークンをAWS Secrets Managerに保管する。CIはそのトークンを使って認証する。ロールのテストが必要な場合はこれが唯一の選択肢だが、トークンのローテーション管理が必要になる。

アプローチC:M2Mトークンによる認証(本記事のメインアプローチ)

CognitoのM2Mクライアント(client_credentialsフロー)を用意し、CIがロールチェックをバイパスできるようにする。MCPサーバーのミドルウェアがトークンの種類を判別し、M2Mトークンにはロールチェックを適用しない。

# M2Mトークン取得例
POST /oauth2/token
grant_type=client_credentials
client_id=<CI_CLIENT_ID>
client_secret=<CI_CLIENT_SECRET>
scope=agent/invoke

この設計のセキュリティ上のポイント:M2Mトークンの取得にはクライアントシークレットが必要で、エンドユーザーには公開されない。そのため「誰でもロールチェックを回避できる」状態にはならない。

アプローチA アプローチB アプローチC
ライブ呼び出し なし あり あり
ロールテスト 不可 可能 不可
CI決定性
適したケース クイックスタート フルE2E 内部ツール向けエージェント

AgentCore Evaluationsの評価モード

評価サービス自体は3つのモードを持つ。

  • オンデマンド評価:特定セッションをいつでも評価。スパンデータを直接API呼び出しに含めてスコアを返す。CI/CDの品質ゲートに使うのがこれ。
  • オンライン評価:本番トラフィックをサンプリングしながら継続的にモニタリング。
  • バッチ評価:CloudWatch Logsを対象に複数セッションを非同期で一括評価。

ビルトイン評価指標には、Helpfulness(有用性)、Correctness(正確性)、GoalSuccessRate、ToolSelectionAccuracy、ToolParameterAccuracy等がある。ツール呼び出し順序を検証するTrajectory系の評価指標(TrajectoryExactOrderMatch等)も備える。LLMをジャッジとして使わないコードベース評価(Lambdaで正規表現・スキーマ検証等を実行)も選択できる。

なお、1回のevaluate()呼び出しに含められるのは単一セッションのスパンのみ。複数セッションを混在させるとValidationExceptionが発生する。


MCPサーバーの3層認証実装

Approach Cを採用する場合、MCPサーバーは以下の3層で認証を処理する。

Layer 1(AgentCoreプラットフォーム):JWTの署名・発行者・有効期限を検証。実装不要。

Layer 2(ヘッダーパススルー)request_header_allowlist=["Authorization"]を設定し、JWTをコンテナまで転送する。

# infrastructure/stack.py
request_header_configuration=CfnRuntime.RequestHeaderConfigurationProperty(
    request_header_allowlist=["Authorization"]
)

Layer 3(AuthMiddleware):FastMCPのネイティブミドルウェアとして実装。JWTのcustom:rolesクレームを読んでツール単位のアクセス制御を行い、M2Mトークンにはロールチェックをスキップする。

mcp.add_middleware(AuthMiddleware())
app = mcp.http_app(stateless_http=True)

実装の起点

記事はGitHubリポジトリで参照実装一式を公開している。CDKスタック(infrastructure/stack.py)1コマンドで、CognitoプールとM2M/ユーザー両クライアント、2つのAgentCoreランタイム、テスト用ユーザー(FinanceUser/HRUser)がすべてデプロイされる。

評価スクリプトの実行にはbedrock-agentcore-starter-toolkitEvaluationクラスを使用し、CloudWatchからのトレース収集とスコアリングを自動化している。

python3 -m venv .venv && source .venv/bin/activate
pip install .
npx cdk deploy --outputs-file outputs.json

詳細はAutomated agent evaluation with Amazon Bedrock AgentCore and GitHub Actionsを参照していただきたい。