微信公众号AI客服 · 一站式部署工作流
> v2.0 · 2026-06-04 · 作者:麻薯(OpenClaw)
架构概览
用户微信 → 公众号消息 → EdgeOne Pages Cloud Function → CNB AI API → 分析回复
│
┌────────────────────────────┘
▼
检测推送标记组合?
├─ [SEND_SERVICES] → 4张服务介绍卡片
├─ [SEND_CASE] → 2张案例卡片
├─ [SEND_VIDEO] → 1张展示卡片
├─ [SEND_QRCODE] → 1张二维码卡片
└─ 无标记 → 纯文本回复
支持组合:SERVICES+QRCODE = 5张卡片
架构优势
| 特性 | 方案 |
|---|---|
| 托管平台 | EdgeOne Pages(腾讯云边缘函数) |
| AI引擎 | CNB AI Chat Completions API(deepseek-v4-flash) |
| 消息类型 | 微信被动回复(text / news 单条/多条) |
| 推送标记 | 4种:SERVICES / CASE / VIDEO / QRCODE,支持组合 |
| 卡片上限 | 微信最多 10 条,自动裁剪 |
| 安全模式 | 微信 AES 加解密(安全模式) |
| 超时保障 | 全部在 5 秒内同步完成,无异步依赖 |
| 人设 | 自定义系统提示词,支持任意企业/行业 |
目录结构
mp-ai-cs-workflow/
├── SKILL.md # 本技能文件
├── templates/
│ ├── wx-callback.js # Cloud Function 模板(完整,含多图文工厂)
│ ├── .env.example # 环境变量模板
│ └── system-prompt.md # 系统提示词模板(可定制)
├── README.md # 项目说明
└── .gitignore
部署流程
Step 0: 前置条件
| 条件 | 说明 |
|---|---|
| 微信服务号 | 已认证的微信服务号(订阅号不支持客服消息回调) |
| 企业微信二维码 | 客户扫码后进入企业微信的二维码图片 |
| CNB 账号 | 有 CNB Token(写权限) |
| EdgeOne 账号 | 已开通 EdgeOne Pages |
| 环境 | edgeone CLI 已安装并登录 |
Step 1: 收集客户信息
与客户确认以下信息:
企业名称:________
客服称呼:________(如 林经理、小张、客服小王)
业务描述:________(一句话概括,如"帮企业做腾讯生态运营")
服务板块(2-4个):________(如 企业微信搭建、广告投放、微信小店)
转化引导:________(如 加企业微信、加个人微信、拨打电话)
二维码图片:________(引导转化的微信群/个人/企业微信二维码)
Step 2: 创建 EdgeOne Pages 项目
# 创建工作目录
mkdir -p wechat-mp-ai && cd wechat-mp-ai
# 创建项目结构(也可以用 edgeone pages init)
mkdir -p cloud-functions .edgeone
# 复制模板文件
cp [skill-path]/templates/wx-callback.js cloud-functions/
cp [skill-path]/templates/.env.example .
# 创建 edgeone.json
cat > edgeone.json << 'EOF'
{
"Name": "wechat-mp-ai"
}
EOF
# 创建 package.json
cat > package.json << 'EOF'
{
"private": true,
"type": "module"
}
EOF
# 部署
edgeone pages deploy
Step 3: 配置系统提示词
编辑 cloud-functions/wx-callback.js 中的 SYSTEM_PROMPT 数组:
- 将名称和角色改为客户的客服人员(如 "李经理"、"小张"等)
- 修改服务板块为客户的业务
- 调整转换引导(如加个人微信、加群、拨打电话等)
- 修改
[SEND_QRCODE]触发条件和示例话术 - 修改二维码图片 URL(
QRCODE_URL),指向已在项目中的二维码图片
提示词结构(详见 templates/system-prompt.md):
1. 身份定义:你是谁,代表谁
2. 核心使命:目标是什么
3. 服务板块:列出所有业务
4. 应答流程:不同场景的回应策略
5. 二维码推送规则:何时触发 [SEND_QRCODE]
6. 风格要求:语气、长度、态度
7. 底线:不能说什么、不能做什么
重要!二维码推送触发规则在提示词中明确说明,
AI 会在末尾添加 [SEND_QRCODE] 标记,
Cloud Function 检测到后自动替换为二维码图文消息。
Step 4: 准备二维码图片
# 将企业微信/个人微信二维码放入项目根目录
cp /path/to/qrcode.png qrcode.png
Step 5: 设置环境变量
在 wx-callback.js 文件中设置:
- QRCODE_URL 指向二维码图片的公开 URL(如 https://your-domain/qrcode.png)
部署时设置 EdgeOne Pages 环境变量:
edgeone pages env set WX_TOKEN your_token
edgeone pages env set WX_APPID your_appid
edgeone pages env set WX_ENCODING_AES_KEY your_aes_key
edgeone pages env set WX_APP_SECRET your_app_secret
edgeone pages env set CNB_TOKEN your_cnb_token
环境变量说明:
| 变量 | 必填 | 说明 |
|---|---|---|
WX_TOKEN |
是 | 微信服务号后台设置的 Token |
WX_APPID |
是 | 微信服务号的 AppId |
WX_ENCODING_AES_KEY |
否(不填则明文模式) | 微信 EncodingAESKey(43位) |
WX_APP_SECRET |
否(图文消息无需此变量) | 微信 AppSecret |
CNB_TOKEN |
是 | CNB API 访问令牌 |
CNB_REPO |
否 | 默认 {owner}/fuwuhao/{repo} |
AI_MODEL |
否 | 默认 deepseek-v4-flash |
AI_TIMEOUT_MS |
否 | AI调用超时,默认 4000ms |
WELCOME_TEXT |
否 | 新关注欢迎词 |
Step 6: 配置微信服务号后台
登录 微信公众平台 → 设置与开发 → 基本配置:
-
服务器配置(启用):
- URL:https://[你的EdgeOne域名]/wx-callback
- Token:WX_TOKEN的值
- EncodingAESKey:WX_ENCODING_AES_KEY的值
- 消息加解密方式: 安全模式(推荐)或明文模式 -
IP白名单(安全模式下无需配置,明文模式需加 EdgeOne 服务器 IP)
-
点击提交,通过验证后开启
Step 7: 部署
git add .
git commit -m "微信公众号AI客服初始化"
git push
edgeone pages deploy
部署完成后,访问你设置的 URL(如 https://fwh.yunjinhong.cn/wx-callback?echostr=test)确认 GET 请求正常返回。
Step 8: 测试
- 关注公众号,触发欢迎语
- 发送"你好",验证 AI 回复
- 发送"发一下二维码"或"加微信",验证图文消息(文字+二维码图片)
核心技术要点
1. 微信被动回复 vs 客服消息
| 方式 | 被动回复(本方案采用) | 客服消息(旧方案) |
|---|---|---|
| 触发 | 用户消息后5秒内 | 任何时间(需access_token) |
| 消息类型 | text / image / news / voice / video | text / image / voice / video / music / news / mpnews |
| 限制 | 每条用户消息只能回复一次 | 每日有数量限制 |
| 可靠性 | ✅ 同步,不依赖外部流程 | ❌ 需额外 API 调用,token 管理 |
| 图文消息 | ✅ 支持 | ❌ 不支持同步回复图文 |
| 本方案 | ⭐ 使用 news 类型:文字+二维码,无需额外 API |
✗ 舍弃(不可靠) |
2. [SEND_QRCODE] 标记检测机制
AI 回复内容 → 检测是否包含 [SEND_QRCODE] 标记:
- 包含 → 移除标记,返回图文消息(news):文字说明 + 二维码图片
- 不包含 → 返回纯文本消息
标记在系统提示词中定义,AI 根据上下文判断是否在回复末尾添加。
3. 图文消息格式
<xml>
<ToUserName><![CDATA[用户openid]]></ToUserName>
<FromUserName><![CDATA[公众号原始id]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[news]]></MsgType>
<ArticleCount>1</ArticleCount>
<Articles>
<item>
<Title><![CDATA[文字说明标题]]></Title>
<Description><![CDATA[文字说明详情]]></Description>
<PicUrl><![CDATA[https://domain/qrcode.png]]></PicUrl>
<Url><![CDATA[https://domain/qrcode.png]]></Url>
</item>
</Articles>
</xml>
4. 安全模式加解密
微信安全模式下,POST 回调数据是 AES-256-CBC 加密的。本方案完整实现了:
- 接收端:签名验证 → 解密 Encrypt → 解析 XML
- 回复端:原文 → 加密 → 组装 Encrypt XML → 签名 → 返回
5. 超时管理
- AI 调用:设置 4 秒超时(
AI_TIMEOUT_MS) - 总耗时:AI(4s) + 处理后返回(<1s) < 微信5秒限制
- 超时回复:"我在思考时遇到了点状况,请再问一次~"
常见问题
Q: 为什么不用异步推送客服消息?
A: 本方案最初使用 context.waitUntil 异步推图片,但在 EdgeOne 运行时被中断。改为同步推送后虽在限制内,但需要额外 API 调用。最终方案用图文消息(news)类型,文字+图片一次返回,0 额外调用,最稳定。
Q: AI 回复内容太长怎么办?
A: 系统提示词中已限制"回复简洁,微信不超过3段",SYSTEM_PROMPT 中的 max_tokens: 500 也控制长度。
Q: 微信安全模式和明文模式选哪个?
A: 推荐安全模式。明文模式可能被中间人篡改消息,安全模式 AES 加密保证完整性。
Q: 二维码图片更新了怎么办?
A: 替换 qrcode.png 文件,重新部署即可生效。
Q: [SEND_QRCODE] 标记跑到用户看到的回复里了?
A: 不会。代码中已 .replace(QRCODE_MARKER, '') 移除标记后再组装回复。
Q: AI 没有知识库,怎么回答产品问题?
A: 核心信息写在系统提示词中。如果业务信息量大,建议增加提示词模板的详细程度,将 FAQ 和产品信息纳入系统提示词。
工作流复盘(开发过程)
开发耗时
| 环节 | 耗时 | 说明 |
|---|---|---|
| 需求分析 | ~15min | 明确AI客服需求、四大业务板块 |
| 首版开发 | ~30min | 基础 Cloud Function + CNB AI 集成 |
| 人设调整 | ~10min | 系统提示词编写与调优 |
| 异步推送→同步推送 | ~20min | 从 context.waitUntil 改为 await |
| 图文消息方案 | ~15min | 从推送改为 news 类型被动回复 |
| 部署调试 | ~30min | EdgeOne 部署、微信配置验证 |
| 总计 | ~2h | 从零到上线 |
关键决策点
- EdgeOne Pages 选型:Cloud Function 5 秒超时适合微信回调;静态资产同时托管。
- CNB AI 选择:不用自建、不用微调,纯通用模型+提示词控制,成本低迭代快。
- 图文消息方案:替代异步客服消息推送,去掉了
context.waitUntil和WX_APP_SECRET依赖。 - 无记忆设计:AI 每次请求独立,不保留上下文,规避微信回调无 session 的问题。
优化的提示词
身份定义 + 核心使命 + 服务板块 + 应答流程
+ 二维码推送规则(含 [SEND_QRCODE] 触发条件)
+ 风格要求 + 底线约束
关键技巧:[SEND_QRCODE] 标记是纯文本字符串,AI 生成时贴在末尾,代码检测并替换。避免了复杂实体识别/结构化输出。
踩坑记录
| 问题 | 原因 | 方案 |
|---|---|---|
| HTTP 567 | EdgeOne WAF 拦截 | 不用 api.edgeone.ai,使用 CLI |
context.waitUntil 不执行 |
运行时可能未实现 | 改为同步 await |
| 客服消息 API 失败 | 需先关注才能 push | 改为 news 类型被动回复 |
| env ls -n 空 | CLI bug | 用 env ls --env production |
| Accept header 412 | DELETE 需 application/json |
记录到仓库删除规范 |