Vercel AI SDK 是什么
Vercel AI SDK 是一个用于构建 AI 应用的 TypeScript 工具包。它的核心价值在于:让前端开发者能轻松构建流式 AI 应用,不需要深入了解 LLM API 的底层细节。
和 LangChain、LlamaIndex 这些 Python 框架不同,Vercel AI SDK 是 TypeScript 优先的,天然适合 Next.js、React、Svelte 等前端框架。如果你是全栈 Web 开发者,这可能是你最顺手的 AI 开发工具。
核心特性
| 特性 | 说明 |
|---|---|
| 流式响应 | 原生支持 SSE 流式传输 |
| 多模型支持 | 统一的 Provider 接口 |
| React Hooks | useChat、useCompletion 等 |
| 工具调用 | 支持 Function Calling |
| 结构化输出 | Zod Schema 验证 |
| 中间件 | 请求/响应拦截 |
| 框架无关 | 支持 Next.js、Nuxt、SvelteKit 等 |
安装与配置
安装
# 核心包
npm install ai
# 模型提供商(按需安装)
npm install @ai-sdk/openai
npm install @ai-sdk/anthropic
npm install @ai-sdk/google
配置环境变量
# .env.local
OPENAI_API_KEY=your-openai-key
ANTHROPIC_API_KEY=your-anthropic-key
Provider 系统
Vercel AI SDK 通过 Provider 系统统一了不同模型的调用接口。
创建模型实例
import { openai } from '@ai-sdk/openai';
import { anthropic } from '@ai-sdk/anthropic';
import { google } from '@ai-sdk/google';
// OpenAI
const gpt4o = openai('gpt-4o');
const gpt4oMini = openai('gpt-4o-mini');
// Anthropic
const claude = anthropic('claude-sonnet-4-20250514');
// Google
const gemini = google('gemini-1.5-pro');
切换模型
因为接口统一,切换模型只需要改一行代码:
import { generateText } from 'ai';
// 用 OpenAI
const result1 = await generateText({
model: openai('gpt-4o-mini'),
prompt: '什么是 TypeScript?'
});
// 切换到 Anthropic,其他代码不变
const result2 = await generateText({
model: anthropic('claude-sonnet-4-20250514'),
prompt: '什么是 TypeScript?'
});
核心 API
generateText — 生成文本
import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';
const { text, usage } = await generateText({
model: openai('gpt-4o-mini'),
system: '你是一个 TypeScript 专家,用中文回答。',
prompt: '解释 TypeScript 的泛型',
});
console.log(text);
console.log(`Token 使用: ${usage.totalTokens}`);
streamText — 流式生成
import { streamText } from 'ai';
import { openai } from '@ai-sdk/openai';
const result = streamText({
model: openai('gpt-4o-mini'),
system: '你是一个技术博客作者。',
prompt: '写一篇关于 WebAssembly 的介绍',
});
// 流式输出
for await (const chunk of result.textStream) {
process.stdout.write(chunk);
}
generateObject — 结构化输出
import { generateObject } from 'ai';
import { openai } from '@ai-sdk/openai';
import { z } from 'zod';
const { object } = await generateObject({
model: openai('gpt-4o-mini'),
schema: z.object({
name: z.string().describe('项目名称'),
description: z.string().describe('项目描述'),
techStack: z.array(z.string()).describe('技术栈'),
difficulty: z.enum(['easy', 'medium', 'hard']).describe('难度'),
}),
prompt: '推荐一个适合初学者的全栈项目',
});
console.log(object);
// {
// name: "Todo App",
// description: "一个简单的待办事项应用...",
// techStack: ["Next.js", "TypeScript", "Prisma", "SQLite"],
// difficulty: "easy"
// }
React Hooks
这是 Vercel AI SDK 最强大的部分——为 React 提供的开箱即用的 Hooks。
useChat — 聊天界面
// app/api/chat/route.ts (Next.js API Route)
import { streamText } from 'ai';
import { openai } from '@ai-sdk/openai';
export async function POST(req: Request) {
const { messages } = await req.json();
const result = streamText({
model: openai('gpt-4o-mini'),
system: '你是一个友好的助手,用中文回答。',
messages,
});
return result.toDataStreamResponse();
}
// components/Chat.tsx
'use client';
import { useChat } from 'ai/react';
export function Chat() {
const { messages, input, handleInputChange, handleSubmit, isLoading } =
useChat();
return (
<div className="flex flex-col h-screen max-w-2xl mx-auto p-4">
{/* 消息列表 */}
<div className="flex-1 overflow-y-auto space-y-4">
{messages.map((message) => (
<div
key={message.id}
className={`p-3 rounded-lg ${
message.role === 'user'
? 'bg-blue-100 ml-auto max-w-[80%]'
: 'bg-gray-100 mr-auto max-w-[80%]'
}`}
>
<p className="text-sm font-medium">
{message.role === 'user' ? '你' : 'AI'}
</p>
<p>{message.content}</p>
</div>
))}
</div>
{/* 输入框 */}
<form onSubmit={handleSubmit} className="flex gap-2 mt-4">
<input
value={input}
onChange={handleInputChange}
placeholder="输入消息..."
className="flex-1 p-2 border rounded-lg"
disabled={isLoading}
/>
<button
type="submit"
disabled={isLoading}
className="px-4 py-2 bg-blue-500 text-white rounded-lg disabled:opacity-50"
>
{isLoading ? '思考中...' : '发送'}
</button>
</form>
</div>
);
}
useChat 的高级用法
const {
messages,
input,
handleInputChange,
handleSubmit,
isLoading,
error,
reload, // 重新生成最后一条回复
stop, // 停止生成
append, // 手动添加消息
setMessages // 设置消息列表
} = useChat({
api: '/api/chat',
initialMessages: [],
onFinish: (message) => {
console.log('生成完成:', message);
},
onError: (error) => {
console.error('出错了:', error);
},
});
useCompletion — 文本补全
'use client';
import { useCompletion } from 'ai/react';
export function CodeGenerator() {
const { completion, input, handleInputChange, handleSubmit, isLoading } =
useCompletion({
api: '/api/completion',
});
return (
<div className="p-4">
<form onSubmit={handleSubmit}>
<textarea
value={input}
onChange={handleInputChange}
placeholder="描述你想要的代码..."
className="w-full p-2 border rounded"
rows={3}
/>
<button
type="submit"
disabled={isLoading}
className="mt-2 px-4 py-2 bg-green-500 text-white rounded"
>
生成代码
</button>
</form>
{completion && (
<pre className="mt-4 p-4 bg-gray-900 text-green-400 rounded overflow-x-auto">
<code>{completion}</code>
</pre>
)}
</div>
);
}
工具调用(Tool Calling)
让 AI 调用你定义的函数:
定义工具
// app/api/chat/route.ts
import { streamText, tool } from 'ai';
import { openai } from '@ai-sdk/openai';
import { z } from 'zod';
export async function POST(req: Request) {
const { messages } = await req.json();
const result = streamText({
model: openai('gpt-4o'),
messages,
tools: {
getWeather: tool({
description: '获取指定城市的天气信息',
parameters: z.object({
city: z.string().describe('城市名称'),
}),
execute: async ({ city }) => {
// 调用天气 API
const weather = await fetchWeather(city);
return {
city,
temperature: weather.temp,
condition: weather.condition,
};
},
}),
searchDocs: tool({
description: '搜索项目文档',
parameters: z.object({
query: z.string().describe('搜索关键词'),
}),
execute: async ({ query }) => {
const results = await searchDocuments(query);
return results;
},
}),
},
});
return result.toDataStreamResponse();
}
多步工具调用
AI 可以连续调用多个工具来完成复杂任务:
const result = streamText({
model: openai('gpt-4o'),
messages,
tools: { getWeather, searchDocs, calculateRoute },
maxSteps: 5, // 最多执行 5 步
});
Next.js 集成
完整的 Chat 应用
项目结构:
app/
api/
chat/
route.ts # API 路由
page.tsx # 页面
components/
Chat.tsx # 聊天组件
MessageList.tsx # 消息列表
ChatInput.tsx # 输入框
API 路由
// app/api/chat/route.ts
import { streamText } from 'ai';
import { openai } from '@ai-sdk/openai';
export const runtime = 'edge'; // 使用 Edge Runtime 获得更好的流式性能
export async function POST(req: Request) {
const { messages } = await req.json();
const result = streamText({
model: openai('gpt-4o-mini'),
system: `你是一个编程助手。
- 用中文回答
- 代码示例使用 TypeScript
- 回答要简洁实用`,
messages,
maxTokens: 2000,
temperature: 0.7,
});
return result.toDataStreamResponse();
}
带 Markdown 渲染的聊天组件
// components/Chat.tsx
'use client';
import { useChat } from 'ai/react';
import ReactMarkdown from 'react-markdown';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { oneDark } from 'react-syntax-highlighter/dist/esm/styles/prism';
export function Chat() {
const { messages, input, handleInputChange, handleSubmit, isLoading } =
useChat();
return (
<div className="max-w-3xl mx-auto p-4">
<div className="space-y-4 mb-4">
{messages.map((m) => (
<div key={m.id} className="flex gap-3">
<div className="font-bold w-16 shrink-0">
{m.role === 'user' ? '你' : 'AI'}
</div>
<div className="prose prose-sm max-w-none">
<ReactMarkdown
components={{
code({ className, children, ...props }) {
const match = /language-(\w+)/.exec(className || '');
return match ? (
<SyntaxHighlighter
style={oneDark}
language={match[1]}
PreTag="div"
>
{String(children).replace(/\n$/, '')}
</SyntaxHighlighter>
) : (
<code className={className} {...props}>
{children}
</code>
);
},
}}
>
{m.content}
</ReactMarkdown>
</div>
</div>
))}
</div>
<form onSubmit={handleSubmit} className="flex gap-2">
<input
value={input}
onChange={handleInputChange}
placeholder="问我任何编程问题..."
className="flex-1 p-3 border rounded-lg"
/>
<button
type="submit"
disabled={isLoading}
className="px-6 py-3 bg-black text-white rounded-lg"
>
发送
</button>
</form>
</div>
);
}
中间件
Vercel AI SDK 支持中间件来拦截和修改请求/响应:
import { streamText, experimental_wrapLanguageModel } from 'ai';
import { openai } from '@ai-sdk/openai';
// 创建带日志的模型
const modelWithLogging = experimental_wrapLanguageModel({
model: openai('gpt-4o-mini'),
middleware: {
wrapGenerate: async ({ doGenerate, params }) => {
console.log('请求参数:', JSON.stringify(params, null, 2));
const result = await doGenerate();
console.log('Token 使用:', result.usage);
return result;
},
},
});
const result = await streamText({
model: modelWithLogging,
prompt: 'Hello!',
});
实用模式
1. 模型回退
import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';
import { anthropic } from '@ai-sdk/anthropic';
async function generateWithFallback(prompt: string) {
try {
return await generateText({
model: openai('gpt-4o-mini'),
prompt,
});
} catch (error) {
console.warn('OpenAI 失败,切换到 Anthropic');
return await generateText({
model: anthropic('claude-sonnet-4-20250514'),
prompt,
});
}
}
2. 速率限制
// 简单的速率限制
const rateLimiter = new Map<string, number[]>();
function checkRateLimit(userId: string, limit = 10, window = 60000) {
const now = Date.now();
const timestamps = rateLimiter.get(userId) || [];
const recent = timestamps.filter(t => now - t < window);
if (recent.length >= limit) {
throw new Error('请求过于频繁,请稍后再试');
}
recent.push(now);
rateLimiter.set(userId, recent);
}
3. 对话历史持久化
// 使用数据库存储对话历史
import { prisma } from '@/lib/prisma';
export async function POST(req: Request) {
const { messages, conversationId } = await req.json();
// 保存用户消息
await prisma.message.create({
data: {
conversationId,
role: 'user',
content: messages[messages.length - 1].content,
},
});
const result = streamText({
model: openai('gpt-4o-mini'),
messages,
onFinish: async ({ text }) => {
// 保存 AI 回复
await prisma.message.create({
data: {
conversationId,
role: 'assistant',
content: text,
},
});
},
});
return result.toDataStreamResponse();
}
部署
Vercel 部署
Vercel AI SDK 和 Vercel 平台天然集成:
# 安装 Vercel CLI
npm i -g vercel
# 部署
vercel
# 设置环境变量
vercel env add OPENAI_API_KEY
其他平台
Vercel AI SDK 不绑定 Vercel 平台,可以部署到任何支持 Node.js 的环境:
- AWS Lambda
- Google Cloud Functions
- Cloudflare Workers(使用 Edge Runtime)
- 自托管 Node.js 服务器
好的 AI 应用不只是调用 API,而是把 AI 能力无缝融入用户体验。Vercel AI SDK 让这件事变得简单。
相关文章
评论
加载中...
评论
加载中...