跳到正文
AWS Machine Learning Blog· Aswath Ram A Srinivasan·· 3 小时前AI 评分34

在 Amazon Bedrock 上用 NVIDIA NeMo Switchyard 为编码智能体请求路由到合适的模型

Route coding agent requests to the right model on Amazon Bedrock with NVIDIA NeMo Switchyard

AI 导读

NVIDIA NeMo Switchyard 是一个开源库,可让 AI 智能体为每个请求选择由哪个模型处理,其 LiteLLM 集成支持 Stage 和 Random 两种路由策略。

正文 · AI 翻译

像 Claude Code 和 OpenAI Codex CLI 这样的编码代理在任务中工作。开发者提出一项更改,代理会读取文件、编辑代码并运行测试,直到工作完成。一个任务可能需要几次模型调用,也可能需要几十次。开发者付费的是任务,而不是单次调用。

仅凭每 token 的价格无法告诉你整个任务的成本。总成本取决于模型需要多少轮、每轮重放多少历史记录,以及任务需要重试或永远无法完成的频率。你为每一次尝试付费,包括那些永远无法完成的任务的尝试。因此,当你在模型之间路由编码代理的请求时,应以每个已解决任务的成本来评判路由:即你所有运行的总成本除以测试通过的运行次数。

NVIDIA NeMo Switchyard 是一个开源库,可帮助 AI 代理为每个请求选择由哪个模型处理。你定义它可以使用的模型以及它遵循的策略。其 LiteLLM 集成 支持两种策略。阶段路由会读取请求历史中最近的工具活动和结果,然后从两个候选模型中选择一个。随机路由从配置的模型中选取,可带权重,用于流量拆分和 A/B 对比。你还可以探索的另一个选项是 LiteLLM,它最近也发布了一个原生内置的 Switchyard 阶段路由器,作为自动路由策略。

在本文中,你使用 AWS Cloud Development Kit (AWS CDK) 在你的 AWS 账户中部署 LiteLLM(一个用于大型语言模型 (LLM) 的开源网关)以及 Switchyard 路由插件。LiteLLM 调用 Amazon Bedrock 上的模型。然后,你使用示例的基准运行器来测量路由模型组和单模型基线组的每个已解决任务成本,以便针对你自己的负载评估路由。

注意: 该示例从 crates.io 安装 switchyard-server 0.3.0,并运行已发布的 LiteLLM v1.102.0 镜像。NVIDIA 将 switchyard-server 0.3.0 记录为演示和评估组件,其配置可能在不同版本之间发生变化。本示例使用实验性的 Switchyard LiteLLM 集成,其配置和 API 可能在不同版本之间发生变化。这是示例代码,供非生产用途使用。在部署前,请与你的安全和法务团队合作,以满足你组织的安全、监管和合规要求。请在生产环境之外的账户中部署该示例,并在依赖它之前进行测试。

解决方案概述

图 1 展示了该解决方案的架构。LiteLLM 和 Switchyard 插件在一个容器镜像中运行,位于私有子网中的 Amazon Elastic Container Service (Amazon ECS) on AWS Fargate 上。

Architecture showing coding agents reaching an Application Load Balancer that routes to LiteLLM and Switchyard on Amazon ECS Fargate, which calls models on Amazon Bedrock

图 1:解决方案架构

请求按以下步骤流转。编号与图中一致。

  1. 编码代理发送一个 OpenAI 兼容请求,其中 model 字段设置为 switchyard(即 Switchyard 路由的 LiteLLM 模型组),并在 Authorization 标头中携带共享网关密钥。端点是你的 HTTPS 主机名,负载均衡器上带有 AWS Certificate Manager (ACM) 证书,并且只有你允许的 IPv4 CIDR 范围可以访问它。如果 Amazon Route 53 中有托管区域,Route 53 会将主机名解析到负载均衡器。
  2. AWS WAF通过 IP 信誉、已知恶意输入和按 IP 的速率限制规则过滤请求。Application Load Balancer 仅将 /v1/chat/completions、/v1/models 和 /health/liveliness 转发到私有子网中的 ECS 任务,对其他所有路径返回 404。
  3. 该任务运行一个容器:带有嵌入式 Switchyard 插件的 LiteLLM。LiteLLM 验证网关密钥并调用插件来选择模型。Stage 在能力强的模型和成本更低的高效模型之间进行选择。它会读取请求历史中的工具活动和结果,因此代理必须发送完整的对话历史。Random 从加权池中进行选择。两种策略都不会调用评判模型。
  4. LiteLLM 通过 Amazon Bedrock Converse 或 ConverseStream API 调用所选模型,并使用任务的 AWS Identity and Access Management (IAM) 角色获取凭证。该调用经由 Amazon Virtual Private Cloud (Amazon VPC) 中的 Amazon Bedrock Runtime 接口端点进行,因此推理流量保留在 AWS 网络内。
  5. 响应或令牌流经 LiteLLM 和负载均衡器返回。x-litellm-model-name 响应头指明应答的模型。响应体中的 model 字段保持为 switchyard。

