mcpField
A
ai-sdk-ui

ai-sdk-ui

github.com/secondsky开发247140 次安装6 周前更新
代码仓库

关于 ai-sdk-ui

ai-sdk-ui 是面向 React 前端开发者的 AI 界面技能,介绍 Vercel AI SDK v5 的 UI Hooks、流式响应及 Next.js 集成,并提供模板和排错参考。

主要功能

  1. 01构建聊天界面
  2. 02流式文本补全
  3. 03生成结构化数据
  4. 04展示工具调用与附件
  5. 05Next.js 路由示例
  6. 06迁移与错误排查指南

适用场景

  1. 01为 React 应用实现多轮聊天
  2. 02在界面中呈现 AI 流式回复
  3. 03生成并展示结构化 JSON
  4. 04升级 useChat v4 代码至 v5

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/secondsky/claude-skills --skill ai-sdk-ui

安装后在 Claude Code 中输入/ai-sdk-ui确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
file-attachments-guide.md
links-to-official-docs.md
message-persistence.md
nextjs-app-router-full.md
nextjs-integration.md
nextjs-pages-router-full.md
streaming-patterns.md
tool-calling-ui.md
top-ui-errors.md
use-chat-migration.md
use-completion-full-reference.md
use-object-full-reference.md
scripts/
check-versions.sh
templates/
custom-message-renderer.tsx
eslint.config.js
message-persistence.tsx
nextjs-api-route.ts
nextjs-chat-app-router.tsx
nextjs-chat-pages-router.tsx
package.json
use-chat-attachments.tsx
use-chat-basic.tsx
use-chat-tools.tsx
use-completion-basic.tsx
use-object-streaming.tsx

详细介绍

AI SDK UI - 前端 React Hooks

使用 Vercel AI SDK v5 构建 AI 驱动用户界面的前端 React hooks。

版本:AI SDK v5.0.116(稳定版) 框架:React 18+、Next.js 15+ 最后更新:2025-12-22

目录

  1. 快速入门
  2. 何时加载参考资料
  3. useChat Hook
  4. useCompletion Hook
  5. useObject Hook
  6. Next.js 集成
  7. 常见 UI 错误与解决方案
  8. 流式传输最佳实践
  9. 何时使用此技能
  10. 软件包版本

快速入门(5 分钟)

安装
bun add ai @ai-sdk/openai  # preferred
# or: bun add ai @ai-sdk/openai
基础聊天组件(v5)
// app/chat/page.tsx
'use client';
import { useChat } from 'ai/react';
import { useState, FormEvent } from 'react';

export default function Chat() {
  const { messages, sendMessage, isLoading } = useChat({
    api: '/api/chat',
  });
  const [input, setInput] = useState('');

  const handleSubmit = (e: FormEvent) => {
    e.preventDefault();
    sendMessage({ content: input });
    setInput('');
  };

  return (
    <div>
      <div>
        {messages.map(m => (
          <div key={m.id}>
            <strong>{m.role}:</strong> {m.content}
          </div>
        ))}
      </div>
      <form onSubmit={handleSubmit}>
        <input
          value={input}
          onChange={(e) => setInput(e.target.value)}
          placeholder="Type a message..."
          disabled={isLoading}
        />
      </form>
    </div>
  );
}
API 路由(Next.js App Router)
// app/api/chat/route.ts
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-4-turbo'),
    messages,
  });

  return result.toDataStreamResponse();
}

结果:仅用约 10 行前端代码,即可实现支持 AI 响应流式传输的聊天界面。


何时加载参考资料

如需详细的实现指南、API 参考和高级模式,请加载以下参考文件:

参考文件加载时机……
references/use-chat-migration.md从 v4 迁移到 v5,了解不兼容变更
references/streaming-patterns.mdUI 流式传输最佳实践、性能优化
references/top-ui-errors.md调试常见 UI 错误、预防错误
references/nextjs-integration.mdNext.js 设置模式、App Router 与 Pages Router 的差异
references/links-to-official-docs.md查找 Vercel AI SDK 官方文档
references/tool-calling-ui.md在聊天 UI 中实现工具/函数调用
references/file-attachments-guide.md为聊天添加文件上传/附件支持
references/message-persistence.md使用 localStorage 持久化聊天记录
references/use-completion-full-reference.md完整的 useCompletion API 和示例
references/use-object-full-reference.md完整的 useObject API 和 Zod 架构
references/nextjs-app-router-full.md完整的 Next.js App Router 实现
references/nextjs-pages-router-full.md完整的 Next.js Pages Router 实现

useChat Hook - 完整参考

基本用法(v5 模式)
'use client';
import { useChat } from 'ai/react';
import { useState, FormEvent } from 'react';

