背景与痛点
传统客服系统往往基于规则引擎或关键词匹配,遇到稍微复杂的问法就“答非所问”。上线 ChatGPT 4.5 后,虽然回答质量肉眼可见地提升,却也带来一堆新坑:
- API 限流:官方按 TPM(Token per Minute)计费,高峰期一不留神就 429。
- 上下文漂移:多轮对话里用户东一句西一句,模型容易“失忆”。
- 响应延迟:平均首字时延 1.2 s,直接怼到用户脸上就是“卡”。
- 数据合规:企业敏感字段不能明文出境,需要脱敏与审计。
一句话:大模型是“聪明”,但让它在企业场景里“稳、准、快”地打工,还得系统性地搭架子。
架构设计:微服务三板斧
把单体拆成三件套,各自独立扩容,谁挂都不影响别人:
- chat-gateway:只做鉴权、限流、日志,把 HTTP 升级成 WebSocket,给用户“秒回”体验。
- dialogue-svc:维护会话状态,决定“要不要调用模型”“要不要查知识库”。
- llm-svc:唯一与 OpenAI 打交道的“翻译官”,内部做重试、缓存、批处理。
再配上 Redis(状态)、Kafka(事件)、Consul(注册中心),整套跑在 K8s 上,峰值扩容 30 s 内完成。
核心实现:代码直接抄
以下示例均基于 Python 3.11,已跑通生产,可直接 CV。
1. 带退避重试的 API 调用
import os, tenacity, openai from openai import OpenAI client = Openai(api_key=os.getenv("OPENAI_API_KEY")) @tenacity.retry( stop=tenacity.stop_after_attempt(5), wait=tenacity.wait_exponential(multiplier=1, min=1, max=16), retry=tenacity.retry_if_exception_type( (openai.RateLimitError, openai.APIConnectionError) ), ) def chat_completion(messages: list[dict], temperature: 0.3) -> str: """带重试的同步调用,返回 content 字符串""" rsp = client.chat.completions.create( model="gpt-4.5-turbo", messages=messages, temperature=temperature, max_tokens=512, ) return rsp.choices[0].message.content要点:
- 指数退避,最大 16 s,避免“撞墙”。
- 只捕获限流 & 网络异常,业务异常直接抛。
2. Redis 管理多轮上下文
import json, redis, uuid from datetime import timedelta r = redis.Redis(host="redis", decode_responses=True) class DialogueManager: def __init__(self, ttl_minutes=30): self.ttl = timedelta(minutes=ttl_minutes) def _key(self, session_id: str) -> str: return f"dg:{session_id}" def append(self, session_id: str, role: str, text: str): key = self._key(session_id) msg = {"role": role, "content": text} r.lpush(key json.dumps(msg)) # 左插,保证顺序 r.expire(key, self.ttl) def get_messages(self, session_id: str) -> list[dict]: key = self._key(session_id) return [json.loads(m) for m in r.lrange(key, 0, -1)]- 用 list 而不是 hash,保证消息顺序。
- 设置 TTL,防止僵尸会话占内存。
3. 基础意图路由
import re def intent_router(text: str) -> str: text = text.lower() if re.search(r"(发票|报销|凭证)", text): return "invoice" if re.search(r"(密码|登录|账户)", text): return "account" return "faq"路由结果写进 Kafka,下游可针对 invoice / account 等走私有插件,减少大模型调用次数 30%+。
性能优化:压测数据说话
| 策略 | 平均 RT | 峰值 QPS | 备注 |
|---|---|---|---|
| 单条同步 | 1.2 s | 8 | 官方默认 |
| 异步 + 限流池 | 0.9 s | 45 | 10 并发槽 |
| 批处理 8 条/次 | 1.5 s | 112 | 牺牲首字延迟,换吞吐 |
结论:
- 对“实时”要求高的场景,选异步限流池。
- 对“离线小结”类,可批量 16 条,换 5 倍吞吐。
避坑指南:上线前 checklist
- 冷启动延迟
首次调用容器要拉模型,RT 飙到 8 s。解决:在镜像里预置/health接口,启动后先发一条“Hello”预热。 - 敏感词过滤
必须本地先过一遍正则 + 公司词库,再送模型;否则一旦返回“政治不正确”,整条业务线都要背锅。 - Token 预算双保险
除了官方限流,自己在网关再按“用户级”做配额,防止某个大客户一夜刷爆预算。
扩展思考:RAG 让模型“懂你家说明书”
把产品手册、FAQ 切成 512 token 的 chunk,用向量库存起来。用户问题先走 Embedding 检索,取 Top3 段落拼进 Prompt,再让 ChatGPT 4.5 生成答案。实测:
- 知识覆盖率从 42% → 78%
- 幻觉率下降 35%
- 首字延迟仅增加 120 ms(检索 < 80 ms)
如果你已经跑到这一步,不妨把“向量召回 + 重排 + LLM 生成”做成标准模板,后续换行业知识只需灌数据,代码一行不改。
写在最后
把大模型搬进客服,不是“调个接口”那么简单,而是“重试、缓存、限流、审计”一个都不能少。上面这套微服务骨架,在我们内部跑了三个月,峰值 2 k QPS 没掉过链子。若你也想亲手搭一套“能听、会想、敢说”的实时对话系统,却又苦于没有现成样板,可以看看这个动手实验——从0打造个人豆包实时通话AI。它把 ASR、LLM、TTS 串成一条完整链路,每一步都有可运行代码,我这种半吊子前端也能跟着跑通。先把它跑起来,再把你今天学到的限流、缓存、RAG 招数嫁接进去,就能快速得到一个企业级可用的“数字客服”。祝你编译不报错,上线不报警!