LiteLLM 在容器中监听端口 4000,是负载均衡器的目标,任务的安全组仅允许负载均衡器访问。路径允许列表使 LiteLLM 管理 UI、API 文档和密钥管理路由不可达。Amazon Elastic Container Registry (Amazon ECR) 存放网关镜像。AWS Secrets Manager 生成网关密钥背后的密钥,容器在启动时添加 sk- 前缀。任务定义传入 LITELLM_CONFIG_TEXT 和 SWITCHYARD_CONFIG_TEXT 中的配置文件,启动脚本在启动 LiteLLM 之前将它们写入 /tmp。日志发送到一个 Amazon CloudWatch 日志组 /<stack name>/litellm,保留 30 天,Container Insights 收集指标。VPC 跨越两个可用区,一个 NAT 网关为镜像拉取和其他 AWS 服务提供出站访问。

该插件支持 Stage 路由(需要恰好两个候选模型)和 Random 路由(需要至少两个,并按权重拆分流量以进行 A/B 测试)。基于分类器的策略(例如 Task 和 Composite 路由)需要中间模型调用,而此集成不支持。有关完整目录,请参阅 Switchyard 路由概览。

先决条件

要完成本演练,您需要以下内容:

  • 一个非生产 AWS 账户,具有对 Claude Opus 5.5 和 NVIDIA Nemotron 3 Super 120B 的 Amazon Bedrock 访问权限。该组合已在美国东部(弗吉尼亚北部)测试。对于其他 AWS 区域,请查看 按模型的区域可用性 和工具调用支持。
  • 已配置凭证并显式指定 AWS 区域的 AWS Command Line Interface (AWS CLI) v2,且所在账户和区域已为 AWS CDK 完成引导。
  • Node.js 20 或更高版本、npm、带 BuildKit 的 Docker,以及 Python 3.11 或更高版本。
  • 您拥有的主机名,以及其域名的公有 Route 53 托管区,或部署区域中该主机名的 ACM 证书。简短的纯 HTTP 测试两者都不需要。

演练

您将定义模型组、配置 Stage、部署并测试网关,并衡量成本。首先克隆示例仓库:

git clone https://github.com/aws-samples/sample-route-coding-agent-requests-Amazon-Bedrock-nemo-switchyard.git
cd sample-route-coding-agent-requests-Amazon-Bedrock-nemo-switchyard

步骤 1:在 LiteLLM 中定义模型组

LiteLLM 模型组是一个公开的模型名称,其背后有一个或多个部署。示例将配置保存在 profiles/ 下的部署配置文件中。每个配置文件将 litellm.yaml(定义模型和网关设置)与 switchyard.toml(控制 Switchyard 如何选择模型)配对。以下 profiles/stage/litellm.yaml 的摘录定义了路由的 switchyard 组、两个单模型基线组以及插件注册:

model_list:
  - model_name: switchyard
    litellm_params:
      model: bedrock/converse/global.anthropic.claude-opus-5-5
      aws_region_name: os.environ/AWS_REGION
  - model_name: switchyard
    litellm_params:
      model: bedrock/converse/nvidia.nemotron-super-3-120b
      aws_region_name: os.environ/AWS_REGION
  # One-model baseline groups, same model strings as the routed candidates.
  - model_name: claude-opus-5-5
    litellm_params:
      model: bedrock/converse/global.anthropic.claude-opus-5-5
      aws_region_name: os.environ/AWS_REGION
  - model_name: nemotron-super-3-120b
    litellm_params:
      model: bedrock/converse/nvidia.nemotron-super-3-120b
      aws_region_name: os.environ/AWS_REGION

# The same object selects a deployment and applies supported request changes.
router_settings:
  plugins:
    - switchyard_gateway.configured.ROUTING_PLUGIN
