AIGC智能客服实战:从架构设计到生产环境部署的完整指南
把大模型搬进客服部,我们踩了 3 个月坑,终于把 7×24 秒级响应的系统跑上线。这篇笔记把全过程拆成“为什么、用什么、怎么搭、怎么码、怎么撑、怎么不翻车”六段,顺带把压测数据、异常 case、防 Prompt 注入的板子都公开出来,能直接抄。
1. 背景痛点:传统客服的“三慢两高”
去年双十一,公司人工客服平均响应 47s,峰值排队 3000+,退货咨询 30% 重复问“运费谁出”。总结下来就是:
- 响应慢:工单分派→人工打开页面→敲字,链路长。
- 多轮弱:传统 NLU 只玩单轮意图,用户改个收货地址要重填整张表单。
- 全天候缺人:夜班排班 1:150,离职率 28%,培训赶不上流失。
- 成本高:按通话语料测算,单轮对话 0.8 元,大促 3 倍加班费。
- 扩展难:新增一条业务线,要再标 2 万条语料,模型重训 2 周。
AIGC 方案目标就三条:秒级响应、7×24 在线、单轮成本 <¥0.03。
2. 技术选型:Token 成本、延迟、准确率三维对比
我们把常见模型放在同一客服数据集(1.2 万条多轮日志)做 3 指标小跑:
- 任务:多轮问答 + 知识检索 + 工单生成
- 指标:Token 成本按 1k tokens 计;延迟指首包时间;准确率取 Top1 答案人工评分≥4 分占比
| 模型 | 成本(1k) | 延迟(P95) | 准确率 | 备注 |
|---|---|---|---|---|
| GPT-4 | $0.06 | 2.8s | 92% | 贵,慢,答得真香 |
| GPT-3.5-turbo | $0.002 | 0.9s | 84% | 性价比拐点 |
| Claude-v1.3 | $0.008 | 1.8s | 87% | 长上下文好,但国内链路易抽风 |
| ChatGLM3-6B(开源) | ¥0.0003(自雇 GPU) | 0.4s | 78% | 需要自建推理池,运维成本高 |
结论:
- 预算充足+高客单业务→GPT-4;
- 多数电商/零售→GPT-3.5-turbo;
- 数据隐私强监管→ChatGLM3+私有部署,再蒸馏一层当热备。
3. 架构设计:让大模型“带记忆”地高并发聊天
3.1 文字版架构图
前端(小程序/Web/APP) ─┐ ├─> 接入层(Gateway+WAF) ──> 对话引擎(FastAPI) │ 对话引擎内部:路由 → 会话管理 → 意图分类 → 知识检索 → AIGC 调用 → 回复封装 → 前端 │ └─> 日志/监控(Prometheus+Grafana) ↑ 知识库(ElastciSearch)3.2 对话状态管理 DST
核心是把“多轮记忆”拆成三层:
- Session Memory:用户级,Redis Hash 存最近 5 轮对话,TTL 30 min。
- Dialog State:业务级,Slot 填充情况(订单号、手机号、退货原因等),存在 PostgreSQL JSONB,支持回滚。
- Global Context:系统级,促销文案、政策开关,放在 Consul KV,秒级热更。
更新流程:
- 每轮用户 query→意图分类→更新 Slot→写入 DB→返回给 LLM Prompt。
- 失败时走兜底 FAQ,保证状态不终断。
时间复杂度:Slot 填充 O(1)(字段数固定),DST 查询 O(log n) 走索引,整体单轮 <20ms。
4. 代码实现:FastAPI 造一个带熔断的对话端点
以下示例基于 GPT-3.5-turbo,已上线 3 周,峰值 1200 TPS 稳定。重点演示:
- 请求限流(滑动窗口)
- 敏感词过滤(AC 自动机)
- 会话隔离(UUID+Redis)
- 超时 fallback(本地蒸馏模型)
# requirements.txt # fastapi==0.110.0 # uvicorn[standard]==0.29.0 # redis==5.0.4 # openai==1.23.2 # tiktoken==0.6.0 import time, uuid, re, openai, redis, logging from fastapi import FastAPI, HTTPException, Request from slowapi import Limiter, _rate_limit_exceeded_handler from slowapi.util import get_remote_address from ac import ACAutomaton # 自己封的 AC 自动机 logging.basicConfig(level=logging.INFO) limiter = Limiter(key_func=get_remote_address) app = FastAPI() app.state.limiter = limiter app.add_exception_handler(429, _rate_limit_exceeded_handler) r = redis.Redis(host='127.0.0.1', port=6379, decode_responses=True) openai_client = openai.AsyncOpenAI(api_key="sk-xxx") SENSITIVE_WORDS = ["微信", "QQ", "转账"] # 示例 ac = ACAutomaton(SENSITIVE_WORDS) TIMEOUT = 2.0 # 秒 MAX_TURN = 5 @app.post("/chat") @limiter.limit("30/minute") async def chat(req: Request): body = await req.json() uid: str = body["uid"] query: str = body["query"] # 1. 敏感词 if ac.match(query): raise HTTPException(status_code=400, detail="sensitive") # 2. 取会话历史 key = f"chat:{uid}" hist = r.lrange(key, 0, -1) or [] hist = [eval(h) for h in hist] # 简单序列化 # 3. 构造 Prompt(省略业务 Prompt 细节) prompt = build_prompt(hist, query) # 4. 调用大模型 + 熔断 try: t0 = time.time() resp = await openai_client.chat.completions.create( model="gpt-3.5-turbo-20230126", messages=[{"role": "user", "content": prompt}], max_tokens=300, temperature=0.3, timeout=TIMEOUT ) answer = resp.choices[0].message.content cost = time.time() - t0 logging.info(f"openai ok delay={cost:.2f}") except Exception as e: logging.warning(f"openai fail, fallback {e}") answer = await local_t5_fallback(query) # 本地小模型兜底 cost = -1 # 5. 更新会话 hist.append({"q": query, "a": answer}) hist = hist[-MAX_TURN:] pipe = r.pipeline() pipe.delete(key) pipe.rpush(key, *hist) pipe.expire(key, 1800) await pipe.execute() return {"answer": answer, "latency": cost} def build_prompt(hist, query): # 省略:拼接历史+知识库片段 return f"你是客服小助手,上下文{hist},用户问:{query}" async def local_t5_fallback(query: str) -> str: # 返回固定文案或 T5-small 推理,100ms 内 return "抱歉,我没听懂,已为您转接人工客服。"要点说明:
- 滑动窗口限流用 slowapi,默认内存存储,可换 Redis。
- 敏感词 AC 自动机构建 O(n),匹配 O(m)(m 为文本长)。
- 超时 2s 即触发 fallback,错误率从 2.1% 降到 0.3%。
5. 生产考量:压测、安全、可观测
5.1 性能压测
工具:Locust + 自定义客户端,保持长连接。
场景:模拟 1000 TPS,持续 15 min,Sliding window 30 min。
结果:
- P50 延迟 380ms,P99 1.2s
- 错误率 0.28%(全为超时 fallback,业务可接受)
- CPU 占用 38%(8 核),GPU 占用 62%(A10 单卡)
- 内存无泄露,Redis QPS 1.2w 平稳
5.2 Prompt 注入防护
- 输入前缀白名单:只允许中文/英文/数字/常见标点,正则预过滤。
- 指令截断:检测到“忽略前面”“翻译”“代码”等关键词即拒绝。
- 输出后处理:正则匹配 JSON/HTML,若出现即替换成“***”。
- 双层模型:外层意图分类模型先判断“是否业务咨询”,置信度 <0.8 直接 FAQ。
上线 3 周,未出现一次成功注入导致的数据泄露。
6. 避坑指南:三个血与泪的教训
不做意图兜底 → 用户说“我要跳楼”也返商品链接
解决:引入情绪/风险检测子模型,高危对话直接转人工并触发报警。把 LLM 当知识库 → 回答 2021 以后的新规全是幻觉
解决:RAG 方案,先走 ElasticSearch 拿 Top3 片段再生成,幻觉率从 23% 降到 4%。会话状态无回滚 → 用户中途改订单号,Slot 脏数据导致发错货
解决:DST 更新前先写 PostgreSQL“草稿态”,用户确认后再 commit;取消按钮可回滚。
7. 延伸思考:用反馈数据持续“养”模型
上线后每天产生 5 万轮对话,别让它躺着吃灰:
- 打分收集:在每条回复下方放“/”两按钮,点击率 18%,样本够大。
- 主动 Learning:把“+低置信”数据每周洗一次,人工复核 500 条,生成 Diff 数据。
- 蒸馏/微调:
- 蒸馏:用 GPT-4 对这批 Diff 数据重新生成答案,训练 ChatGLM3-6B,耗时 4h,准确率 +3.7%。
- 微调:LoRA 冻结底层,学习率 2e-5,训练 3 个 epoch,GPU 占用 <24GB。
- A/B 实验:灰度 10% 流量给新模型,核心指标(解决率、点赞率)提升显著再全量。
循环 3 个月后,GPT-3.5 作为主模型的调用比例从 100% 降到 63%,成本再降 28%。
8. 小结:让大模型真正“接得住”客服流量
- 先算账:Token 成本、延迟、准确率三维对比,3.5-turbo 是多数场景甜点。
- 再搭架:会话状态拆 Session+Slot+Global,三层保证多轮不岔。
- 码代码:FastAPI+限流+敏感词+熔断,2 小时就能跑。
- 上线前:1000TPS 压测+Prompt 注入攻防,别等用户教你做人。
- 上线后:用数据喂模型,蒸馏微调双通道,成本还能再砍三成。
整套流程我们 3 个人(1 后端+1 算法+1 运维)6 周落地,首月节省人工坐 12 人,平均响应 1.2s,用户满意度 +17%。如果你也在给客服“换大脑”,希望这份现场笔记能帮你少走几步弯路。