WeChaty 微信机器人防封实战:把账号活过 90 天的四步法
【免费下载链接】wechat-bot🤖 Multi-platform IM AI Agent for Telegram, WhatsApp, Lark, and WeChat. Connects ChatGPT / Claude / Kimi / DeepSeek / Ollama / Pi for auto-replies, community analysis, contact management, and inactive-friend detection.项目地址: https://gitcode.com/GitHub_Trending/we/wechat-bot
跑 wechat-bot 第 17 天,账号收到「功能受限」的提示:一个 3000 人的群里,机器人连续两周「有问必答」,回复间隔稳定在 800 毫秒左右——太稳定,本身就是一种机器特征。问题不出在 AI 服务,而出在运行方式。这份笔记按运营时间线,把 WeChaty 微信机器人防封的四个阶段(上线之前、运行之中、出问题时、长期运营)拆开讲,每一条都能对照项目源码核实。
上线之前:先做四项风险自查,再加固登录环境
最大的风险变量不是回复逻辑,而是登录通道和网络环境。代码当天能改,账号环境一周内改不了。先弄清一个词:协议,指机器人登录微信所用的「通道」,越接近官方客户端的通道,风控关注度越低。项目默认的 puppet 是wechaty-puppet-wechat4u(Web 类协议),配置见 src/wechaty/bot.js;README 里作者明确提示:微信对 Web 协议审查已非常严格,存在警告或封号风险,padlocal 协议作者也已停止维护。选 puppet 时优先选持续维护、更接近设备端的协议;必须用 Web 协议时,把它限制在低频、小范围场景。
拿到代码:git clone https://gitcode.com/GitHub_Trending/we/wechat-bot,然后npm i、cp .env.example .env。Pi + 微信渠道的快速启动流程见 docs/pi-im-agent.md,配好后用wb agent --im wechat --agent pi扫码登录。
环境加固,按顺序做四件事:
- 选账号:用实名、有一定使用历史的账号;新号先养再上;首次部署放在「丢了不心疼」的备用号上验证。
- 收窄白名单:
ALIAS_WHITELIST和ROOM_WHITELIST只填真正活跃的好友与群。群聊默认要求 @机器人才回复,逻辑在 src/wechaty/sendMessage.js;再给AUTO_REPLY_PREFIX设一个前缀,让机器人只在被「点名」时应答,而不是全程旁听。同时打开消息落盘,为后面排障留证据:
BOT_NAME='@机器人名' ALIAS_WHITELIST='好友备注1,好友备注2' ROOM_WHITELIST='群名1' AUTO_REPLY_PREFIX='问一下:' WECHAT_STORE_MESSAGES='true'- 固定网络:一台机器、一个号、一个出口 IP,三者长期绑定;24 小时内不要跨地区切换登录地。
- 收敛模型通道:AI 服务请求走代理时固定出口。项目内置 12 个模型通道,分发逻辑在 src/wechaty/serve.js,需要同时接多个服务时,聚合 API 平台能减少代理切换次数、也便于单通道故障时回滚,下图是这类服务常见的形态:
切换模型通道每周不超过两次。通道越稳定,机器人的网络行为越「无聊」,越像真人。
运行之中:把发送频率和话术拉进人类区间
风控看的是消息流的形状。人类行为有三个特征:延迟、作息、变化。机器人也要做出这三个特征。
把回复间隔拉到 1-3 秒随机
为什么:固定间隔等于机器签名。AI 生成一条回复本身要 0.5-2 秒,生成完立刻发出,时间线上对不上。
怎么做:每条回复前先等 1-3 秒随机延迟;长文本项目已按 500 字切段发送(trySay,见 src/wechaty/sendMessage.js),段与段之间再补 0.5-1 秒,避免「机关枪」式连发;同一人连续两条回复不要一字不差,AI 对同一问题倾向给出同样的答案,换行、换说法都行。最小可用的封装如下,放进src/wechaty/,再把原有的contact.say(response)/room.say(response)替换为它:
import { setTimeout as sleep } from 'node:timers/promises' const OPENERS = ['', '嗯,', '换个说法:', '简单说,'] // 先随机等待 1-3 秒,再拼随机开头,替换原 say 调用 export async function humanizeSay(target, text) { await sleep(1000 + Math.floor(Math.random() * 2000)) const opener = OPENERS[Math.floor(Math.random() * OPENERS.length)] await target.say(opener + text) }把夜间响应概率压到 5%
23:00-7:00 让机器人「睡觉」:群聊 @ 一律不接,只保留白名单私聊且按 5% 概率响应;非白名单消息夜间直接丢弃。白天把发送峰值压到每小时 20 条以内,超了就排队缓发,不 burst。主动类功能(如不活跃好友检测)只在白天低峰跑。
给 AI 回复加变化
同一问题换句式回答,随机加前后缀,偶尔一句话短答;同一会话内不要连续两次使用相同开头。人设感交给各服务的 system prompt 配置(.env里的CLAUDE_SYSTEM、OLLAMA_SYSTEM_MESSAGE等),去掉「我是一个 AI 助手」这类模板味。
出问题时:先看信号,再决定降级、暂停还是恢复
不要等微信团队的提示,自己的日志更快。项目会把每条消息写入.data/wechat/messages.jsonl(实现见 src/platforms/wechat/messageStore.js),这是判断的第一手材料。盯三类信号,再排除一类干扰:
- 回复延迟:机器人回复后,后续消息间隔反复超过 5 秒,或发送接口偶发超时。
- 登录抖动:二维码无故重发,登录 24 小时内掉线。
- 明确警告:微信团队服务号下发提示消息(分片逻辑里已有针对「微信团队」的跳过处理,见 src/wechaty/sendMessage.js)。
- 排除项:AI 服务返回 429 或超时。429 是模型服务商的限流(「你问得太快,我先扣着」),与微信封号无关,先换通道再下结论,别误伤判断。
⚠️ 前三类信号出现任一,按下面的处置决策流走,不凭感觉操作:
对应动作:
- 降级(延迟信号):停掉所有群聊,只保留白名单私聊;发送间隔翻倍;关闭一切主动功能。
- 暂停(登录抖动):停进程,不要反复扫码——每次扫码都是一次新的登录事件;等 24 小时,从固定网络、固定设备重新登录。
- 恢复(明确警告):账号转纯人工使用 3-7 天,期间不启动机器人;提示消失后从小白名单、小流量重新接回。
- 原则只有一条:账号价值高于机器人可用性。进程随时能重启,账号不能。
长期运营:每周一份八项检查单
✅ 防封线是漂移的,靠制度不靠感觉。每周花十分钟过一遍:
| 动作 | 频率 | 达标判断 |
|---|---|---|
| 核对周发送量与每小时峰值 | 每周 | 峰值低于 30 条/小时,趋势不升 |
| 审计白名单,移除不活跃好友和群 | 每周 | 白名单数量与真实活跃用户一致 |
| 抽查连续两条相同回复 | 每周 | 0 条;发现就加强话术变异 |
| 检查网络出口与登录设备记录 | 每月 | 24 小时内无跨地区跳转 |
| 演练一次模型通道切换 | 每月 | 切换耗时低于 10 分钟 |
| 检查 .data/wechat 日志占用 | 每月 | 磁盘占用不无限增长 |
| 给账号放一天「人工假」 | 每月 | 停机器人 24 小时后发送延迟回落 |
| 跟踪 puppet / 协议维护状态 | 持续 | 上游停更则先停机器人再换协议 |
三条持续迭代的提醒:
- 微信风控策略在动,上面的线是今天的基线,不是上限;每月重校一次阈值。
- 更换协议或 puppet 版本后,先在备用账号跑一周,再上生产账号。
- 不相信任何「绝对防封」的说法;主账号永远押在已验证过的通道上。
防封不是一次性配置,而是使用强度与账号价值之间的持续权衡。账号活着,其余都能重来。
【免费下载链接】wechat-bot🤖 Multi-platform IM AI Agent for Telegram, WhatsApp, Lark, and WeChat. Connects ChatGPT / Claude / Kimi / DeepSeek / Ollama / Pi for auto-replies, community analysis, contact management, and inactive-friend detection.项目地址: https://gitcode.com/GitHub_Trending/we/wechat-bot
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考