AI 聊天

通过 Vercel AI SDK 与 AI Elements 流式返回 OpenAI 响应。

模板在 /ai/chat 提供了一个 Example(示例) 聊天界面,由 AI Elements、 AI SDK 的 useChat Hook 与流式 /api/chat 路由组成。

当前路由对外公开,尚未实现身份认证、限流、配额、内容审核或服务端模型白名单。 请把它当作开发示例,而不是可直接上线的聊天端点。

提供的能力

  • 流式 UI 消息,以及文本、推理过程和来源片段的渲染组件。
  • 文件附件选择、停止、重试、复制和模型切换控件。
  • 使用 streamText() 的 OpenAI Route Handler。
  • 位于 src/components/ai-elements/ 的可复用聊天组件。

重要文件

文件用途
src/components/ai/ChatBot.tsx客户端 UI、useChat、传输层和模型选择器
src/components/ai-elements/对话、消息、输入、推理和来源 UI
src/app/api/chat/route.ts公开的流式 POST 端点
src/app/[locale]/(marketing)/ai/chat/page.tsx/ai/chat 页面

配置

.env 中加入仅服务端可见的 OpenAI 密钥:

OPENAI_API_KEY=your-openai-api-key

重启 pnpm dev,打开 /ai/chat 并发送消息,确认回答逐步显示。密钥由 @ai-sdk/openai 在服务端读取,绝不能放进 NEXT_PUBLIC_* 变量。

请求与流式响应

  1. ChatBot/api/chat 创建 DefaultChatTransport,并把所选 modelwebSearch 放入请求体。
  2. useChat 管理消息以及 submittedstreaming 状态。
  3. 路由通过 convertToModelMessages() 转换 UIMessage[],再调用 streamText({ model: openai(modelId), messages })
  4. toUIMessageStreamResponse({ sendSources: true, sendReasoning: true }) 把 UI 消息片段流式传回浏览器。
  5. AI Elements 渲染文本、推理、来源、附件和操作按钮。

客户端会把附件作为消息文件片段发送;所选模型能否实际处理附件,仍取决于模型 及提供商的能力。

模型与响应选项

ChatBot.tsx 当前提供:

显示名称模型 ID
GPT 5.2gpt-5.2
Deepseek R1deepseek-r1

UI 默认选择第一项 gpt-5.2。只有请求没有携带 model 时,服务端路由才会 回退到 gpt-4o

模型选择器不是安全边界。/api/chat 会把客户端提交的任意模型字符串传给 openai(...)。还应确认 UI 中每个模型 ID 确实可由你的 OpenAI 提供商账户调用; 选择器中出现某个名称,并不等于提供商一定支持它。

修改 ChatBot.tsx 中的 models 即可调整 UI 选项。生产环境还必须在服务端 维护同一份白名单,并在调用 streamText 前拒绝未知 ID:

const allowedModels = new Set(["gpt-5.2"]);
const modelId = allowedModels.has(requestedModel)
  ? requestedModel
  : "gpt-5.2";

响应开启了 sendReasoningsendSources,UI 也能渲染这两种片段;但只有 模型或提供商实际返回对应数据时,它们才会出现。

Search 开关

当前 webSearch 选项没有配置联网搜索。开启后,路由只会加入空的 tools: {}。代码没有注册搜索服务、OpenAI 搜索工具或自定义工具,因此模型 无法通过这段实现浏览网页。

若要真正接入搜索,请在服务端路由注册兼容 AI SDK 的搜索工具,校验何时允许调用, 并渲染工具与来源片段。不要把客户端布尔值当作授权或计费依据。

生产加固

向真实用户开放前,请完成:

  • 校验服务端会话,并强制执行用户/租户访问边界。
  • 校验消息数量、角色、文本长度、附件和请求体大小。
  • 在服务端执行模型与工具白名单。
  • 增加按用户和 IP 的限流、用量配额与并发限制。
  • 增加内容审核和上传内容策略。
  • 限制 token、工具调用次数、执行时长和高成本模型访问。
  • 记录用量、延迟、失败和成本;默认不要记录敏感提示词。
  • 返回安全的结构化错误,并处理主动中止和提供商流式失败。

相关页面

On this page