AB
AiBoss
Tutorials

用 Vercel AI Gateway 统一调用多模型并配置故障回退

Tutorials

用 Vercel AI Gateway 统一调用多模型并配置故障回退

Vercel AI Gateway 把 OpenAI、Anthropic、Google 等多家模型收敛到一个入口:一个 API 密钥、creator/model 形式的模型 ID、按成本或首字延迟排序供应商,并在某条路径失败时自动换路。本教程从环境变量与最小调用讲起,逐步加入供应商过滤、模型回退、Virtual Models 与零数据保留,并说明速率限制、BYOK 与计费上的边界。

Vercel AI Gateway 是 Vercel 提供的一层模型网关:应用只向网关发一次请求,由网关把请求分发给 OpenAI、Anthropic、Google 等不同供应商。它要解决的问题很具体——当你的产品依赖模型调用时,单一供应商的速率限制、区域性故障和模型迭代都会直接变成用户可见的错误。把调用收敛到网关之后,换模型只是改一个字符串,某条路径失败时可以自动换到另一条路径。

这篇教程面向第一次接触 AI Gateway、希望真正把它跑起来的人。内容覆盖最小可运行配置、供应商排序与过滤、两级回退、用 Virtual Models 把配置移出代码、Eval 场景下的模型替换,以及速率限制、BYOK、数据保留这些上线前必须弄清楚的边界。文中涉及的价格、免费额度、模型清单与套餐限制都可能调整,请以官网当前信息为准。

准备工作

账号与密钥

你需要一个 Vercel 账号,并在团队下开通 AI Gateway。调用侧需要准备一个网关 API 密钥,通过环境变量 AI_GATEWAY_API_KEY 提供给应用。密钥在 Vercel 侧创建,不要写进代码仓库。

如果你的应用本身就部署在 Vercel 上,可以改用 OIDC 认证:部署后的应用会自动获得 VERCEL_OIDC_TOKEN,无需自行签发和轮换网关密钥。这样少了一个可能泄露的密钥,也省掉了定期更新的运维动作。是否启用 OIDC 取决于你的部署环境,非 Vercel 环境仍然使用 API 密钥。

依赖安装

示例统一使用 Vercel AI SDK 的 generateText,先安装 SDK:

npm install ai

如果你已有基于 OpenAI 或 Anthropic 官方 SDK 的代码,也可以不换 SDK,只把 base URL 指向网关即可迁移。这种方式适合存量项目,但本文的示例仍以 AI SDK 为主,因为模型 ID 与 providerOptions 的表达更直接。

确认模型 ID

网关用 creator/model 形式的字符串标识模型,例如 google/gemini-3.8-flash。具体有哪些模型、每个模型对应哪些供应商名称,需要查模型列表页面确认,不要凭记忆拼写。

操作步骤

第一步:跑通最小调用

设置好 AI_GATEWAY_API_KEY 之后,把模型 ID 直接传给 generateText:

import { generateText } from 'ai';

const { text } = await generateText({
  model: 'google/gemini-3.8-flash',
  prompt: 'Hello, world!',
});

console.log(text);

这一步已经体现了网关最直接的收益:不需要为每个供应商安装各自的 SDK,也不需要分别管理各家密钥。想换模型,改 model 这一个字符串即可,其余代码不动。

第二步:控制供应商的选择方式

默认情况下,网关会根据最近的可用性(uptime)和延迟来选择供应商。需要更精细的控制时,用 providerOptions.gateway 传入选项:

选项作用
order指定供应商的优先顺序,从左到右依次尝试
only只允许指定的供应商处理请求
sort按 cost、ttft、tps 对供应商排序
models所有供应商都失败后,依次尝试的替代模型
tags给请求打标签,便于成本归集

一个同时使用过滤、排序、模型回退和标签的调用如下:

import { generateText } from 'ai';

