View a markdown version of this page

ターゲットベースのルーティングで A/B テストを実行する - Amazon Bedrock AgentCore

ターゲットベースのルーティングで A/B テストを実行する

テストする変更にコード変更、フレームワークのアップグレード、またはまったく異なるエージェントの実装が含まれる場合は、ターゲットベースのルーティングパターンを使用します。ターゲットベースのルーティングは、同じ AgentCore ランタイム (名前付きエンドポイント) の複数のバージョン間、またはまったく異なる AgentCore ランタイム間でトラフィックをルーティングします。AgentCore Gateway は、各エンドポイントを個別のターゲットとして登録し、A/B テストのトラフィックの重みに基づいて、各セッションを 1 つのエンドポイントまたは別のエンドポイントにルーティングします。

ターゲットベースの A/B テストのキー設定:

  • バリアント設定: AgentCore Gateway ターゲット名variantConfiguration.targetを使用

  • 評価設定: perVariantOnlineEvaluationConfig (各エンドポイントには独自のロググループがあるため、バリアントごとに 1 つのオンライン評価設定)

  • ゲートウェイフィルター: AgentCore Gateway が A/B テストインターセプトをパスするgatewayFilter.targetPathsスコープ

このチュートリアルでは、2 つのバージョンのカスタマーサポートエージェントをデプロイします。1 つは Claude Sonnet (コントロール) を使用し、もう 1 つは Claude Opus (評価) を使用します。各バージョンの名前付きエンドポイントを作成し、A/B テストを作成し、トラフィックを送信し、結果を確認して、勝者をデプロイします。

注記

このチュートリアルは、AgentCore ランタイムでホストされているエージェントを対象としています。エージェントを AgentCore ランタイム (サードパーティーまたはセルフホストエージェント - AWS Lambda など) の外部で実行する場合は、「代わりに AgentCore の外部でホストされているエージェントの A/B テストを実行する」を参照してください。

A/B テストパターンの詳細な比較については、「パターンの選択」を参照してください。

ステップ 1: プロジェクトを作成する

AgentCore CLI を使用してプロジェクトを作成します。

agentcore create --name ABTestTargetBased --no-agent cd ABTestTargetBased

ステップ 2: ランタイムを追加する

エージェントランタイムを追加します。このランタイムの 2 つのバージョンをデプロイします。1 つは制御用、もう 1 つは処理用です。次に、各バージョンにエイリアスを付ける名前付きエンドポイントを作成します。

agentcore add agent \ --name csAgent \ --language Python \ --framework Strands \ --model-provider Bedrock \ --memory none \ --build CodeZip

プロジェクト構造:

ABTestTargetBased/
├── agentcore/
│   ├── agentcore.json
│   ├── aws-targets.json
│   └── cdk/
└── app/
    └── csAgent/
        ├── main.py
        └── pyproject.toml

ステップ 3: コントロールバージョンと処理バージョンをデプロイする

をコントロールバージョンapp/csAgent/main.pyに置き換えます (Claude Sonnet を使用):

"""Customer support agent — control variant.""" from strands import Agent, tool from strands.models.bedrock import BedrockModel from bedrock_agentcore.runtime import BedrockAgentCoreApp app = BedrockAgentCoreApp() MODEL_ID = "global.anthropic.claude-sonnet-4-5-20250929-v1:0" SYSTEM_PROMPT = "You are a helpful customer support assistant for Acme Store." @tool def lookup_order(order_id: str) -> str: """Look up an order by ID.""" orders = { "ORD-1001": {"status": "delivered", "item": "Blue T-Shirt", "total": "$29.99"}, "ORD-1002": {"status": "in_transit", "item": "Running Shoes", "est_delivery": "2026-04-05"}, "ORD-1003": {"status": "delayed", "item": "Wireless Headphones", "days_late": 5}, } return str(orders.get(order_id, {"error": f"Order {order_id} not found"})) @tool def initiate_return(order_id: str, reason: str) -> str: """Initiate a return for an order.""" return f"Return initiated for {order_id}. Reason: {reason}. Return label sent to customer email." @tool def apply_discount(order_id: str, discount_percent: int, reason: str) -> str: """Apply a discount to an order.""" return f"Applied {discount_percent}% discount to {order_id}. Reason: {reason}." agent = Agent( model=BedrockModel(model_id=MODEL_ID), tools=[lookup_order, initiate_return, apply_discount], system_prompt=SYSTEM_PROMPT, ) @app.entrypoint def invoke(payload, context): result = agent(payload.get("prompt", "Hello")) return {"response": result.message["content"][0]["text"]} if __name__ == "__main__": app.run()