litellm_settings:
  callbacks:
    - switchyard_gateway.configured.ROUTING_PLUGIN
  drop_params: true
  request_timeout: 600
  num_retries: 2
general_settings:
  master_key: os.environ/LITELLM_MASTER_KEY

两个候选模型共享 model_name: switchyard,因此你的客户端发送 "model": "switchyard",Switchyard 选择一个候选模型。将能力强的模型列在前面,高效的模型列在后面,因为 Stage 会按此顺序读取角色。

claude-opus-5-5 和 nemotron-super-3-120b 组是单模型基线。每个组始终用自己的模型作答,因此你可以在同一部署中比较路由组的成本与通过率与单独使用每个模型的情况。仅 Stage 插件会拒绝没有两个候选模型的组,因此镜像注册了一个小型包装器 switchyard_gateway.configured.ROUTING_PLUGIN。它将 Switchyard 应用于具有两个或更多唯一候选模型的组,并让单模型组直接通过。配置将包装器注册两次:一次用于选择模型,一次用于应用 Switchyard 记录的请求更改。

每个模型都使用 bedrock/converse/<id>,因此每个候选模型都通过 Amazon Bedrock Converse API,验证会拒绝任何其他路由。LiteLLM 的 request_timeout 为 600 秒,与负载均衡器的 10 分钟空闲超时相匹配。

该文件不包含凭证。LiteLLM 从环境读取网关密钥,任务角色提供 AWS 凭证。切勿在 litellm_params 下添加诸如 aws_access_key_id、aws_secret_access_key 或 api_key 之类的凭证:堆栈会将整个 litellm.yaml 以明文复制到任务定义和 AWS CloudFormation 模板中。

堆栈从此文件派生任务角色的 Amazon Bedrock 权限。对于全球跨区域推理配置文件,基础模型资源使用 * 区域和末尾的 *,因此它也会匹配具有相同前缀的其他模型 ID。部署前请审查派生出的策略。

global. 前缀标记一个全球跨区域推理配置文件,Amazon Bedrock 可能会在全球受支持的商业 AWS 区域处理这些请求。如果处理位置很重要,请改用地理配置文件或区域内模型 ID。对于 Nemotron 3 Super,配置文件使用区域内模型 ID nvidia.nemotron-super-3-120b,你可以将其替换为任何模型进行测试。

步骤 2:配置 Stage 路由

Switchyard 从 switchyard.toml 读取其算法和设置。默认配置文件 profiles/stage/switchyard.toml 配置 Stage:

# Model inventory is in litellm.yaml. This file configures selection behavior.
algorithm = "stage"
# Prefer the efficient candidate when history signals are inconclusive.
picker = "efficient_first"
confidence_threshold = 0.5
# Inspect the three most recent tool results for execution signals.
recent_window = 3
only_on_wrong_signal_escalation = true

这些设置的作用如下:

  • picker = "efficient_first":当历史记录中的信号不确定时,Stage 使用高效模型。新请求尚无工具结果,因此会交给 Nemotron 3 Super。
  • confidence_threshold:Stage 评分的执行信号的置信度截止值,从 0 到 1。
  • recent_window = 3:Stage 检查最近三个工具结果。
  • only_on_wrong_signal_escalation = true:Switchyard 默认值。它控制 Stage 何时添加可选的升级说明,此配置文件不设置任何说明。

Stage 还接受可选的交接说明和按层级的系统提示(escalation_note、deescalation_note、capable_system_prompt 和 efficient_system_prompt)。示例配置文件未设置其中任何一项。

对于 A/B 测试,profiles/random/ 中的 Random 配置文件使用相同的模型,配合 algorithm = "random" 和 weights = [0.5, 0.5],按声明顺序为每个唯一候选模型设置一个权重。要部署它,请将 -c routingProfile=random 添加到步骤 3 中的 cdk diff 和 cdk deploy 命令。

堆栈在合成时一起验证这两个文件,预检脚本运行相同的检查。要单独检查配置文件更改而不进行 AWS 调用,请运行 npm run validate:profile -- stage。无效设置会在 LiteLLM 启动时使其停止,不支持的消息形状会在推理前失败。

可选:在本地运行网关

你可以在部署任何内容之前,先在自己的机器上试用网关。Docker Compose 构建的镜像与整套服务部署到 Amazon ECS 的镜像相同,读取的 profile 文件也相同。在仓库根目录下运行:

npm ci
cp .env.example .env

