7 天召回

Akke · 企微好友单聊

7 天召回 · 部署与验证指南

给企微好友里加了资料就沉默的客户做召回:结合抖音+企微对话和画像,从甲方话术库里挑 7 个可能戳中他的话题,每天发一条、连推 7 天,把人唤回、最终邀约到店。这一页写给帮忙部署验证的同事——照着走即可。

当前状态
服务端大脑已部署 · 候选验通 5 个
账号 + 派单五人各一行 · cron 已挂
待办各自云电脑部署(B→C)
真发开关默认关(dry-run)

01它是怎么跑起来的

一条流水线,两半:服务端「大脑」选人选话术,云电脑「手」去发。

① 扫沉默客户
Vercel cron 扫企微会话:最后一条是我方发的、≥24h 没回、没删你、没在人工聊
② 选题 + 写话术
首日 LLM 从甲方话题库挑 7 个、排序、冻结;每天取当天话题按画像写一条勾回的话
③ 入队
写进 wecom_recall_dispatch_queue,等云电脑来拉
④ 云电脑发
搜到人 → 身份门确认 → 点开 → 发 → 探红点感叹号 → 回执
自清场 & 出库,全自动
客户一回复 → 最后一条变成他发的 → 下一轮自动掉出队列;发消息出红点感叹号(被删)→ 只白发这 1 条、永久出库;满 7 次 → 出库;连推没回应 → 从每天改隔天(退避)。

027 天召回的逻辑

这套系统怎么决定「发给谁 · 发什么 · 发几次 · 什么时候停」——设置召回前先看懂这四件事。

① 谁会被召回:入池 4 个条件,全满足才进

1企微好友,且这段对话最后一条是我方发的(他没接话)
2已经 ≥24 小时没回——不是刚发完就当他沉默
3没删你、没在人工深聊(有潜力、人工在跟的客户标 handed_off 自动豁免,不打扰)
4这 7 次召回还没走完、也不在冷却里

这四条每天扫一遍自动判定。他一旦回复,「最后一条」就变成他发的 → 第 2 条自动不成立 → 当天起不再召回(自清场,不用人管)。

② 发什么:7 个话题怎么挑、怎么排

客户首次进池那一刻,系统让 AI 看他的抖音+企微对话和画像,从下面这个话题库(甲方话术 9 类 + 4 个画像钩子,共 13 项)里挑出 7 个最可能戳中他的、排好顺序、一次冻结(后面 6 天都照这份走,不天天重挑)。

AI 选中话题的 3 条标准:

  1. 贴他的实际诉求和画像——他最初求什么、聊到过什么(户型 / 面积 / 城市 / 风格 / 预算 / 顾虑),就优先选相关话题。
  2. 画像钩子只在画像真有对应信息时才选——比如没读到城市/户型就不选「同小区实拍」,防止 AI 脑补穿帮。
  3. 由浅入深排序——先勾兴趣、再谈价值、后推行动,不会第 1 天就硬推报价或催名额。
先勾兴趣同小区实拍 / 免费效果图 / 硬核配置单——低门槛、跟他有关,先把人唤回来
再谈价值品质保障 / 服务流程 / 样板房专属权益——建立信任
后推行动稀缺名额 / 按面积粗估报价——制造行动理由,引导到店
甲方话术库

9 类 · 主动可抛