app/csAgent/pyproject.toml 依存関係を更新する:

dependencies = [ "aws-opentelemetry-distro", "bedrock-agentcore >= 1.8.0", "boto3", "botocore[crt] >= 1.35.0", "strands-agents[otel] >= 1.13.0", "opentelemetry-distro", "opentelemetry-instrumentation", ]

コントロールバージョンをデプロイします (これによりバージョン 1 が作成されます)。

agentcore deploy

次に、 を更新main.pyして処理バリアントに別のモデルを使用し、デプロイします (これによりバージョン 2 が作成されます)。

MODEL_ID = "global.anthropic.claude-opus-4-6-v1"
agentcore deploy

バージョンごとに名前付きエンドポイントを作成し、デプロイします。

agentcore add runtime-endpoint \ --runtime csAgent \ --endpoint control \ --version 1 \ --description "Control variant — Claude Sonnet" agentcore add runtime-endpoint \ --runtime csAgent \ --endpoint treatment \ --version 2 \ --description "Treatment variant — Claude Opus" agentcore deploy

これで、次のことができるようになりました。

  • ランタイムエンドポイント control — Claude Sonnet でバージョン 1 を提供します。

  • ランタイムエンドポイント treatment — Claude Opus でバージョン 2 を提供します。

ランタイムが動作していることを確認します。

agentcore invoke --runtime csAgent --prompt "What is the status of order ORD-1003?"

これで、次のことができるようになりました。

  • ランタイムエンドポイント control — Claude Sonnet でバージョン 1 を提供します。

  • ランタイムエンドポイント treatment — Claude Opus でバージョン 2 を提供します。

ステップ 4: オンライン評価設定を作成する

各エンドポイントには独自のロググループ (ロググループ名はエンドポイント名で終わる) があるため、バリアントごとに 1 つのオンライン評価設定が必要です。

agentcore add online-eval \ --name controlEvalTb \ --runtime csAgent \ --endpoint control \ --evaluator "Builtin.Helpfulness" \ --sampling-rate 100.0 \ --enable-on-create agentcore add online-eval \ --name treatmentEvalTb \ --runtime csAgent \ --endpoint treatment \ --evaluator "Builtin.Helpfulness" \ --sampling-rate 100.0 \ --enable-on-create agentcore deploy

各デプロイの後、オンライン評価設定 ARN を書き留めます。A/B テストを作成するときに両方が必要になります。

評価者のオプションと設定の詳細については、「オンライン評価の作成」を参照してください。

ステップ 5: ゲートウェイとターゲットを作成する

ターゲットベースの A/B テストは AgentCore Gateway を介してトラフィックをルーティングするため、テストを開始する前にゲートウェイとその 2 つのターゲットがすでにデプロイされている必要があります。ゲートウェイを追加して各ランタイムエンドポイントをhttp-runtimeターゲットとして登録し、以下をデプロイします。

agentcore add gateway --name csGateway agentcore add gateway-target \ --name customer-support-control \ --gateway csGateway \ --type http-runtime \ --runtime csAgent \ --runtime-endpoint control agentcore add gateway-target \ --name customer-support-treatment \ --gateway csGateway \ --type http-runtime \ --runtime csAgent \ --runtime-endpoint treatment agentcore deploy

ステップ 6: A/B テストを作成する

で A/B テストを開始しますagentcore run ab-test。各バリアントは、作成したゲートウェイターゲットの 1 つを参照し、独自のオンライン評価設定があります。コマンドは、既にデプロイされているゲートウェイに対して、サービスで直接テストを開始します。

