前端工程师如何把大模型接入业务系统?这份AI中间层实战指南请收好 本文来自一个前端工程师在智慧社区项目中落地 AI 对话系统的真实经验。不聊模型训练只聊工程化——怎么把大模型接入业务系统让它真正能用。一、为什么要做AI 中间层去年我在一个智慧社区项目里接到需求给物业管理系统接入 AI 对话助手让用户能用自然语言查工单、查缴费、报修。一开始我想得简单——前端直接调大模型 API 不就行了结果踩了三个坑供应商切换领导说先用便宜的后面效果好再换贵的。直接调 API 意味着每次换模型都要改前端代码流式响应大模型生成一个字就回一个字前端不做处理的话用户要等 10 秒才能看到完整回复业务融合AI 不能只聊天——用户说查 3 栋 501 的物业费AI 得真的去数据库查这三个问题指向同一个答案在前后端之间加一层 AI 中间层。架构长这样POST /api/chatSSE流式推送路由选择路由选择路由选择工具调用结构化数据前端 - Vue3AI中间层 - Node.js ExpressClaude APIDeepSeek API通义千问 API业务数据库二、多模型路由三级降级设计生产环境不能只有一个模型——挂了就全挂了。我设计了一个三级路由functionrouteModel(userId,requestPrefix){// 第1级请求里带了模型名前缀直接路由// 比如用户输入 claude:帮我查工单if(requestPrefixclaude:)return{model:claude-3-sonnet,provider:anthropic}if(requestPrefixdeepseek:)return{model:deepseek-chat,provider:deepseek}if(requestPrefixqwen:)return{model:qwen-turbo,provider:aliyun}// 第2级读数据库里的用户偏好配置constuserConfigdb.getUserAIConfig(userId)if(userConfig?.preferredModel)returnuserConfig// 第3级环境变量默认值最便宜的通义千问兜底return{model:process.env.DEFAULT_AI_MODEL||qwen-turbo,provider:aliyun}}三个层级的逻辑第1级让运营人员可以在输入框里临时指定模型适用于效果对比测试第2级让系统管理员在后台配置默认模型适用于正式上线后的全局策略第3级兜底保证服务永远不挂环境变量不改就不会出问题配合 try-catch 自动降级asyncfunctionchatWithFallback(options){try{returnawaitcallModel(options.model)}catch(err){console.warn(Model${options.model}failed:,err.message)// 自动降级到通义千问returnawaitcallModel(qwen-turbo)}}三、SSE 流式对话让 AI “边想边说”大模型生成文本是一字一字出来的。如果不做流式处理前端要等完整回复生成完才能显示——10 秒白屏谁也受不了。后端推送Expressapp.post(/api/chat,async(req,res){// 设置 SSE 响应头res.setHeader(Content-Type,text/event-stream)res.setHeader(Cache-Control,no-cache)res.setHeader(Connection,keep-alive)res.setHeader(X-Accel-Buffering,no)// 禁用 Nginx 缓冲const{message,role}req.body// 调用大模型 API 获取流式响应conststreamawaitaiClient.chat({messages:buildHistory(message,role),stream:true})// 逐块推送forawait(constchunkofstream){if(chunk.typecontent){res.write(data:${JSON.stringify({type:text,content:chunk.text})}\n\n)}elseif(chunk.typetool_call){// AI 要调用工具了推送一个特殊事件res.write(data:${JSON.stringify({type:tool_call,name:chunk.name})}\n\n)// 执行工具调用...}}res.write(data: [DONE]\n\n)res.end()})前端消费Vue3 Composition APIasyncfunctionsendMessage(msg:string){constresponseawaitfetch(/api/chat,{method:POST,headers:{Content-Type:application/json},body:JSON.stringify({message:msg,role:currentRole.value})})constreaderresponse.body!.getReader()constdecodernewTextDecoder()letfullTextwhile(true){const{done,value}awaitreader.read()if(done)breakconstchunkdecoder.decode(value,{stream:true})constlineschunk.split(\n)for(constlineoflines){if(line.startsWith(data: )){constdataJSON.parse(line.slice(6))if(data.typetext){fullTextdata.content messages.value[messages.value.length-1].contentfullText}if(data.typecard){// 业务数据卡片——直接渲染到聊天界面messages.value.push({type:card,data:data.payload})}}}}}为什么用 SSE 不用 WebSocket对话场景是单向的服务端推客户端只需要发一次请求SSE 比 WebSocket 更轻量不需要心跳保活、不需要升级协议浏览器原生支持EventSource虽然我们用了更灵活的 fetch 方案如果需要双向通信比如用户中途打断 AI可以补一个 WebSocket 做打断指令四、Docker 部署一行命令上线中间层做完部署也不能拖后腿FROM node:20-alpine WORKDIR /app COPY package*.json ./ RUN npm ci --production COPY . . EXPOSE 3000 CMD [node, server.js]配合 Nginx 反向代理 PM2 进程管理整个 AI 中间层跑在 1 核 2G 的服务器上就能支撑日均千级的对话量。location /api/chat { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; proxy_set_header Connection ; proxy_buffering off; # 关键关闭缓冲否则 SSE 变成一次性返回 proxy_read_timeout 300s; # 长连接超时保护 }五、总结前端工程师做 AI 应用开发不是去训练模型而是做四件事路由——让请求走到合适的模型流控——让 AI 的回答丝滑流畅地呈现工具——让 AI 能真正操作系统部署——让这一切在生产环境稳定运行这四件事恰好都是前端工程化的基本功。