返回博客
vibcoding Team4 分钟阅读

Vercel AI SDK 实战:构建流式 AI 对话应用

从零开始使用 Vercel AI SDK 构建流式 AI 对话应用,涵盖多模型支持、Tool Use、错误处理等实用技巧。

#Vercel AI SDK#React#Next.js#流式输出#AI开发
Vercel AI SDK 实战:构建流式 AI 对话应用

Vercel AI SDK 实战:构建流式 AI 对话应用

为什么选择 Vercel AI SDK?

在构建 AI 应用时,最头疼的问题之一就是流式输出。用户不想看着空白页面等待 10 秒才出结果,他们希望看到 AI 逐字打印。

Vercel AI SDK 完美解决了这个问题,而且:

  • 支持 OpenAI、Anthropic、Google 等多家提供商
  • 内置 React Hooks,开发体验极佳
  • 支持 Tool Use(函数调用)
  • 完善的 TypeScript 类型支持

快速开始

1. 安装依赖

bash
npm install ai @ai-sdk/openai @ai-sdk/anthropic

2. 创建 API 路由

typescript
// app/api/chat/route.ts
import { openai } from '@ai-sdk/openai';
import { streamText } from 'ai';

export async function POST(req: Request) {
  const { messages } = await req.json();

  const result = streamText({
    model: openai('gpt-4o'),
    messages,
  });

  return result.toDataStreamResponse();
}

3. 创建聊天界面

tsx
// app/chat/page.tsx
'use client';

import { useChat } from 'ai/react';

export default function ChatPage() {
  const { messages, input, handleInputChange, handleSubmit } = 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((m) => (
          <div key={m.id} className={`p-4 rounded-lg ${
            m.role === 'user' ? 'bg-blue-100' : 'bg-gray-100'
          }`}>
            <strong>{m.role === 'user' ? '你' : 'AI'}:</strong>
            <p className="mt-1">{m.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"
        />
        <button type="submit" className="px-4 py-2 bg-blue-500 text-white rounded">
          发送
        </button>
      </form>
    </div>
  );
}

就这样,你已经有了一个完整的流式聊天应用!

进阶用法

多模型支持

typescript
import { openai } from '@ai-sdk/openai';
import { anthropic } from '@ai-sdk/anthropic';
import { google } from '@ai-sdk/google';

// 根据用户选择切换模型
function getModel(provider: string, modelId: string) {
  switch (provider) {
    case 'openai':
      return openai(modelId);
    case 'anthropic':
      return anthropic(modelId);
    case 'google':
      return google(modelId);
    default:
      throw new Error(`Unknown provider: ${provider}`);
  }
}

Tool Use(函数调用)

typescript
import { streamText, tool } from 'ai';
import { z } from 'zod';

const result = streamText({
  model: openai('gpt-4o'),
  messages,
  tools: {
    weather: tool({
      description: '获取指定城市的天气',
      parameters: z.object({
        city: z.string().describe('城市名称'),
      }),
      execute: async ({ city }) => {
        // 调用天气 API
        const weather = await fetchWeather(city);
        return weather;
      },
    }),
    calculator: tool({
      description: '计算数学表达式',
      parameters: z.object({
        expression: z.string().describe('数学表达式'),
      }),
      execute: async ({ expression }) => {
        return eval(expression);
      },
    }),
  },
});

错误处理

tsx
const { messages, error, isLoading, reload } = useChat({
  onError: (error) => {
    console.error('Chat error:', error);
    toast.error('发送失败,请重试');
  },
});

// 显示错误状态
{error && (
  <div className="p-4 bg-red-100 rounded">
    <p>出错了: {error.message}</p>
    <button onClick={reload}>重试</button>
  </div>
)}

自定义请求头

tsx
const { messages } = useChat({
  api: '/api/chat',
  headers: {
    'X-Custom-Header': 'value',
  },
  body: {
    model: 'gpt-4o',
    temperature: 0.7,
  },
});

性能优化技巧

1. 使用 Edge Runtime

typescript
// app/api/chat/route.ts
export const runtime = 'edge';

Edge Runtime 可以显著降低延迟,尤其是在全球用户分布的场景。

2. 实现消息缓存

typescript
import { kv } from '@vercel/kv';

// 缓存常见问题的回答
const cachedResponse = await kv.get(`chat:${messageHash}`);
if (cachedResponse) {
  return new Response(cachedResponse);
}

3. 限流保护

typescript
import { Ratelimit } from '@upstash/ratelimit';

const ratelimit = new Ratelimit({
  redis: kv,
  limiter: Ratelimit.slidingWindow(10, '1 m'),
});

const { success } = await ratelimit.limit(userId);
if (!success) {
  return new Response('请求过于频繁', { status: 429 });
}

常见问题

Q: 为什么流式输出很慢?

可能原因:

  1. 模型响应慢 - 尝试更快的模型如 gpt-4o-mini
  2. 网络问题 - 使用 Edge Runtime
  3. 前端渲染问题 - 检查是否有不必要的重渲染

Q: 如何处理长对话的 token 限制?

typescript
// 实现对话历史裁剪
function trimMessages(messages: Message[], maxTokens: number) {
  // 保留系统消息和最近的 N 条消息
  const systemMessage = messages.find(m => m.role === 'system');
  const recentMessages = messages.slice(-10);
  return systemMessage ? [systemMessage, ...recentMessages] : recentMessages;
}

总结

Vercel AI SDK 让构建 AI 应用变得简单,但要构建生产级应用,还需要考虑:

  • 错误处理和重试机制
  • 速率限制和成本控制
  • 用户体验优化
  • 多模型策略

完整代码可以在我们的 GitHub 仓库 找到。


下一篇:我们将探讨如何搭建统一的 AI API 网关,实现多模型管理。

v
vibcoding Team
vibcoding 技术团队
觉得有帮助?分享给朋友!