抖音私信 · 自动化回复

机制 · 优化 · 时效 | 2026-07-06
全自动闭环 4 处根因修复
客户回复 → AI 起草 → 内容闸自动过滤 → 干净的自动发、可能说错的转人工。今天修了 4 处根因(护栏误挡 / 多轮漏读 / 发送还在走 VL / 回声误判真客户)。| 部署那两台看 浏览器部署页 →
全自动AI起草→闸→自动发
4根因修复 PR
~1 分钟当前实测最快(待提速)
9s草稿生成(快·不是瓶颈)

01自动回复怎么跑(全自动闭环)

不是「读到就无脑回」,是「AI 起草 → 内容闸自动过滤 → 干净的自动发、可能说错的转人工」。这是设计上的安全闸,不是要人逐条点。

客户回复
↓ DOM 捕获(红点,每 15s)
秒级起草:捕获即触发端点生成草稿(~9s,原等 5min cron)
↓ 过 autoSend 内容闸
干净 → 自动 approved → agent 立即插队发出 ✅ 全自动
踩雷(谈判 / 报价 / 护栏 / 空或崩 / 疑回声)→ 转人工 needs_human
为什么保留「转人工」这道闸:防 AI 把错价格、进入谈判、说废话直接怼到客户脸上。优化 A 就是把「麻烦」这种本该自动发的误挡拆掉,让全自动更顺,而不是拆掉安全闸本身。

02今天的 4 处根因修复(全账号生效)

A · 加微确认被「负面护栏」误挡 PR #773 已合

客户发来微信号、草稿「好的,我们添加您啦,麻烦通过一下~」这类加微确认,被判「负面/投诉」转人工、不自动发——破坏全自动、丢单。

根因:负面护栏词表里有个裸 "烦",用「包含」匹配,把超高频礼貌词 「麻烦」(麻烦您 / 麻烦通过)全扫成负面。"烦" → 前缀式负面词 好烦/很烦/太烦/真烦/别烦/厌烦(都不可能是「麻烦X」的子串);硬负面(投诉/差评/拉黑/别发了…)一个没动。补了回归测试。

B · 多轮对话「无红点漏读」 PR #776 已合

在聊天框已经聊了好几轮,客户接着发消息却没有红点,自动回复漏读不回。

漏读机制(修复前)
自动回一条 → 发送脚本把会话停在打开态
客户在这个「已打开」的 thread 里接着回
抖音判「已读」不标红点 → 只认红点的捕获 漏读
:发送成功后(气泡已确认发出)自动导航离开会话回抖音首页。客户后续每一条消息都落在「非打开态」会话 → 红点恢复可靠,捕获照抓。不动任何判定逻辑(红点+昵称匹配链完全保留)→ 零「认错人」风险。

C · 自动回复的「发送」原来一直走 VL(不是 DOM) PR #778 已合 · 关键

查时效时挖出的地基问题:AKKE_WEB_DM_USE_DOM=1 只作用在「捕获」侧;自动回复的发送reply_in_web → process_web一直走老 VL(截图/像素),从没走 DOM。

环节修复前#778 后
捕获客户回复DOM ✓DOM ✓
首触发 DMDOM ✓DOM ✓
自动回复·发送VL ✗DOM ✓
后果(修复前):① 这是发出段慢(中位 99s)的主因——VL 发送 ~35s+;② 优化 B 的「离开会话」加在 DOM 发送里,对走 VL 的回复路径无效——多轮漏读其实没真修好。
reply_in_webAKKE_WEB_DM_USE_DOM=1 时改用 DOM 发送(连不上 Edge 才回退 VL,绝不丢回复)。一举三得:① 发出段大降;② 优化 B 的离开会话对回复路径真生效;③ 捕获/首触/回复全链路统一 DOM。生效需云电脑更新脚本 + 重启(见部署页)。

D · 回声防护误判真客户(「你好,」启发式太宽) PR #779 已合

真客户「你好,我看你 IP 在四川,想做全屋定制」被判成我方 opener 回声、转人工不自动回(小罗案)。

