微信机器人接 AI 客服
微信机器人接 AI 客服:GPT/Claude/DeepSeek 多模型切换实战
很多团队的 AI 客服是这样长出来的:立项时接了一个大模型,业务代码里到处都是这家模型的请求格式。三个月后模型涨价了、或者出了个效果更好的新模型,想换——发现要改十几个地方,测试回归一圈,最后不了了之。模型绑定是 AI 客服最常见的技术债。这篇给一个解法:在微信通道和大模型之间加一个统一的 LLM 网关层,换模型只改配置,主模型挂了自动降级到备用模型。
为什么需要网关层
三个现实问题,每个都值回这一层代码:
- 各家格式不统一:GPT 是
choices[0].message.content,Claude 是content[0].text,请求头、参数结构都不一样。没有网关层,换模型就是改业务代码。 - 单点故障:任何一家模型都有抖动和宕机。绑死一家,它挂你的客服就挂。
- 成本分层:简单问题(“营业时间”)和复杂问题(“帮我对比三款产品”)用同一个旗舰模型,纯属烧钱。
网关层设计:统一入口,配置驱动
核心抽象就一句话:messages 进,文本出,内部消化各家差异。
# llm_gateway.py
import requests
PROVIDERS = {
"gpt": {
"url": "https://api.openai.com/v1/chat/completions",
"key": "<OPENAI_KEY>",
"model": "gpt-4o-mini",
"format": "openai",
},
"claude": {
"url": "https://api.anthropic.com/v1/messages",
"key": "<ANTHROPIC_KEY>",
"model": "claude-3-5-haiku-latest",
"format": "anthropic",
},
"deepseek": {
"url": "https://api.deepseek.com/v1/chat/completions",
"key": "<DEEPSEEK_KEY>",
"model": "deepseek-chat",
"format": "openai", # DeepSeek 兼容 OpenAI 格式
},
}
def ask(provider, messages, timeout=15):
"""统一调用入口:messages 进,文本出"""
p = PROVIDERS[provider]
if p["format"] == "openai":
r = requests.post(p["url"],
headers={"Authorization": f"Bearer {p['key']}"},
json={"model": p["model"], "messages": messages},
timeout=timeout).json()
return r["choices"][0]["message"]["content"]
else: # anthropic 格式
r = requests.post(p["url"],
headers={"x-api-key": p["key"],
"anthropic-version": "2023-06-01",
"Content-Type": "application/json"},
json={"model": p["model"],
"max_tokens": 1024,
"messages": messages},
timeout=timeout).json()
return r["content"][0]["text"]
新增一家模型?往 PROVIDERS 里加一条配置就行。业务代码永远只调 ask(provider, messages)。
故障降级链:主模型挂了,客服不挂
CHAIN = ["deepseek", "gpt", "claude"] # 按你的成本/稳定性偏好排序
def ask_with_fallback(messages):
for provider in CHAIN:
try:
reply = ask(provider, messages)
log_usage(provider, success=True) # 记录谁答的,做观测
return reply
except Exception as e:
log_usage(provider, success=False, err=str(e))
continue
return None # 三家全挂 → 走关键词兜底或转人工
log_usage 别省:每个 provider 的成功率和耗时都要记,跑两周你就知道该把谁排在链首——模型选型从"拍脑袋"变成"看数据"。
成本路由:简单问题别用大模型
SIMPLE_KEYS = ["营业时间", "地址", "电话", "价格表"]
def pick_model(content):
"""按问题复杂度路由:简单走便宜模型,复杂走强模型"""
if len(content) < 20 or any(k in content for k in SIMPLE_KEYS):
return "deepseek" # 便宜够用
return "gpt" # 复杂问题再上好模型
实战经验:客服场景 60% 以上是简单问题,全走便宜模型,token 成本能砍掉一大半。更省的一招:超高频问题(比如"营业时间")干脆别调模型,关键词直回固定答案,零成本毫秒级。
接到微信上:网关层插在中间
和微信侧的对接反而简单,前面文章讲过的结构原样保留,只把"调模型"那一步换成网关:
微信消息 → WTAPI Webhook → 队列 → pick_model → ask_with_fallback
↓
WTAPI postText ← 生成回复(或兜底话术)
WTAPI 负责收消息(Webhook)和回写(postText),网关层负责模型调度——两层各管各的,模型侧的任何折腾都碰不到微信代码,反过来微信侧换实例、换部署形态也碰不到模型代码。回调侧的两条老规矩不变:3 秒内返回(所以走队列异步)、Appid + NewMsgId 去重。
def handle_text(session_id, from_wxid, content):
provider = pick_model(content)
messages = build_messages(session_id, content) # 带会话上下文
reply = ask_with_fallback(messages)
if reply is None:
reply = "当前咨询较多,人工客服马上来~" # 全挂时的兜底话术
notify_human(session_id, content)
send_text(from_wxid, reply) # WTAPI postText 回写
微信侧的
postText和 Webhook 配置,想在线调一遍的:WTAPI 开发文档(weiti.apifox.cn)支持在线调试——目前提供 7 天接口调用权限,后台附带 Demo 示例可供本地调试。接口路径与字段以文档实时内容为准。
上线前两个提醒
- 回复内容要过审:AI 生成的话术可能蹦出敏感词或夸大承诺,发送前过一道内容审核(关键词过滤起步),客服场景的说错话成本比不回复高。
- 会话上下文要隔离:多客户共用一个机器人,上下文必须按会话 ID 分开存,A 客户的对话历史绝不能串到 B 客户的 prompt 里——这既是体验问题,也是数据安全问题。
合规声明
本文示例仅用于技术学习与合规私域自动化场景,请使用注册 3 个月以上、已实名的合规账号,遵守平台规范与各大模型服务商的使用条款,自动回复内容应经审核,不得用于骚扰、欺诈等违规场景。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)