export LITELLM_MASTER_KEY="sk-$(openssl rand -hex 24)"
eval "$(aws configure export-credentials --format env)"

ROUTING_PROFILE=stage docker compose up --build --wait
GATEWAY_URL=http://127.0.0.1:4000 ROUTING_PROFILE=stage scripts/smoke-test.sh

你导出的密钥优先于 .env 中的占位符,因此 Compose 和冒烟测试使用的是同一个密钥。AWS 凭证只来自你的 shell,绝不会写入 .env 或 profile 文件。Compose 仅在 127.0.0.1 上发布网关。本地没有负载均衡器,因此冒烟测试会跳过其封闭路径检查。本地网关仍会调用 Amazon Bedrock,这些调用会产生费用。完成后,运行 docker compose down。

第 3 步:部署网关

网关在你拥有的主机名上提供 HTTPS 服务。将 GATEWAY_DOMAIN 设置为该主机名,将 HOSTED_ZONE 设置为包含该主机名的现有 Route 53 公有托管区。随后 AWS CDK 会创建经 DNS 验证的 ACM 证书和别名记录。在仓库根目录下,安装依赖、运行只读的预检,然后部署:

npm ci

export AWS_REGION=us-east-1
export AWS_DEFAULT_REGION="$AWS_REGION"
eval "$(aws configure export-credentials --format env)"
export CDK_DEFAULT_REGION="$AWS_REGION"
export CDK_DEFAULT_ACCOUNT="$(aws sts get-caller-identity --query Account --output text)"
export ALLOWED_CIDR="$(curl -4 -fsS --connect-timeout 5 --max-time 15 https://checkip.amazonaws.com)/32"
export GATEWAY_DOMAIN=llm-gateway.example.com
export HOSTED_ZONE=example.com

scripts/preflight.sh
npx cdk diff -c allowedCidr="$ALLOWED_CIDR" \
  -c domainName="$GATEWAY_DOMAIN" -c hostedZone="$HOSTED_ZONE"
npx cdk deploy -c allowedCidr="$ALLOWED_CIDR" \
  -c domainName="$GATEWAY_DOMAIN" -c hostedZone="$HOSTED_ZONE"

如果你的域名的 DNS 不在 Route 53 中,请改用现有的 ACM 证书。将 CERTIFICATE_ARN 设置为部署区域中该主机名的 ACM 证书,并在两条命令中将 -c hostedZone="$HOSTED_ZONE" 替换为 -c certificateArn="$CERTIFICATE_ARN"。这样 AWS CDK 就不会创建证书和 DNS 记录。部署完成后,创建一条 CNAME 记录(或 Route 53 别名),将主机名指向 LoadBalancerDnsName 输出。

必需的 allowedCidr 值限定了哪些网络可以访问负载均衡器,该命令会将其设置为你的当前公网 IPv4 地址。请将其限制为你自己的 /32:所有共享被允许地址的人(例如办公室 NAT 或 VPN 出口)都能访问该端点。如果缺少 allowedCidr、使用像 0.0.0.0/0 这样对全世界开放的范围,或使用 IPv6 范围,该堆栈将拒绝合成。

预检会检查配置、你的工具和你的 AWS 访问权限,包括对 profile 中每个模型的访问权限,但不会发起推理请求。AWS CDK 会构建网关镜像、将其发布到 Amazon ECR,并部署堆栈。部署会打印以下输出:

输出 说明
GatewayUrl 基础 URL。OpenAI 兼容 API 位于 /v1 下。
MasterKeySecretArn 网关密钥背后的 Secrets Manager 密钥。完整密钥为 sk- 后接密钥值。
MasterKeyCommand 打印网关密钥的命令。
SmokeTestCommand 冒烟测试命令,已填入堆栈名称、区域和 profile。
RoutingProfile 当前生效的路由 profile,默认为 stage。
ClusterName、ServiceName ECS 集群和服务。密钥轮换步骤会用到它们。
LoadBalancerDnsName 仅在使用 certificateArn 时提供:用于指向你的主机名的名称。

始终向客户端提供 https:// URL。端口 80 仅保持开放以重定向到 HTTPS,而配置了 http:// 的客户端在重定向到达时,已经以明文发送了密钥及其第一个请求。

