AI 聊天

Nuxt 模板中基于 Vercel AI Gateway 的 AI 聊天。

模板包含一个 AI 聊天示例:Vue 前端支持流式渲染,Nitro 接口通过 Vercel AI Gateway 调用模型。服务端目前固定使用 openai/gpt-5.2

已提供的能力

  • /ai/chat 页面与可复用的 ChatBot.vue
  • 对话、消息、输入框、附件、推理、来源、加载、复制和重新生成等 AI Elements。
  • 使用 @ai-sdk/vueChat 类接收流式 UI message。
  • 延迟初始化的 AI Gateway 客户端与 Nitro 流式响应。
  • 默认要求登录,另有显式公开演示开关,并用 Zod 校验请求。

重要文件

文件作用
app/pages/(marketing)/ai/chat.vue聊天页面外壳
app/components/ai/ChatBot.vue聊天状态、输入控件与消息渲染
app/components/ai-elements/*可复用聊天 UI 基础组件
server/api/chat.tsGateway 请求校验与流式响应
server/utils/ai-auth.tsrequireAiAuth 的演示/认证策略
nuxt.config.tsaiGatewayApiKeypublic.aiPublicDemo

配置

将 Gateway key 设置为服务端变量:

NUXT_AI_GATEWAY_API_KEY=your-ai-gateway-api-key

修改 .env 后重启 pnpm dev。不要给该 key 加 NUXT_PUBLIC_ 前缀。

请求与流式流程

ChatBot.vue 创建 new Chat({}),把 UI message 发到 /api/chat,再逐个渲染 流式 message part。来源、推理、文本、提交状态、附件、复制与重试均已有 UI。

server/api/chat.ts 使用 defineLazyEventHandler,首次调用后复用 Gateway 客户端。每个请求依次:

  1. 调用 requireAiAuth(event)
  2. 用 Zod 解析非空 messages 数组;
  3. 通过 convertToModelMessages 转换消息;
  4. gateway("openai/gpt-5.2") 调用 streamText
  5. 返回 toUIMessageStreamResponse({ sendSources: true, sendReasoning: true })

当模型/提供商实际返回来源或推理 part 时,现有 UI 可以显示它们。

当前控件限制

模型下拉框与 Search 开关目前只是 UI starter。客户端虽然发送 modelwebSearch,服务端 schema 只读取 messages,且始终调用 openai/gpt-5.2;也没有配置搜索工具。因此选择 DeepSeek 或打开 Search 都不会改变后端行为。

若产品只用一个模型,直接修改 server/api/chat.ts 的固定模型,并移除会误导 用户的控件。若允许用户选择模型,应在服务端增加 Zod enum,并通过小型白名单 映射;不要把客户端任意模型字符串直接传给付费提供商。搜索还需真正接入工具或 提供商选项,并处理其来源 part。

访问控制

requireAiAuth 默认要求 session;只有下面的值严格为 true 时允许匿名访问:

NUXT_PUBLIC_AI_PUBLIC_DEMO=true

该开关会改变公开演示行为,因此本身是 public 配置。生产环境应保持未设置或 false。现有认证与请求校验并不能限制已登录用户能花费多少。

生产加固

上线前应补充:

  • 按用户和套餐计算的用量配额;
  • token/输出上限及按模型的成本上限;
  • 符合产品场景的输入/输出审核;
  • 服务端模型白名单,并移除或接通 UI-only 控件;
  • 用量、耗时、提供商错误与成本的结构化日志,默认不保存敏感 prompt;
  • 取消、超时和面向用户的错误状态;
  • 作为推荐附加项的限流(模板未内置)。

验证

  • 缺少 NUXT_AI_GATEWAY_API_KEY 时服务端日志有明确错误。
  • 关闭公开演示时,未登录请求返回 401。
  • 登录后的 prompt 能流式输出,来源/推理 UI 不会崩溃。
  • 空或畸形 messages 返回 400 类校验错误。
  • 部署模型与页面可见控件一致。
  • 上线前配额与成本告警能阻止过量付费调用。

相关页面

On this page