话题聊什么什么样的客户会被选中(标准)
产品核心配置ENF 环保兜底 · 三大品牌板材任选 · 悍高五金 · PUR封边 · 六面防伪还没确认过配置/价格,或最初就是冲板材 / 性价比 / 环保来的
正品与品质保障环保补充协议 + 假一赔三,白纸黑字盖公章、有法律效力可能担心品质 / 真假,性格谨慎,或问过品牌真伪
标准化服务流程设计→生产→安装→售后全流程 SOP,总部系统全程兜底担心售后 / 交付掉链子,或第一次装修没经验
样板房活动稀缺性568 补贴的由来,名额按套限量、抢完即止有一定意向但在犹豫 / 拖延,需要一个行动理由
样板房专属权益每平直降 300 + 品质工艺加码 + 顶配设计师和安装班组在意性价比 / 预算,或想要更好的设计与落地效果
报价与预算按面积给个总价区间的钩子(细清单留到到店算)问过价格 / 预算,或画像里有面积但没报过总价
⚑ 需画像有:面积 / 户型
板材防伪与选材六面防伪 vs 5 个防伪等级,选板材看等级+基材才不踩坑在多家比价,或很在意板材真假 / 等级
售后方案免费基础(保修1年+终身保养)/ 升级 5 年超长保修,二选一担心后期维修找不到人,或问过质保
品牌与口碑答疑客观看待网上评价(有评价=正规品牌),绝不主动评竞品提过对品牌的疑虑,看过负面评价,或问过认不认识某品牌
画像钩子

4 个 · 画像里有对应信息才选

话题聊什么什么样的客户会被选中(标准)
同小区/同户型实拍拿他所在城市/小区或同户型的真实落地案例勾(「你们那边刚做完一套同户型」)用地域/户型相关性制造「这跟我有关」的信任
⚑ 需画像有:城市 / 小区 / 户型 / 面积
免费效果图钩子针对他户型/风格,提「可以先给你出个参考效果图看看」表达过要效果图/看设计,或画像有明确风格/户型
⚑ 需画像有:风格 / 户型 / 面积
风格灵感/搭配建议顺着他偏好的装修风格(法式/极简/现代…)聊落地要点或搭配画像里有明确装修风格偏好
⚑ 需画像有:装修风格
新样板房名额同步「本片区新放出样板房名额」的限时钩子,给一个再聊的由头之前有意向但沉默,需要一个不突兀的重启话题(无画像门槛,可兜底)

选好后,每天取当天那个话题,结合他的画像写成一条自然的、主动勾回的话,不是干巴巴甩海报——实测里客户就是被「重复自我介绍 + 重问已知信息」这种话问沉默的。

③ 发几次、隔多久:节奏时间线

1
第 1 天
话题 ①
每天
2
第 2 天
话题 ②
每天
3
第 3 天
话题 ③
每天
4
第 5 天
话题 ④
退避·隔天
5
第 7 天
话题 ⑤
隔天
6
第 9 天
话题 ⑥
隔天
7
第 11 天
话题 ⑦
发完出库

前 3 次每天一条;连推 3 次他都没回应 = 暂时不想聊,系统自动放慢到隔天一条,把剩下 4 次摊开——既保持节奏、又压低骚扰/拉黑/封号风险。7 个话题走完约 1.5 周。(这就是你定的「连推 7 天、遇信号退避」。)

④ 随时可能提前出库:三个停止条件

他回复了→ 立刻停,转正常对话/人工。召回的目的就是把他唤回,达到即止。
发消息出红点感叹号 = 被删→ 永久出库,只白发这 1 条、不再推剩下的。
满 7 次→ 7 个话题走完,正常出库。

03两块拼图

Block A 是服务端「大脑」(已上线),Block B 是云电脑「手」(本次要部署验证的部分)。

Block A服务端大脑

已合并部署、迁移已 apply。全程 dry-run,什么都不发。

  • 新建召回队列表 + 节奏状态表 + 派单/回执/选题 RPC
  • 候选筛选 + LLM 选 7 话题 + 按画像写当天话术
  • cron 派单 + 端点 claim_recall/complete_recall 供云电脑拉/回执
src/lib/wecom-recall/ · /api/cron/wecom-recall-dispatch

Block B云电脑主动发起腿

代码已在 main。云电脑现在只会被动回未读,这条腿补上主动找人发——按阶段 B 更新上去。

  • 经端点领当天召回话术 → 点搜索框搜客户名
  • 身份门:读会话标题匹配才发(无 DOM 下防发错人的唯一防线)
  • 复用现有发送 + 落库 + 计数;发后 VL 探红点感叹号判是否被删
worker/scripts/wecom-chat/wecom_reply_loop.py