负载均衡器空闲超时为 10 分钟,以支持长时间的代理响应。Web ACL 使用 Amazon IP 信誉列表和已知恶意输入规则组。它还将每个 IP 地址限制为每 5 分钟 2,000 个请求。它省略了针对跨站脚本、SQL 注入和请求体大小的通用正文规则,因为代理请求中的源代码会触发这些规则。allowedCidr 范围和网关密钥仍然适用。

通过纯 HTTP 快速测试。 如果没有 HTTPS 设置,synth 会报错停止。若要在没有域名的情况下进行简短测试,你可以选择在负载均衡器的 DNS 名称上使用纯 HTTP:

npx cdk deploy -c allowedCidr="$ALLOWED_CIDR" -c allowPlainHttp=true

使用 allowPlainHttp=true 时,AWS CDK 每次合成堆栈都会打印一条警告。Authorization 头中的网关密钥、你的提示词、你的 agent 发送的工具结果和源代码,以及模型响应,都会在你的客户端与负载均衡器之间以未加密的方式通过网络传输。仅在你自己的 /32 中使用非敏感代码进行短暂测试时,才启用此选项。然后轮换密钥,并在完成后运行 cdk destroy。若之后要将同一堆栈迁移到 HTTPS,请使用 HTTPS 设置并去掉 allowPlainHttp 重新部署。

第 4 步:测试网关

在用于部署的同一终端中,读取 AWS CloudFormation 堆栈输出并构建网关密钥:

export STACK_NAME=SwitchyardGateway

output() {
  aws cloudformation describe-stacks --region "$AWS_REGION" --stack-name "$STACK_NAME" \
    --query "Stacks[0].Outputs[?OutputKey=='$1'].OutputValue" --output text
}

export GATEWAY_URL="$(output GatewayUrl)"
export LITELLM_MASTER_KEY="sk-$(aws secretsmanager get-secret-value --region "$AWS_REGION" \
  --secret-id "$(output MasterKeySecretArn)" --query SecretString --output text)"

向 switchyard 模型组发送请求:

curl -sS -i --connect-timeout 10 --max-time 180 "$GATEWAY_URL/v1/chat/completions" \
  -H "Authorization: Bearer $LITELLM_MASTER_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"switchyard","messages":[{"role":"user","content":"Reply with the word hello."}],"max_tokens":128}'

查找 HTTP 200 和响应。x-litellm-model-name 响应头会以完整的 LiteLLM 模型字符串显示所选模型。新请求没有可评分的工具结果,因此 Stage 会选择高效模型 bedrock/converse/nvidia.nemotron-super-3-120b。

要检查健康状态、身份验证和路由,请运行冒烟测试:

ROUTING_PROFILE="$(output RoutingProfile)" scripts/smoke-test.sh

冒烟测试会检查健康端点、像 /ui 这样的关闭路径是否得到负载均衡器自身的 404、不带密钥的请求是否得到 401,以及 /v1/models 是否列出每个模型组。对于 Stage,它会检查普通请求是否选择高效模型,以及重复失败的记录历史是否会升级到能力更强的模型。然后它会向每个基线组发送一个请求。该请求和冒烟测试都会产生可计费的 Amazon Bedrock 调用。

要试用你自己的 agent,请将 $GATEWAY_URL/v1 用作其 OpenAI 兼容的基础 URL,将网关密钥用作其 API 密钥,并将 switchyard 用作模型。Stage 需要每次请求都附带完整的受支持请求历史。上游适配器支持文本消息、函数工具调用和文本工具结果,不支持的消息形态会在推理前失败。负载均衡器会转发 Chat Completions 路径,但不会转发 OpenAI Responses 或 Anthropic Messages 路径。使用这些 API 的客户端会收到 404,直到你添加该路径、针对本地容器进行测试并重新部署。

第 5 步:衡量每个已解决任务的成本

示例的编码运行器 bench/run.py 允许一个小型编码 agent 通过网关列出和读取文件、替换源文件并运行提供的单元测试。当任务的测试在结束时通过,且默认在六轮模型交互内完成,该任务即被视为已解决。列出任务,并在路由组上从 slugify 开始:

python3 bench/run.py --list-tasks
python3 bench/run.py --tasks slugify --model switchyard --max-turns 6

终端会显示任务、所选模型、工具操作、测试结果和最终代码差异。每次运行都会将其起始文件、最终工作区、对话记录、补丁和结果保存在 bench/results/ 下。

