为什么让前端完成Chat Completion: 一套通用的多模型流式对话架构设计
🔌 为什么让前端执行 Chat Completion:一套通用的多模型流式对话架构设计 副标题 / 摘要 在现代 AI 聊天系统中,很多人会问:为什么不直接在后端调用 OpenAI API? 本文将带你理解一种更灵活的架构——让前端承担推理执行,后端负责调度和状态同步。适合需要支持多模型、本地推理或用户自带 API Key 的开发者。 目标读者 AI 聊天应用开发者 WebSocket / Socket.IO 实践者 想构建多模型、多端协作聊天系统的架构师 🧠 背景 / 动机 传统的聊天后端往往直接在服务器调用 OpenAI API: resp = client.chat.completions.create(model="gpt-4o", messages=messages) 虽然简单,但带来几个现实问题: 所有请求都消耗服务器的 Key,成本高且难追踪; 无法支持用户自定义 Key(BYOK 模式); 无法连接用户本地推理(如 Ollama、LM Studio); 无法切换不同模型或 API Base URL; 前后端状态不同步,不利于流式消息推送。 为了解决这些问题,一些开源系统(如 Open-WebUI、Chatbot-UI 增强版)采用了更灵活的 Socket.IO 双向通信架构。 服务端负责「调度与状态流」,前端负责「执行与回传」。 🧩 核心概念 概念 说明 Socket.IO 基于 WebSocket 的实时双向通信库,支持事件与回调。 event_emitter 服务端向前端广播事件(推送消息/状态)。 event_caller (sio.call) 服务端请求前端执行任务(RPC),并等待前端 callback 返回。 request:chat:completion 一种自定义事件类型,用于请求前端执行 chat completion。 BYOK 模式 “Bring Your Own Key”,用户使用自己的 OpenAI Key 调用 API。 Executor 架构 前端承担推理任务的执行者,后端作为协调者。 🧭 实践指南 / 步骤 1️⃣ 服务端发送调用请求 res = await event_caller({ "type": "request:chat:completion", "data": { "form_data": form_data, "model": models[form_data["model"]], "channel": channel, "session_id": session_id, }, }) 这里的 event_caller 使用 sio.call() 发送事件给指定客户端,并等待 callback 返回。 ...