前置阅读:建议先阅读 Vercel AI SDK 指南 了解基础概念。
关键概念:Vercel AI SDK 3.0+ 将核心拆分为
ai(通用接口)、@ai-sdk/provider(提供商协议)和@ai-sdk/react(前端 Hooks),实现了模型无关的 AI 应用开发。
² 核心架构与包结构
┌─────────────────┐ │ @ai-sdk/react │ ← useChat / useCompletion / useObject (前端 Hooks) ├─────────────────┤ │ ai │ ← streamText / generateObject / embed (核心运行时) ├─────────────────┤ │ @ai-sdk/openai │ ← OpenAI 提供商适配 │ @ai-sdk/anthropic│ ← Anthropic 适配 │ @ai-sdk/google │ ← Google Gemini 适配 │ @ai-sdk/mistral │ ← Mistral 适配 │ ... │ └─────────────────┘包 职责 典型使用场景 ai通用 AI 运行时 Server Action / API Route 中调用 @ai-sdk/openaiOpenAI 提供商 gpt-4o/gpt-4o-mini模型@ai-sdk/reactReact Hooks 前端流式 UI 组件 @ai-sdk/svelteSvelte 支持 SvelteKit 项目 npm install ai @ai-sdk/openai @ai-sdk/react zod³ 类型安全的结构化输出(generateObject)
相比 JSON 模式,
generateObject提供编译期类型安全 + 运行时校验:// app/api/analyze/route.ts import { openai } from "@ai-sdk/openai"; import { generateObject } from "ai"; import { z } from "zod"; const AnalysisSchema = z.object({ sentiment: z.enum(["positive", "neutral", "negative"]), confidence: z.number().min(0).max(1), keyTopics: z.array(z.string()).max(5), actionItems: z.array(z.object({ priority: z.enum(["high", "medium", "low"]), description: z.string(), })).max(3), }); export type AnalysisResult = z.infer<typeof AnalysisSchema>; export async function POST(req: Request) { const { text } = await req.json(); const { object } = await generateObject({ model: openai("gpt-4o-mini"), schema: AnalysisSchema, prompt: `Analyze the following text and return structured insights:\n\n${text}`, // 自动重试策略:如果解析失败,最多重试 3 次 maxRetries: 3, }); return Response.json(object); // 类型为 AnalysisResult }前端 Hook 版本(
useObject):// app/components/Analyzer.tsx "use client"; import { useObject } from "@ai-sdk/react"; export function Analyzer() { const { object, submit, isLoading } = useObject({ api: "/api/analyze", schema: AnalysisSchema, }); return ( <div> <button onClick={() => submit("Our Q3 revenue grew 45% QoQ...")}> Analyze </button> {isLoading && <span>Processing...</span>} {object && ( <div> <p>Sentiment: {object.sentiment} ({object.confidence})</p> <ul>{object.keyTopics?.map(t => <li key={t}>{t}</li>)}</ul> </div> )} </div> ); }⁴ 流式工具调用(streamText + tools)
核心优势:工具执行状态实时流回前端,无需等待完整响应:
// app/api/chat/route.ts import { streamText, tool } from "ai"; import { openai } from "@ai-sdk/openai"; import { z } from "zod"; const weatherTool = tool({ description: "Get current weather for a location", parameters: z.object({ city: z.string().describe("City name in English"), unit: z.enum(["celsius", "fahrenheit"]).default("celsius"), }), execute: async ({ city, unit }) => { // 实际调用天气 API const res = await fetch( `https://api.weather.example.com/v1/current?city=${city}&unit=${unit}` ); return res.json(); }, }); const calculatorTool = tool({ description: "Perform calculations", parameters: z.object({ expression: z.string().describe("Math expression, e.g. '15 * 23'"), }), execute: async ({ expression }) => { // 安全评估:限制为数学表达式 const safeExpr = expression.replace(/[^0-9+\-*/().\s]/g, ""); return { result: Function(""return ${safeExpr}`)() }; }, }); export async function POST(req: Request) { const { messages } = await req.json(); const result = streamText({ model: openai("gpt-4o"), messages, tools: { weather: weatherTool, calculator: calculatorTool }, maxSteps: 5, // 允许模型自主执行最多 5 轮工具调用 }); return result.toDataStreamResponse(); }前端消费流式工具状态:
// app/components/Chat.tsx "use client"; import { useChat } from "@ai-sdk/react"; export function Chat() { const { messages, input, handleInputChange, handleSubmit, toolInvocations } = useChat({ api: "/api/chat", }); return ( <div> {messages.map(m => ( <div key={m.id}> <strong>{m.role}:</strong> {m.content} {m.toolInvocations?.map(tool => ( <div key={tool.toolCallId} className="tool-call"> <span>🔧 Calling {tool.toolName}...</span> {tool.state === "result" && ( <pre>{JSON.stringify(tool.result, null, 2)}</pre> )} </div> ))} </div> ))} <form onSubmit={handleSubmit}> <input value={input} onChange={handleInputChange} placeholder="Ask about weather or math..." /> </form> </div> ); }⁵ 多模型路由与故障回退
// lib/ai-router.ts import { openai } from "@ai-sdk/openai"; import { anthropic } from "@ai-sdk/anthropic"; import { google } from "@ai-sdk/google"; import { LanguageModel } from "ai"; type ModelTier = "fast" | "balanced" | "quality"; type TaskType = "chat" | "code" | "analysis" | "creative"; const MODEL_REGISTRY: Record<ModelTier, Record<TaskType, LanguageModel[]>> = { fast: { chat: [openai("gpt-4o-mini"), google("gemini-1.5-flash")], code: [openai("gpt-4o-mini")], analysis: [google("gemini-1.5-flash")], creative: [openai("gpt-4o-mini")], }, balanced: { chat: [openai("gpt-4o"), anthropic("claude-3-5-sonnet-20241022")], code: [anthropic("claude-3-5-sonnet-20241022"), openai("gpt-4o")], analysis: [openai("gpt-4o")], creative: [anthropic("claude-3-5-sonnet-20241022")], }, quality: { chat: [anthropic("claude-3-opus-20240229"), openai("gpt-4o")], code: [anthropic("claude-3-opus-20240229")], analysis: [openai("gpt-4o")], creative: [anthropic("claude-3-opus-20240229")], }, }; export class ModelRouter { async routeWithFallback( tier: ModelTier, task: TaskType, promptFn: (model: LanguageModel) => Promise<any> ): Promise<{ result: any; model: string; attempts: number }> { const candidates = MODEL_REGISTRY[tier][task]; let lastError: Error | null = null; for (let i = 0; i < candidates.length; i++) { try { const result = await promptFn(candidates[i]); return { result, model: candidates[i].modelId, attempts: i + 1, }; } catch (err) { lastError = err as Error; console.warn(`Model ${candidates[i].modelId} failed:`, err.message); // 指数退避 await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000)); } } throw new Error( `All ${candidates.length} models failed. Last error: ${lastError?.message}` ); } } // 使用示例:Route 并自动降级 const router = new ModelRouter(); const { result, model, attempts } = await router.routeWithFallback( "balanced", "code", async (model) => { const { text } = await generateText({ model, prompt: "Explain async/await in Python" }); return text; } ); console.log(`Used ${model} after ${attempts} attempt(s)`);⁶ Server Action 集成(Next.js App Router)
无需 API Route,直接在 Server Action 中调用 AI SDK:
// app/actions/generate.ts "use server"; import { generateText, streamText } from "ai"; import { openai } from "@ai-sdk/openai"; import { createStreamableValue } from "ai/rsc"; // 同步生成 export async function generateSummary(content: string) { const { text } = await generateText({ model: openai("gpt-4o-mini"), prompt: `Summarize in 3 bullet points:\n${content}`, }); return text; } // 流式生成(Server Component 流式传输) export async function streamSummary(content: string) { const stream = createStreamableValue(""); (async () => { const { textStream } = await streamText({ model: openai("gpt-4o-mini"), prompt: `Summarize:\n${content}`, }); for await (const delta of textStream) { stream.update(delta); } stream.done(); })(); return stream.value; }// app/components/Summary.tsx import { useStreamableValue } from "ai/rsc"; import { streamSummary } from "@/app/actions/generate"; export async function SummaryCard({ content }: { content: string }) { const stream = await streamSummary(content); return <StreamingContent stream={stream} />; } "use client"; function StreamingContent({ stream }: { stream: any }) { const [text] = useStreamableValue(stream); return <div className="whitespace-pre-wrap">{text}</div>; }⁷ 性能基准与最佳实践
模式 首字节延迟 (TTFB) 总延迟 适用场景 generateText800-1500ms 完整后返回 短回答、结构化输出 streamText200-500ms 流式持续 长文本生成、Chat UI generateObject1000-2000ms 完整后返回 需要类型安全的 API streamObject300-600ms 流式持续 结构化数据的渐进渲染 关键优化:
// 启用响应式流式传输 const result = streamText({ model: openai("gpt-4o-mini"), prompt: "...", // 将长文本分块发送,减少前端等待 experimental_streamData: true, // 限制最大 Token,控制成本和延迟 maxTokens: 2048, // 温度控制:确定任务用 0,创意任务用 0.7+ temperature: 0.3, });
延伸阅读:
- Vercel AI SDK 指南 — AI SDK 基础概念与 Vercel 平台原生集成
- Vercel Edge Functions 深度指南 — 流式响应的网络层优化
- LLM API 基础调用指南 — 底层 API 调用与 Token 经济学
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。
「工具与平台」更多文章
Vercel Edge Config 完全指南:毫秒级配置下发与 A/B 测试驱动
深入 Vercel Edge Config 全局键值存储:与 Edge Functions / Middleware 的低延迟集成、A/B 测试与功能开关实现、多环境管理、版本控制与回滚策略,提供 TypeScript 端到端实现与性能基准。
Vercel Analytics 深度指南:Web Vitals 监控、真实用户性能与转化归因
全面解析 Vercel Analytics(真实用户监控 RUM)与 Speed Insights(Web Vitals)两大工具,覆盖安装集成、自定义事件追踪、性能瓶颈诊断、转化归因分析,以及与 Google Analytics 4 / Datadog 的对比选型。
Cloudflare Workers AI 高级实战:自定义模型部署、批量推理与 AI Gateway 缓存策略
深入 Cloudflare Workers AI 生产级应用:Workers AI Catalog 模型量化原理、批量推理优化、AI Gateway 多级缓存与智能限流、自定义模型 Workers AI 部署(TensorFlow.js / ONNX Runtime),含完整 TypeScript 实现与成本基准。