根因:防回声(怕把我方自己发的 opener 抓回、自己回自己)用了脆弱启发式 /^你好[,,]/ + 长度≥12 猜「这是我方 opener」,而真客户正好也以「你好,」开头就中招。:改用回声比对——把触发消息跟我方真实发给该用户的历史消息比对(互相包含才算回声,覆盖预览截断),不再猜前缀;只有我方会说的反问钩(你家几室几厅 等)保留。真客户「你好,」开头不再误伤,真回声照拦。

03端到端时效 · 实测口径

用库里三时戳直查(inbound 记录 messages.created_at → 草稿 drafts.created_at → 发出 sent_at),近 7 天 sent 草稿 n=18:

实测(秒)说明
ΔA 生成(记录→草稿 ready)min 7 · 中位 9 · p90 29很快,不是瓶颈
ΔC 发出(草稿 ready→发出)min 36 · 中位 99 · p90 581瓶颈:等 poll 领取 + 发送走 VL(优化 C 前)+ 老机节流
端到端(记录→发出)min 52 · 中位 361(6 分钟) · p90 862
+ 捕获段(红点 + 轮询)再加 ~5–20s起点是「我们写库」,还没算客户实发→我们看到
诚实说:当前实测最快也要 ~1 分钟(端到端 min 52s + 捕获段),中位在老系统上是 6 分钟。瓶颈在发出段(ΔC 中位 99s),不在生成(9s)。
发出段为什么慢 + 怎么提速:① 发送原来走 VL → 优化 C(#778)已切 DOM,预计显著下降(待新数据验证);② 发送要等 poll 下一轮领取 → 可改事件驱动/短轮询;③ DOM 开会话每次重新 goto 主页 + 等 networkidle → 可复用已开会话、去死等;④ 老机 AKKE_DM_AUTOREPLY_INTERVAL 节流(p90 到 10 分钟=排队)→ 已设 15s。「发出段提速」单列优化项,待排期。

04待优化 · 连发消息「合并成一轮回」

客户常连着发好几条:在吗想问下全屋定制多少钱。希望等他发完、把这几条当一轮回一次,而不是对第一条抢答、或漏掉后面。

现状(已读代码确认)
会不会回多次不会 ✓ 占位机制保证一会话同时只有一个草稿
会不会抢答半句会 ✗ 秒级端点「捕获到就起草」,没等静默
后面的消息各生成一份草稿、连珠炮发多条 ✗(更正:占位按消息不按会话,第二条不是被忽略,是各自成稿全发出去)
同一 15s 窗口内快连发中间几条丢 捕获读列表预览=最后一条

方案对比

方案做法取舍
A · 定时去抖最后一条静默 N 秒才起草每条回复都晚 N 秒(单条也白等)
B · 新消息作废重 draft 已上线 #787草稿发出前又来新消息 → 作废旧草稿、带新消息重 draft;走自然轮询节奏单条零延迟;连发自动合并;顺带修「第二条被忽略」
代价:连发多烧几次 LLM token(前几次白烧,非延迟)
C · 读 thread 兜底 二期有活动的会话开一次 thread 读近几条气泡全抓同窗口极快连发也全抓、最彻底(改动最大)
推荐 B 为主,C 作二期:B 不牺牲单条速度就把「抢答/忽略后续」根治。注意:B 只解决「连发合并」,对「1 分钟太慢」没帮助——那是发出段的事(优化 C + 发出段提速)。

方案 B · 连发 3 条的时效(近 24h 实测拼,从「最后一条」算起)

例:客户连发 在吗想问下全屋多少钱。方案 B 把起点钉在最后一条(第 3 条)、不抢答。B 不改各段耗时,所以时效=当前端到端实测、锚到第 3 条。下面数字全是库里直查(sent 草稿 n=11,近 24h):

段 / 操作实测(秒)连发 3 条场景里
捕获段(客户发出 → 我们捕获写库)~5–15s(未埋点·估)前 2 条也各走一遍
① 起草 ΔA(写库 → 草稿 ready)min 7 · 中位 9 · max 17msg1/msg2 各烧一次(并行客户打字 → 被作废),msg3 这次进关键路径
② 发送 ΔC(草稿 ready → 发出)min 43 · 中位 74 · max 163瓶颈,跟连发几条无关
端到端(写库 → 发出)min 60 · 中位 83 · max 295(≈5min)从 msg3 被我们捕获算
连发 3 条 · 实测结论:从「最后一条被我们捕获」到「回复发出」= 最快 ~60s / 典型 ~83s / 最慢 ~295s(约 5 分钟)(近 24h n=11)。再加捕获段 ~5–15s,才是从客户真发完第 3 条算起。
怎么读这组数:① 大头是发送段 ΔC(中位 74s),跟连发几条无关——要快得靠「发出段提速」+ 优化 C 的 #778 DOM(还没上机验证,上了应降);② 起草很快(9s),B 的代价是 msg1/msg2 各多烧一次 ~9s 起草的 token(并行客户打字,不加最终延迟);③ 单条消息 = 同一组数——B 不给单条加固定等待,这正是它比「定时去抖 A」强的地方。
口径诚实说明:以上是当前实测(发送还走 VL、#778 未上机、方案 B 未开发)。#778 DOM 上机 + 发出段提速 + B 落地后,ΔC 应显著下降,届时重测更新——不提前编数。
状态更新(07-07):方案 B(连发合并)已上线——PR #787 改 record_dm_inbound:客户新消息入库即作废本会话未发出的 approved 草稿、按最新消息重新起草,一轮只发一条。只动 approved(needs_human 人工队列 / sending 发送中不碰)。发出段提速仍待排期。

05部署更新指南(这 4 处修复怎么上到线上)

4 处修复分两类:后端改动(合并即自动部署,无需动云电脑) vs 云电脑脚本改动(要手动更新 + 重启)

修复改哪怎么生效
A 护栏「麻烦」#773Vercel 后端 src/lib/dm-reply/guardrails.ts合并 main → Vercel 自动部署 ✓ 云电脑无需操作
D 回声误判 #779Vercel 后端 gate.ts / run.ts合并 main → Vercel 自动部署 ✓ 云电脑无需操作
B 多轮漏读 #776云电脑 douyin_dm_web_send_dom.py✅ 07-07 已更新两台(小文/文哥)+ 重启
C 发送切 DOM #778云电脑 douyin_dm_web_reply.py✅ 07-07 已更新两台(小文/文哥)+ 重启,ΔC 待新样本验证
A、D(后端)已随合并自动上线——护栏不再误挡「麻烦」、回声不再误判真客户,所有账号即时生效,运营无需做任何事。

B、C(云电脑脚本)· 每台更新 2 个文件 + 重启

每台跑浏览器 DOM 版的云电脑(小文/文哥/…)PowerShell 里,一台一台来:

⚠️ 下面是一条命令(分号连接、可整段粘贴,无影远程桌面粘贴不怕丢换行):

Get-Process python,py,pythonw -ErrorAction SilentlyContinue | Stop-Process -Force; cd C:\akke-wuying\wuying-dm; $b='https://cdn.jsdelivr.net/gh/upioai/wiki@d6c3a57ee99127e02372a82f32c58f8edcde41c5/public/akke/wuying-dm'; foreach($f in 'douyin_dm_web_reply.py','douyin_dm_web_send_dom.py'){ Copy-Item $f "$f.bak-778" -Force -EA 0; curl.exe -fsS --retry 5 --retry-delay 2 --connect-timeout 15 -o $f "$b/$f"; '{0,-30} {1}' -f $f,(Get-Item $f).Length }

核对两行字节数(reply=4373 / send_dom=19310)后,单独跑启动:

py -u wuying_poll_agent.py
核对字节数douyin_dm_web_reply.py4373douyin_dm_web_send_dom.py19310。横幅 rc=off + 你的 account。(完整部署/保活见 浏览器部署页 →
验证(别只信文档):重启后盯几条真实自动回复——黑窗应出 DOM 的 [sent];若出 [reply] DOM 连不上 CDP → 回退 VL = Edge 没连上,检查调试版 Edge。更新后过一阵,从库里重测 ΔC 看是否真降。