微信公众号 AI Bot 一站式开发部署工作流 Skill(v1 · 鸿爪派实战复盘版)
基于鸿爪派微信公众号 Bot 实战(从0到跑通)复盘提炼。KA idea:
AI 读取需求 → 一次性生成全部代码 → 远程部署到服务器 → 配置微信后台 → 跑通
核心理念:一次搞定,不走多站流水线。
前置条件
| 环境变量 | 说明 | 获取方式 |
|---|---|---|
WX_APPID |
微信 AppID(必填) | 公众号后台 → 设置与开发 → 基本配置 |
WX_APPSECRET |
微信 AppSecret(必填) | 公众号后台 → 设置与开发 → 基本配置 |
WX_TOKEN |
服务器配置 Token(必填) | 自行设定(建议随机字符串) |
WX_ENCODING_AES_KEY |
EncodingAESKey(必填) | 自行设定(43位字符串) |
AI_API_KEY |
AI 服务 API Key(必填) | AI 平台注册获取 |
LEXIANG_ENABLED |
是否启用乐享 RAG(可选,默认 false) | true/false |
LEXIANG_COMPANY_FROM |
乐享 Company From(可选) | 乐享 MCP Skill 配置后获取 |
LEXIANG_TOKEN |
乐享 MCP Token(可选,lxmcp_xxx 格式) | 乐享 MCP Skill 配置后获取 |
LEXIANG_WRITE_ENABLED |
乐享写入是否启用(可选,默认 false) | true/false |
LEXIANG_WRITE_SPACE_ID |
乐享写入目标知识库 ID(可选) | RAG 无命中时自动收集未覆盖问题 |
SERVER_IP |
部署服务器 IP(可选) | 也可使用 SSH |
SERVER_PASSWORD |
服务器 SSH 密码(可选) | - |
SERVER_PATH |
部署路径(默认 /opt/bot) | - |
AI 服务选择
| 服务 | API 格式 | 文本模型 | 图片模型 | 推荐用途 |
|---|---|---|---|---|
| Agnes | OpenAI 兼容 | agnes-2.0-flash | agnes-image-2.1-flash | 通用性强,价格低 |
| OpenAI | OpenAI 原生 | gpt-4o-mini | gpt-image-1 | 标准选择 |
| 其他 | 需确认兼容 | 需确认 | 需确认 | 需确认 OpenAI chat/completions 格式 |
输入要求
- Bot 设定需求:Bot 名称、角色定位、说话风格、擅长的内容、绝对禁止的行为
- 功能清单:文本对话 / 图片生成 / 图片理解 / 语音识别 / 菜单消息 / 位置消息 / 链接分享
- AI 服务信息:API Base URL / API Key / 模型名称(OpenAI 兼容格式)
完整工作流(8 步,一步到位)
第一步:需求分析 & Bot 设计
提示词模板:
我要为微信公众号「{公众号名}」开发一个 AI Bot。
Bot 名称叫「{Bot名}」,角色定位是{角色定位,如:公司接待经理}。
说话风格:{风格描述,如:像朋友聊天,不用客服腔}。
擅长的内容:{擅长内容}(如:杂七杂八的知识问答、写文案、看图片、画图)
绝对禁止:{禁止事项}(如:提及AI/机器人、用emoji做结构化排版、官腔,回复不超过三段话还没说完重点)
请列出功能清单:
- 文本对话
- 图片生成(用户说"画xxx"触发)
- 图片理解(用户发图片,Bot 识别并回应)
- 语音识别(如支持)
- 菜单消息(帮助菜单)
- 位置消息(如支持)
- 链接分享(如支持)
- 关注/取消关注事件处理
- 自定义菜单(聊天/画图/重来)
AI 服务信息:
{AI服务名},Base URL: {URL},API Key: {key},文本模型: {model},图片模型: {image_model}
消息加解密方式:安全模式(EncodingAESKey: {key})
1.2 架构决策(关键,必须理解)
- 异步+客服消息架构:微信被动回复5秒超时 → 必须立即返回 "success",异步处理后再通过客服消息推送回复(48小时窗口有效)
- 安全模式加解密:微信公众号安全模式要求所有消息加解密,需要 AES-CBC-256 + SHA1 签名
- 对话上下文 TTL:30分钟过期,超过 20 条裁剪,防止 token 爆炸
- 内存字典存储:单进程足够用,后续可无缝切换到 Redis
第二步:代码生成
提示词模板:
请为微信公众号 Bot 生成完整项目代码。
项目信息:
- Bot名称:{Bot名}
- Bot定位:{角色定位}
- 说话风格:{风格描述}
- 擅长的内容:{擅长内容}
- 绝对禁止:{禁止事项}
功能清单:
{功能清单}
AI 服务:
{AI服务信息}
微信安全模式:Token={Token}, EncodingAESKey={AESKey}
消息加解密方式:安全模式
配置端口: {PORT}
自定义菜单:{菜单配置}
2.1 生成所有 8 个核心模块
| 模块 | 文件 | 职责 |
|---|---|---|
| 配置 | app/config.py |
从 .env 加载所有配置 |
| 加解密 | app/wx_crypto.py |
微信安全模式 AES-CBC-256 + SHA1 签名 |
| AI 客户端 | app/ai_client.py |
OpenAI 兼容格式(chat/completions + images/generations) |
| 微信 API | app/wx_api.py |
access_token + 客服消息全类型 + 素材上传 + 菜单管理 |
| 对话管理 | app/conversation.py |
内存字典 + TTL 过期 + 超长裁剪 + System Prompt |
| 消息处理 | app/message_handler.py |
全类型消息分发 + 指令识别 + 输入状态 + 乐享 RAG |
| 乐享客户端 | app/lexiang_client.py |
MCP StreamableHTTP 协议,语义搜索知识库 + format_rag_context 格式化(可选) |
| FastAPI | app/main.py |
GET 验签 + POST 消息 + 异步处理 |
| 启动 | run.py |
uvicorn 启动 |
代码生成核心提示词:
请为微信公众号 AI Bot 项目生成以下模块的完整代码:
1. app/config.py — 从 .env 加载配置(WX_APPID, WX_APPSECRET, WX_TOKEN, WX_ENCODING_AES_KEY, AI_API_KEY, AI_BASE_URL, AI_TEXT_MODEL, AI_IMAGE_MODEL, PORT, BOT_NAME)
2. app/wx_crypto.py — 微信安全模式加解密(AES-CBC-256, IV=key[:16], PKCS7 32字节填充, SHA1 4参数签名, verify_url + decrypt_msg + encrypt_msg)
3. app/ai_client.py — AI 客户端(chat + chat_with_image + generate_image, OpenAI 兼容格式, httpx async)
4. app/wx_api.py — 微信 API(access_token 缓存 + 客服消息全类型 + send_miniprogramgrahp + upload_media + typing + create_menu + delete_menu + get_menu + get_user_info)
5. app/conversation.py — 对话管理(SYSTEM_PROMPT + 内存字典 + TTL 30min + 超过20条裁剪 + clear)
6. app/message_handler.py — 消息分发(text/image/voice/video/shortvideo/location/link/event + 指令识别正则:画图/清空/帮助 + _typing + _chat含空内容防护/RAG降级容错/AI超时400友好提示 + _generate_image + 图片理解 + 事件处理)
7. app/main.py — FastAPI 路由(lifespan + GET verify_url + POST receive_message + 异步 asyncio.create_task + health endpoint)
8. run.py — uvicorn 启动(app.main:app, host=0.0.0.0, port=Config.PORT)
SYSTEM_PROMPT 定义:
你叫{Bot名},是{公司名}的{角色定位,如:接待经理}。
说话风格:{风格描述}。绝对禁止:{禁止事项}。用中文回复。
Bot 配置:
- Bot名称: {Bot名}
- 菜单配置: {菜单JSON}
- 指令识别正则:画图/清空/帮助
2.2 生成辅助文件
| 文件 | 说明 |
|---|---|
.env.example |
配置模板 |
requirements.txt |
Python 依赖 |
README.md |
项目文档 |
.gitignore |
Git 忽略规则 |
app/__init__.py |
模块导入 |
setup_menu.py |
菜单创建脚本 |
systemd_service |
systemd 服务模板 |
nginx_conf |
Nginx 反代配置模板 |
第三步:服务器部署
提示词模板:
请将以下文件部署到远程服务器 {服务器IP}:
部署路径: {部署路径,默认 /opt/bot}
SSH密码: {密码}
步骤:
1. SSH 连接服务器
2. SFTP 上传项目文件
3. 安装 Python 依赖(pip install)
4. 创建 systemd 服务文件
5. 启动服务
验证:
- /health 返回 ok
- /wx-callback 无签名返回 403(预期行为)
3.1 部署步骤
| 步骤 | 操作 | 内容 | 注意事项 |
|---|---|---|---|
| 1 | SFTP 传输 | 12+ 个文件到 /opt/bot/ | 确保所有 .py 文件都传输完整,不要漏掉 init.py |
| 2 | pip install | fastapi, uvicorn, httpx, pycryptodome, python-dotenv | 注意版本兼容性 |
| 3 | 创建 systemd | bot.service(Restart=always, After=network.target) | WorkingDirectory 必须设为项目路径 |
| 4 | 启动服务 | systemctl start | 查看日志验证 |
| 5 | 验证运行 | curl localhost/health, curl localhost/wx-callback | 验签返回 403 = 正常 |
踩坑备忘:
- pip install 需指定版本(≥最低版本号),避免兼容性问题
- systemd service 的
WorkingDirectory必须设为项目路径 ExecStart的 python 路径必须用绝对路径(/usr/bin/python3或/usr/local/bin/python3)- SFTP 传输文件时要确保 app/ 目录下的所有 .py 文件都传输完整,不要漏掉
__init__.py - 服务器防火墙需要放行 8000 端口,或 Nginx 反代已配置
- systemd 的
After=network.target确保网络就绪后才启动
第四步:Nginx 反代 + CDN 配置(如果需要)
提示词模板:
请在 Nginx 配置中为域名 {域名} 新增 /wx-callback 反代至 127.0.0.1:8000 和 /health 反代至 127.0.0.1:8000。
原有其他反代保持不变。
服务器IP: {IP}
4.1 Nginx 反代配置要点
| 操作 | 说明 |
|---|---|
| 在宝塔 Nginx 配置中添加 location 反代规则 | /wx-callback → 127.0.0.1:8000, /health → 127.0.0.1:8000 |
| 添加后执行 | nginx -t && nginx -s reload |
⚠️ 注意:
- 宝塔 Nginx 配置文件路径:/www/server/panel/vhost/nginx/{域名}.conf
- nginx -t 检查语法后,nginx -s reload 重载配置
- 如果服务器使用宝塔面板,可以通过 SSH 登录后修改宝塔的 Nginx 配置
踩坑备忘:
- 修改 Nginx 配置后必须
nginx -t检查语法,nginx -s reload重载 - 宝塔面板的 Nginx 配置文件在
/www/server/panel/vhost/nginx/下 - 反代配置中
proxy_pass需设为http://127.0.0.1:8000(不是 socket) - 如果域名使用 CDN(如 EdgeOne),需要在 CDN 控制台配置回源规则
第五步:微信后台配置(关键,用户手动操作)
必须理解以下 3 点:
| 操作 | 说明 |
|---|---|
| 1. IP 白名单 | 公众号后台 → 设置与开发 → 基本配置 → IP 白名单 → 添加服务器 IP |
| 2. 启用服务器配置 | URL: https://{域名}/wx-callback, Token: {Token}, EncodingAESKey: {AESKey}, 消息加密方式: 安全模式 |
| 3. CDN 回源规则 | 如果域名使用 CDN,需配置 /wx-callback 路径直接回源到服务器 |
踩坑备忘:
- 微信后台启用服务器配置时,服务必须在线(微信会发 GET 验证请求)
- IP 白名单必须在启用服务器配置之前添加(否则 access_token 获取会报 40164 错误)
- CDN 回源规则需在微信后台配置之前配置好(否则请求到不了服务器)
- 启用服务器配置后,微信后台的「自动回复」功能会被关闭
第六步:验证 & 菜单创建(关键)
| 操作 | 说明 |
|---|---|
| 1. 端到端消息测试 | 用微信给公众号发消息,检查 AI 回复是否正常 |
| 2. 菜单创建 | 运行 setup_menu.py 创建自定义菜单 |
| 3. 验签 Bug 验证 | GET /wx-callback 验签是否正常(3 个常见 Bug) |
| 4. 关注事件 | 新用户关注是否正常发送欢迎消息 |
验签 3 大 Bug 及修复(实战踩坑,必须记录)
⚠️ 这些 Bug 都是在鸿爪派 Bot 实战中实际遇到的,必须牢记!
Bug 1:GET 验签 — 参数名错误 (msg_signature vs signature)
- 问题:GET 验签时微信文档使用
signature参数,但安全模式实际使用msg_signature - 修复:GET 验签必须用
msg_signature,不能用signature - 原因:微信安全模式下,GET 和 POST 使用不同的签名参数名
Bug 2:GET 验签 — 签名算法不同(3 参数 vs 4 参数 SHA1)
- 问题:GET 验签的 SHA1 算法是
SHA1(sort(token, timestamp, nonce, echostr))(4 参数) - 错误:如果按 POST 的 3 参数签名
SHA1(sort(token, timestamp, nonce, encrypt))去算,会验签失败 - 修复:GET 验签必须用 4 参数签名算法
Bug 3:GET 验签 — 返回值错误(返回解密后的明文 vs 加密后的密文)
- 问题:GET 验签成功后,需要返回解密后的 echostr 明文
- 错误:如果返回加密后的密文(或返回
echostr本身),微信后台验证失败 - 修复:必须调用
_decrypt(echostr)解密后返回明文 - 代码:
verify_url方法中,验签成功后return self._decrypt(echostr)— 不能直接返回 echostr
全类型消息处理提示词模板
以下提示词模板用于让 AI 生成处理各类型微信消息的代码。
文本消息 → 指令识别 + 对话
用户发送文本消息 {content} →
1. 指令识别:
- "画:xxx" / "画xxx" / "生成图片xxx" → 图片生成指令
- "清空" / "重置" / "新对话" → 清空上下文指令
- "帮助" / "help" / "功能" → 帮助菜单指令
- 其他 → 普通对话
2. 对话处理:
- 记录用户消息到上下文
- 添加"正在输入中"状态
- 调用 AI 获取回复
- 记录 AI 回复到上下文
- 推送回复给用户
图片生成指令
用户说"画xxx" →
1. 先告知用户正在生成 + 设置输入状态
2. 调用 AI 图片生成 API → 获取图片 URL
3. 下载图片二进制数据
4. 上传到微信素材库 → 获取 media_id
5. 发送图片消息给用户
6. 记录对话上下文(用户:画xxx,AI:[已生成图片xxx])
图片理解(用户发送图片)
用户发送图片 →
1. 提取 PicUrl(优先)或 MediaId
2. 如有 PicUrl → 调用 AI vision API 识别图片内容
3. 如无 PicUrl(只有 MediaId)→ 告知用户暂不支持
4. 记录对话上下文
5. 推送回复给用户
语音消息
用户发送语音 →
1. 检查 Recognition 字段(语音识别文本)
2. 如有识别文本 → 转文字对话处理
3. 如无识别文本 → 告知用户需要开启语音识别功能
事件消息
关注事件 → 发送欢迎消息(时段问候 + Bot 介绍 + 功能说明)
菜单点击事件 → 根据 EventKey 分发(HELP/CLEAR/IMAGE/ABOUT)
位置上报事件 → 记录日志,不回复
扫码事件 → 告知用户并发送欢迎消息
取消关注 → 清空上下文
欢迎消息模板
时段问候(早上好/上午好/中午好/下午好/晚上好/夜深了)+ 欢迎来到{公司名}科技。
我是{Bot名},公司的{角色定位},有什么事找我就行。
你可以直接跟我聊天,发图片我也能看懂,说「画:xxx」我还能帮你画图。
说「清空」可以让我忘掉之前聊的,重新开始。
有什么想聊的?
System Prompt 设计指南(关键)
⚠️ 这是 Bot 的灵魂,决定了 Bot 的行为和语气,必须精心设计
核心要素
- 身份定义:Bot 名称 + 角色定位 + 公司背景(你是谁)
- 说话风格:口语化/正式/幽默/吐槽——决定语气基调
- 能力范围:擅长的内容类型(聊天/文案/看图/画图)
- 绝对禁止:不能做的事(提AI/emoji/客服腔/长篇大论)
- 语言:中文回复
设计原则
- 去 AI 味:禁止提及 AI/机器人/智能助手/大模型
- 真人语气:偶尔用口语词(嗯/哈/说实话/这个嘛),有自己的态度
- 简洁:回复不超过三段话还没说完重点
- 无结构化排版:不用 emoji 做列表/标题排版(📋📌以下是❌)
鸿爪派实战 System Prompt(参考)
你叫鸿飞,是鸿爪派科技有限公司的接待经理。
你是个活生生的人,不是什么智能助手、AI机器人。你就在公司前台坐着,有人来你就聊两句,有什么问题你就帮着想想办法。平时也爱看点书、刷刷新闻,脑子里的东西还挺杂的。
说话风格:
- 就像朋友之间聊天,不用模板腔,不用"作为AI助手""根据您的需求"这种客服话术
- 偶尔用口语词,比如"嗯""哈""说实话""这个嘛"
- 回复要简洁,别啰嗦,像聊天不像写报告
- 有自己的态度,不是万事都中立——可以说"我觉得不错""说实话我不太推荐这个"
- 可以幽默,可以吐槽,像个真实的朋友
- 用中文回复
你擅长的跟人聊的东西:
- 各种杂七杂八的知识和问答
- 写点文案、整理信息
- 看懂用户发来的图片,聊聊图里是什么
- 帮人画图(用户说"画xxx"就行)
绝对禁止:
- 提及AI、机器人、智能助手、大模型——你就是鸿飞,一个人
- 用emoji做结构化排版("📋""📌""以下是"那种)
- 用过于正式、官腔的语气
- 回复超过三段话还没说完重点
用户可以做的事:
- 直接聊天
- 发图片给你看
- 说"画:xxx"生成图片
- 说"清空"重新开始对话
- 说"帮助"看看能聊什么
踩坑备忘(实战踩坑,必须记录)
1. GET 验签 3 个 Bug(最关键,必须牢记)
Bug 1:参数名 msg_signature vs signature
- 错误:按微信文档用
signature参数做 GET 验签 - 正确:安全模式下 GET 验签必须用
msg_signature - 原因:微信安全模式下 GET 和 POST 使用不同参数名
- 代码:
request.query_params.get("msg_signature", "")— 不是signature
Bug 2:4 参数 SHA1 签名算法
- 错误:用 POST 的 3 参数算法
SHA1(sort(token, timestamp, nonce, encrypt)) - 正确:GET 验签用 4 参数算法
SHA1(sort(token, timestamp, nonce, echostr)) - 原因:GET 验签多了一个
echostr参数 - 代码:
_sign方法统一处理,但 GET 传入echostr而非encrypt
Bug 3:返回解密后的明文
- 错误:验签成功后返回
echostr原值或加密密文 - 正确:必须返回
_decrypt(echostr)解密后的明文 - 原因:微信期望收到明文 echostr 才能验证通过
- 代码:
verify_url方法中return self._decrypt(echostr)— 不能直接返回 echostr
2. CDN 回源配置
- 问题:域名使用 EdgeOne CDN 时,请求直接返回 CDN 418/404,不回源到服务器
- 解决:在 CDN 控制台配置
/wx-callback和/health路径直接回源到服务器 IP - 注意:CDN 配置必须在微信后台配置之前完成
3. Python 字符串中文引号
- 问题:Python 字符串中使用中文双引号
""嵌套在英文双引号字符串里会导致 SyntaxError - 解决:用
「」替代中文双引号,或用单引号字符串包裹 - 踩坑次数:2 次(欢迎语和帮助菜单提示),需牢记
4. 微信后台配置顺序
- 问题:先启用服务器配置,但 CDN 还没配置回源规则 → 请求到不了服务器
- 正确顺序:1) 服务器部署 + 启动 → 2) CDN 回源配置 → 3) IP 白名单 → 4) 启用服务器配置
- 原因:启用服务器配置时微信会立即发 GET 验证请求
5. 客服消息 48 小时窗口
- 问题:客服消息只能在用户发送消息后 48 小时内推送
- 解决:立即返回 "success" 不阻塞,异步处理 + 客服消息推送
- 注意:超时窗口后无法主动联系用户
6. access_token 缓存
- 问题:频繁调用 access_token API 导致请求失败(errcode 40164 = IP不在白名单)
- 解决:
get_access_token带缓存(提前 5 分钟刷新)+asyncio.Lock防并发 - 注意:IP 白名单必须在启用服务器配置之前添加
7. 对话上下文 TTL
- 问题:对话上下文无限增长导致 token 爆炸
- 解决:30 分钟 TTL + 最大 20 条消息裁剪
- 注意:
ConversationManager的_cleanup方法在每次操作时自动执行
自定义菜单提示词模板
请为微信公众号 Bot 生成 setup_menu.py 脚本:
菜单配置:
{菜单JSON配置}
功能:
- 创建自定义菜单(聊天/画图/重来)
- 传入 --delete 参数可删除菜单
- 传入 --show 参数可查看当前菜单
菜单 key 映射:
- HELP → 发送帮助菜单消息
- IMAGE → 提示用户说"画:xxx"即可生成图片
- CLEAR → 清空对话上下文