基于大模型的营销智能客服实现:从架构设计到生产环境部署实战

📅 发布时间:2026/7/5 21:11:29 👁️ 浏览次数:
基于大模型的营销智能客服实现:从架构设计到生产环境部署实战
背景痛点传统规则引擎在营销场景下的三大瓶颈去年“618”大促我们组的客服系统被用户吐槽到飞起促销话术更新滞后运营凌晨改价格规则库要到第二天中午才上线结果早上 9 点用户问“前 100 名半价还有吗”机器人只会回“请稍等转人工”。用户画像利用不足老客复购意向模型已经算到 87%对话里却还在推新客券转化率惨不忍睹。多轮对话维护难活动页叠券逻辑一改开发要在 2000 条 if-else 里找分支上线两周后自己都看不懂。一句话规则引擎在营销这种“高频、高并发、高变化”的三高场景下基本跑不动。技术选型GPT-4 vs Claude 3 实测对比我们拿 5 万条真实营销语料做了离线评测指标三件套意图准确率、情感 F1、平均延迟。模型意图准确率情感 F1平均延迟商用成本/1k sessionGPT-494.2%0.91680 ms0.42$Claude 3 Sonnet92.7%0.89410 ms0.30$自研 7B 微调88.4%0.85190 ms0.08$结论延迟敏感 → Claude 3 胜出410 ms 在 500 TPS 下 GPU 利用率还能压到 65%。商用成本 → 自研 7B 最低但准确率差 6 个点营销场景不能忍。最终拍板线上用 Claude 3兜底用自研 7B做级联降级。核心实现LangChain RAG 异步流水线1. 对话状态机把“营销套路”画成图营销客服最大的套路就是“发券→领券→下单→追单”。用 LangChain 的GraphState十分钟就能画出来from langchain.graph import StateGraph, END class MarketingState: START START COUPON_PUSH COUPON_PUSH ORDER_ASK ORDER_ASK CHASE_ORDER CHASE_ORDER END END transitions [ (MarketingState.START, ask_coupon, MarketingState.COUPON_PUSH), (MarketingState.COUPON_PUSH,ask_order, MarketingState.ORDER_ASK), (MarketingState.ORDER_ASK, no_order, MarketingState.CHASE_ORDER), (MarketingState.CHASE_ORDER,finish, MarketingState.END), ] graph StateGraph(statesMarketingState, transitionstransitions)状态节点里再塞 RAG 提示词就能把“券”讲清楚。2. 带缓存的向量检索别让 Milvus 被 QPS 打爆营销知识库 30 万条 SKU活动纯向量检索 QPS 上 500 直接跪。我们加了一层 Redis 缓存key 是“用户问题 3-gram 指纹”value 是 top-5 结果 ID 列表TTL 300 s。import hashlib from typing import List import redis, pymilvus class CachedRetriever: def __init__(self, milvus_collection, redis_client): self.col milvus_collection self.rds redis_client def search(self, text: str, top_k: int 5) - List[str]: key hashlib.md5(text.encode()).hexdigest() cached self.rds.get(key) if cached: return cached.decode().split(,) # 走 Milvus vec self._encode(text) res self.col.search(vec, top_k) ids [r.id for r in res[0]] self.rds.setex(key, 300, ,.join(ids)) return ids3. 异步流水线把 CPU 等 GPU 的时间省出来Claude 3 一次生成 600 msIO 等待占 70%。我们用 FastAPI asyncio aioproducer把“向量检索→LLM 调用→后处理”拆成三阶段队列网关层收到请求即返回“已受理”把事件推入 Kafka。消费端异步做检索LLM结果写回 Redis Stream。网关层 SSE 推送给前端轮询延迟从 800 ms 降到 220 ms。压测结果单卡 A10 从 120 QPS 提到 420 QPSGPU 利用率 92%。生产考量压测、日志、脱敏1. JMeter 配置要点线程组500 并发Ramp-up 60 s循环 300 次。报文JSON带 Authorization Bearer动态提取 user_id 用 CSV 数据集。断言响应码 200 JSON 字段statusanswered。监控Backend Listener 打到 InfluxDBGrafana 看 P99 延迟曲线。2. 对话日志脱敏正则一把梭import re def desensitize(text: str) - str: text re.sub(r\d{11}, PHONE, text) text re.sub(r\d{17}[\dXx], ID, text) return text落库前再调用字段级 AES-加密密钥放 KMS审计表只存哈希。避坑指南幻觉、版本、热更新1. 大模型幻觉三件套双重检索校验RAG 返回的 top-1 相似度 0.82 时强制走“暂无答案”模板。规则后置过滤正则黑名单 247 条含“100% 治愈”“绝对赚钱”等广告法雷区。置信度打分让模型输出[[confidence:0.87]]后端阈值 0.75以下走人工兜底。2. 知识库增量更新版本控制Milvus 里给每个 doc 加version_tag格式yyyymmddhhmm。上线流程新数据写带新 version 的集合。灰度 5% 流量对比点击率/转人工率。全量切换后旧集合延迟 24 h 删除支持秒级回滚。代码规范PEP8 防御式编程关键函数示例from typing import Optional import logging def query_llm(prompt: str, max_tokens: int 512) - Optional[str]: if not isinstance(prompt, str) or not prompt.strip(): raise ValueError(prompt must be non-empty string) if not (0 max_tokens 4096): raise ValueError(max_tokens out of range) try: resp claude_client.completions.create(promptpromptmax_tokensmax_tokens) return resp.text except Exception as e: logging.exception(llm call failed) return None每函数 ≤ 20 行圈复杂度 ≤ 10。所有外部 IO 打日志带 trace_id方便链路追踪。互动提问用户连续追问“那券能不能叠加红包”时你的上下文窗口只剩 2 k token前面 SKU 信息却占 3 k怎么优雅地做“遗忘”又不丢关键信息欢迎留言聊聊你的 truncation 策略。