上个月老板突然说要搞个微信客服机器人,能自动回复产品咨询、处理售后问题,还得接大模型让回复"像人"。我看了眼掘金热榜,OpenClaw 刚好在风口上,就花了三天时间从零搭了一套出来。踩坑不少,但最终效果还行——日均处理 400+ 条消息,客户满意度从 62% 拉到了 89%。这篇把完整流程和坑都记下来。

OpenClaw 本质是一个 AI Agent 运行框架,通过它的微信协议适配层(基于 itchat 魔改)拿到消息收发能力,再把用户消息丢给大模型处理,最后把回复推回微信。整个链路大概 1.2-1.8 秒响应,体感上跟真人客服差不多。

先说结论

维度 结果
部署耗时 首次约 40 分钟(含踩坑),熟练后 15 分钟
响应延迟 P95 约 1.4s(Claude Sonnet 4.6)/ 2.1s(GPT-5.5)
日均处理量 400-600 条(单实例)
稳定性 连续运行 9 天没掉线(之前 itchat 方案 2 天必挂)
月成本 约 ¥380(日均 500 条,每条平均 800 token)

环境准备

我的环境:Ubuntu 22.04 / Python 3.11 / Docker 24.0

# 拉 OpenClaw 最新镜像(2026-04-26 的 v0.9.3)
docker pull openclaw/openclaw:0.9.3

# 创建工作目录
mkdir -p ~/openclaw-wechat && cd ~/openclaw-wechat

需要提前准备:
- 一个不常用的微信号(别用主号,万一封了哭都来不及)
- 大模型 API Key(后面细说选哪个模型)
- 一台至少 2C4G 的服务器,香港或新加坡延迟最低

方案一:OpenClaw 原生微信适配器

OpenClaw 从 v0.8.0 开始内置了微信协议支持,不用再自己魔改 itchat 了。

# config.yaml
agent:
 name: "customer_service_bot"
 description: "企业售后客服"

channels:
 - type: wechat
 login_type: qrcode
 auto_accept_friend: true
 group_whitelist:
 - "售后服务群"
 - "VIP客户群"

model:
 provider: openai_compatible
 base_url: "https://api.ofox.ai/v1"
 api_key: "${OFOX_API_KEY}"
 model_name: "claude-sonnet-4-6"
 temperature: 0.3
 max_tokens: 1024

prompts:
 system: |
 你是「XX科技」的售后客服小助手。
 回复要求:
 1. 简洁友好,每次回复不超过100字
 2. 涉及退款/换货时,引导用户提供订单号
 3. 无法解决的问题回复「正在为您转接人工客服」
 4. 不要编造产品信息,不确定就说不知道

启动:

docker run -d \
 --name openclaw-wechat \
 -v $(pwd)/config.yaml:/app/config.yaml \
 -e OFOX_API_KEY="sk-your-key-here" \
 -p 8080:8080 \
 openclaw/openclaw:0.9.3

启动后终端会弹出二维码,用准备好的微信号扫码登录。我第一次扫码等了 30 秒才成功,别着急。

sequenceDiagram
 participant User as 微信用户
 participant WX as 微信服务器
 participant OC as OpenClaw
 participant LLM as 大模型API

 User->>WX: 发送消息"我的订单什么时候发货?"
 WX->>OC: 推送消息(WebSocket)
 OC->>OC: 提取上下文 + 构造 Prompt
 OC->>LLM: POST /chat/completions
 LLM->>OC: 流式返回回复
 OC->>OC: 拼接回复 + 过滤
 OC->>WX: 发送回复
 WX->>User: "您好!请提供订单号,我帮您查询发货状态~"

方案二:OpenClaw + 企业微信 Webhook(更稳定)

说实话个人微信协议方案我心里一直没底,怕封号。后来发现 OpenClaw 支持企业微信的 Webhook 回调模式,这个是官方 API,稳定性好太多了。

# wechat_work_handler.py
from openai import OpenAI
from flask import Flask, request
import hashlib
import xml.etree.ElementTree as ET

app = Flask(__name__)

client = OpenAI(
 api_key="sk-your-key",
 base_url="https://api.ofox.ai/v1"
)

# 会话记忆(生产环境换 Redis)
conversations = {}

@app.route("/wechat/callback", methods=["POST"])
def handle_message():
 data = request.get_data(as_text=True)
 root = ET.fromstring(data)

 user_id = root.find("FromUserName").text
 content = root.find("Content").text

 # 维护最近 5 轮对话
 if user_id not in conversations:
 conversations[user_id] = []
 conversations[user_id].append({"role": "user", "content": content})
 conversations[user_id] = conversations[user_id][-10:] # 保留最近10条

 messages = [
 {"role": "system", "content": "你是XX科技的客服助手,简洁回复,不超过80字。"},
 *conversations[user_id]
 ]

 try:
 response = client.chat.completions.create(
 model="claude-sonnet-4-6",
 messages=messages,
 temperature=0.3,
 max_tokens=512
 )
 reply = response.choices[0].message.content
 conversations[user_id].append({"role": "assistant", "content": reply})
 except Exception as e:
 reply = "系统繁忙,请稍后再试~"
 print(f"API Error: {e}")

 return build_xml_response(user_id, reply)

