自动回复 · 加微完成后停止自动培育
2026-07-07 | #782 加微停培育 · #787 连发合并 · #788 防重复轰炸 | 晚间补充:时延拆解 + 当日失败逐条复盘(§07-09) | 昨日 4 处修复见
07-06 页 →
已上线 · 全账号生效
纯后端 · 云电脑不用动
一句话:客户给了微信号、我们回了「添加您啦,麻烦通过一下」之后,客户再回「好的」——以前系统还会自动发一条「你家是哪个户型呀?」重新培育;现在阵地转微信,抖音侧闭嘴:纯确认静默不回,实质新消息转人工,绝不再自动发培育话术。
01问题(小罗案实录)
修复前的实际对话
客户:15243039817(发来微信号)
↓
我方(自动):好的,我们添加您啦,麻烦通过一下~ ✓ 正常
↓
客户:好的
↓
我方(自动):小罗,你家是哪个户型呀?我让设计师私信你发整套案例参考下… ✗ 多余且轴
根因两层:① 管线没有「不需要回」分支——只要最后一条是客户,必生成草稿;② 没有「加微已完成」状态——stage 机(ice_break/nurture/decision)不知道对话已转场微信,chatReply 照 nurture 剧本重新盘户型,还说「我让设计师私信你」,跟已发生的加微自相矛盾。
02关键洞察:「好的」是多义词,含义取决于我方上一条
| 我方上一条 | 客户「好的」= | 正确处置 |
| 「辛苦通过一下」「已添加你」 | 确认收尾 | 静默不回(阵地已转微信) |
| 「我发你整套案例?」「我让设计师加你」 | 同意、等你兑现 | 不该发新话术,该去做那件事 → 转人工兑现 |
| 「你家几室几厅?」 | 答非所问 / 敷衍 | 别追问 |
所以不能一刀切「好的→静默」——会把「同意收材料」也吞掉。判定必须结合我方上一条消息:只有「加微已办完」语境下的纯确认才静默。
03方案取舍(选了 B)
| 方案 | 做法 | 结论 |
| A · 纯确认语词表静默 | 「好的/嗯嗯」一律不回 | 弃——会吞掉「同意收材料」场景 |
| B · 加微完成状态 已上线 #782 | 从我方历史消息推断「加微受理已完成」;完成后纯确认静默、实质消息转人工 | 零 migration、确定性、可回归测试 |
| C · LLM 判「该不该回」 | 每条烧一次 LLM 判定 | 先不上——成本+不确定性,看 B 覆盖率再说 |
04上线后的行为(触发条件必须同时满足两个)
条件 ①:这个客户的加微已「受理完成」
系统查我方发给这个人的历史消息,出现过完成时态的受理话术:「我们添加您啦」/「麻烦通过一下」/「已加你 / 加你了」。
⚠️ 不包括「索要」话术:「你方便发个微信号过来吗 我让设计师加你」是在要微信(还没完成)——此时客户回什么都照常处理,客户发号会正常自动回「添加您啦」。词表按真实 messages 扫描定的,专门避开这条误伤。
时序:从哪一刻起算「完成」
我方:「方便发个微信号吗?」 ← 索要,不算完成,一切照常
↓
客户:「15243039817」 ← 照常自动回
↓
我方:「好的,添加您啦,麻烦通过一下~」 ← 从这条起 = 受理完成 ✓
↓
客户:「好的」 ← 静默不回 ✓(修复后)
条件 ②:客户这条消息是「纯收尾确认」
| 客户说 | 算吗 | 处置 |
| 「好的」「好嘞」「嗯嗯」「收到」「可以的」「OK」「谢谢」(≤8 字,可带 ~。👌) | 纯确认 ✓ | 静默不回(写缓存出队,不空转不烧 LLM) |
| 「好的你发我吧」(真实样本) | ✗ 同意+要求兑现 | 转人工去兑现(真发材料) |
| 「好的,多少钱」 | ✗ 带新问题 | 转人工(生成参考草稿但不自动发) |
| 「125平」「毛坯」「在吗」 | ✗ 新信息/召唤 | 转人工 |
设计取向:从严匹配——词表拿不准的一律当「不是纯确认」→ 转人工。宁可多几条进人工队列,绝不静默吞掉一条该处理的消息。加微完成后系统永远不再自动发培育话术,实质消息都是「生成参考草稿 + 转人工」,人工决定在微信还是抖音接。
05实现要点
| 点 | 怎么做的 |
| 零 migration | 不加状态列——每次实时从我方历史 AI 消息推断(与 #779 回声比对共用同一次查询,零新增开销) |
| 静默怎么「出队」 | 写 messages.inbound_reply_check='rejected' 缓存(复用语义门机制)→ 下轮 awaiting 命中缓存直接跳过,不空转、不烧 LLM |
| 词表来源 | 扫真实 messages 定的:受理完成 vs 索要 的区分、「好的你发我吧」这类边界都来自真实样本 |
| 测试 | wechat-exchange.test.ts 全覆盖(受理/索要/短确认边界),dm-reply 全套 66 passed |
| 已知盲区 | 人工在手机上回的「加你了」不入库 → 检测不到(自动回复闭环内的受理话术都能检测) |
06部署方式
纯后端改动(src/lib/dm-reply/),PR #782 合并 main → Vercel 自动部署,全账号即时生效。云电脑零操作。回滚 = revert PR 再合,一步。
与昨日修复的关系:#773 护栏「麻烦」误挡(让「添加您啦」能自动发出)是本修复的前置——先保证受理话术发得出去,再管受理完成后的静默。5 处修复清单见 07-06 自动化回复页。
07为什么还要 ~1 分钟(时延拆解 · 当日实测)
今天一次过的两条 e2e = 70s / 77s——这就是当前架构的地板。先更正旧账:早期说过「~35s」,那是把 DOM 发送错估成 ~10s 的纸上数,实测 DOM 发送要 30–40s,已在 07-06 页更正过。地板的组成:
| 段 | 耗时 | 为什么 |
| ① 捕获轮询 | 0–15s(期望 ~8s) | AKKE_POLL_INTERVAL=15,红点落在哪一轮看运气 |
| ② LLM 生成 | 8–20s | 模型推理,难压 |
| ③ 发送领取 | 0–15s(期望 ~8s) | 已有「插队」逻辑,但要等主循环醒来 |
| ④ DOM 发送 | 30–40s ← 大头 | goto 主页+等加载 ~10s;逐字键入 50ms/字(100 字=5s);点私信重试;验气泡 7×1s + 2.5s 风控复核;离开会话 |
可选的提速项(评估过,当前决定:都不做、维持现状):A 轮询 15s→5s(省 ~10s,DB/CDP 负载×3);B 键入改整段注入(省 3–7s,需真机验 Draft.js 兼容);C 验气泡首查提前(省 1–2s)。三项落地可到 ~45–50s。要到 35s 必须放弃 sec_uid 改按昵称开会话(D)——有认错人风险,不做。②生成和 2.5s 风控复核是该花的钱,不省。
08当日 journey 逐条复盘(6 条草稿全量 · DB 直查)
| 账号 / 客户 | 结果 | 时延 | 具体原因 |
| 有大有小 / 大女人👩 | sent ×2 | e2e 70s / 77s | 一次过 = 架构地板,正常 |
| 有大有小 / 大女人👩 | unverified ×3 → 转人工 | — | 假阴性:草稿含 🦆,抖音把 emoji 渲染成图片、气泡文本丢 emoji → 验证比对在 emoji 处断裂 → 实际已发出却记失败 → 重试 3 次可能三连发(已让运营核对会话)。根因已修:#788 三层防线 |
| 有大有小 / ▁_"蛋蛋■🇨🇳 | no_row ×3 → 转人工 | — | 真失败(没发出):发生在该机更新 DOM 脚本之前——旧配置漂移跑了 PC 版代码,按昵称定位不到会话。运营已手动补发;该机当日已更新脚本走 DOM,此路径不复存在 |
| 文哥 / 陆轻阳 | sent(att=1) | e2e 180s | 超 2 分钟的唯一原因=第一次发送失败 → #763 有界重试第二次才成,e2e 被失败翻倍(首次失败的具体错误码已被成功状态覆盖,属可观测性缺口——P4-P7 埋点待做)。根因是失败率不是链路慢;今天把两大失败源(emoji 假阴性 / 配置漂移 no_row)都治了,此类应显著减少 |
| 文哥 / 小陈不吃芹菜! | sent(att=1) | e2e 547s(9min) |
07-08 早间追加 · 饭粒「Yik-.」案:journey 归因显示错了,真凶是未部署的旧脚本
| journey 页显示 | 真实发生(DB 直查) |
| P3 护栏 | ⏸「微信外引拦截(预期行为)」 | 通过了:LLM 原稿自冒微信词 → 护栏自动改写成「让设计师私信你发」→ 放行 approved |
| P4-P6 发送 | 没走(⋯) | 走了 3 次(att=3):每次实际发出 → 旧脚本恒判 rejected → #763 重试 |
| 结局 | 护栏转人工 | 发送侧假拒收 3 次转人工,客户可能收到 3 遍 |
根因:_check_rejected 4 元组漏拆包 → 恒判「对方拒收」——7/6 已修(a059951a、进镜像),但饭粒的云电脑没拉新脚本。铁证:饭粒近 48h 仅有的 2 条自动回复 100% rejected、全部 att=3(恒判特征)。两条(Yik-. / 西瓜不见了)已 discard 防二次发送,请人工核对是否三连发。连带发现:journey 的归因是「拿 flags + needs_human 猜」,err=rejected 也被归到护栏箱——归因逻辑要修(与 P4-P7 埋点同属可观测性欠账)。
连带风险已处置:大女人/蛋蛋两条挂在人工队列的 needs_human 草稿已置 discarded(防二次发送);「unverified 大概率已发出、重试=重发骚扰」这一类,#788 后不再自动重试、直接转人工核对。
09部署指南(今日全部修复怎么生效)
| 修复 | 生效方式 | 状态 |
| #782 加微完成停培育 | 后端 → Vercel 自动 | ✅ 已生效 |
| #787 连发合并(supersession) | DB migration 自动 push | ✅ 已生效 |
| #788-③ unverified 不重试 | DB migration 自动 push | ✅ 已生效 |
| #788-①② 剥 emoji 比对 + 发送前幂等防重发 | 云电脑脚本 douyin_dm_web_send_dom.py | 需三台(小文/文哥/有大有小)更新 + 重启 |
| rejected 恒判修复(a059951a·7/6)+ 全套 DOM | 云电脑脚本 douyin_dm_web_grounded.py 等 3 件 | ⚠️ 饭粒机未部署(Yik 案实锤);零星机待确认 |
云电脑更新 A(小文/文哥/有大有小——已更过 07-07 早批的机器,只补 send_dom)——一条命令整段粘贴:
Get-Process python,py,pythonw -ErrorAction SilentlyContinue | Stop-Process -Force; cd C:\akke-wuying\wuying-dm; Copy-Item douyin_dm_web_send_dom.py douyin_dm_web_send_dom.py.bak-788 -Force -EA 0; curl.exe -fsS --retry 5 --retry-delay 2 --connect-timeout 15 -o douyin_dm_web_send_dom.py 'https://cdn.jsdelivr.net/gh/upioai/wiki@788b0e84272f623ea575ee1023f4502e1739d8dd/public/akke/wuying-dm/douyin_dm_web_send_dom.py'; (Get-Item douyin_dm_web_send_dom.py).Length
核对字节数 = 22549(旧版 19310 = 没下到新的,回报)。然后单独跑启动:
py -u wuying_poll_agent.py
云电脑更新 B(饭粒/零星——一直没更过的机器,三件套全下)——一条命令整段粘贴:
Get-Process python,py,pythonw -ErrorAction SilentlyContinue | Stop-Process -Force; cd C:\akke-wuying\wuying-dm; $b='https://cdn.jsdelivr.net/gh/upioai/wiki@788b0e84272f623ea575ee1023f4502e1739d8dd/public/akke/wuying-dm'; foreach($f in 'douyin_dm_web_grounded.py','douyin_dm_web_reply.py','douyin_dm_web_send_dom.py'){ Copy-Item $f "$f.bak" -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 }
核对:grounded=26195(rejected 恒判修复;此前页面误写 26627——那是含 #770 滚顶的中间态,滚顶已被 #772 撤销,26195 为正确版本)/ reply=4373(发送走 DOM)/ send_dom=22549(防重发三层)。再确认 .env 有 AKKE_WEB_DM_USE_DOM=1,然后 py -u wuying_poll_agent.py 重启。
验证:横幅 rc=off + 本机 account;之后若出现重试场景,黑窗应打 [幂等] 会话里已有本文案气泡 → 归位 sent, 不重发。含 emoji 草稿不再 unverified。回滚=把 .bak-788 改回原名重启;migration 回滚 SQL 在 migrations-rollback/20260707220706_*。