export default function ChatComponent() {
  const { messages, sendMessage, isLoading, error } = useChat({
    api: '/api/chat',
  });
  const [input, setInput] = useState('');

  const handleSubmit = (e: FormEvent) => {
    e.preventDefault();
    if (!input.trim()) return;

    sendMessage({ content: input });
    setInput('');
  };

  return (
    <div className="flex flex-col h-screen">
      {/* Messages */}
      <div className="flex-1 overflow-y-auto p-4">
        {messages.map(message => (
          <div
            key={message.id}
            className={message.role === 'user' ? 'text-right' : 'text-left'}
          >
            <div className="inline-block p-2 rounded bg-gray-100">
              {message.content}
            </div>
          </div>
        ))}
        {isLoading && <div className="text-gray-500">AI is thinking...</div>}
      </div>

      {/* Input */}
      <form onSubmit={handleSubmit} className="p-4 border-t">
        <input
          value={input}
          onChange={(e) => setInput(e.target.value)}
          placeholder="Type a message..."
          disabled={isLoading}
          className="w-full p-2 border rounded"
        />
      </form>

      {/* Error */}
      {error && <div className="text-red-500 p-4">{error.message}</div>}
    </div>
  );
}
完整 API 参考
const {
  // Messages
  messages,           // Message[] - Chat history
  setMessages,        // (messages: Message[]) => void - Update messages

  // Actions
  sendMessage,        // (message: { content: string }) => void - Send message (v5)
  reload,             // () => void - Reload last response
  stop,               // () => void - Stop current generation

  // State
  isLoading,          // boolean - Is AI responding?
  error,              // Error | undefined - Error if any

  // Data
  data,               // any[] - Custom data from stream
  metadata,           // object - Response metadata
} = useChat({
  // Required
  api: '/api/chat',   // API endpoint

  // Optional
  id: 'chat-1',       // Chat ID for persistence
  initialMessages: [], // Initial messages (controlled mode)

  // Callbacks
  onFinish: (message, options) => {},  // Called when response completes
  onError: (error) => {},              // Called on error

  // Configuration
  headers: {},        // Custom headers
  body: {},           // Additional body data
  credentials: 'same-origin', // Fetch credentials

  // Streaming
  streamProtocol: 'data', // 'data' | 'text' (default: 'data')
});
v4 → v5 不兼容变更

重要:v5 中的 useChat 不再管理输入状态!

v4(旧版 - 请勿使用):

const { messages, input, handleInputChange, handleSubmit, append } = useChat();

<form onSubmit={handleSubmit}>
  <input value={input} onChange={handleInputChange} />
</form>

v5(新版 - 正确用法):

const { messages, sendMessage } = useChat();
const [input, setInput] = useState('');

<form onSubmit={(e) => {
  e.preventDefault();
  sendMessage({ content: input });
  setInput('');
}}>
  <input value={input} onChange={(e) => setInput(e.target.value)} />
</form>

v5 变更摘要:

  1. 移除输入管理:不再提供 input、handleInputChange、handleSubmit
  2. append() → sendMessage():用于发送消息的新方法
  3. 移除 onResponse:改用 onFinish
  4. initialMessages → 受控模式:使用 messages 属性进行全面控制
  5. 移除 maxSteps:仅在服务器端处理

完整迁移指南请参阅 references/use-chat-migration.md。

**高级功能:**useChat 支持工具调用(显示 message.toolInvocations)、文件附件(experimental_attachments)和消息持久化(使用 id + initialMessages 的 localStorage)。实现示例请参阅官方文档。


useCompletion 和 useObject Hooks

useCompletion:用于单提示词补全(而非多轮聊天)。返回 { completion, complete, isLoading }。调用 complete(prompt) 进行生成。API 路由使用 streamText()。

useObject:使用 Zod 架构流式传输结构化 JSON,并实时更新。返回 { object, submit, isLoading },其中 object 是会逐步更新的 Partial<T>。API 路由使用 streamObject()。

完整 API 参考和示例请参阅官方文档。


Next.js 集成

为 App Router 和 Pages Router 提供完整可用的示例,包含完整的聊天 UI 组件、API 路由和正确的流式传输设置。

📖 加载 references/nextjs-integration.md,查看完整实现代码,包括:

  • App Router:完整的聊天页面,包含自动滚动、加载状态、错误处理和 API 路由
  • Pages Router:包含正确流式传输设置的完整聊天实现
  • 主要区别:toDataStreamResponse() 与 pipeDataStreamToResponse()

常见 UI 错误及解决方案

完整文档请参见 references/top-ui-errors.md。速查:

1. useChat 无法解析流

错误:SyntaxError: Unexpected token in JSON at position X

原因:API 路由未返回正确的流格式。

解决方案:

// ✅ CORRECT
return result.toDataStreamResponse();

// ❌ WRONG
return new Response(result.textStream);
2. useChat 没有响应

原因:API 路由未正确进行流式传输。

解决方案:

// App Router - use toDataStreamResponse()
export async function POST(req: Request) {
  const result = streamText({ /* ... */ });
  return result.toDataStreamResponse(); // ✅
}

