名称: ai-sdk-ui 描述: Vercel AI SDK v5 React 钩子 (useChat, useCompletion, useObject) 用于 AI 聊天界面。适用于 React/Next.js AI 应用或遇到解析流错误、无响应、流式问题的情况。
关键词: ai sdk ui, useChat 钩子, useCompletion 钩子, useObject 钩子, react ai 聊天, ai 聊天界面, 流式 ai ui, nextjs ai 聊天, vercel ai ui, react 流式, ai sdk react, 聊天消息状态, ai 文件附件, 消息持久化, useChat 错误, 流式失败 ui, 解析流错误, useChat 无响应, react ai 钩子, nextjs app 路由器 ai, nextjs pages 路由器 ai 许可证: MIT
AI SDK UI - 前端 React 钩子
用于 Vercel AI SDK v5 的 AI 驱动用户界面的前端 React 钩子。
版本: AI SDK v5.0.116 (稳定) 框架: React 18+, Next.js 15+ 最后更新: 2025-12-22
目录
快速开始 (5 分钟)
安装
bun add ai @ai-sdk/openai # 推荐
# 或: 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="输入消息..."
disabled={isLoading}
/>
</form>
</div>
);
}
API 路由 (Next.js App 路由器)
// 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();
}
结果: 一个功能性的聊天界面,流式 AI 响应,约 10 行前端代码。
何时加载参考
对于详细的实现指南、API 参考和高级模式,加载以下参考文件:
| 参考文件 | 加载时机… |
|---|---|
references/use-chat-migration.md |
从 v4 迁移到 v5,了解破坏性更改 |
references/streaming-patterns.md |
UI 流式最佳实践,性能优化 |
references/top-ui-errors.md |
调试常见 UI 错误,错误预防 |
references/nextjs-integration.md |
Next.js 设置模式,App 与 Pages 路由器差异 |
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 |
使用 Zod 模式的完整 useObject API |
references/nextjs-app-router-full.md |
完整的 Next.js App 路由器实现 |
references/nextjs-pages-router-full.md |
完整的 Next.js Pages 路由器实现 |
useChat 钩子 - 完整参考
基本使用 (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">
{/* 消息 */}
<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 正在思考...</div>}
</div>
{/* 输入 */}
<form onSubmit={handleSubmit} className="p-4 border-t">
<input
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="输入消息..."
disabled={isLoading}
className="w-full p-2 border rounded"
/>
</form>
{/* 错误 */}
{error && <div className="text-red-500 p-4">{error.message}</div>}
</div>
);
}
完整 API 参考
const {
// 消息
messages, // Message[] - 聊天历史
setMessages, // (messages: Message[]) => void - 更新消息
// 操作
sendMessage, // (message: { content: string }) => void - 发送消息 (v5)
reload, // () => void - 重新加载最后响应
stop, // () => void - 停止当前生成
// 状态
isLoading, // boolean - AI 是否在响应?
error, // Error | undefined - 错误(如果有)
// 数据
data, // any[] - 来自流的自定义数据
metadata, // object - 响应元数据
} = useChat({
// 必需
api: '/api/chat', // API 端点
// 可选
id: 'chat-1', // 聊天 ID,用于持久化
initialMessages: [], // 初始消息(控制模式)
// 回调
onFinish: (message, options) => {}, // 响应完成时调用
onError: (error) => {}, // 错误时调用
// 配置
headers: {}, // 自定义头部
body: {}, // 额外主体数据
credentials: 'same-origin', // 获取凭据
// 流式
streamProtocol: 'data', // 'data' | 'text' (默认: 'data')
});
v4 → v5 破坏性更改
关键:useChat 在 v5 中不再管理输入状态!
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 更改摘要:
- 输入管理移除:
input,handleInputChange,handleSubmit不再存在 append()→sendMessage(): 发送消息的新方法onResponse移除: 使用onFinish代替initialMessages→ 控制模式: 使用messages属性进行完全控制maxSteps移除: 仅在服务器端处理
查看 references/use-chat-migration.md 获取完整迁移指南。
高级功能: useChat 支持工具调用(显示 message.toolInvocations)、文件附件(experimental_attachments)和消息持久化(使用 id + initialMessages 的 localStorage)。查看官方文档获取实现示例。
useCompletion 和 useObject 钩子
useCompletion: 用于单提示完成(不是多轮聊天)。返回 { completion, complete, isLoading }。调用 complete(prompt) 生成。API 路由使用 streamText()。
useObject: 使用 Zod 模式流式传输结构化 JSON 并实时更新。返回 { object, submit, isLoading },其中 object 是逐步更新的 Partial<T>。API 路由使用 streamObject()。
查看官方文档获取完整的 API 参考和示例。
Next.js 集成
完整的 App 路由器和 Pages 路由器工作示例,包括全功能聊天 UI 组件、API 路由和适当的流式设置。
📖 加载 references/nextjs-integration.md 获取完整实现代码,包括:
- App 路由器: 带有自动滚动、加载状态、错误处理和 API 路由的完整聊天页面
- Pages 路由器: 带有适当流式设置的完整聊天实现
- 关键差异:
toDataStreamResponse()与pipeDataStreamToResponse()
常见 UI 错误与解决方案
查看 references/top-ui-errors.md 获取完整文档。快速参考:
1. useChat 解析流失败
错误: SyntaxError: Unexpected token in JSON at position X
原因: API 路由未返回正确的流格式。
解决方案:
// ✅ 正确
return result.toDataStreamResponse();
// ❌ 错误
return new Response(result.textStream);
2. useChat 无响应
原因: API 路由未正确流式传输。
解决方案:
// App 路由器 - 使用 toDataStreamResponse()
export async function POST(req: Request) {
const result = streamText({ /* ... */ });
return result.toDataStreamResponse(); // ✅
}
// Pages 路由器 - 使用 pipeDataStreamToResponse()
export default async function handler(req, res) {
const result = streamText({ /* ... */ });
return result.pipeDataStreamToResponse(res); // ✅
}
3. 部署时流式不工作
原因: 部署平台缓冲响应。
解决方案: Vercel 自动检测流式。其他平台可能需要配置。
4. useChat 中陈旧的主体值
原因: body 选项仅在首次渲染时捕获。
解决方案:
// ❌ 错误 - body 仅捕获一次
const { userId } = useUser();
const { messages } = useChat({
body: { userId }, // 陈旧!
});
// ✅ 正确 - 使用控制模式
const { userId } = useUser();
const { messages, sendMessage } = useChat();
sendMessage({
content: input,
data: { userId }, // 每次发送时新鲜
});
5. React 最大更新深度
原因: useEffect 中的无限循环。
解决方案:
// ❌ 错误
useEffect(() => {
saveMessages(messages);
}, [messages, saveMessages]); // saveMessages 触发重新渲染!
// ✅ 正确
useEffect(() => {
saveMessages(messages);
}, [messages]); // 仅依赖 messages
查看 references/top-ui-errors.md 获取另外 7 个常见错误。
流式最佳实践
性能
始终使用流式以获得更好的用户体验:
// ✅ 好 - 流式(显示令牌到达时)
const { messages } = useChat({ api: '/api/chat' });
// ❌ 坏 - 非流式(用户等待完整响应)
const response = await fetch('/api/chat', { method: 'POST' });
UX 模式
显示加载状态:
{isLoading && <div>AI 正在输入...</div>}
提供停止按钮:
{isLoading && <button onClick={stop}>停止</button>}
自动滚动到最新消息:
useEffect(() => {
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
}, [messages]);
加载时禁用输入:
<input disabled={isLoading} />
查看 references/streaming-patterns.md 获取全面的最佳实践。
何时使用此技能
使用 ai-sdk-ui 当:
- 构建 React 聊天界面
- 在 UI 中实现 AI 完成
- 流式 AI 响应到前端
- 构建 Next.js AI 应用
- 处理聊天消息状态
- 在 UI 中显示工具调用
- 管理 AI 的文件附件
- 从 v4 迁移到 v5 (UI 钩子)
- 遇到 useChat/useCompletion 错误
不要使用当:
- 需要后端 AI 功能 → 使用 ai-sdk-core 代替
- 构建非 React 前端 (Svelte, Vue) → 检查官方文档
- 需要生成式 UI / RSC → 参见 https://ai-sdk.dev/docs/ai-sdk-rsc
- 构建原生应用 → 需要不同的 SDK
相关技能:
- ai-sdk-core - 后端文本生成、结构化输出、工具、代理
- 组合两者以构建全栈 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 钩子:
- AI SDK UI 概述: https://ai-sdk.dev/docs/ai-sdk-ui/overview
- useChat: https://ai-sdk.dev/docs/ai-sdk-ui/chatbot
- useCompletion: https://ai-sdk.dev/docs/ai-sdk-ui/completion
- useObject: https://ai-sdk.dev/docs/ai-sdk-ui/object-generation
高级主题 (仅链接):
- 生成式 UI (RSC): https://ai-sdk.dev/docs/ai-sdk-rsc/overview
- 流协议: https://ai-sdk.dev/docs/ai-sdk-ui/stream-protocols
- 消息元数据: https://ai-sdk.dev/docs/ai-sdk-ui/message-metadata
Next.js 集成:
- Next.js App 路由器: https://ai-sdk.dev/docs/getting-started/nextjs-app-router
- Next.js Pages 路由器: https://ai-sdk.dev/docs/getting-started/nextjs-pages-router
迁移与故障排除:
- v4→v5 迁移: https://ai-sdk.dev/docs/migration-guides/migration-guide-5-0
- 故障排除: https://ai-sdk.dev/docs/troubleshooting
- 常见问题: https://ai-sdk.dev/docs/troubleshooting/common-issues
Vercel 部署:
- Vercel 函数: https://vercel.com/docs/functions
- Vercel 上的流式: https://vercel.com/docs/functions/streaming
模板
此技能包含以下模板在 templates/ 中:
- use-chat-basic.tsx - 手动输入的基本聊天 (v5 模式)
- use-chat-tools.tsx - 工具调用 UI 渲染的聊天
- use-chat-attachments.tsx - 文件附件支持
- use-completion-basic.tsx - 基本文本完成
- use-object-streaming.tsx - 流式结构化数据
- nextjs-chat-app-router.tsx - Next.js App 路由器完整示例
- nextjs-chat-pages-router.tsx - Next.js Pages 路由器完整示例
- nextjs-api-route.ts - App 和 Pages 路由器的 API 路由
- message-persistence.tsx - 保存/加载聊天历史
- custom-message-renderer.tsx - 自定义消息组件,支持 Markdown
- 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