企微好友单聊 AI 自动代回 · 全景报告

方案B(GUI 自动化)· 从 0→1 到批量试跑 · 更新于 2026-07-05
Skia 自绘 UI · 只能 VL 读屏 Qwen-VL 读 + GUI 打字发 3 销售号 · 54 条 AI 代回 3 天灰度试跑 主号无隔离 · 灰度从严
客户在企业微信里给销售发消息 → 云电脑自动截屏读出来 → AI(小艳/小夏/小范/小文人设)生成回复 → 自动打字发出去。 全程无人值守。本页讲清:① 已完成的部署 + 0→1 原理图;② 批量跑后的真实数据;③ 踩过的各类 badcase 与对应优化;④ 下一步待做;⑤ 云电脑部署指南。
01 / Deployment & Architecture

已完成的部署操作 & 0→1 逻辑原理图

为什么是「GUI 自动化」这条路(0→1 由来)

2026-06-10
方案A(微信客服 kf API)全链路代码上线(PR #268)——但保存回调时撞上「回调域名 ICP 备案主体校验」硬阻塞:境外域名 vercel.app / fly.dev / upio.ai 全被拒,配置链锁死 → 方案A 冻结待域名
2026-06-11 → 06-29
转 Windows GUI 自动化(方案B)。探针实测:企微 PC 主界面是 Skia 自绘原生 UI,UIA 控件树恒空、DOM/CDP 也拿不到聊天 → 读消息只能靠截图 + Qwen-VL(判死,别再试 UIA/CDP)。
2026-06-29
V1 上线:迁移 + 大脑端点(PR #645)+ Fly 中转(fc25cdcd)+ 云电脑 loop(含风控)。云电脑 DRY_RUN=1 空跑验证通过后开真发。
2026-06-30 → 07-02
3 销售号批量灰度试跑(小夏/小范/小文)。橘枳等真实会话一天暴露 9 类事故 → loop 迭代 v2026-07-02.1 → .11 + 服务端连修(详见第 3 节 badcase)。
2026-07-05(本周)
三项工程加固 PR:#760 脚本自动同步 · #761 loop 心跳入库 + 存活告警 cron · #762 代回接入 stage 推进 + 客户画像回写。

0→1 逻辑原理图(一条消息的往返)

① 客户发消息
企业微信好友单聊里,业主发来一条消息
② 云电脑 · 读(wecom_reply_loop.py)
双通道扫未读(①轮询当前打开会话 + ②遍历左侧红点)→ 截屏 → Qwen-VL 逐条列出消息 → 代码取最底一条 + 确定性归属判定
云电脑国内 IP 连不上 vercel.app
③ Fly Tokyo 中转(wecom_relay.py)
纯透传:云电脑 → akke-worker-prod.fly.dev/wecom/chat/reply → Vercel(Fly→Vercel 必通),不持密钥
④ Vercel 大脑(/api/wecom/chat/reply)
chatReply 出小艳人设回复(按 stage:首触/nurture/decision)+ 确定性海报匹配 + 客户画像回写 + Langfuse 追踪 + 成本记账
⑤ Supabase
conversations / messages 落库;指纹幂等去重
▲ 回 reply ┃ ▼ 发送
⑥ 云电脑 · 发
拟人延迟 → 点输入框 → SendInput 逐字打字 → Enter 发送(换行切段封顶 3 条)
⑦ confirm 落库
GUI 真发出后才回调落 AI 消息(显式失败:没发成不记账)
蓝 = 云电脑(只做 GUI I/O) · 紫 = Vercel(大脑/DB/成本全在这) · 黄 = Supabase。 核心分工:Python 端不碰任何企微 API、不做任何判断——读靠 VL、发靠模拟输入,大脑与账本全在服务器。这也是它绕开方案A 那道 ICP 墙的原因(云电脑→Vercel 是普通入站请求,不调企微接口)。

已上线的部署资产

组件位置锚点状态
channel wecom_chat 迁移supabasePR #645 / 20260629165140已上线
大脑端点 /api/wecom/chat/replyVercelPR #645已上线
Fly Tokyo 透传中转akke-worker-prodfc25cdcd已上线
云电脑 loop + 风控(工作时间/日限20/时限8/连发6/STOP自停)云电脑wecom_reply_loop.py已上线
3 销售身份壳(小夏/小范/小文·福建漳州)Vercel + loopPR #669 起已上线
脚本自动同步(消灭"改了没生效")GitHub ActionsPR #760评审通过·待合
loop 心跳入库 + 存活告警 cronVercel + DB + loopPR #761评审通过·待合
stage 推进(→decision)+ 客户画像回写VercelPR #762评审中·待合
02 / Batch Metrics

批量化执行后的真实统计

数据源:生产 Supabase channel='wecom_chat' 实时查询(scripts/_wecom-stats.ts,2026-07-05 拉取)。非估算、非样例。
25
代回会话(客户)
54
AI 代回消息
61
客户来消息
3
销售号(人设壳)
22/25
会话获得 AI 回复
23/25
会话有客户互动
3 天
试跑窗口 06-30~07-02
~18
日均 AI 代回

每日 AI 代回量

06-3017
07-0122
07-0215

会话阶段分布(stage)

nurture22
ice_break3
decision0
数据自证缺口 → 25 个会话里 0 个进入 decision(收口)阶段0 个写下客户画像customer_profile 全空)。根因:试跑期 wecom 路径把 chatReply 的 toolCalls 直接丢了 → stage 永远停在 nurture、record_customer_info 从不回写。本周 PR #762 已修,合并后新会话会正常推进到 decision 并累积画像。
诚实边界(别当终局 KPI):这是一次 3 天灰度试跑——主号无隔离、日限 20/时限 8 从严、样本 25 会话/54 条。07-02 之后为集中修 badcase 暂停发送。数字用于定性验证「通路跑通、客户有回」,不代表规模化转化率。加微/成交等业务口径需在正式放量后另计。
03 / Badcases & Fixes

踩过的各类 Badcase · 优化方式 · 进展

GUI 自动化把「位置/布局/发送方判断」这类任务交给了 VL 与隐式机制 → 一旦看歪就静默丢单或发错。以下按层归类,均可追溯到具体修复 PR。

A读取层 —— 读错 / 漏读客户消息

现象根因优化方式进展
漏读最底部最新客户消息长会话滚不到底、被上方大气泡带偏;只信 VL 判「哪条最新」打开先滚到底 → read_latest_bottom() 裁底部 58~88% 专读最后一条 → 改「按序列出全部→代码取最后」+ 确定性归属判定,不信 VL 左右根治 #705/707/708/709
VL 把客户消息误判成 self → 卡死跳过发送方归属 100% 靠单次 VL 看图,非确定性不再信 VL 的 customer/self,改:读最底一条,只要非我方近发文案/非会话名/本会话没回过就当客户新消息已修
名字系统性读空会话列表分隔条被拖宽 → 裁剪切进标题读空改整屏兜底只问标题;裁剪比例提为 env AKKE_WECOM_CROP_RATIO 可调已修
消息被截半句 → 去重失效重复回裁剪比例 0.15 切进最左气泡裁剪比例降到 0.12;底部窄带二读复核紧贴我方回复下的小气泡已修

B防自回 / 防重复 —— 发错对象 / 发重复

现象根因优化方式进展
自问自答(回复自己)VL 把我方气泡误判成客户消息护栏① 我方近发文案模糊匹配拦截(读串一两字也拦)已修 #695/703
把自家黑窗日志当客户消息回出去截图圈进了 loop 自己的控制台读取侧前台校验 + 黑窗日志误读检测已修
同一条消息回两遍VL 漏读右侧我方气泡时 burst 混入已答旧行护栏③ 每会话回复台账,去重降到逐行已修 #704
好友验证系统样板被当客户开口回「我通过了你的验证/现在可以聊天了」被 VL 读成左气泡两个变体(有/无"我们")双侧正则过滤,剔空则跳过已修

C发送层 —— 发送形态不像真人

现象根因优化方式进展
一条回复被切成多条气泡(无上限)回复里的 \n 被企微当 Enter=发送发送前按 \n 切段、封顶 3 条、超出用空格连不丢内容已修
首触被拆条 / 固定连发 3 条太机械换行发送副作用 + 固定条数首触 single_bubble 钉死单条;代回气泡数随机 1-3 条已修 #692/714
抢窗口不稳 → 坐标落偏点空无影上 activate/maximize 常没真铺满屏focus_wecom 硬置前 + 最大化 + 铺满屏校验,没铺满就跳过本轮已修 #694

D身份 / 会话 —— 串台 / 碎记忆

现象根因优化方式进展
同一客户裂成多条会话、称呼念成「橘枳@微信」VL 读显示名当身份,后缀/空格差一字撞不上唯一键normalizeCustomerName 剥「@微信」后缀 + 空格归一过渡已修
跨销售号同名客户"通灵"(说出没对本号讲过的城市)身份只用裸显示名,跨号共享历史身份键改 persona:客户名,按销售号隔离已修
同号同名仍会串(无稳定 userid)GUI 拿不到官方 external_userid,架构级天花板确定性根治只剩官方付费「会话存档 API」P2 · 已拍板搁置

E话术 / 人设 —— 回复质量

现象根因优化方式进展
给已加微客户发「发个微信号我让设计师加你」ice_break 会话代回落了抖音冷开场模板route 把 ice_break stage 强转 nurture + wecomOpener 企微专属覆盖(禁要微信号/禁逼单)已修
把海报记账标记 [图片:config-568] 当文字打给客户LLM 学舌历史里的去重记账标记喂历史前 + 回复后 + confirm 落库三道剥离已修
客服腔重 / 人设密度不足 / 不主动挖需求nurture 只说"短"、没钉死节奏与人设few-shot 正例 + 4 号人设密度加密 + nurture 注入 SPIN 主动挖需求 + 客服腔自审已修 #754/756/757
企微号署名冒出抖音「小艳」few-shot 署名未按渠道隔离署名 persona 感知;few-shot fallback 按渠道隔离已修 #758

F架构 / 运维 —— 静默失效风险

现象根因优化方式进展
会话聚焦时客户秒回不弹红点 → 漏触发触发只靠左侧红点双通道:①轮询当前打开会话 + ②遍历红点会话已修
改了 loop 但云电脑没生效,排查半天wecom-chat 不在自动同步范围,靠人工传文件纳入 sync-wuying-scripts.yml 镜像 + update-wecom.bat token-free 自取PR #760 待合
loop 崩了/没起来,几小时无人知心跳只写本地 json、无远端监控心跳入库 + wecom-heartbeat-watch cron 工作时段超时推 Lark 云电脑监控群PR #761 待合
engaged 客户永不进 decision、画像永远空wecom 路径丢弃 chatReply 的 toolCalls接入 stage 启发式推进 + record_customer_info 画像回写PR #762 待合
04 / Roadmap

下一步待做的优化列表

优先级说明状态
立即云电脑拉新版 loopPR #760/#761/#762 合并后,在每台云电脑跑 update-wecom.bat + 重启,心跳/stage/画像才真生效待部署
立即合并 3 个 PR#760 先合(loop 才能同步),再 #761/#762;#761 触发建表迁移评审通过
正式放量 + 业务口径灰度稳定后逐步放开日限,接入加微/成交口径做真 KPI待定
token / 查询小优化HISTORY_LIMIT=40 每次喂 235B 偏贵可裁;matchPosters 全表拉取可加索引待办
跨会话记忆loadCustomerHistory 硬绑 douyin_user_id;wecom 身份已单会话合并、收益小暂缓
决策会话存档 API(P2)确定性读 + 稳定 userid,一步解决 VL 误读 + 身份漂移;卡点是 ~¥1800/号/年 + 认证主体 + 客户侧存档合规提示已拍板:先不接
决策转人工已拍板:不做
两条天花板(非技术阻塞,业务决策):读取靠 VL 单点、身份靠显示名漂移——两者确定性根治都指向同一把钥匙:官方会话存档 API。已决定先不接,读取地基继续用加固后的 VL 方案;转人工明确不做。
05 / Deployment Guide

云电脑部署指南

在一台无影云电脑(Windows)上把这套跑起来。后端(大脑端点 / Fly 中转 / 服务器密钥)PM 已一次性就绪,新机只做「读屏 + 打字」。完整逐步版见 upio.ai/akke/cloud-pc-wecom-autoreply-deploy

前置物料(开工前找 PM 要齐)

一次性配置(9 步)

装企业微信 + 登录一次
登录加了客户好友的主号;窗口保持打开、别最小化到托盘(最小化截不到屏)。重启一次确认登录是否保持。
确认 Python 3.x
python --version。没有就 winget install -e --id Python.Python.3.12 --scope machine,新开窗口再验。
拉脚本到 C:\akke-wecom
从公开镜像 raw.githubusercontent.com/upioai/wiki/main/public/akke/wecom-chat/ 下载 wecom_reply_loop.py / start-wecom-reply.bat / update-wecom.bat(合并 #760 后 token-free 可用)。
bootstrap 装依赖
.\bootstrap-wecom.bat 自动装 pyautogui 等 + 从模板生成 .env
量坐标(最易错·必做)
python measure_wecom_coords.py,按 6 秒倒计时把鼠标停在「输入框 / 发送按钮 / 会话列表第一行」,得到 AKKE_WECOM_C_INPUT/C_SEND/C_SESSION1——每台机分辨率不同,必须量自己的
填 .env
填 OpenRouter key、WECOM_CHAT_SECRET(内部取)、上一步坐标;WECOM_CHAT_ENDPOINT=https://akke-worker-prod.fly.dev/wecom/chat/reply(固定别改);设 AKKE_WECOM_PERSONA(xiaoxia/xiaofan/xiaowen,本机绑哪个销售号)。
空跑验证(DRY_RUN=1)
默认 AKKE_WECOM_DRY_RUN=1:只读+生成+打印,不真发。看它能否正确读出客户消息、生成合理回复、坐标点得准。
发送测试
python test_send_wecom.py 往一个测试会话真发一条,确认打字/发送键正常(企微设置若是 Ctrl+Enter 就把 AKKE_WECOM_SEND_KEY=ctrl+enter)。
开真发
AKKE_WECOM_DRY_RUN=0,双击 start-wecom-reply.bat 启动(崩溃自重启、遇 STOP 锁住)。启动行会打印 VERSION,核对是最新版。

日常运维

安全纪律:本页公开,不含任何密钥值WECOM_CHAT_SECRET / OpenRouter key 一律走团队内部 Lark 取,别写进任何公开文档或截图。主号无隔离 → 日限/时限从严,别擅自调高。
企微好友单聊 AI 自动代回 · 全景报告 · 2026-07-05
数据源:生产 Supabase 实时查询(scripts/_wecom-stats.ts)· badcase 谱系可追溯至各修复 PR · 架构与决策见团队 memory project_akke_wecom_kf_integration / feedback_wecom_routeb_gui_loop_read_send_traps
相关页:部署手册 · 架构详解 · 客户旅程实时页。