别把对话组件写成一次性脚本——Vue3封装AI对话组件对接统一网关,我先踩过的三个坑
先说说那些失败的做法
在讲正确做法之前,我想先复盘几次典型的失败经历。独立开发者和小团队最容易掉进下面这几个坑里,而且往往在项目后期才意识到问题的严重性。
坑一:把 API 调用直接写进组件里。 很多人拿到 API Key 后的第一反应是在 Chat.vue 组件里直接 fetch,把 URL、Key、模型名全部硬编码。上线两周后想换模型、加重试逻辑、加多轮会话记忆,才发现组件已经长成了一坨面条代码——每个调用点都要改一遍。
坑二:在前端裸奔式暴露 Key。 为了省事,把 API Key 直接放在前端代码里打包发布。这在演示阶段看起来没问题,但只要页面公开访问,Key 就等于送出去了。轻则配额被刷爆,重则账单失控。哪怕你的应用只是内部工具,这个习惯也迟早会出事。
坑三:绑定单一供应商的私有协议。 直接用某家模型的专用 SDK 和私有参数格式,深度耦合。模型要切换或对比测试时,整个调用层要推倒重写,组件里的流式解析逻辑全部报废。
正确路径其实只有一句话:前端组件只负责交互,调用逻辑收敛到一个封装好的服务层,再通过统一网关访问模型。下面以 ThisToken.AI 这类统一网关为例走一遍完整流程。
第一步:注册账号并获取 API Key
- 打开 ThisToken.AI 官网,进入注册页面,使用邮箱完成注册(关于费用模式与套餐,以官网价格页为准,本文不展开)。
- 登录后进入控制台,找到 API Key 管理页面,创建一个新的 Key。
- 立刻把 Key 复制保存到安全位置,并确保它只存在于服务端环境变量中,永远不会进入前端构建产物。
统一网关的好处在于:接口遵循 OpenAI 兼容风格,你只需要一个 base_url,就可以在同一个协议下使用不同的模型,切换时只改一个模型名字符串。
第二步:跑通第一段代码
先用最少的代码验证 Key 和网关连通性。建议先用 Python 在本地测一下(也可以用 Node.js,思路相同):
from openai import OpenAI
client = OpenAI(
api_key="你的_API_KEY", # 生产环境请从环境变量读取
base_url="https://api.thistoken.ai/v1"
)
response = client.chat.completions.create(
model="gpt-4o-mini", # 模型名以网关文档支持的列表为准
messages=[
{"role": "system", "content": "你是一个简洁的中文助手。"},
{"role": "user", "content": "用一句话介绍 Vue3 的组合式 API"}
],
stream=False
)
print(response.choices[0].message.content)这段代码能跑通,说明账号、Key、网关、模型名四件事都没问题。跑不通时先检查三点:Key 是否复制完整、base_url 是否拼写到 /v1 结尾、模型名是否在网关支持列表中。
第三步:封装服务层(而不是塞进组件)
跑通之后,把调用逻辑封装到一个独立模块,比如 src/services/ai.js:
// src/services/ai.js
// 注意:生产环境应经由你自己的后端转发请求,避免在前端暴露 Key
const BASE_URL = 'https://api.thistoken.ai/v1'
export async function sendChat(messages, { model, signal } = {}) {
const res = await fetch(`${BASE_URL}/chat/completions`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${import.meta.env.VITE_AI_KEY}`
},
body: JSON.stringify({ model, messages, stream: true }),
signal
})
if (!res.ok) throw new Error(`网关返回 ${res.status}`)
return res.body // 返回流,交给组件逐块解析
}然后封装一个可复用的 AiChat 组件:输入框、消息列表、加载状态、中断按钮,内部通过 useAiChat() 组合式函数管理消息数组和流式追加渲染。这样换页面、换项目,组件直接搬走,调用层一行不用动。
几条落地建议
- Key 的最终归宿是后端。 前端调用你的后端,后端持有 Key 调网关。这是唯一安全的形态,上文的简化写法只适合本地开发。
- 重试与超时放在服务层统一处理,组件只消费结果,不要在每个组件里各写一套。
- 模型名做成配置项,切换模型就是改一个字符串,这正是统一网关最大的价值。
把这三步做完,你就拥有了一个可迁移的对话组件和一个干净的接入层。还没注册的话,可以直接从这里开始:https://api.thistoken.ai/register
---
不想折腾多家供应商的接入差异?在 https://api.thistoken.ai/register 注册,用一个 base_url 调用所有模型。