04部署流程 · 加到云电脑现有的企微自动回复上

召回腿和被动代回是同一个 loop——部署 = 更新那个文件 + 加几个 env + 量一个坐标 + 重启。分四个阶段:先配后台,再更新云电脑,空跑验证,最后灰度真发。

先理清关系
云电脑上 C:\akke-wecom\wecom_reply_loop.py 那个常驻脚本,现在多了一条召回腿(代码已在 main)。它跟原来的被动代回串在同一个 loop 里、不抢窗口,且默认关。所以不用新装东西,只是把这个文件更新到新版 + 配置 + 逐步打开。全程被动回复照常工作。
🟢 2026-07-21 起:真发已经开了,召回是活的

在此之前云电脑腿一直开着、cron 每 2h 也在跑,但服务端那道真发闸从没打开 → 只算候选不写队列 → 一条召回都没真发过(队列 7/18 之后零新行、wecom_recall_state 全是 touch_count=0)。现在闸开了,首次真派单 = 07-21 16:00

开的方式是翻代码里的默认值,不是设 Vercel 环境变量 —— akke 项目挂在 Gus 的 team 下,其他人改不到线上 env。所以下面凡是写「去 Vercel 设 WECOM_RECALL_AUTOSEND_ENABLED=true」的地方都已作废,见阶段 D。

✅ 服务端全就绪并验通
候选查询修复 · 按人设隔离(多操作员不串号)· 企微账号已建(野荞 / 饭粒 / 夏夏 / Gus / 子扬 各一行,见阶段 A 表)· 派单 cron 已挂(每 2h)· dry-run 验通(隔离后各出各自会话、各用各自人设)。剩下 = 各人在自己云电脑部署(阶段 B → C)。
A

服务端配置

后台一次性,新人接入才需要动
  1. ✅ 建企微销售号的账号行 —— 已由我建好(每个操作员一行)

    召回按各自账号走、按人设隔离(只发自己的客户)。已建好这两行,阶段 B 填你自己那行的 id

    操作员personaAKKE_ACCOUNT_ID(阶段 B 用)
    野荞(小文)xiaowen0242b7ff-e003-44df-b929-ce71722e6853
    饭粒(小范)xiaofana78b96e9-5acb-4946-ae5a-f365e0854acb
    夏夏(小夏)xiaoxiae494e462-21dd-445b-b1b5-1327861c12ed
    Gus(小武)xiaowu297b50a4-6ade-4070-b934-18d456ba0941
    子扬(小杨)xiaoyang89aff532-3657-4f7a-a2f3-149f4182d2fb

    加新人要做两件事,别只做一件:
    建账号行channel_pref='wecom' + wecom_persona=<key>,零代码。
    确认这个 persona key 在代码里存在SALES_PERSONASsrc/lib/llm.ts)。这步不是零代码 —— key 不在注册表里不会报错,而是静默回退成小艳(抖音 DM 的默认人设),企微那套价格口径、风格块、召回专属块全都不生效,人却照发。小杨(xiaoyang)是 2026-07-21 新加的第 5 个壳,已在代码里。

  2. ✅ persona 已随账号设好 —— 不用再动 Vercel

    人设现在设在账号行上accounts.wecom_persona=xiaowen),已建好。每个操作员的账号带各自人设、只发各自客户,互不串。全局 WECOM_RECALL_PERSONA 只在账号没填时兜底 —— 各操作员不用设
    真发总开关已于 2026-07-21 打开(改的是代码默认值,Vercel 那边不用设也设不了),细节见阶段 D。

B

更新云电脑上的自动回复