企微方案的好处是不怕封号,坏处是只能在企业微信生态里用。我们最终两套都部署了——企微走正式客服,个人微信号走 VIP 社群。

踩坑记录

坑 1:消息重复回复

上线第一天就出问题了,同一条消息 OpenClaw 回复了 3 次。查日志发现是微信服务器超时重试导致的。

2026-04-18 14:32:01 [WARN] Duplicate message detected: msgid=1208374651
2026-04-18 14:32:01 [WARN] Duplicate message detected: msgid=1208374651

解决:加了个 Redis 去重,msgid 做 key,TTL 30 秒。

import redis
r = redis.Redis()

def is_duplicate(msg_id):
 if r.exists(f"msg:{msg_id}"):
 return True
 r.setex(f"msg:{msg_id}", 30, "1")
 return False

坑 2:API 超时导致微信那边显示"对方正在输入"卡住

Claude Sonnet 4.6 偶尔会出现 3-5 秒的慢响应(应该是排队),微信那边用户就看到"对方正在输入..."卡很久。

我的方案是设 timeout=8s,超时就先回一句"稍等,正在查询中~",然后异步等结果出来再发第二条。体验好了很多。

坑 3:凌晨 3 点 WebSocket 断连

2026-04-20 03:14:22 [ERROR] WebSocket connection lost: ConnectionResetError
2026-04-20 03:14:22 [ERROR] Reconnect attempt 1/5 failed
2026-04-20 03:14:52 [INFO] Reconnect attempt 2/5 succeeded

OpenClaw 自带重连机制但默认只试 3 次,我改成了 5 次,间隔从 10s 改成 30s,之后没再出过问题。在 config.yaml 里加:

channels:
 - type: wechat
 reconnect_attempts: 5
 reconnect_interval: 30

坑 4:群聊里 @bot 识别失败

群里有人发"@客服助手 怎么退货",但 OpenClaw 没响应。debug 发现微信群消息里 @ 的格式不是纯文本,而是带了一个特殊 Unicode 字符(\u2005)。

# 修复:清理 @ 前缀
content = content.replace("\u2005", " ").strip()
if content.startswith("@客服助手"):
 content = content[len("@客服助手"):].strip()

这个坑折腾了我大半天,网上几乎搜不到。

模型选择:客服场景实测

跑了一周数据,对比了几个模型在客服场景的表现:

模型 平均延迟 回复质量(人工评分) 日成本(500条) 适合场景
Claude Sonnet 4.6 1.1s 9.2/10 ¥12.8 复杂售后、需要推理
GPT-5.5 1.6s 8.8/10 ¥18.4 通用问答
DeepSeek V3.2 0.8s 8.1/10 ¥3.2 简单FAQ、高并发
Qwen3 0.9s 7.9/10 ¥2.8 预算紧张

最终选了分层策略:简单问题(关键词匹配到 FAQ)走 DeepSeek V3.2 省钱,复杂问题走 Claude Sonnet 4.6 保质量。OpenClaw 的 router 模块天然支持这个:

model_router:
 rules:
 - condition: "message contains ['发货', '快递', '物流']"
 model: "deepseek-v3.2"
 - condition: "message contains ['退款', '投诉', '质量问题']"
 model: "claude-sonnet-4-6"
 - condition: "default"
 model: "deepseek-v3.2"

这样月成本从纯用 Claude 的 ¥384 降到了 ¥156 左右。一天 ¥5.2,比雇个兼职客服便宜太多了。

生产环境加固

几个上线前必须做的事:

过滤——别让模型瞎说。我用了一个本地的 DFA 过滤器,把竞品名称、政治、价格承诺相关的词都拦掉。

消息频率限制——防止有人恶意刷消息把 token 额度烧光。单用户每分钟最多 5 条,超了就回"您发送消息过于频繁,请稍后再试"。

人工接管机制——模型回复里如果出现"转接人工"关键词,自动 @ 群里的真人客服,同时把对话上下文转发过去。

小结

OpenClaw 做微信客服机器人这条路走得通,核心就是把消息收发和大模型调用串起来。个人微信协议方案有封号风险但灵活,企业微信方案稳定但生态受限,看自己业务选。

模型选择上我也不确定 DeepSeek V3.2 是不是客服场景的最优解——它偶尔会生成一些过于"官方"的回复,不够口语化。目前还在调 prompt,有更好方案的朋友欢迎评论区交流。

多模型切换这块,我用的 ofox.ai 做聚合网关(OpenRouter 也行,不过 OpenRouter 要收 5.5% 手续费),改 base_url 就能在不同模型间切换,不用每个模型单独管理 Key,团队后台能看到每天各模型分别烧了多少 token,排查成本异常挺方便。

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