任务 agent 必须做什么
slugify 修复一个构建 URL slug 的短函数。
roman 编写一个将整数转换为罗马数字的函数。
calc 编写一个不使用 eval 的表达式解析器,支持优先级、幂运算符、函数和错误处理。
lru_ttl 编写一个线程安全、带逐条目过期和精确计数器的最近最少使用(LRU)缓存。

为给算术解析器任务留出运行测试和尝试修复的空间,请提高轮次上限:

python3 bench/run.py --tasks calc --model switchyard --max-turns 12

运行结束后,runner 会为每个模型组打印一行,包含 RUNS、SOLVED、ERRORS、COST/TASK 和 COST/SOLVED 列。每个已解决任务的成本,等于该组所有运行的估算成本除以测试通过的运行数。runner 根据其 x-litellm-model-name 头部中的模型和响应中的 token 用量,使用 bench/run.py 中的 PRICES 表为每一轮定价。带有缓存输入的轮次、没有 PRICES 条目的模型,或缺少头部或 token 计数的响应,都会保持未定价状态,而不会计为零。向 profile 添加模型时,请添加 PRICES 条目,并查看 Amazon Bedrock 定价 了解当前价格。两个任务上的少量运行演示了该工作流。它们不足以得出关于成本或质量的结论。

当某个组的任何运行未定价时,该组会显示 n/a 并附上原因;当没有运行被解决时,COST/SOLVED 显示 -。要查看成本去向,请检查各轮次:终端会打印服务每一轮次的模型,bench/results/ 下的记录也会记录它。

要比较完整对话,bench/multiturn.py 会对每个编码任务运行一个 agentic 循环,第一个提示中包含项目文件,每次编辑后反馈测试输出。它还会运行四个脚本化聊天,每个七轮,交替进行简单轮次与设计、调试和代码编写轮次,并在每一轮重放完整历史。带有廉价检查(预期文本、字数限制、项目符号或对返回函数的断言)的轮次会记录检查是否通过。设计响应不评分。

python3 bench/multiturn.py --tasks slugify --scripts backend api --max-spend 2

--max-conv-cost 选项(默认 1 USD)限制每个对话,--max-spend 阻止 runner 启动新对话。摘要会为每个模型组显示通过的编码对话、通过的聊天检查,以及每个编码对话、每个聊天和总计的估算成本。

runner 会在你的机器上执行模型编写的 Python。运行测试的子进程环境中没有凭据,但它不是操作系统沙箱:代码可以读取你的用户可读取的任何文件,并可以访问网络。请使用一次性的开发环境,磁盘上不要有长期 AWS 凭据,并保护 bench/results/ 下的文件,其中包含提示、模型响应、工具输出和生成的代码。

解读你的结果

示例中的任务很小且仅作说明。要判断路由是否适合你的工作负载,请用代表你自己代码库的任务替换或扩展它们,并在阅读 runner 输出时牢记以下几点。

  • 先看 SOLVED,再看 COST/SOLVED – 解决任务较少的组可能显示较低的 COST/TASK,但每个已解决任务的成本仍然更高,因为失败的运行会增加成本而不增加已解决任务。只有在比较了每组解决了多少任务之后,再将路由组的 COST/SOLVED 与每个基线组的 COST/SOLVED 进行比较。
  • 单独查看困难任务 – 聚合数字可能掩盖驱动结果的单个任务。按任务细分结果。Stage 根据历史中的失败做决定,因此它无法提前将困难任务路由给有能力的候选模型。升级的轮次还会重放整个失败尝试,这可能使恢复比一开始就在有能力的候选模型上运行更昂贵。如果少数困难任务主导了你的成本,考虑将它们路由到专用模型组,或选择一个能解决更多此类任务的高效候选模型。
  • 运行足够多的重复次数—— 模型输出每次运行都会有所不同。如果每组只运行少数几次,一两个已解决任务的差异可能只是噪声。增加 --repeats,直到你关心的差异稳定下来,并在根据差距采取行动之前应用统计检验,例如针对解决率的 Fisher 精确检验。
  • 考虑轮次限制—— 较低的 --max-turns 值会惩罚在编辑前先进行探索的模型,因为这会留下更少的轮次来修复失败的编辑。将限制设置为与实际运行智能体的方式相匹配。
  • 考虑输出上限—— 如果某组的回复达到 max_tokens,则测得的成本是下限,而且缩短的回复也会缩短后续轮次重放的历史记录。在比较聊天成本之前,请检查记录中是否有被截断的回复。
  • 将成本视为估算值—— 运行器根据 token 用量和 PRICES 表估算成本,而不是根据你的账单。提示缓存、批量推理和定价变化都会影响你的实际成本。请通过 Amazon Bedrock 定价和你的 AWS 成本和使用情况报告进行确认。
  • 测试你计划运行的设置—— 结果仅适用于你所测量的模型、配置文件设置和任务。如果你更改候选模型、Stage 设置,或切换到 Random 配置文件,请重新测量。