操作员(野荞 / 饭粒 / 夏夏 / Gus / 子扬)在自己的云电脑 PowerShell 里按顺序跑,每步看一眼输出;被动回复不受影响
⚠ 部署前先查 CROP_RATIO(饭粒实测踩过、坑很大)
有些机器的 AKKE_WECOM_CROP_RATIO=0.18 会把客户气泡 + 会话标题整个裁掉 → 机器人把自己发的话当成客户消息回复、自问自答,还会真发出垃圾(饭粒那台回过「哈哈您抢我词儿啦」)。日志里出现 客户[小范](自己人设名)或 客户[系统横幅碎片] 就是中招了。先查:
Select-String -Path C:\akke-wecom\.env -Pattern "AKKE_WECOM_CROP_RATIO"
0.10x 就没事;是 0.18 或日志有自问自答 → 别抄别人的值(跟屏幕分辨率/会话列表宽度绑死),截张企微全屏图发 Claude,它给你算。改完重启生效。
  1. 停当前正在跑的 loop
    ni C:\akke-wecom\wecom_reply_STOP
    Get-CimInstance Win32_Process | ? {$_.CommandLine -like '*wecom_reply_loop*'} | % { Stop-Process -Id $_.ProcessId -Force }
  2. 把两个脚本更新到新版(wecom_reply_loop.py + measure_wecom_coords.py)
    🟢 2026-07-21 起:所有机器统一走这一条,不用管有没有 git 仓库

    upio.ai 上那份分发脚本以前一直没人维护、冻在 v2026-07-02.11,现在已同步到最新并会持续更新,直接拉就行:

    cd C:\akke-wecom
    copy wecom_reply_loop.py wecom_reply_loop.py.bak-$(Get-Date -f yyyyMMdd)   # 先备份,回滚用
    iwr https://upio.ai/akke/wecom-chat/wecom_reply_loop.py -OutFile wecom_reply_loop.py

    核对版本号,必须是 v2026-07-20.redblue-test-22 或更新:

    Select-String -Path wecom_reply_loop.py -Pattern '^VERSION'

    ⛔ 别从 jsDelivr 镜像拉 —— 那个冻在 v2026-07-02.11(旧版、没召回)。
    有 git 仓库的机器C:\Users 下能搜到 .git)也可以照旧 git pull 后 copy,两种都行;measure_wecom_coords.py(量坐标用,只有初次部署/换分辨率才需要)仍走 git 或人工传。

  3. .env 加召回 4 变量(RECALL 先关,AKKE_ACCOUNT_ID 填你自己那行

    <你的账号id> 换成阶段 A 表里你自己那行(野荞 0242b7ff… / 饭粒 a78b96e9… / 夏夏 e494e462… / Gus 297b50a4…):

    Add-Content C:\akke-wecom\.env "`nAKKE_WECOM_RECALL_ENABLED=0`nAKKE_ACCOUNT_ID=<你的账号id>`nAKKE_WECOM_C_SEARCH=`nAKKE_WECOM_RECALL_CLAIM_LIMIT=2"
  4. 量搜索框坐标 → 填进 .env
    cd C:\akke-wecom
    python measure_wecom_coords.py

    鼠标悬停在企微左上角搜索框上,它打印 AKKE_WECOM_C_SEARCH=x,y;把这行填进 .envAKKE_WECOM_C_SEARCH=(纯读坐标,不点击不发消息)。

  5. 删 STOP + 重启,确认没搞坏现有功能
    del C:\akke-wecom\wecom_reply_STOP
    cd C:\akke-wecom
    .\start-wecom-reply.bat

    黑窗第一行的版本号带 recall-b3(或更新的 recall-bN)就对 —— 说明拉到的是含召回的新版;要是还是旧的没 recall 字样的版本,说明 git pull/copy 没成功,回上一步重来。此时召回还关着,原来的被动自动回复应照常工作

C

空跑验证

不发任何消息,验通了再开真发
  1. ✅ 本机 dry-run —— dev 机器(有 repo)上跑,已由我跑过

    这步在有代码仓库的电脑上跑、不是云电脑,同事不用管。已跑过,结果:选出 5 个候选、话题/话术正常。需要重跑时:

    # 务必带 eval key,不烧生产额度
    AKKE_USE_EVAL_KEY=1 AKKE_ORG_ID=00000000-0000-0000-0000-000000000001 \
      pnpm tsx scripts/_wecom-recall-dryrun.ts --max=10

    ⚠️ 候选里可能混着测试/误加的联系人(实测见到 fanny、某工程师号)。真上线前扫一眼那几个候选是不是真客户,不是的把会话标 handed_off 排除。

  2. 云电脑 DRY_RUN:空跑验召回腿(野荞做)

    用记事本打开 C:\akke-wecom\.env,把这两行改成:

    AKKE_WECOM_RECALL_ENABLED=1    # 打开召回腿
    AKKE_WECOM_DRY_RUN=1          # 只空跑不真发

    存盘后重启(建 wecom_reply_STOP → 删 → 跑 start-wecom-reply.bat)。看黑窗日志走完一整条但不真发

    [recall] claim 到 N 条待召回  →  搜人身份门读标题点开  →  [DRY_RUN] 不真发

    重点验三件事点得准:搜到人 · 身份门读对标题 · 点开对话,顺便看红点探测。坐标偏就回上一步重量搜索框。

    ⚠ DRY_RUN=1 是全局的
    这期间被动自动回复也会暂时只空跑不真发(同一个开关管整个 loop)。所以别在 DRY_RUN=1 状态停太久;验完召回腿点得准,就进阶段 D 把 DRY_RUN 改回 0,被动回复 + 召回一起真发。
D

真发(已开)

服务端闸 2026-07-21 打开,日限 5 起
🟢 服务端闸已开,但「你那台发不发」取决于你自己

服务端现在会派单了。不过队列行只有云电脑侧也开了召回腿的号才会被取走 —— 你那台没开 AKKE_WECOM_RECALL_ENABLED=1,派给你的单就一直 pending 堆着(每号 backlog 门自会短路,不会无限涨),不会往外发。所以「服务端开了」不等于「你被迫上线」,节奏还在你手里。

开关是翻在代码默认值里的(src/app/api/cron/wecom-recall-dispatch/route.ts),不是 Vercel 环境变量 —— akke 挂在 Gus 的 team 下,别人改不到线上 env。所以别再去 Vercel 找 WECOM_RECALL_AUTOSEND_ENABLED 了,那儿没有。

  1. 云电脑侧开腿,日限压到 5

    确认阶段 C 都点得准后,在自己那台.env 里:

    # 云电脑 .env  AKKE_WECOM_RECALL_ENABLED = 1
    # 云电脑 .env  AKKE_WECOM_DRY_RUN = 0
    # 云电脑 .env  AKKE_ACCOUNT_ID = <阶段 A 表里你那行>

    重启,盯账号状态没异常再慢慢往上爬。任何异常先建 wecom_reply_STOP 急停(见下方急停回滚)。

    服务端日限默认 WECOM_RECALL_DAILY_CAP=5(每号每天最多 5 条),云电脑侧还有一层独立日限 AKKE_WECOM_RECALL_DAILY_LIMIT=5,两层都在,取严的那层。

  2. 第一批盯什么

    队列里出现 pending 新行 + 云电脑日志出现 [recall] claim 到 N 条待召回 = 通了。然后看三件事:

    ① 发出去的话像不像你本人说的(人设对不对);② 有没有 身份门不匹配 的日志(搜到人但开错会话,不发是对的,多了就要查名字);③ 发完有没有红色感叹号(被删 → 那人自动出库)。

05配置清单

两处:Vercel 后台(服务端)+ 云电脑 .env(发送端)。带 开关 的默认关。

Vercel 环境变量(服务端大脑)

变量作用建议值
WECOM_RECALL_AUTOSEND_ENABLED总真发开关。2026-07-21 起默认就是开(代码里翻的默认值),设 false 才回到 dry-run。线上 Vercel 没有这个变量、也改不了(项目在 Gus 的 team 下)不用设;要关走急停三档
WECOM_RECALL_PERSONA全局兜底人设(现在 persona 存在账号行 wecom_persona,此项仅账号没填时用)可不设
WECOM_RECALL_DAILY_CAP单号召回日上限起步 5
WECOM_RECALL_MIN_HOURS最后一条我方消息隔多久没回才进队24
WECOM_RECALL_COMBINED_HOURLY_CAPDM+召回合并 1h 活跃门3
WECOM_RECALL_CHANNEL_PREF企微号在 accounts 的通道值wecom

云电脑 .env(发送端,C:\akke-wecom\.env

变量作用
AKKE_WECOM_RECALL_ENABLED云电脑侧召回腿开关 开关灰度前 0;上线 1
AKKE_ACCOUNT_ID企微销售号 accounts.id(已建好的 wecom 账号)0242b7ff-…-ce71722e6853
AKKE_WECOM_C_SEARCH顶部搜索框坐标(measure 量出)如 60,30
AKKE_WECOM_DRY_RUN只读空跑(验腿用)/ 真发验证 1 → 上线 0
AKKE_WECOM_RECALL_CLAIM_LIMIT每轮最多领几条召回2
⚠ persona 按账号隔离(每个操作员各一份)
人设现在存在账号行上:每个 wecom 账号的 wecom_persona 决定该操作员召回用谁的口吻 + 只发谁的客户(按 persona:% 隔离,不串号)。野荞账号已设 xiaowen。以后加夏夏/饭粒/Gus,各自账号填各自 persona(xiaoxia / xiaofan / xiaowu)。全局 WECOM_RECALL_PERSONA 仅兜底。

06防翻车护栏

好友单聊主动推,封号风险最高。护栏都在代码里,这里是心里有数。

发之前

  • 进队门槛:≥24h 没回才进,不会刚发完就当沉默
  • 排除人工在聊:把有潜力、人工在深聊的客户标 handed_off,自动豁免、不打扰
  • 身份门:搜到的人标题对不上就不发,防重名发错人

发之后 / 节奏

  • 红点感叹号=被删 → 只白发 1 条、永久出库
  • 满 7 次出库;连推没回应 → 每天改隔天退避
  • 封号护栏:日限 5 起步 + DM/召回合并 1h 门 + 工作时间 9–21,灰度从低起、盯账号随时停

对齐企微平台规则 · 调研 2026-07-16

企微给客户发消息分三条通道、规则各不同——我们的召回只走第三条「好友单聊」,运营听到的「只能连续发 7 天」是另一条通道(群发)的事,不约束我们。

发送通道平台规则 / 硬性上限用不用
群发助手硬额度:每天 1 条 / 每周 7 条 / 每月当月天数。运营听到的「只能连续发 7 天」= 这里的每周 7 条群发不走
微信客服 kf客户发消息后 48h 内最多回 5 条(会话窗口)不走
好友单聊 1:1
成员 GUI 手打
「发 X 条 / 连续 X 天」的硬 API 上限,只受风控约束✓ 走这条

好友单聊没有硬性条数上限,真正的约束是风控(触发 → 限流停 24h 甚至封号)。上面那两块护栏,正是对着风控每条红线做的:

风控红线我们对应的护栏
官方建议 ≤ 1 条/天每天最多 1 条;连推没回应自动退避到隔天
消息相似度 > 70%7 条话术防复读、不复用句式
客户回复率骤降 > 40% / 骚扰投诉一回复 / 被删 / 满 7 次立即出库
好友请求成功率 < 85%只召回已加成功的好友,不新增加人请求
✅ 一句话结论
7 天召回不碰平台任何硬规则,也贴着风控红线内侧走——所以稳。

07急停 & 回滚

出任何异常,先停再查。三条独立开关,任一即停。

⏹ 立即停发(三选一,都是秒级生效)
# 1. 自己那台停消费     .env 设 AKKE_WECOM_RECALL_ENABLED=0  ← 最快,派了也没人取
# 2. 全局停派单        有 Vercel 权限的人设 WECOM_RECALL_AUTOSEND_ENABLED=false,或 revert 5aa5e294
# 3. 云电脑一键急停     在 C:\akke-wecom\ 建空文件 wecom_reply_STOP

数据库要回退整套表:跑 supabase/migrations-rollback/20260716120432_wecom_recall_rollback.sql(drop 新表/RPC,无数据依赖)。