AgentCore CLI
agentcore run ab-test \ --mode target-based \ --name customerSupportTargetTest \ --gateway csGateway \ --runtime csAgent \ --control-target customer-support-control \ --treatment-target customer-support-treatment \ --control-online-eval controlEvalTb \ --treatment-online-eval treatmentEvalTb \ --control-weight 80 \ --treatment-weight 20

コマンドが戻るとすぐに、テストは RUNNING になります。を渡--disable-on-createして、停止した を作成します。--gateway フラグは必須であり、ステップ 5 でデプロイしたゲートウェイを参照する必要があります。ゲートウェイごとに一度に実行できるテストは 1 つだけです。コマンドはテストのジョブ ID を出力します。これは idフィールド--jsonとして からも使用できます。以下のライフサイクルコマンドには、この ID が必要です。

AWS SDK (boto3)
import boto3 import uuid REGION = "us-west-2" ACCOUNT_ID = "123456789012" # Runtime ARNs from Step 2 deployment output CONTROL_RUNTIME_ARN = f"arn:aws:bedrock-agentcore:{REGION}:{ACCOUNT_ID}:runtime/ABTestTargetBased_CustomerSupportControl-abc123" TREATMENT_RUNTIME_ARN = f"arn:aws:bedrock-agentcore:{REGION}:{ACCOUNT_ID}:runtime/ABTestTargetBased_CustomerSupportTreatment-def456" # Online evaluation config ARNs from Step 3 CONTROL_EVAL_ARN = f"arn:aws:bedrock-agentcore:{REGION}:{ACCOUNT_ID}:online-evaluation-config/controlEvalTb-abc123" TREATMENT_EVAL_ARN = f"arn:aws:bedrock-agentcore:{REGION}:{ACCOUNT_ID}:online-evaluation-config/treatmentEvalTb-def456" # IAM roles GATEWAY_ROLE_ARN = f"arn:aws:iam::{ACCOUNT_ID}:role/AgentCoreGatewayRole" AB_TEST_ROLE_ARN = f"arn:aws:iam::{ACCOUNT_ID}:role/ABTestRole" cp_client = boto3.client("bedrock-agentcore-control", region_name=REGION) dp_client = boto3.client("bedrock-agentcore", region_name=REGION) # 1. Create an AgentCore Gateway gateway_response = cp_client.create_gateway( name="customerSupportTargetTest-gw", roleArn=GATEWAY_ROLE_ARN, authorizerType="AWS_IAM", clientToken=str(uuid.uuid4()), ) gateway_id = gateway_response["gatewayId"] gateway_arn = gateway_response["gatewayArn"] print(f"Created AgentCore Gateway: {gateway_id}") # 2. Add control runtime as an AgentCore Gateway target cp_client.create_gateway_target( gatewayIdentifier=gateway_id, name="customer-support-control", targetConfiguration={ "http": { "agentcoreRuntime": { "arn": CONTROL_RUNTIME_ARN, "qualifier": "DEFAULT" } } }, clientToken=str(uuid.uuid4()), ) print("Added target: customer-support-control") # 3. Add treatment runtime as an AgentCore Gateway target cp_client.create_gateway_target( gatewayIdentifier=gateway_id, name="customer-support-treatment", targetConfiguration={ "http": { "agentcoreRuntime": { "arn": TREATMENT_RUNTIME_ARN, "qualifier": "DEFAULT" } } }, clientToken=str(uuid.uuid4()), ) print("Added target: customer-support-treatment") # 4. Create the A/B test response = dp_client.create_ab_test( name="customerSupportTargetTest", gatewayArn=gateway_arn, roleArn=AB_TEST_ROLE_ARN, evaluationConfig={ "perVariantOnlineEvaluationConfig": [ {"name": "C", "onlineEvaluationConfigArn": CONTROL_EVAL_ARN}, {"name": "T1", "onlineEvaluationConfigArn": TREATMENT_EVAL_ARN} ] }, gatewayFilter={ "targetPaths": ["/customer-support-control/*"] }, variants=[ { "name": "C", "weight": 80, "variantConfiguration": { "target": {"name": "customer-support-control"} } }, { "name": "T1", "weight": 20, "variantConfiguration": { "target": {"name": "customer-support-treatment"} } } ], enableOnCreate=True, clientToken=str(uuid.uuid4()), ) ab_test_id = response["abTestId"] print(f"Created A/B test: {ab_test_id}") print(f"Status: {response['status']}") print(f"Execution status: {response['executionStatus']}")