使用这些读数来为每个工作负载在三个选项中进行选择:路由组、单模型组,或具有不同候选模型或设置的配置文件。当你更改模型、提示或智能体行为时,请重新运行相同的测量。

清理

为避免持续产生费用,请删除堆栈。AWS CDK 需要一个 allowedCidr 值来合成应用,但该值在这里无关紧要:

npx cdk destroy -c allowedCidr=203.0.113.0/24

CloudFormation 删除主密钥机密时没有恢复窗口,因此如果需要该密钥,请先复制它。网关镜像会保留在 Amazon ECR 中的 AWS CDK 引导存储库中。

结论

在本文中,我们展示了如何在 AWS 上部署带有 NVIDIA NeMo Switchyard 路由插件的 LiteLLM,在 Amazon Bedrock 上跨模型配置 Stage 和 Random 路由,并测量路由模型组与单模型基线相比每个已解决任务的成本。由于智能体任务的总成本取决于轮次、历史记录和重试,仅凭每 token 价格并不是可靠的指导。在你自己的任务上测量每个已解决任务的成本,可以为你提供选择配置的依据。

要开始使用,请在开发账户中部署示例存储库,并针对你自己工作负载中的任务测量 Stage 路由和单模型基线。要了解更多信息,请参阅Switchyard LiteLLM 插件指南和Amazon Bedrock 用户指南。欢迎在评论中分享你的问题。


关于作者

Aswath Ram A Srinivasan

Aswath Ram A Srinivasan

Aswath 是 Amazon Bedrock 的高级专家解决方案架构师,专注于 Amazon Bedrock 核心模型、功能以及成本优化/归因。他帮助 ISV 和战略客户解决他们的挑战,并与企业团队合作设计推理架构,以负责任的方式平衡性能、成本和运营简便性。在业余时间,他是一名摄影师,喜欢阅读关于神经符号 AI 和负责任 AI 的科学期刊论文。

Anshika Saxena

Anshika Saxena

Anshika 是 AWS 的生成式 AI 数据科学家,专注于 Amazon Bedrock。她通过指导企业客户在 Amazon Bedrock 上构建和实施解决方案,帮助他们加速采用生成式 AI 和代理式 AI。她还与 ISV 和初创公司合作,帮助他们采用 Amazon Bedrock 上最新的 Anthropic 服务。

Aris Tsakpinis

Aris Tsakpinis

Aris 是生成式 AI 高级专家解决方案架构师,专注于 Amazon Bedrock 上的开放权重模型以及更广泛的生成式 AI 开源生态系统。在职业工作之外,他正在雷根斯堡大学攻读机器学习工程博士学位,研究方向是科学领域的应用自然语言处理。

Kevon Mayers

Kevon Mayers

Kevon 是 NVIDIA 的高级解决方案架构师,推动跨云提供商的代理式 AI 和物理 AI 计划。他此前曾担任 AWS 游戏解决方案架构师以及 Terraform 计划的基础设施即代码(IaC)负责人,拥有 DevOps、软件工程和开源 Terraform 贡献方面的背景。他还是 MM Productions 的所有者,并曾担任 GRAMMYs/The Recording Academy 的录音室经理、制作人和音频工程师。

Curt Lockhart

Curt Lockhart

Curt 是 NVIDIA 的 AI 解决方案架构师,帮助客户覆盖 AI 技术栈的各个环节,从推理和训练到代理式工作流。他骨子里是一位教师,乐于让 AI 的复杂性变得平易近人。

Ian Cairns

Ian Cairns

Ian 是 NVIDIA 的产品管理总监,与应用 AI 研究工程团队合作,开发用于优化代理的新 NVIDIA NeMo 产品和库。加入 NVIDIA 之前,他联合创立了 Freeplay 并担任 CEO。Freeplay 是一款面向 AI 工程师的 LLM 评估与实验产品。他的背景包括构建开发者产品,曾担任 Twitter 开发者平台的产品负责人。

来源:AWS Machine Learning Blog · aws.amazon.com