// Pages Router - use pipeDataStreamToResponse()
export default async function handler(req, res) {
  const result = streamText({ /* ... */ });
  return result.pipeDataStreamToResponse(res); // ✅
}
3. 部署后流式传输无法正常工作

原因:部署平台缓冲了响应。

解决方案:Vercel 会自动检测流式传输。其他平台可能需要配置。

4. useChat 的 body 值过时

原因:body 选项仅在首次渲染时捕获。

解决方案:

// ❌ WRONG - body captured once
const { userId } = useUser();
const { messages } = useChat({
  body: { userId },  // Stale!
});

// ✅ CORRECT - use controlled mode
const { userId } = useUser();
const { messages, sendMessage } = useChat();

sendMessage({
  content: input,
  data: { userId },  // Fresh on each send
});
5. React 最大更新深度错误

原因:useEffect 中出现无限循环。

解决方案:

// ❌ WRONG
useEffect(() => {
  saveMessages(messages);
}, [messages, saveMessages]); // saveMessages triggers re-render!

// ✅ CORRECT
useEffect(() => {
  saveMessages(messages);
}, [messages]); // Only depend on messages

另有 7 个常见错误,请参见 references/top-ui-errors.md。


流式传输最佳实践

性能

始终使用流式传输,以提升用户体验:

// ✅ GOOD - Streaming (shows tokens as they arrive)
const { messages } = useChat({ api: '/api/chat' });

// ❌ BAD - Non-streaming (user waits for full response)
const response = await fetch('/api/chat', { method: 'POST' });
用户体验模式

显示加载状态:

{isLoading && <div>AI is typing...</div>}

提供停止按钮:

{isLoading && <button onClick={stop}>Stop</button>}

自动滚动到最新消息:

useEffect(() => {
  messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
}, [messages]);

加载时禁用输入:

<input disabled={isLoading} />

全面的最佳实践请参见 references/streaming-patterns.md。


何时使用此技能

适用于以下场景:
  • 构建 React 聊天界面
  • 在 UI 中实现 AI 补全
  • 将 AI 响应流式传输到前端
  • 构建 Next.js AI 应用
  • 处理聊天消息状态
  • 在 UI 中显示工具调用
  • 管理 AI 文件附件
  • 从 v4 迁移到 v5(UI Hooks)
  • 遇到 useChat/useCompletion 错误
不适用于以下场景:
  • 需要后端 AI 功能 → 改用 ai-sdk-core
  • 构建非 React 前端(Svelte、Vue)→ 查看官方文档
  • 需要 Generative UI / RSC → 请参见 https://ai-sdk.dev/docs/ai-sdk-rsc
  • 构建原生应用 → 需要使用其他 SDK
相关技能:
  • ai-sdk-core - 后端文本生成、结构化输出、工具、Agent
  • 组合使用两者,构建全栈 AI 应用

软件包版本

必需版本:

{
  "dependencies": {
    "ai": "^5.0.116",
    "@ai-sdk/openai": "^2.0.88",
    "react": "^18.2.0",
    "zod": "^3.23.8",
    "isomorphic-dompurify": "^2.16.0"
  }
}

Next.js:

{
  "dependencies": {
    "next": "^14.0.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  }
}

版本说明:

  • AI SDK v5.0.116+(稳定版)
  • React 18+(支持 React 19)
  • 推荐使用 Next.js 14+(13.4+ 也可用)
  • 使用 Zod 3.23.8+ 进行架构验证

官方文档链接

核心 UI Hooks:

进阶主题(仅提供链接):

Next.js 集成:

迁移与故障排除:

Vercel 部署:


模板

此技能在 templates/ 中包含以下模板:

  1. use-chat-basic.tsx - 使用手动输入的基础聊天(v5 模式)
  2. use-chat-tools.tsx - 带工具调用 UI 渲染的聊天
  3. use-chat-attachments.tsx - 支持文件附件
  4. use-completion-basic.tsx - 基础文本补全
  5. use-object-streaming.tsx - 流式结构化数据
  6. nextjs-chat-app-router.tsx - Next.js App Router 完整示例
  7. nextjs-chat-pages-router.tsx - Next.js Pages Router 完整示例
  8. nextjs-api-route.ts - 适用于 App Router 和 Pages Router 的 API 路由
  9. message-persistence.tsx - 保存/加载聊天历史
  10. custom-message-renderer.tsx - 使用 Markdown 的自定义消息组件
  11. package.json - 依赖项模板

参考文档

参见 references/ 中的文档:

  • use-chat-migration.md - 完整的 v4→v5 迁移指南
  • streaming-patterns.md - UI 流式传输最佳实践
  • top-ui-errors.md - 12 个常见 UI 错误及解决方案
  • nextjs-integration.md - Next.js 设置模式
  • links-to-official-docs.md - 按类别整理的官方文档链接

生产环境测试:WordPress Auditor (https://wordpress-auditor.webfonts.workers.dev) 最后更新:2025-10-22

评论

支持 Markdown