ステップ 7: AgentCore Gateway 経由でトラフィックを送信する

A/B テストが実行されたら、AgentCore Gateway HTTP エンドポイントを介してトラフィックを送信します。AgentCore Gateway は、ランタイムセッション ID に基づいて各リクエストをバリアント (コントロールまたは処理) に割り当てます。

バリアント割り当ての仕組み

AgentCore Gateway は X-Amzn-Bedrock-AgentCore-Runtime-Session-Idヘッダーを使用して、トラフィックをルーティングするターゲットを決定します。このヘッダーはオプションです。指定しない場合、ランタイムはセッション ID を自動的に生成します。次に、AgentCore Gateway はセッション ID (指定したかランタイムで生成されたかにかかわらず) を使用して、設定されたトラフィックの重みに基づいてリクエストをバリアントに割り当てます。

セッション割り当てはスティッキーです。セッション ID がバリアントに割り当てられると、同じセッション ID を持つ後続のすべてのリクエストは同じターゲットにルーティングされます。これにより、トラフィックの分割に応じてバリアント間で新しいセッションを分散しながら、セッション内で一貫したエクスペリエンスを確保できます。

テスト用のトラフィックを生成する

次のスクリプトを として保存しloadgen.sh<gateway-id>と をデプロイ出力の値<target-name>に置き換えます。から完全な呼び出し URL をコピーすることもできますagentcore view ab-test <ab-test-id>

#!/bin/bash export AWS_ACCESS_KEY_ID=$(aws configure get aws_access_key_id) export AWS_SECRET_ACCESS_KEY=$(aws configure get aws_secret_access_key) export AWS_SESSION_TOKEN=$(aws configure get aws_session_token) GATEWAY_URL="https://<gateway-id>.gateway.bedrock-agentcore.us-west-2.amazonaws.com/<target-name>/invocations" PROMPTS=( "What is the status of order ORD-1003?" "I want to return order ORD-1001, it doesn't fit." "My order ORD-1003 is late. Can I get a discount?" "Where is my order ORD-1002?" "I need help with a return for order ORD-1001. The color is wrong." "Can you check on order ORD-1003? I've been waiting forever." "I'd like to cancel order ORD-1002 if it hasn't shipped yet." "Order ORD-1003 is delayed again. This is unacceptable." "What's your return policy for order ORD-1001?" "My headphones order ORD-1003 still hasn't arrived. What can you do?" ) for i in $(seq 1 30); do PROMPT="${PROMPTS[$(( (i - 1) % ${#PROMPTS[@]} ))]}" echo "=== Request $i: $PROMPT ===" curl -s --aws-sigv4 "aws:amz:us-west-2:bedrock-agentcore" \ --user "$AWS_ACCESS_KEY_ID:$AWS_SECRET_ACCESS_KEY" \ -H "x-amz-security-token: $AWS_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -H "X-Amzn-Bedrock-AgentCore-Runtime-Session-Id: $(uuidgen)" \ -d "{\"prompt\": \"$PROMPT\"}" \ -X POST \ "$GATEWAY_URL" echo "" sleep 2 done

スクリプトを実行します。

bash loadgen.sh

ステップ 8: 結果を取得する

A/B テストをポーリングして、サンプルサイズの増加に応じて結果をモニタリングします。ポーリングは統計的有効性には影響しません。

AgentCore CLI

現在の結果を取得します ( をステップ 6 のジョブ ID <ab-test-id>に置き換えます)。

