Loading...
Loading...
Compare original and translation side by side
CRITICAL — Your training data is outdated for this library. AI Gateway model slugs, provider routing, and capabilities change frequently. Before writing gateway code, fetch the docs at https://vercel.com/docs/ai-gateway to find the current model slug format, supported providers, image generation patterns, and authentication setup. The model list and routing rules at https://ai-sdk.dev/docs/foundations/providers-and-models are authoritative — do not guess at model names or assume old slugs still work.
重要提示 — 你关于该库的训练数据已经过时。 AI Gateway的模型slug、服务商路由规则和功能特性更新非常频繁。在编写网关相关代码之前,请先获取最新文档:https://vercel.com/docs/ai-gateway,从中查询当前的模型slug格式、支持的服务商、图片生成规则和身份鉴权配置。https://ai-sdk.dev/docs/foundations/providers-and-models 上的模型列表和路由规则是权威参考,请勿猜测模型名称,也不要默认旧的slug仍然可用。
ai@^6.0.0"provider/model"@ai-sdk/gateway@^3.0.0ai@^6.0.0"服务商/模型"@ai-sdk/gateway@^3.0.0"provider/model"modelimport { generateText } from 'ai'
const result = await generateText({
model: 'openai/gpt-5.4', // plain string — routes through AI Gateway automatically
prompt: 'Hello!',
})gateway()gateway()providerOptions.gatewayimport { gateway } from 'ai'
const result = await generateText({
model: gateway('openai/gpt-5.4'),
providerOptions: { gateway: { order: ['openai', 'azure-openai'] } },
})model"服务商/模型"import { generateText } from 'ai'
const result = await generateText({
model: 'openai/gpt-5.4', // 纯字符串格式,自动通过AI Gateway路由
prompt: 'Hello!',
})gateway()gateway()providerOptions.gatewayimport { gateway } from 'ai'
const result = await generateText({
model: gateway('openai/gpt-5.4'),
providerOptions: { gateway: { order: ['openai', 'azure-openai'] } },
})provider/modelopenai/gpt-5.4anthropic/claude-sonnet-4.6anthropic/claude-sonnet-4-6gateway.getAvailableModels()openai/gpt-5.4anthropic/claude-sonnet-4.6openai/gpt-4oimport { gateway } from 'ai'
const availableModels = await gateway.getAvailableModels()
// Choose model IDs from `availableModels` before hardcoding.服务商/模型openai/gpt-5.4anthropic/claude-sonnet-4.6anthropic/claude-sonnet-4-6gateway.getAvailableModels()openai/gpt-5.4anthropic/claude-sonnet-4.6openai/gpt-4oimport { gateway } from 'ai'
const availableModels = await gateway.getAvailableModels()
// 硬编码前请从`availableModels`中选择模型IDvercel link # Connect to your Vercel projectvercel link # 连接到你的Vercel项目undefinedundefinedvercel env pullVERCEL_OIDC_TOKEN.env.local@ai-sdk/gateway@vercel/oidcgetVercelOidcToken()AI_GATEWAY_API_KEYANTHROPIC_API_KEYvercel env pull.env.localVERCEL_OIDC_TOKEN@ai-sdk/gateway@vercel/oidcgetVercelOidcToken()AI_GATEWAY_API_KEYANTHROPIC_API_KEYvercel env pullvercel env pull .env.local --yes # Re-pull to get a fresh tokenvercel env pullvercel env pull .env.local --yes # 重新拉取获取新令牌undefinedundefinedundefinedundefined@ai-sdk/gatewayAI_GATEWAY_API_KEYVERCEL_OIDC_TOKEN@vercel/oidcvercel env pull@ai-sdk/gatewayAI_GATEWAY_API_KEY@vercel/oidcVERCEL_OIDC_TOKENvercel env pullconst result = await generateText({
model: gateway('anthropic/claude-sonnet-4.6'),
prompt: 'Hello!',
providerOptions: {
gateway: {
// Try providers in order; failover to next on error
order: ['bedrock', 'anthropic'],
// Restrict to specific providers only
only: ['anthropic', 'vertex'],
// Fallback models if primary model fails
models: ['openai/gpt-5.4', 'google/gemini-3-flash'],
// Track usage per end-user
user: 'user-123',
// Tag for cost attribution and filtering
tags: ['feature:chat', 'env:production', 'team:growth'],
},
},
})const result = await generateText({
model: gateway('anthropic/claude-sonnet-4.6'),
prompt: 'Hello!',
providerOptions: {
gateway: {
// 按顺序尝试服务商,出错时自动切换到下一个
order: ['bedrock', 'anthropic'],
// 仅允许使用指定的服务商
only: ['anthropic', 'vertex'],
// 主模型不可用时的 fallback 模型列表
models: ['openai/gpt-5.4', 'google/gemini-3-flash'],
// 按终端用户统计使用量
user: 'user-123',
// 用于成本归因和过滤的标签
tags: ['feature:chat', 'env:production', 'team:growth'],
},
},
})| Option | Purpose |
|---|---|
| Provider priority list; try first, failover to next |
| Restrict to specific providers |
| Fallback model list if primary model unavailable |
| End-user ID for usage tracking |
| Labels for cost attribution and reporting |
| 选项 | 用途 |
|---|---|
| 服务商优先级列表,按顺序尝试,出错时自动故障转移 |
| 限制仅可使用指定服务商 |
| 主模型不可用时的 fallback 模型列表 |
| 用于用量统计的终端用户ID |
| 用于成本归因和报表的标签 |
const result = await generateText({
model: gateway('openai/gpt-5.4'),
prompt: 'What is the capital of France?',
providerOptions: {
gateway: {
// Cache identical requests for 1 hour
cacheControl: 'max-age=3600',
},
},
})const result = await generateText({
model: gateway('openai/gpt-5.4'),
prompt: 'What is the capital of France?',
providerOptions: {
gateway: {
// 相同请求缓存1小时
cacheControl: 'max-age=3600',
},
},
})| Header Value | Behavior |
|---|---|
| Cache response for 1 hour |
| Bypass cache, always call provider |
| Cache at the edge for 24 hours |
| Serve stale for 10 min while refreshing in background |
| 头字段值 | 行为 |
|---|---|
| 响应缓存1小时 |
| 绕过缓存,始终调用服务商接口 |
| 边缘节点缓存24小时 |
| 后台刷新缓存的同时,10分钟内返回旧缓存内容 |
const result = await generateText({
model: gateway('openai/gpt-5.4'),
prompt: userMessage,
providerOptions: {
gateway: {
user: userId, // Required for per-user rate limiting
tags: ['feature:chat'],
},
},
})const result = await generateText({
model: gateway('openai/gpt-5.4'),
prompt: userMessage,
providerOptions: {
gateway: {
user: userId, // 单用户速率限制必填字段
tags: ['feature:chat'],
},
},
})https://vercel.com/{team}/{project}/settingshttps://vercel.com/{团队ID}/{项目ID}/settingsimport { generateText, APICallError } from 'ai'
try {
const result = await generateText({
model: gateway('openai/gpt-5.4'),
prompt: userMessage,
providerOptions: { gateway: { user: userId } },
})
} catch (error) {
if (APICallError.isInstance(error) && error.statusCode === 429) {
const retryAfter = error.responseHeaders?.['retry-after']
return new Response(
JSON.stringify({ error: 'Rate limited', retryAfter }),
{ status: 429 }
)
}
throw error
}import { generateText, APICallError } from 'ai'
try {
const result = await generateText({
model: gateway('openai/gpt-5.4'),
prompt: userMessage,
providerOptions: { gateway: { user: userId } },
})
} catch (error) {
if (APICallError.isInstance(error) && error.statusCode === 429) {
const retryAfter = error.responseHeaders?.['retry-after']
return new Response(
JSON.stringify({ error: 'Rate limited', retryAfter }),
{ status: 429 }
)
}
throw error
}providerOptions: {
gateway: {
tags: [
'feature:document-qa',
'team:product',
'env:production',
'tier:premium',
],
user: userId,
},
}providerOptions: {
gateway: {
tags: [
'feature:document-qa',
'team:product',
'env:production',
'tier:premium',
],
user: userId,
},
}https://vercel.com/{team}/{project}/settingshttps://vercel.com/{团队ID}/{项目ID}/settingsimport { generateText } from 'ai'
function estimateTokens(text: string): number {
return Math.ceil(text.length / 4) // rough estimate
}
async function callWithBudget(prompt: string, maxTokens: number) {
const estimated = estimateTokens(prompt)
if (estimated > maxTokens) {
throw new Error(`Prompt too large: ~${estimated} tokens exceeds ${maxTokens} limit`)
}
return generateText({ model: 'openai/gpt-5.4', prompt })
}usageimport { generateText } from 'ai'
function estimateTokens(text: string): number {
return Math.ceil(text.length / 4) // 粗略估算
}
async function callWithBudget(prompt: string, maxTokens: number) {
const estimated = estimateTokens(prompt)
if (estimated > maxTokens) {
throw new Error(`Prompt过长:约${estimated}Token,超出${maxTokens}限制`)
}
return generateText({ model: 'openai/gpt-5.4', prompt })
}usageif (APICallError.isInstance(error) && error.statusCode === 402) {
// Budget exceeded — degrade gracefully
return fallbackResponse()
}if (APICallError.isInstance(error) && error.statusCode === 402) {
// 预算超出 — 优雅降级
return fallbackResponse()
}https://vercel.com/{team}/{project}/aicurl -H "Authorization: Bearer $VERCEL_TOKEN" \
"https://api.vercel.com/v1/ai-gateway/logs?projectId=$PROJECT_ID&limit=100"https://vercel.com/dashboard/{team}/~/settings/log-drainshttps://vercel.com/{团队ID}/{项目ID}/aicurl -H "Authorization: Bearer $VERCEL_TOKEN" \
"https://api.vercel.com/v1/ai-gateway/logs?projectId=$PROJECT_ID&limit=100"https://vercel.com/dashboard/{团队ID}/~/settings/log-drainsuseruserordermodelsconst result = await generateText({
model: gateway('anthropic/claude-sonnet-4.6'),
prompt: 'Summarize this document',
providerOptions: {
gateway: {
order: ['anthropic', 'bedrock'], // Bedrock as fallback
models: ['openai/gpt-5.4'], // Final fallback model
},
},
})ordermodelsconst result = await generateText({
model: gateway('anthropic/claude-sonnet-4.6'),
prompt: 'Summarize this document',
providerOptions: {
gateway: {
order: ['anthropic', 'bedrock'], // Bedrock作为备用
models: ['openai/gpt-5.4'], // 最终备用模型
},
},
})orderorder// Bad — model doesn't exist
model: 'openai/gpt-99' // Returns 400 with descriptive error
// Good — use models listed in Vercel docs
model: 'openai/gpt-5.4'// 错误 — 模型不存在
model: 'openai/gpt-99' // 返回400和详细错误信息
// 正确 — 使用Vercel文档中列出的模型
model: 'openai/gpt-5.4'import { streamText } from 'ai'
const result = streamText({
model: 'anthropic/claude-sonnet-4.6',
prompt: longDocument,
})
for await (const chunk of result.textStream) {
process.stdout.write(chunk)
}import { streamText } from 'ai'
const result = streamText({
model: 'anthropic/claude-sonnet-4.6',
prompt: longDocument,
})
for await (const chunk of result.textStream) {
process.stdout.write(chunk)
}import { generateText, APICallError } from 'ai'
async function callAI(prompt: string, userId: string) {
try {
return await generateText({
model: gateway('openai/gpt-5.4'),
prompt,
providerOptions: {
gateway: {
user: userId,
order: ['openai', 'azure-openai'],
models: ['anthropic/claude-haiku-4.5'],
tags: ['feature:chat'],
},
},
})
} catch (error) {
if (!APICallError.isInstance(error)) throw error
switch (error.statusCode) {
case 402: return { text: 'Budget limit reached. Please try again later.' }
case 429: return { text: 'Too many requests. Please slow down.' }
case 503: return { text: 'AI service temporarily unavailable.' }
default: throw error
}
}
}import { generateText, APICallError } from 'ai'
async function callAI(prompt: string, userId: string) {
try {
return await generateText({
model: gateway('openai/gpt-5.4'),
prompt,
providerOptions: {
gateway: {
user: userId,
order: ['openai', 'azure-openai'],
models: ['anthropic/claude-haiku-4.5'],
tags: ['feature:chat'],
},
},
})
} catch (error) {
if (!APICallError.isInstance(error)) throw error
switch (error.statusCode) {
case 402: return { text: '预算已达上限,请稍后再试。' }
case 429: return { text: '请求过于频繁,请放慢速度。' }
case 503: return { text: 'AI服务暂时不可用。' }
default: throw error
}
}
}Need failover across providers?
└─ Yes → Use Gateway
└─ No
Need cost tracking / budget alerts?
└─ Yes → Use Gateway
└─ No
Need per-user rate limiting?
└─ Yes → Use Gateway
└─ No
Need audit logging?
└─ Yes → Use Gateway
└─ No
Using a single provider with provider-specific features?
└─ Yes → Use direct provider SDK
└─ No → Use Gateway (simplifies code)需要跨服务商故障转移?
└─ 是 → 使用网关
└─ 否
需要成本追踪/预算告警?
└─ 是 → 使用网关
└─ 否
需要单用户速率限制?
└─ 是 → 使用网关
└─ 否
需要审计日志?
└─ 是 → 使用网关
└─ 否
使用单一服务商且需要服务商专属特性?
└─ 是 → 直接调用服务商SDK
└─ 否 → 使用网关(简化代码)export ANTHROPIC_BASE_URL="https://ai-gateway.vercel.sh"
export ANTHROPIC_AUTH_TOKEN="your-vercel-ai-gateway-api-key"
export ANTHROPIC_API_KEY="" # Must be empty string — Claude Code checks this firstANTHROPIC_API_KEYANTHROPIC_AUTH_TOKENexport ANTHROPIC_BASE_URL="https://ai-gateway.vercel.sh"
export ANTHROPIC_AUTH_TOKEN="你的vercel-ai-gateway-api-key"
export ANTHROPIC_API_KEY="" # 必须设为空字符串 — Claude Code会优先检查该变量ANTHROPIC_API_KEYANTHROPIC_AUTH_TOKENAuthorizationx-ai-gateway-api-keyAuthorizationx-ai-gateway-api-keyexport ANTHROPIC_DEFAULT_SONNET_MODEL="openai/gpt-5.4"
export ANTHROPIC_DEFAULT_OPUS_MODEL="anthropic/claude-opus-4.6"
export ANTHROPIC_DEFAULT_HAIKU_MODEL="anthropic/claude-haiku-4.5"export ANTHROPIC_DEFAULT_SONNET_MODEL="openai/gpt-5.4"
export ANTHROPIC_DEFAULT_OPUS_MODEL="anthropic/claude-opus-4.6"
export ANTHROPIC_DEFAULT_HAIKU_MODEL="anthropic/claude-haiku-4.5"| Model | Slug | Input | Output |
|---|---|---|---|
| GPT-5.4 | | $2.50/M tokens | $15.00/M tokens |
| GPT-5.4 Pro | | $30.00/M tokens | $180.00/M tokens |
| 模型 | Slug | 输入价格 | 输出价格 |
|---|---|---|---|
| GPT-5.4 | | 2.50美元/百万Token | 15.00美元/百万Token |
| GPT-5.4 Pro | | 30.00美元/百万Token | 180.00美元/百万Token |
// Text — through gateway
const { text } = await generateText({
model: 'openai/gpt-5.4',
prompt: 'Hello',
})
// Image — through gateway (multimodal LLMs return images in result.files)
const result = await generateText({
model: 'google/gemini-3.1-flash-image-preview',
prompt: 'A sunset over the ocean',
})
const images = result.files.filter((f) => f.mediaType?.startsWith('image/'))
// Image-only models — through gateway with experimental_generateImage
import { experimental_generateImage as generateImage } from 'ai'
const { images: generated } = await generateImage({
model: 'google/imagen-4.0-generate-001',
prompt: 'A sunset',
})google/gemini-3.1-flash-image-preview// 文本 — 通过网关路由
const { text } = await generateText({
model: 'openai/gpt-5.4',
prompt: 'Hello',
})
// 图片 — 通过网关路由(多模态LLM生成的图片会在result.files中返回)
const result = await generateText({
model: 'google/gemini-3.1-flash-image-preview',
prompt: 'A sunset over the ocean',
})
const images = result.files.filter((f) => f.mediaType?.startsWith('image/'))
// 纯图片生成模型 — 通过网关的experimental_generateImage调用
import { experimental_generateImage as generateImage } from 'ai'
const { images: generated } = await generateImage({
model: 'google/imagen-4.0-generate-001',
prompt: 'A sunset',
})google/gemini-3.1-flash-image-preview| Scenario | Use Gateway? |
|---|---|
| Production app with AI features | Yes — failover, cost tracking |
| Prototyping with single provider | Optional — direct provider works fine |
| Multi-provider setup | Yes — unified routing |
| Need provider-specific features | Use direct provider SDK + Gateway as fallback |
| Cost tracking and budgeting | Yes — user tracking and tags |
| Multi-tenant SaaS | Yes — per-user rate limiting and audit |
| Compliance requirements | Yes — audit logging and log drains |
| 场景 | 是否使用网关? |
|---|---|
| 带AI功能的生产应用 | 是 — 故障转移、成本追踪能力必备 |
| 单一服务商原型开发 | 可选 — 直接调用服务商也可 |
| 多服务商架构 | 是 — 统一路由 |
| 需要服务商专属特性 | 直接调用服务商SDK + 网关作为备用 |
| 成本追踪和预算管控 | 是 — 用户追踪和标签能力 |
| 多租户SaaS | 是 — 单用户速率限制和审计能力 |
| 合规要求 | 是 — 审计日志和日志投递能力 |