企微自动代回 · 读取层系统档案

系统的眼睛
VL 读屏

企微好友单聊的 AI 自动代回,不是"读"聊天记录,是"看"聊天截图。看,就会看错——漏回、答非所问、自问自答,九成事故都出在这一环。这页讲清它为什么换不掉、会怎么翻车、以及怎么治。

// 面向运营与产品 · 结合真实事故与修复记录

QWEN3-VL-30B 读屏 QWEN3-235B 对话 SKIA 自绘 · 无接口 像素 DIFF 定位读 TEST-22 全读复核 红蓝对抗挖雷
SCROLL / 向下滚动
01
Reply Loop · Three Roles

一次自动回复 = 三个角色接力

VL = Vision-Language 模型,"能看图说话的 AI"。它只负责整条流水线里的"看"——眼睛和脑子是两个不同的模型,所以"漏看消息"和"回复质量差"是两类问题,别混为一谈。

Eye · 眼睛👀 VL

截屏识读

云电脑 · 每轮 tick

给企微窗口拍截图 → VL 模型认出每个气泡的文字、判断靠左(客户)还是靠右(我方)、找出待回的新消息。

qwen3-vl-30b-a3b-instruct
Brain · 脑子🧠 LLM

生成回复

云端服务器 · chatReply

读出来的客户消息发给对话大模型,结合整段历史与客户画像,以"小艳"人设想好这句怎么回。

qwen3-235b-a22b-2507
Hand · 手🖐️ GUI

打字发送

云电脑 · SendInput

把回复一个字一个字打进企微输入框、按发送——跟真人操作一模一样,企微侧看不出任何自动化痕迹。

坐标 GUI · 上屏核验
先记住

同事说的"卡顿",绝大多数是眼睛看漏了,不是脑子想不出来。眼睛是整条链里唯一的非确定性读取环节——后面所有的坑和修法都围绕它展开。

02
Why Screenshots · Four Dead Roads

为什么只能看截图:四条正经路全试过了

"别猜像素了,直接拿结构化数据不行吗?"——这个念头被完整验证过:四条路全是死路,每条都有实测证据。

路线实测结论判定
无障碍接口(UIA)企微聊天区是自绘界面,系统无障碍树里是空的,一个字都读不到。✗ DEAD
浏览器调试口(CDP)企微确实开着调试端口,但只挂到内嵌的"腾讯文档"网页——聊天主窗根本不是网页(Skia 自绘),够不着。✗ DEAD
官方 API腾讯不提供"替员工在好友单聊里发言"的接口;客服接口只管客服会话,不管好友聊天。✗ DEAD
会话存档(付费)技术上能读结构化消息,但客户端会给客户弹"对方已开启会话存档"——直接穿帮,"真人小艳"人设崩了。⚠ 业务否决
架构级结论

VL 看截图不是偷懒的权宜之计,是平台逼出来的唯一可行读法。既然眼睛换不掉,功夫就只能花在"给这双会看错的眼睛配护栏"上——别再花时间重探结构化读取。

03
Failure Catalog · All Real Incidents

翻车图鉴:眼睛的五种看错姿势

VL 不是每次都错,它是概率性的——偶尔看错一次,后果就是漏回或答错人。以下五种全部真实发生过:

🫥

MISS · 漏抄漏抄短气泡

客户紧贴我方长回复下面发了句"嗯嗯",小气泡贴着屏幕底边,VL 整条没看见——这句话就"消失"了。

🔄

FLIP · 判反左右归属判反

我方发的长文案气泡接近满宽,VL 把它判成"靠左=客户说的"——机器把自己的话当客户消息,自问自答回给真客户。

📋

NOISE · 误读系统条当消息

"你撤回了一条消息"这种居中灰条被读成客户发言——对着系统提示一本正经地回复。

🏷️

DRIFT · 读飘名字读飘

同一个客户昵称,这次读"愿"、下次读"原"——系统以为是仨人,聊天记忆被拆碎、上下文接不上。

✂️

CUT · 截断输出被截断