const { text } = await generateText({
  model: 'google/gemini-3.8-flash',
  prompt: essay,
  providerOptions: {
    gateway: {
      // 只在这两个供应商之间处理
      only: ['vertex', 'google'],
      // 优先选择首字延迟更低的供应商
      sort: 'ttft',
      // 全部供应商失败后的替代模型
      models: ['google/gemini-3.7-flash'],
      // 成本归集用的标签
      tags: ['essay-review'],
    },
  },
});

如果希望自己决定优先顺序而不是交给排序算法,把 sort 换成 order:

providerOptions: {
  gateway: {
    order: ['vertex', 'google'], // 从左到右依次尝试
  },
},

only 和 order 里写的供应商名称因模型而异。以 Gemini 为例是 google 与 vertex,其他模型要查对应模型页面,写错名称不会生效。

sort 的取值按用途选:cost 适合成本敏感的大批量处理,ttft(首个 token 的时间)适合用户需要等待的交互式功能,tps(token 速度)适合长文本生成。排序在请求时计算,供应商的新增、价格与速度变化会自动反映到结果里,不需要你维护静态名单。

第三步:理解两级回退

回退分两层,作用范围不同:

  • 同一模型的另一个供应商:某个供应商失败时,网关自动换到下一个供应商重试。这一层不需要额外配置。
  • 换到另一个模型:只有在 models 里显式列出时才会发生,且触发条件是当前模型的所有供应商都失败。

两层回退的语义差别很大。第一层通常输出质量一致,只是换了执行路径;第二层换了模型,即使同系列不同版本,同样的提示词也可能产出不同结果。回退的目的是可用性,不保证质量等价。因此建议先用「同模型换供应商」兜底,是否要跨模型回退,按功能重要程度决定:关键功能可以准备针对替代模型调过的提示词,非关键功能也可以选择直接返回错误。

实际是哪条路径、哪个供应商响应的,可以从日志或响应元数据里查到,这也是后续排查的依据。

第四步:用 Virtual Models 把配置移出代码

当模型、路径、回退策略需要频繁调整时,每次改代码再重新部署并不划算。Virtual Models 允许把一组配置保存成一个模型 ID,形式为 vmc/<slug>,应用侧只引用这个 ID。修改配置后,应用不需要重新部署。

Virtual Model 可以在控制台创建,也可以用 Vercel CLI 创建:

vercel ai-gateway virtual-models create essay-review \
  --model google/gemini-3.8-flash \
  --config '{"zeroDataRetention":true}'

应用侧把模型 ID 换成 vmc/ 前缀的标识即可:

const { text } = await generateText({
  model: 'vmc/essay-review',
  prompt: essay,
});

这种做法的思路接近在代码之外管理提示词:模型选型、回退链路这类易变配置留在网关侧,代码只负责「调用某个能力」。对需要按环境、按功能区分模型的团队尤其省事。

第五步:在 Eval 流程中替换模型

评估流程需要反复更换被测模型,而网关让这件事退化成改一个字符串。把模型 ID 从外部传入,就能在不改评估逻辑的前提下切换被测对象:

import { generateText } from 'ai';

// 通过环境变量替换待评估的模型
const MODEL = process.env.EVAL_MODEL ?? 'google/gemini-3.8-flash';

const { text } = await generateText({
  model: MODEL,
  prompt: essay,
});

配合 Virtual Models,还可以把「评估用」的模型组合固定成一个 vmc/ 标识,评估脚本只认这个标识,具体用哪个模型、走哪条路径、失败后回退到哪里,全部在网关侧调整。

第六步:按需开启零数据保留

网关本身不保存提示词与响应,请求完成后即删除。如果业务要求零数据保留(ZDR),可以在请求级别指定:

providerOptions: {
  gateway: {
    zeroDataRetention: true,
  },
},

开启后,请求只会被发送到具备 ZDR 约定的供应商;如果没有符合条件的供应商,请求会直接报错,而不是降级到普通路径。请求级别的 ZDR 指定与套餐相关,具体可用范围以官网当前信息为准。

一个完整示例