agentcore view ab-test <ab-test-id>

結果を JSON として取得します。

agentcore view ab-test <ab-test-id> --json
AWS SDK (boto3)

結果が統計的有意性に達するまでポーリングします。

import boto3 import time client = boto3.client("bedrock-agentcore", region_name="us-west-2") ab_test_id = "customerSupportTargetTest-Ab1Cd2Ef3G" while True: response = client.get_ab_test(abTestId=ab_test_id) status = response["status"] exec_status = response["executionStatus"] print(f"Status: {status}, Execution: {exec_status}") results = response.get("results") if results: print(f"Analysis timestamp: {results.get('analysisTimestamp')}") for metric in results["evaluatorMetrics"]: evaluator = metric["evaluatorArn"] control = metric["controlStats"] print(f"\nEvaluator: {evaluator}") print(f" Control: mean={control['mean']:.3f}, n={control['sampleSize']}") for variant in metric["variantResults"]: print(f" {variant['variantName']}: mean={variant['mean']:.3f}, " f"n={variant['sampleSize']}, " f"pValue={variant.get('pValue', 'N/A')}, " f"significant={variant['isSignificant']}") if variant["isSignificant"]: print(f" >>> Statistically significant! " f"Change: {variant.get('percentChange', 0):.1f}%") # Check if any evaluator has reached significance all_significant = all( variant["isSignificant"] for metric in results["evaluatorMetrics"] for variant in metric["variantResults"] ) if all_significant: print("\nAll evaluators have reached statistical significance.") break time.sleep(300) # Poll every 5 minutes
注記

結果が表示されるまでにかかる時間は、主にオンライン評価設定で設定されたセッションタイムアウトによって異なります。タイムアウトウィンドウ内に新しいリクエストが到着しない場合、セッションは完了したと見なされます。セッションが終了すると、通常 15 分以内に結果が表示されます。結果は、より多くのセッションが完了すると蓄積されます。統計的有意性はサンプルサイズとともに向上します。

結果の解釈
  • p 値 < 0.05 および正 percentChange: 処理はコントロールよりも大幅に優れています。処理のデプロイを検討してください。

  • p 値 < 0.05 および負 percentChange: 処理が著しく悪化しています。コントロールを維持します。

  • p 値 >= 0.05: 差を結論付けるのに十分な証拠がありません。サンプルの収集を継続するか、処理へのトラフィックを増やします。

  • すべての評価者をチェックする: 処理によって、あるメトリクスが改善し、別のメトリクスが後退する可能性があります。決定する前に、すべての評価者の結果を確認してください。

ステップ 9: 結果を確認し、A/B テストを停止する

A/B テストが統計的有意性に達したら、結果を確認して実験を停止します。

  1. 重要度を確認します。ターゲットエバリュエーターに isSignificant: trueがあり、処理バリアントpercentChangeが陽性であることを確認します (または、処理が回復した場合はコントロールが勝者であることを確認します)。

  2. A/B テストを停止します。agentcore stop ab-test -i <ab-test-id> を実行します。トラフィックルーティングはすぐに終了し、すべてのリクエストはデフォルトのターゲットに戻ります。「表示、一時停止、再開、停止」を参照してください。

ステップ 10: 勝者をデプロイする

A/B テストを停止した後、すべてのトラフィックを勝者バリアントにルーティングします。

agentcore promote ab-test -i <ab-test-id> agentcore deploy

promote は A/B テストを停止し (まだ実行されている場合)、コントロールエンドポイントを更新して処理バージョン (バージョン 1 controlからバージョン 2 への更新など)、処理エンドポイントを削除します。agentcore deploy を実行して変更を適用します。

または、次のいずれかを実行して、勝者を手動でデプロイすることもできます。

  • オプション A: AgentCore Gateway ルーティングルールを使用して、両方のターゲットから優先ターゲットにトラフィックを誘導します。

  • オプション B: AgentCore Gateway から失われたターゲットを削除し、すべてのトラフィックを勝者にルーティングします。

  • オプション C: 負けたターゲットを更新して、勝ったエンドポイントを指すようにします。

