Vercel AI SDK与AI Gateway:大模型应用接入与治理实践
写 LLM 应用时很多团队都会遇到一种“看似没什么技术含量却反复消耗时间”的状态聊天页面并不复杂模型调用也不复杂但把两者接起来、换模型、调超时、排查 429、统计 token、回滚到另一个供应商每一步都有一堆“协议级”的细节。Vercel 的 AI SDK 和 AI Gateway 正是为了解决这条链路中的不同问题而出现的。先给一个明确判断AI SDK 解决的是代码层的“模型调用标准化”AI Gateway 解决的是基础设施层的“统一入口与治理”二者不是同一个东西也无法互相替代但搭配使用时可以把一个 LLM 应用从“能跑”推向“好维护”。这篇文章会从免费账号开始走到真实可用的聊天应用再到 AI Gateway 的接入方式最后给出测试用例、域名绑定和排错清单。如果你想在 Next.js 项目里快速接上大模型又不想把代码写死在某一家厂商 API 上这篇文章正好适合你。1. 这篇文章真正要解决的问题很多团队第一次接触大模型 API 时会直接按照官方文档写一个服务端fetch或 Python 调用。但这种写法在项目里活不过第二周因为很快就会遇到一连串问题OpenAI、Anthropic、Google 的请求和响应结构不一致切换模型服务商时客户端代码要跟着改。流式响应不是简单读字段需要解析 SSE、拼接增量、处理中断。每次调用都手动拼messages、数 token、处理超时缺少可复用层。在客户端用 React 展示流式输出时需要自己维护 loading、message 队列和滚动逻辑。成本、缓存、限流、故障转移这些“平台级能力”散落在不同服务商的后台无法统一查看。Vercel AI SDK 解决的是前四类问题。它把“调用模型”抽象成generateText、streamText、generateObject这类函数并提供了useChat这样的前端 Hook让流式文本直接落到 UI。AI Gateway 解决的是后一类问题。它处于你的应用与模型服务商之间像一个 API 入口负责把请求转发到实际模型同时集中处理缓存、限流、统计和异常。换句话说面向读者如果你是前端或全栈工程师想在 Next.js 里快速做出 AI 功能优先学习 AI SDK。如果你的系统已经接入了多个模型服务商或者需要在生产环境控制成本和排查调用链AI Gateway 才是你真正缺的那一层。如果你只是写个人 DemoAI SDK 免费且容易上手AI Gateway 通常也有免费额度可以先用小流量验证。2. AI SDK 与 AI Gateway概念、边界与常见误解2.1 AI SDK 是什么Vercel AI SDK 是一个面向 JavaScript/TypeScript 的库提供了与语言模型交互的标准接口。它支持的不仅是某个模型服务商而是通过 provider 机制接入多种模型包括 OpenAI、Anthropic、Google Gemini、Mistral 等。写一段最小调用并不需要关心底层请求是 REST 还是 SSEimport { generateText } from ai; import { openai } from ai-sdk/openai; const { text } await generateText({ model: openai(gpt-4o-mini), prompt: 用一句话解释什么是 AI SDK, }); console.log(text);这段代码的价值不在于“少写了多少行”而在于调用方式被统一了。如果换成 Anthropic 的模型只需要更换 provider 和模型名。AI SDK 的核心抽象包括generateText一次性生成完整文本适合非流式场景。streamText以流式方式返回文本适合聊天型交互。generateObject要求模型返回结构化对象常配合zod做类型校验。tool主动声明并执行工具调用适合做 Agent。useChat、useCompletion面向 React 的 Hook管理消息历史和流式状态。从架构上看AI SDK 不关心你在哪个框架上运行。它可以在 Next.js 的路由处理器中使用也可以在 Node.js 服务、Express、Cloudflare Workers 等环境中使用只是 Next.js 与 Vercel 的整合体验最顺手。2.2 AI Gateway 是什么AI Gateway 是一个网关型产品。你可以把它理解成模型 API 前面的“总机”应用不直接拨给某个模型厂商而是先拨给总机由总机根据路由策略转发到 OpenAI、Anthropic 或其他服务。一个典型的网关流程是应用向网关发起请求请求里带上模型名和消息内容。网关检查缓存如果命中直接返回缓存结果不再转发给模型商。如果未命中网关按配置转发到目标模型服务商。成功后网关记录 token 用量与耗时并把响应返回给应用。如果目标服务商返回 429 或 5xx网关可以尝试切换到备用模型服务商。这个流程解决的是 LLM 工程里的“横切关注点”。你不需要在每个后端路由里重新实现缓存、限流、日志网关统一承担。2.3 常见误解第一个误解把 AI SDK 和 AI Gateway 当成同一个产品。实际上 AI SDK 是代码库AI Gateway 是基础设施AI SDK 装进应用后可以通过配置把请求指向 AI Gateway也可以不经过网关直接连模型服务商。很多场景下两者只是“可以配合”并不是“必须绑定”。第二个误解以为 AI Gateway 只适合大流量场景。个人项目也可以使用网关来统一账号、统计消耗、避免把多个模型服务商的 API Key 分散写在各个环境里。第三个误解以为有了 AI SDK就不再需要网关了。这个问题反过来说更清楚——如果你的代码只调用一个模型服务商的接口SDK 确实足够当你开始管理多个模型、多个项目、多套密钥并需要限流、缓存和故障回退时SDK 不能替代网关。一句话总结SDK 做的是“应用层抽象”Gateway 做的是“基础设施治理”。两者维度不同但目标一致让开发者专心写业务而不是处理各家模型协议的细节。3. Vercel 免费账号创建与项目部署Vercel 对个人用户非常友好。免费计划可以部署个人项目日常学习、写 Demo 基本够了。注册时推荐使用 GitHub 账号因为后续将仓库导入 Vercel 会少很多步骤。3.1 注册免费账号打开 Vercel 官网点击注册选择 Continuue with GitHub授权后完成登录。Vercel 的免费计划通常被称为 Hobby 计划。在该计划下可以部署个人项目包含基本的构建带宽和 Serverless Function 配额。如果你的项目一开始使用量不大完全可以先跑在免费计划上。注册完成后进入 Dashboard。Dashboard 会显示你已经部署的项目。首次使用没有任何项目可以先初始化一个 Empty Project也可以从 Git 仓库导入。3.2 初始化一个 Next.js 项目并部署如果你本地还没有项目可以先创建一个最小 Next.js 项目npx create-next-applatest ai-sdk-demo cd ai-sdk-demo npm run dev接着在 GitHub 上新建一个仓库将代码推送上去。然后回到 Vercel Dashboard点击 Add New Project选择对应仓库保持默认配置后点击 Deploy。部署完成后Vercel 会分配一个形如xxx.vercel.app的域名这就是你的公网访问地址。3.3 使用 Vercel CLI 部署如果你不想每次通过网页导入仓库也可以使用 Vercel CLInpm i -g vercel vercel login vercel第一次运行 CLI 会在终端打开浏览器完成登录。部署完成后终端会输出一个公网预览地址。这里提醒一点在绑定自定义域名时需要保证域名本身已完成备案、whois 信息等合规要求。本文只讲平台侧的绑定操作不展开地域访问相关的网络处理。4. Next.js AI SDK 环境准备在开始写代码前先整理一下环境Node.js 18 或更高版本推荐当前 LTS 版本。npm、pnpm 或 yarn任选一个即可。Next.js 项目推荐 App Router也就是app/目录结构。一个模型服务商的 API Key例如 OpenAI API Key。安装依赖npm install ai ai-sdk/react ai-sdk/openai zod各包的作用aiAI SDK 核心包提供generateText、streamText、tool等函数。ai-sdk/reactReact Hooks如useChat。ai-sdk/openaiOpenAI provider让 AI SDK 可以调用 OpenAI 模型。zod用于结构化输出的类型校验后续写 tool 时会用到。设置环境变量新建.env.localOPENAI_API_KEY你的_openai_key注意不要给环境变量加NEXT_PUBLIC_前缀否则 API Key 会被打进浏览器端代码这是非常危险的做法。5. 完整示例用 AI SDK 实现一个聊天应用下面以一个最小可运行的聊天应用为例。5.1 后端路由服务端流式转发在app/api/chat/route.ts中创建路由处理器聊天请求会发送到这个接口。// app/api/chat/route.ts import { streamText } from ai; import { openai } from ai-sdk/openai; export const dynamic force-dynamic; export async function POST(req: Request) { const { messages } await req.json(); const result streamText({ model: openai(gpt-4o-mini), system: 你是一位乐于助人的技术助手。回答尽量简洁使用中文。, messages, }); return result.toDataStreamResponse(); }这段代码的核心是streamText。它会把模型生成的内容按流式返回前端可以实时展示而不是等全部内容生成完再一次性显示。toDataStreamResponse()是 AI SDK 提供的方法目的是把 LLM 生成流转换为前端useChat可以直接解析的数据流格式。这里不需要自己写 SSE 解析降低了接入成本。5.2 前端页面useChat Hook在app/page.tsx中编写聊天界面。// app/page.tsx use client; import { useChat } from ai-sdk/react; export default function Page() { const { messages, input, handleInputChange, handleSubmit, isLoading } useChat(); return ( main style{{ maxWidth: 700, margin: 0 auto, padding: 24 }} h1AI SDK Chat Demo/h1 div style{{ whiteSpace: pre-wrap }} {messages.map((m) ( div key{m.id} style{{ background: m.role user ? #eef2ff : #f8fafc, marginBottom: 12, padding: 12, borderRadius: 8, }} strong{m.role user ? 我 : AI}/strong {m.content} /div ))} /div form onSubmit{handleSubmit} style{{ marginTop: 16 }} input value{input} onChange{handleInputChange} placeholder输入你的问题... style{{ width: 80%, padding: 10 }} / button typesubmit disabled{isLoading} 发送 /button /form /main ); }useChat自动管理消息数组和输入框状态。发送消息时它会调用/api/chat这个默认接口并把真实调用每个请求的 messages 历史维护好。页面里m.role就是user或assistant。m.content是当前消息文本在流式场景下AI SDK 会不断更新最新一条 assistant 消息的 content 字段所以不需要手动拼接增量。5.3 本地运行与验证在终端运行npm run dev打开http://localhost:3000输入一个问题例如“你好”如果页面上出现 AI 回复说明 SDK 调用链路已经跑通。这里有一个小提醒如果在 Hobby 计划的 Serverless 环境里调用外部模型请留意平台对函数执行时间的限制。生产项目中不要省略 maxDuration 配置例如export const maxDuration 30;但如果你的本地 Node 环境没有这个限制这句配置不会影响本地运行。6. 接入 AI Gateway统一入口与缓存治理如果只是写一个轻量 Demo上面代码已经可以满足。但当你有多个环境、多个项目并且需要统一查看 token 消耗、限制某个用户的调用频率或希望模型服务商挂掉时自动回退AI Gateway 就会出现。6.1 AI Gateway 在整个链路中的位置应用后端通过 AI SDK 调用“模型 provider”而 provider 可以通过一个自定义baseURL指向 AI Gateway。请求路径变成Next.js Route Handler ↓ AI SDKstreamText / generateText ↓ AI Gateway 统一入口 ↓ OpenAI / Anthropic / Google 等模型服务商网关不关心上层是什么框架只要请求符合标准 OpenAI 兼容协议或网关自定义协议就能接入。6.2 通过环境变量切换直连或网关在实际项目中更推荐把模型连接做成“可切换”的。开发环境直接连模型服务商生产环境走 AI Gateway这样排查问题更容易。在.env.local中增加两个变量OPENAI_API_KEY你的_openai_key AI_GATEWAY_BASE_URL AI_GATEWAY_API_KEY如果配置了网关地址SDK 的 OpenAI provider 会把请求发到网关如果没有配置就直连 OpenAI。后续在 Vercel 项目中配置环境变量时开发环境和生产环境可以使用不同值。也就是说本地开发时可以不配网关 URL部署到生产时配置网关 URL代码本身不需要修改。6.3 AI Gateway 接入示例由于网关通常提供 OpenAI 兼容的baseURL可以使用createOpenAI创建自定义 provider。// lib/model.ts import { createOpenAI } from ai-sdk/openai; import { streamText } from ai; const gatewayProvider createOpenAI({ name: openai-gateway, apiKey: process.env.AI_GATEWAY_API_KEY || process.env.OPENAI_API_KEY, baseURL: process.env.AI_GATEWAY_BASE_URL || undefined, }); export async function askModel({ system, messages, }: { system?: string; messages: Array{ role: user | assistant; content: string }; }) { const result streamText({ model: gatewayProvider(gpt-4o-mini), system, messages, }); return result.toDataStreamResponse(); }在createOpenAI中baseURL指向真正的 OpenAI API 地址或 AI Gateway 地址。当请求进入 AI Gateway 后网关会代为转发到模型服务商。你依然可以配置模型名、temperature 等参数AI SDK 不需要知道自己背后到底接的是谁。由于不同网关注册 endpoint 的方式不同建议以你在控制台开通网关时拿到的 API 文档为准把实际地址填入环境变量即可。6.4 为什么网关里的缓存能省钱一个高频场景是系统提示词固定、问题相近时模型的输出可能高度重复。AI Gateway 可以在服务端缓存模型响应下次相同请求直接返回缓存不再调用模型。这种缓存对大模型成本的影响非常明显。以一次调用耗时 2 秒、消耗数千 token 为例网关命中缓存后这 2 秒和数千 token 的成本都可以省下。但要注意不是所有模型输出都适合缓存。依赖实时数据的业务例如查询天气、查库存就需要关闭缓存或设置较弱缓存策略否则会出现数据过期问题。6.5 网关更适合的团队形态如果团队里有多个业务线各自直接申请模型 API Key容易造成密钥分散管理离职时难以回收。每个业务线自己实现限流标准不统一。无法看到公司级别的模型调用开销。模型服务商故障时没有统一的降级预案。AI Gateway 把这些问题集中到基础设施层对业务代码是透明的。业务服务只需要知道一个网关地址和一个网关密钥不用关心请求最终落到哪家模型商。7. Vercel AI 场景的测试用例设计任何一个真实 AI 应用测试都不能只停留在“能跑通”层面。可以按用例分层来设计。7.1 单元测试不调用外部模型单元测试应该避免真实调用模型否则每次测试都会消耗 token还会因为网络波动导致测试不稳定。可以把“系统提示词构造”“消息历史拼装”这类纯函数单独抽出来然后测试// lib/prompts.ts export function buildSystemPrompt(topic: string) { return 你是一位严谨的技术助手。本次讨论主题是${topic}。回答不要超过 200 字。; }测试它是否按预期返回// tests/prompts.test.ts import { describe, expect, it } from vitest; import { buildSystemPrompt } from ../lib/prompts; describe(buildSystemPrompt, () { it(应包含传入主题和长度限制, () { const prompt buildSystemPrompt(AI Gateway); expect(prompt).toContain(AI Gateway); expect(prompt).toContain(200 字); }); });这类测试不依赖网络执行速度很快适合在 CI 中跑。7.2 冒烟测试真实调用模型当代码真正接入模型后可以保留少量冒烟测试并配合环境变量控制是否执行。// tests/llm.smoke.test.ts import { generateText } from ai; import { openai } from ai-sdk/openai; import { describe, expect, it } from vitest; const runReal process.env.OPENAI_API_KEY ? describe : describe.skip; runReal(模型冒烟测试, () { it( 应返回非空文本, async () { const { text } await generateText({ model: openai(gpt-4o-mini), prompt: 只回复四个字测试通过, }); expect(text).toContain(测试通过); }, 30000 ); });当没有设置OPENAI_API_KEY时测试自动跳过。本地需要触真实调用时再设置 key。这个模式适合验证模型 provider 的连通性也适合检查 AI Gateway 地址是否配置正确。7.3 接口测试通过 HTTP 调用聊天接口你还可以用 curl 直接模拟前端请求curl -X POST http://localhost:3000/api/chat \ -H Content-Type: application/json \ -d { messages: [ { role: user, content: 用三句话介绍 Vercel AI SDK } ] }如果接口正常终端会输出一段数据流其中包含模型回复内容。如果回复没有输出大概率是 API Key 无效、模型名错误或网关配置问题。7.4 测试用例要关注的核心断言AI 应用的断言不能只写死文本更推荐检查这些特征返回内容是否非空。返回内容是否符合格式要求比如是否包含必填关键词。是否能在超时时间内完成。是否有流量入日志或观测平台。当模型服务商故意抛出 500 时是否会回退到备用模型。生产环境中错误路径比正常路径更重要。网关的故障切换、SDK 的超时处理都应该有对应的测试验证。8. Vercel 绑定自定义域名部署完成后Vercel 项目默认使用*.vercel.app域名。很多读者希望绑定自己的域名这里给出通用步骤。8.1 添加域名进入 Vercel 项目页面打开 Settings找到 Domains。在输入框中填写你要绑定的域名例如ai.example.com点击 Add。Vercel 会检测域名是否开启了 Vercel 的 DNS 服务。如果域名不在 Vercel DNS 上会提示你配置 DNS 记录。8.2 到 DNS 控制台配置记录在你的域名 DNS 管理控制台添加记录。不同服务商操作方式有所差异核心步骤如下记录类型主机记录记录值用途CNAMEaicname.vercel-dns.com将子域名解析到 VercelA76.76.21.21根域名解析到 Vercel如果你的域名服务商支持 ALIAS/ANAME根域名也可以使用 CNAME 方式。配置完成后等待 DNS 生效即可。请确保域名解析前已经按规定完成域名实名认证、ICP 备案等合规要求。不同地区、不同服务商要求不同请以实际合规情况为准本文不展开地域网络层面的处理方式。8.3 等待证书自动签发Vercel 检测到 DNS 记录生效后会自动为域名申请并更新 TLS 证书。正常情况下几分钟内 HTTPS 就会生效。如果长时间显示证书未签发可以回到 Domains 页面查看状态确认 DNS 记录是否真的添加正确。9. 常见问题与排查思路9.1 接口返回 401 或 403一般原因是 API Key 无效或环境变量没有加载到当前运行环境中。排查顺序检查.env.local是否存在并且本地开发服务是否重启。检查 Vercel 的 Environment Variables 是否正确配置到对应环境。检查密钥本身是否还有额度。如果使用了 AI Gateway确认网关密钥没有被误用在直连模式。9.2 接口返回 429429 通常是触发了限流。可能来自模型服务商也可能来自 AI Gateway。可以先看错误消息是哪个层返回。如果是模型服务商返回说明你的账号调用频率超过了允许值如果是网关返回说明网关节点的限流策略设置过严。解决办法包括降低请求 QPS、开启网关缓存、配置备用模型或申请更高配额。9.3 聊天接口没有流式效果等待很久才一次性出现可能原因是没有正确使用streamText或者前端没有解析数据流。确认后端返回的是toDataStreamResponse()而不是把整个文本Response.json()返回。还需要确认前端是否使用useChat因为useChat默认会按 AI SDK 数据流格式解析。9.4 AI Gateway 能通但直连 OpenAI 不通这种情况一般说明问题不在代码而在网络或密钥配置。排查时建议先分离变量。如果网关能通说明模型 Key 和模型名本身没问题。直连不通时优先检查环境变量OPENAI_API_KEY是否配置。如果是在服务器环境检查出网策略是否允许访问对应 API 域名。9.5 本地能跑部署到 Vercel 构建失败Vercel 构建时不会执行路由处理器中的业务代码但会安装依赖并检查类型。构建失败通常是依赖版本不一致或 TypeScript 类型错误。建议在本地先执行npm run build构建通过后再推送部署。9.6 完整问题排查表问题现象可能原因排查方式解决方案部署后 API 返回 500环境变量未配置在 Vercel 项目设置中检查环境变量配置OPENAI_API_KEY并重新部署聊天页面报错 404路由文件路径错误检查app/api/chat/route.ts按 App Router 规范调整路径回复内容为空模型没返回文本或超时查看函数日志可用 curl 测试接口缩小范围输出延迟严重没有真正使用流式查看 Network 响应类型确认返回DataStreamResponse构建时报 zod 版本冲突项目依赖版本不一致查看安装日志统一 zod 版本后重新安装AI Gateway 不生效baseURL未传给 provider打印 provider 配置检查AI_GATEWAY_BASE_URL环境变量10. 最佳实践与工程建议10.1 只把密钥放在服务端AI SDK 本身不限制你在哪端使用但安全边界一定要清晰。任何模型 API Key 都不能出现在浏览器端。不要把OPENAI_API_KEY设置为NEXT_PUBLIC_开头的环境变量。前端任何代码都拿不到真正需要读取密钥的代码必须运行在 Node.js 服务端。10.2 尽量使用流式响应用户对大模型的等待耐心有限。一个需要 5 秒才能完整生成的长文本如果使用非流式接口用户会看到空白页面使用流式后用户会看到文字逐字出现体验有本质差别。在 AI SDK 中聊天类场景优先streamText(...)在离线任务、日志总结、一次性提取等无需实时反馈的场景再使用generateText。10.3 统一封装模型调用不要让业务代码直接引用openai(gpt-4o-mini)而是放到一个统一的lib/model.ts中。这样一旦需要切换模型或接入网关只需要改一个文件而不是全局替换。10.4 保持网关层的缓存策略清晰开启缓存能省钱但也可能带来数据陈旧。推荐把请求分为两类确定性回答类常见问题、产品介绍、代码解释开启缓存。实时状态类天气、库存、用户自定义数据不缓存或极短缓存。10.5 日志和观测在生产环境中务必记录每次模型请求的模型名、耗时、token 用量、错误码和请求来源。AI Gateway 往往自带观测能力但业务层也应该保留最基本的 trace id便于联动排查。不要打日志的敏感字段包括API Key用户隐私字段需要脱敏的业务数据完整 prompt 如果没有必要10.6 不要把 AI SDK 与 Next.js 强绑定虽然本文示例基于 Next.js但 AI SDK 可以在 Vite、Express、Node HTTP Server 中使用。如果你的团队不一定切换到 Next.js也可以在现有 Node 服务中引入 AI SDK 的纯函数部分再自行封装路由接口。10.7 在架构上预留回退AI Gateway 的一个重要能力是模型回退。当主模型服务商出现故障时自动切换备用模型。即使你没有接入网关在代码层也应该预留一个模型选择的开关// lib/model.ts export const primaryModel process.env.PRIMARY_MODEL || gpt-4o-mini; export const fallbackModel process.env.FALLBACK_MODEL || claude-3-5-haiku;当 API 调用失败时先识别错误类型再决定是否重试、是否切换模型、是否触发缓存的新鲜度刷新。写在最后对开发者来说Vercel AI SDK 和 AI Gateway 解决的是两个不同层级的问题。AI SDK 让代码不再跟某一家模型服务商的方言绑定把生成文本、流式输出、React 状态管理、工具调用这些高频需求沉淀成标准函数。不管底层模型换成谁你的业务代码可以保持稳定。AI Gateway 则把限流、缓存、日志、故障回退从业务代码中剥离出来放到更靠近网络请求的位置。它不是必须的但当你需要治理多个模型请求时它比在业务代码里手写一百个 if 要可靠得多。建议你从本文的聊天示例开始先用免费账号跑通 AI SDK再把模型 provider 改成网关地址然后补上冒烟测试和域名绑定。整套链路跑下来你其实就建立起了一个可用、可观测、可持续迭代的 LLM 应用骨架。下一步可以继续研究 AI SDK 的 tool calling、generateObject 结构化输出以及网关的灰度分流策略。