下面把前面的要素串成一个可运行的脚本:使用网关密钥、限定供应商范围、按首字延迟排序、配置模型回退、打上成本标签,并允许通过环境变量切换模型。

import { generateText } from 'ai';

const MODEL = process.env.EVAL_MODEL ?? 'google/gemini-3.8-flash';

async function reviewEssay(essay) {
  const { text } = await generateText({
    model: MODEL,
    prompt: essay,
    providerOptions: {
      gateway: {
        only: ['vertex', 'google'],
        sort: 'ttft',
        models: ['google/gemini-3.7-flash'],
        tags: ['essay-review'],
      },
    },
  });

  return text;
}

const result = await reviewEssay('请批改这篇小论文……');
console.log(result);

运行前确认环境变量已设置:

export AI_GATEWAY_API_KEY=你的网关密钥
node review.mjs

如果部署在 Vercel 上并启用了 OIDC,则不需要设置 AI_GATEWAY_API_KEY,运行时使用 VERCEL_OIDC_TOKEN 完成认证。想验证回退是否真的生效,可以临时把 only 收窄到一个供应商,观察失败后请求是否被另一条路径接住,并对照日志确认实际响应的模型与供应商。

注意事项

速率限制

429 错误来自供应商按模型、按供应商设定的上限。使用网关的额度(未接入自有密钥)时,免费额度阶段每个模型的速率限制较低;购买额度进入付费阶段后,网关侧的限制不再适用。但付费阶段并不等于完全没有限制,上游供应商仍可能返回 429。如果业务确实受影响,可以在官方文档中查看联系 Vercel 销售协商自定义上限的方式。

429 有时等待片刻重试即可通过,应用侧建议加入次数受限的重试逻辑,避免无限重试放大问题。

BYOK 的计费与限制

BYOK 指注册并使用自己的供应商密钥。正常请求按你与供应商的合同计费,网关不加价,也不消耗网关额度。但自有密钥调用失败时,网关会用网关密钥自动重试,这部分会计入网关额度并受网关侧速率限制。由于存在这部分计费,使用 BYOK 需要先购买额度。另外,自有密钥的调用仍然受供应商侧的速率限制约束。

ZDR 与 BYOK 有一个容易踩的组合:开启 ZDR 后,BYOK 默认不会被使用,因为 BYOK 遵循你与供应商之间的合同。如果自有密钥本身具备 ZDR 约定,需要在密钥级别标记为支持 ZDR,它才会被纳入 ZDR 路径。

数据可观测性

网关不保存提示词与响应内容,因此它擅长回答「走了哪条路径、花了多少」,不擅长回答「模型到底说了什么」。需要查看内容时,用 Langfuse 之类的可观测性工具补齐。把职责分开——网关管路径与成本,可观测性工具管内容——排查会清晰很多。

架构与功能边界

  • 请求链路多了一跳,端到端延迟会受影响,评估性能时要把它算进去。
  • 上游供应商的容量上限与拥塞导致的错误(如 429)不会因为接入网关而彻底消失。
  • 这是托管服务,不能自托管。
  • 部分能力单独计费,例如团队级 ZDR 与用于报表的标签写入,具体单价以官网当前信息为准。
  • 与其他网关产品的定位不同:有的产品强在边缘侧的缓存与限流控制,Vercel AI Gateway 的侧重是开发体验与可调用模型的广度。选型时按自己的痛点取舍。

关于跨模型回退的判断

是否允许回退到别的模型,本质是产品取舍。一个可用的原则是:输出略有差异,通常比直接报错对用户体验更好。但这不意味着可以默认替代模型质量相当——同系列不同版本的输出也会有差别。先守住「同模型换供应商」,再按功能重要程度决定是否跨模型回退,并通过日志持续观察回退发生的频率与场景。

落地节奏上,建议先用最小配置跑通一次调用,确认密钥与模型 ID 无误,再逐步加上供应商过滤、排序、模型回退与 Virtual Models。模型替换频繁的场景(例如评估流水线)会最快感受到这套配置带来的便利。