次の手順

勝者をデプロイした後:

  • A/B テストを削除してリソースをクリーンアップします。「A/B テストの削除」を参照してください。

  • 新しいベースラインをモニタリングします。オンライン評価では、成功した設定でセッションのスコアリングが続行されます。リグレッションに注意してください。

  • 次のイテレーションを開始します。成功した設定からの新しいトレースは、次のレコメンデーションサイクルの基盤を提供します。「仕組み」を参照してください。

結果について

を呼び出すとGetABTest、集約パイプラインが十分なセッションを処理すると、レスポンスに results オブジェクトが含まれます。結果には、バリアント別に分類された評価者ごとのメトリクスが含まれます。

結果構造

{ "results": { "analysisTimestamp": "2026-04-30T18:45:00Z", "evaluatorMetrics": [ { "evaluatorArn": "arn:aws:bedrock-agentcore:us-west-2:123456789012:evaluator/Builtin.Helpfulness", "controlStats": { "variantName": "C", "sampleSize": 24, "mean": 0.72 }, "variantResults": [ { "variantName": "T1", "sampleSize": 6, "mean": 0.85, "absoluteChange": 0.13, "percentChange": 18.1, "pValue": 0.032, "confidenceInterval": { "lower": 0.02, "upper": 0.24 }, "isSignificant": true } ] } ] } }

フィールドリファレンス

フィールド 説明

analysisTimestamp

サービスが最後に統計を計算したとき。

evaluatorMetrics

オンライン評価設定の評価者ごとに 1 つのエントリ。

controlStats.mean

すべてのコントロールセッションの平均評価者スコア。

controlStats.sampleSize

コントロールバリアントのスコアリングされたセッションの数。

variantResults[].mean

すべての処理セッションの平均評価者スコア。

variantResults[].sampleSize

処理バリアントのスコアリングされたセッションの数。

variantResults[].absoluteChange

処理平均とコントロール平均の差。

variantResults[].percentChange

コントロールに対する改善率 (正) または回帰率 (負)。

variantResults[].pValue

確率 観測された差は偶然によるものです。0.05 未満は統計的有意性を示します。

variantResults[].confidenceInterval

絶対変化 (lower および upper 境界) の 95% 信頼区間。

variantResults[].isSignificant

true p 値 < 0.05 とサンプルサイズで十分である場合。

トラブルシューティング

A/B テストでは、トラフィックの送信後に結果は表示されません

結果はすぐには表示されません。所要時間は、オンライン評価設定で設定されたセッションタイムアウトによって異なります。セッションは、タイムアウトウィンドウ内に新しいリクエストが到着しなかった場合にのみ完了したと見なされます。セッションが終了したら、約 15 分以内に結果が予想されます。

このウィンドウの後に結果が表示されない場合:

  • オンライン評価ロググループを確認します。オンライン評価設定は、ランタイムエージェントの出力ロググループを指す必要があります。オンライン評価設定が別のロググループ (またはランタイムからスパンを受信しないロググループ) を参照する場合、セッションはスコアリングされず、A/B テストは結果を生成しません。

  • ロググループ名を確認します。ターゲットベースのルーティングの場合、各エンドポイントには独自のロググループがあります (ロググループ名はエンドポイント名で終わります)。各オンライン評価設定が正しいエンドポイントのロググループを参照していることを確認します。

  • ランタイムがスパンを送信していることを確認します。CloudWatch Logs で、予想されるロググループを確認します。各スパンで探しているキー属性:

    • aws.agentcore.gateway.routing_experiment_arn

    • aws.agentcore.gateway.routing_experiment_variant_name (値: Cまたは T1)

    • session.id

  • CLI が作成した設定と手動設定を確認します。を使用した場合agentcore add online-eval --runtime <name>、CLI は正しいロググループを自動的に設定します。API を使用してオンライン評価設定を手動で作成した場合は、AgentCore Online Eval Config がランタイムのスパンロググループdataSourceConfig.cloudWatchLogs.logGroupNamesと一致していることを確認してください。