AI 赋能传统客服系统:话术推荐与实时情绪分析的流式架构

📅 2026/7/8 14:45:48
AI 赋能传统客服系统:话术推荐与实时情绪分析的流式架构
AI 赋能传统客服系统话术推荐与实时情绪分析的流式架构一、客服系统的沉默痛点打字的速度跟不上客户的耐心传统客服台席的工作流程客户发消息 → 客服阅读 → 客服思考回复内容 → 打字 → 发送。这个过程平均耗时 15-30 秒。对于简单的咨询如怎么退换货这个时间勉强可以接受。但对于需要查询多个系统的复杂问题如我的订单 12345 到哪了同时我想改一下收货地址等待时间可能超过 2 分钟。客户的耐心是有限的。Zendesk 的数据显示客服响应时间超过 1 分钟后客户满意度下降 15%。AI 可以介入两个环节话术推荐——基于客户问题和上下文实时推荐可能的回复话术情绪分析——检测客户消息中的情绪倾向提醒客服升级处理或调整沟通策略。graph TB C[客户消息] --|WebSocket 推送| S[客服台席] C -- AI1[情绪分析模型] AI1 -- E1{情绪判断} E1 --|愤怒| R1[台席提示: 升级处理] E1 --|焦虑| R2[台席提示: 安抚话术] E1 --|正常| R3[无提示] C -- AI2[话术推荐引擎] AI2 --|匹配上下文| DB[(知识库)] AI2 -- R4[推荐 Top 3 话术] R4 -- S R1 -- S R2 -- S S --|点击推荐话术| REP[自动填充输入框] S --|修改后发送| C2[回复客户] style AI1 fill:#4dabf7,color:#fff style AI2 fill:#4dabf7,color:#fff style R1 fill:#ff6b6b,color:#fff本文将设计一套实时话术推荐与情绪分析的流式架构通过 WebSocket LLM 实现毫秒级的智能客服增强。二、流式架构的设计WebSocket 管道中的 AI 推理传统客服系统的 AI 增强往往采用消息保存到数据库 → 定时任务拉取 → AI 分析 → 结果写入 → 前端轮询的架构。延迟通常在 5-15 秒。流式架构的设计思路不同客户消息通过 WebSocket 实时推送到客服台席的同时消息也被推送到 AI 分析管道。分析结果通过同一个 WebSocket 连接推送给台席整个链路延迟控制在 500ms 以内。管道结构消息接入层WebSocket Server接收客户消息广播给客服和 AI 管道情绪分析层LLM 调用对每条客户消息进行情绪分类愤怒/焦虑/困惑/正常话术检索层Embedding 向量检索在知识库中找到最匹配的 3 条话术结果推送层WebSocket将分析结果推给客服台席为什么用 WebSocket 而不是 SSESSE 是单向的服务端到客户端客服的点击话术操作是客户端到服务端WebSocket 的双向通道更适合。三、完整实现WebSocket LLM 的实时客服增强服务端Node.js wsconst { WebSocketServer } require(ws); const OpenAI require(openai); const http require(http); const openai new OpenAI({ apiKey: process.env.OPENAI_API_KEY }); const server http.createServer(); const wss new WebSocketServer({ server }); // 存储客服连接 const agents new Map(); // 模拟知识库生产环境使用向量数据库 const knowledgeBase [ { id: 1, keywords: [退货, 退款], text: 您的退货申请已收到。请在个人中心查看退货地址寄回商品后我们将为您退款。 }, { id: 2, keywords: [换货, 更换], text: 请提供您的订单号和要更换的商品信息。我来为您处理换货流程。 }, { id: 3, keywords: [物流, 到哪, 快递], text: 请提供订单号我帮您查询最新的物流信息。 }, { id: 4, keywords: [地址, 修改, 收货], text: 请提供订单号和新的收货地址省/市/区/详细地址/收件人/电话我来帮您修改。 }, { id: 5, keywords: [投诉, 态度, 很差], text: 非常抱歉给您带来不好的体验。请告知具体情况我会立即为您处理并反馈给相关部门。 }, ]; function matchKnowledge(query) { const queryLower query.toLowerCase(); return knowledgeBase .map(item ({ ...item, score: item.keywords.filter(kw queryLower.includes(kw)).length, })) .filter(item item.score 0) .sort((a, b) b.score - a.score) .slice(0, 3); } // AI 情绪分析 async function analyzeSentiment(text) { try { const response await openai.chat.completions.create({ model: gpt-4o-mini, messages: [ { role: system, content: 分析客户消息的情绪。只返回以下之一angry愤怒、anxious焦虑、confused困惑、normal正常。输出格式: {sentiment: angry|anxious|confused|normal}, }, { role: user, content: text }, ], temperature: 0, max_tokens: 50, response_format: { type: json_object }, }); return JSON.parse(response.choices[0].message.content).sentiment; } catch (err) { console.error(Sentiment analysis error:, err); return normal; // 降级为正常 } } // AI 智能话术生成 async function generateScript(context) { try { const response await openai.chat.completions.create({ model: gpt-4o-mini, messages: [ { role: system, content: 你是客服话术推荐助手。基于对话上下文生成 3 条专业的客服回复话术。输出 JSON 数组: [话术1, 话术2, 话术3], }, { role: user, content: 对话历史:\n${context}\n\n请推荐回复话术。 }, ], temperature: 0.3, max_tokens: 500, response_format: { type: json_object }, }); return JSON.parse(response.choices[0].message.content); } catch (err) { console.error(Script generation error:, err); return []; } } wss.on(connection, (ws, req) { const agentId new URL(req.url, http://localhost).searchParams.get(agentId); if (!agentId) { ws.close(4001, agentId required); return; } agents.set(agentId, ws); console.log(Agent ${agentId} connected); ws.on(message, async (data) { const message JSON.parse(data.toString()); switch (message.type) { case customer_message: { const text message.text; // 并行执行情绪分析和话术匹配 const [sentiment, matchedScripts] await Promise.all([ analyzeSentiment(text), Promise.resolve(matchKnowledge(text)), ]); // 推送给所有客服台席 for (const [id, agentWs] of agents) { if (agentWs.readyState ws.OPEN) { agentWs.send(JSON.stringify({ type: ai_suggestions, sentiment, sentimentAlert: sentiment ! normal ? getSentimentAlert(sentiment) : null, scripts: matchedScripts.map(s s.text), timestamp: Date.now(), })); } } break; } case script_clicked: { // 记录客服点击话术用于后续统计和话术排序优化 console.log(Agent ${agentId} clicked script: ${message.script}); break; } } }); ws.on(close, () { agents.delete(agentId); console.log(Agent ${agentId} disconnected); }); }); function getSentimentAlert(sentiment) { const alerts { angry: ⚠️ 客户情绪激动建议优先安抚情绪避免争辩。, anxious: ⚠️ 客户较为焦虑建议加快响应并提供明确的时间预期。, confused: ℹ️ 客户有些困惑建议用简单的语言描述操作步骤。, }; return alerts[sentiment] || null; } server.listen(3001, () { console.log(WebSocket server on port 3001); });四、性能与工程的现实考量延迟目标整个管道WebSocket 接收 → LLM 分析 → 推送结果的 P95 延迟应在 2 秒以内。情绪分析开销小~200ms话术生成开销大~1.5s。如果延迟过高可以先用关键词匹配提供即时话术推荐LLM 生成的结果异步补充。并发处理一个 WebSocket 服务器可以处理数千并发连接。但 LLM API 的并发是瓶颈——OpenAI 有 RPM每分钟请求数限制。建议在 LLM 调用前加入本地队列控制并发数。不适用场景客服量 10 人/天AI 增强的投入产出比不高高度专业化的 B2B 客服如法律咨询通用 LLM 的专业知识不足需要微调纯语音客服本方案基于文本语音场景需要先做 ASR五、总结AI 赋能客服系统的核心是实时 辅助而非自动 替代。话术推荐帮客服减少打字时间情绪分析帮客服调整沟通策略但最终的决策仍在人手中。落地路径先实现 WebSocket 通道和关键词匹配的话术推荐无需 LLM验证实时推送的可行性再接入 LLM 做情绪分析和智能话术生成最后收集客服的点击率和修改率数据持续优化推荐质量。技术是辅助不是替代。少即是多——在合适的环节引入 AI而不是试图用 AI 替代整个客服流程。