VL 回答撞上字数上限,吐出半截坏数据,整轮读取作废。现修法:坏数据里能捞出完整的部分先用上(截断抢救)。

🙈

BLIND · 失明窗口被遮挡

截屏机制的天生软肋:企微不在前台 / 被别的窗口盖住 = 系统整轮失明空转。桌面必须保持无遮挡。

04
Pixel Baseline vs Semantic Read

关键一课:diff 矫正为什么一度失灵

为了少看错,系统用像素对比(diff):把上次截图存成基线,新截图跟基线一比,哪块像素变了就只让 VL 看那一小块。想法很好,但早期版本埋了个雷:

像素
可靠
diff 检出"画面变了"——客户真的发了新消息,像素对比这一侧是可靠的
VL
看走眼
VL 去读变化区域,却说"那块没消息呀"——短气泡漏抄了,语义读取这一侧不可靠
老代码
踩雷
照样把新截图存成新基线——这条消息的像素"进了账"却没被处理,之后每轮对比都说"没变化"
结果
沉默
永久沉默:客户这句话再也不会被发现,只能靠人工重启救回(重启=清基线走全屏重读)

// 根因一句话:让不可靠的一方(VL)推进了可靠一方(像素基线)的状态——方向反了。

Fix · test-22(已上线)

抓住矛盾信号:像素说"变了"、VL 却说"没消息"——两者打架时绝不推进基线,改走一次全屏重读复核(就是以前"重启能救回来"的那条路,现在每轮自动走)。连续两次全读确认无待回,才当已读回执之类的噪音放行。一句话:把"重启大法"做成了系统的自动反射

05
Governance · Four Guardrail Principles

四条护栏原则,比逐个打补丁管用

个案补丁打不完。真正让同类事故收敛的,是这四条通用原则——每条都对应着一族被消灭的 bug:

🧾

RULE 1失败不消费状态

读取、生成、发送任何一步失败,都不许把消息"记账"成已处理——留给下一轮重试。上一节的基线雷、"生成失败后永久沉默"的弃单雷,根子都是违反了这条。

🙅

RULE 2弃权优于瞎猜

拿不准就这轮不回。未回的消息一直在屏幕上,下轮还能看到;瞎回一条错话,代价大得多——只治随机误读,系统性误读靠别的规则兜。

🎨

RULE 3确定性兜底

能用死规则判的绝不交给 AI 猜:我方气泡是浅蓝色、客户是灰白色——查像素颜色比让 VL 判"左右"可靠,用它做发送前的最后一道否决。

📊

RULE 4可观测

给"看错率、弃权率、回复时延"埋点数数。没有度量,每次修复都不知道有没有效、也排不出主矛盾(误发 vs 漏读)——这是"同类 bug 反复出现"的元根因。

这些雷是怎么被挖出来的 · 红蓝对抗

另一台云电脑跑一个 AI 扮演的假客户,按完整人设连续找真系统聊天,专门把它聊到出错。单元测试测不出的链路脆弱点,被镜像对手一冲就现形——一轮对抗挖出 14 个缺陷。

06
Field Guide · For Operators

下次再遇到"卡顿",这样判断

给运营同学的三步现场动线——先想机制,再自查环境,最后带证据上报:

STEP 1
归因
客户发了消息没人回、或答非所问 → 先想"是不是眼睛看漏/看错了",而不是"模型变笨了"
STEP 2
自查
企微必须在前台、不被遮挡——窗口被盖住=系统失明;重启后确认脚本版本是最新(云电脑不自动更新代码,改了仓库不等于云电脑生效)
STEP 3
上报
反馈问题时带上时间点 + 客户名 + 截图——工程侧能对着当轮日志和 VL 实际看到的画面快速定位
一句话总括:企微不给数据接口,系统只能"看截图"聊天——看,就会偶尔看错。治它不靠换眼睛(换不掉),靠像素 diff 缩小范围、矛盾时全读复核、失败不记账、拿不准就弃权。每一次"卡顿"被定位,护栏就厚一层。