使用基于目标的路由进行 A/B 测试
当您正在测试的更改涉及代码更改、框架升级或完全不同的代理实现时,请使用基于目标的路由模式。 Target-based 路由在同一 AgentCore 运行时的多个版本(命名端点)之间或完全不同的 AgentCore 运行时之间路由流量。 AgentCore 网关将每个端点注册为单独的目标,并根据 A/B 测试的流量权重将每个会话路由到一个或另一个端点。
基于目标的 A/B 测试的关键配置:
-
变体配置:
variantConfiguration.target使用 AgentCore 网关目标名称 -
评估配置:
perVariantOnlineEvaluationConfig(每个变体都有一个在线评估配置,因为每个端点都有自己的日志组) -
网关过滤器: A/B 测试截获的 AgentCore 网关路径的
gatewayFilter.targetPaths作用域
本演练部署了两个版本的客户支持代理——一个使用 Claude Sonnet(控制),另一个使用 Claude Opus(治疗)——为每个版本创建命名端点、创建 A/B 测试、发送流量、查看结果并部署获胜者。
注意
本演练适用于 AgentCore 运行时上托管的代理。如果您的代理在 AgentCore 运行时外部运行(第三方代理或自托管代理,例如在 Lamb AWS da 上),请参阅改为运行 A/B 时外部 AgentCore托管的代理运行测试。
有关 A/B 测试模式的详细比较,请参阅选择模式。
步骤 1:创建项目
使用 AgentCore CLI 创建项目:
agentcore create --name ABTestTargetBased --no-agent cd ABTestTargetBased
第 2 步:添加运行时
添加代理运行时。您将部署此运行时的两个版本(一个用于控制,一个用于治疗),然后创建命名的端点来为每个版本设置别名。
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:创建在线评估配置
每个端点都有自己的日志组(日志组名称以端点名称结尾),因此每个变体都需要一个在线评估配置:
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 网关路由流量,因此在开始测试之前,必须已经部署了网关及其两个目标。添加网关并将每个运行时端点注册为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。每个变体都引用您创建的网关目标之一,并且有自己的在线评估配置。该命令直接在服务上针对已部署的网关启动测试。
例
步骤 7:通过 AgentCore 网关发送流量
A/B 测试运行后,通过 AgentCore 网关 HTTP 端点发送流量。 AgentCore Gateway 根据运行时会话 ID 将每个请求分配给变体(对照或治疗)。
变体赋值的工作原理
AgentCore 网关使用标X-Amzn-Bedrock-AgentCore-Runtime-Session-Id头来确定要将流量路由到哪个目标。此标头是可选的,如果您不提供该标头,则运行时会自动生成会话 ID。然后, AgentCore 网关使用会话 ID(无论是您提供的,还是运行时生成的),根据您配置的流量权重将请求分配给变体。
会话分配是粘性的:将会话 ID 分配给变体后,所有具有相同会话 ID 的后续请求都会路由到同一个目标。这样可以确保在会话中获得一致的体验,同时仍能根据您的流量分配跨变体分配新会话。
生成用于测试的流量
将以下脚本另存为 loadgen.sh<gateway-id>,<target-name>用部署输出中的值替换和。您也可以从agentcore view ab-test <ab-test-id>以下地址复制完整的调用 URL:
#!/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 测试进行轮询以监控结果。轮询不影响统计的有效性。
例
注意
显示结果所需的时间主要取决于在线评估配置中配置的会话超时。如果在超时窗口内没有新的请求到达,则认为会话已完成。会话结束后,结果通常会在 15 分钟内出现。结果会随着更多会话的完成而累积——统计显著性随着样本量的增加而提高。
解析结果
-
p 值 < 0.05 且呈阳性
percentChange:治疗明显优于对照组。考虑部署治疗方案。 -
p 值 < 0.05 且为阴性
percentChange:治疗明显恶化。保持控制权。 -
p 值 >= 0.05:没有足够的证据来得出差异结论。继续收集样本或增加前往治疗的流量。
-
检查所有评估者:一种治疗可以改善一个指标,而另一个指标却倒退。在做出决定之前,请先查看所有评估者的结果。
第 9 步:确认结果并停止 A/B 测试
一旦 A/B 检验达到统计显著性,请查看结果并停止实验。
-
确认重要性。验证目标评估者对
isSignificant: true治疗变异的检测结果是否为阳性percentChange(或者如果治疗恶化,则确认对照组是赢家)。 -
停止 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 测试(如果仍在运行),更新控制端点以指向治疗版本(例如,control从版本 1 更新到版本 2),并移除治疗端点。运行agentcore deploy以应用更改。
或者,您可以通过执行以下任一操作来手动部署获胜者:
-
选项 A:使用AgentCore 网关路由规则将流量从两个目标引导到获胜目标。
-
选项 B:从 AgentCore 网关中移除失败的目标,并将所有流量路由到获胜者。
-
选项 C:更新失败的目标以指向获胜端点。
后续步骤
部署获胜者后:
了解结果
当您调用时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 } ] } ] } }
字段引用
| 字段 | 说明 |
|---|---|
|
|
服务上次计算统计数据的时间。 |
|
|
在线评估配置中每位评估者只能输入一个条目。 |
|
|
所有对照会话中评估者的平均分数。 |
|
|
对照变体的得分会话数。 |
|
|
所有治疗疗程中评估者的平均分数。 |
|
|
该治疗变体的评分疗程数。 |
|
|
治疗均值和对照均值之间的差异。 |
|
|
相对于对照组的改善百分比(正)或回归(负)。 |
|
|
概率观测到的差异是偶然造成的。低于 0.05 表示统计学显著性。 |
|
|
绝对变化( |
|
|
|
问题排查
A/B 发送流量后测试未显示任何结果
结果不会立即出现。所需时间取决于在线评估配置中配置的会话超时——只有在超时窗口内没有新的请求到达后,才会认为会话已完成。会话结束后,预计将在大约 15 分钟内获得结果。
如果在此窗口之后仍未显示结果:
-
验证在线评估日志组。在线评估配置必须指向运行时代理的输出日志组。如果在线评估配置引用了不同的日志组(或未从运行时接收跨度的日志组),则不会对会话进行评分, A/B 测试也永远不会产生结果。
-
检查日志组名称。对于基于目标的路由,每个端点都有自己的日志组(日志组名称以终端节点名称结尾)。确保每个在线评估配置都引用了正确的端点日志组。
-
确认运行时正在发出跨度。检查 CloudWatch 日志以了解预期的日志组。你要在每个跨度上寻找的关键属性:
-
aws.agentcore.gateway.routing_experiment_arn -
aws.agentcore.gateway.routing_experiment_variant_name(值:C或T1) -
session.id
-
-
验证配置 CLI-created 与手动配置。如果您使用了
agentcore add online-eval --runtime <name>,CLI 会自动配置正确的日志组。如果您通过 API 手动创建了在线评估配置,请确保 Onl AgentCore ine Eval ConfigdataSourceConfig.cloudWatchLogs.logGroupNames与运行时的跨度日志组相匹配。