云电脑三号合并一机 · 镜像操作手册

饭粒(一筑·全屋定制)零星(小星=夏夏) 两台无影云电脑上跑的整套自动化, 原样「镜像」到 野荞(小文) 那台机器 ecd-5qfbmvz3yvpvbiog0 上,三个抖音号在同一台云电脑并行跑。
目标机 ecd-5qfbmvz3yvpvbiog0(成都 · 6核12G · 系统盘80G) 整理日期 2026-07-28 状态 有 3 个阻断项,未解决前不要开工
⚠️ 方向已更正:这份不是当前要做的事。 实际需求是「把饭粒机和夏夏机各克隆成一台新云电脑(走自定义镜像)」,不是把三个号合并到一台。 请看 👉 云电脑克隆镜像操作手册
本页保留:其中「一机多号的三个阻断项」分析将来若真要合并仍然有效。
先看这一条:这个方案不是「复制粘贴就能跑」。 三个号合并到一台机器,会同时撞上 代码层的端口冲突(三个 Edge 抢同一个 9222 调试口)和 抖音风控层的一机多号 + 搜人量叠加(06-23 / 06-26 两次搜索软封的直接成因)。 下面第 ② 节的三个阻断项必须先处理完,否则搬过去的结果是:三个 poll agent 同时操作同一个浏览器、 把三个号的私信全发到同一个抖音账号上,而且发不了几天就集体搜不到人。

1现状盘点 · 三个号现在各自跑什么

下表 account_id / channel_pref / daily_limit 于 2026-07-28 16:46 BJT 直查线上 accounts 表,三个号心跳当时全部新鲜(<5min)。
运营 / 号account_id通道日限心跳部署目录(机上)
小文(野荞)
目标机,保持不动
81cc9678-9b53-413b-9f40-7964341f4af1 cloud_pc30 正常 C:\akke-wuying\wuying-dm
饭粒(一筑·全屋定制)
待迁入
c5d236e1-fd80-4cff-b349-506dfd09699b cloud_pc30 正常 C:\akke-wuying\wuying-dm(自己那台)
零星(小星=夏夏)
待迁入
8af08f10-6db5-4d83-8942-b908349efbda cloud_pc30 正常 C:\akke-wuying\wuying-dm(自己那台)
同名账号别取错。「零星」在 accounts 表里有两条:8af08f10…cloud_pc,就是云电脑这条) 和 d7ac1384…manual,已 archived)。按 name 取 row[0] 会绑到错的那条, 结果就是「按 A 号 claim、却在 B 号前台发」。云电脑永远指 8af08f10

各腿现在跑的是哪套脚本

DM 腿(首触 + 回复捕获)route-B 腿(二次触达)开机自启
饭粒 浏览器 DOM
douyin_dm_web_send_dom.py + douyin_dm_web_capture_dom.py
DOM(07-08 切)
douyin_touch_web_dom.py,独立 start-routeb.bat 两窗
AkkeDomDmStart(30s) + AkkeRouteBStart(120s)
零星 浏览器 DOM(同上) DOM(07-08 切),route-B tail 焊在 akke-start.ps1 AkkeDomDmStart + AkkeRouteBStart
野荞 现场确认项 手上资料只记录了 07-03 给饭粒 + 零星切 DOM,没有野荞那台切 DOM 的记录,它可能还在跑抖音 PC 客户端 GUI 版 douyin_dm_grounded.py。开工第一步先在野荞机上跑确认命令(见 Step 1)。
为什么这条必须先确认:如果野荞还是 PC 客户端 GUI 版,它需要「抖音客户端前台最大化 + 2560×1600 + 英文输入法」独占前台; 而 DOM 版是最小化跑、不抢焦点。两者混在一台机上,GUI 那条会被另外两个 Edge 的窗口活动打断。 合并前野荞必须一起切成 DOM,三条腿才可能共存。

2三个阻断项 · 未解决不要开工

ACDP 调试端口 9222 写死在代码里,没有 env 开关

三个号必须各开一个独立 Edge(各登一个抖音号),端口只能错开成 9222 / 9223 / 9224。但现在这几处全是硬编码常量:

文件现在的值
douyin_dm_web_send_dom.py43CDP = "http://127.0.0.1:9222"
douyin_dm_web_capture_dom.py39CDP = "http://127.0.0.1:9222"
douyin_touch_web_dom.py45CDP = "http://127.0.0.1:9222"
start-edge-debug.bat22-23set PORT=9222 / set PROFILE=C:\akke-edge-debug
watchdog-dm-routeb.ps142-43, 101profile 与 9222 均写死
不改的后果不是报错,是静默发错号。三个 poll agent 各读各的 .env(account_id 是对的、领的单也是对的), 但发送时全部连到 127.0.0.1:9222 这一个浏览器 —— 也就是三个号领的单,全部从同一个抖音账号发出去。 DB 里会记成三个号各自发了,实际只有一个号在发。这是最坏的一类故障:日志全绿、数据全假。

改法(三个 .py 各一行,.bat / .ps1 收参数):

# 三个 .py 统一改成读 env、默认仍是 9222(老机器零行为变化)
CDP = "http://127.0.0.1:" + os.environ.get("AKKE_CDP_PORT", "9222")

# start-edge-debug.bat 收 env,未设时退回原值
if "%AKKE_CDP_PORT%"=="" (set PORT=9222) else (set PORT=%AKKE_CDP_PORT%)
if "%AKKE_EDGE_PROFILE%"=="" (set PROFILE=C:\akke-edge-debug) else (set PROFILE=%AKKE_EDGE_PROFILE%)
改动落在 worker/scripts/wuying-dm/,不在高危路径清单里,但建议走 PR(这条链上任何一处漏改都会导致上面那个静默发错号)。 合 main 后由 sync-wuying-scripts.yml 同步到公共镜像,云电脑才拉得到。 只推镜像不合 main 是无效的 —— 下次任何 wuying 改动合 main 会拿旧版把镜像覆盖回去,修复静默还原。

Bpoll agent 固定读「自己所在目录」的 .env,三个号不能共用一个目录

# wuying_poll_agent.py:47,57
WORK_DIR = Path(__file__).resolve().parent
load_dotenv(WORK_DIR / '.env')

脚本从自己所在目录读 .envAKKE_ACCOUNT_ID 是 1:1 绑死的。 所以一机三号 = 三份完整独立的部署目录,不能共用一个 C:\akke-wuying\wuying-dm。 目录规划见第 ③ 节。

连带影响:sent_log_YYYYMMDD.csvagent.logtemplates\ 也都是按目录走的,三套各自独立, 不要为了省事做符号链接指到同一份 —— sent_log 一旦被三个进程同时 append, 会触发「无表头 → csv.DictReader 把首行数据当表头 → 全标 failed 但其实真发了」那个老坑。

C抖音风控:一机三号 = 设备聚集 × 搜人量三倍叠加

这一条没有代码能绕开,只能靠调节奏压住。两次实证:

三号合一机是同时踩中放大器和扳机:真·同一台设备(比克隆更彻底)、同一个出口 IP、 而且三个号的搜人动作(DM 搜人 + route-B 搜人 + 关注)全部堆到同一台机器上,日搜人量直接 ×3。 另有一层更重的风险:三个号「出现在同一台设备」会形成账号关联,某个号违规有连坐封号可能(比搜索软封重得多)。

缓解措施(合并当天就要做,不是出事再做):

顺带一个要现场压测的:12G 内存够不够

合并后这台机要同时跑:3 × 调试版 Edge(各带独立 user-data-dir,实测每个约 0.8–1.5G) + 3 × poll agent + route-B 的 watch / consume 进程。6 核 12G 是原本按单号配的。

没有实测数据,不敢拍「够」或「不够」。Step 8 里安排了一步内存实测;如果吃紧, 要么升配(企业办公型可扩),要么这个合并方案只能放两个号。

3合并后的目标状态 · 目录 / 端口 / 账号分配表

这张表是整个迁移的「设计图」,每一步操作都对着它做。三列互不重叠是硬要求。
account_id部署目录Edge profileCDP 端口开机任务
小文(野荞) 81cc9678…4f1 C:\akke-wuying\wuying-dm
保持原样
C:\akke-edge-debug 9222 AkkeDomDmStart
饭粒(一筑) c5d236e1…69b C:\akke-wuying\wuying-dm-yizhu C:\akke-edge-debug-yizhu 9223 AkkeDomDmStart-Yizhu
零星(小星) 8af08f10…bda C:\akke-wuying\wuying-dm-xiaoxing C:\akke-edge-debug-xiaoxing 9224 AkkeDomDmStart-Xiaoxing
三条铁律:① 一个号一个目录(.env 隔离)② 一个号一个 Edge profile(登录态 + 指纹隔离) ③ 一个号一个端口(发送不串号)。任何一条打破,都会退化成「三个号发同一个号」或「A 号的单发到 B 号」。

4逐步操作 · 每步都标了在哪台机器跑

💻 本机 = 运营自己的 Mac 终端(多数由 Claude 代跑) ·  🖥️ 云电脑 = 无影里的 PowerShell(提示符 PS C:\Users\admin>) ·  🗄️ DB = Supabase 改字段

0前置改造:把端口参数化合进 main💻 本机

就是第 ② 节的阻断项 A。改 5 个文件 → PR → 合 main → 等 sync-wuying-scripts.yml 把脚本同步到公共镜像。 这一步没做完,后面全部白做。

验证同步到位:浏览器打开 https://raw.githubusercontent.com/upioai/wiki/main/public/akke/wuying-dm/douyin_dm_web_send_dom.py, 搜 AKKE_CDP_PORT 能搜到即镜像已更新。

1确认野荞机 DM 腿现状🖥️ 野荞机

cd C:\akke-wuying\wuying-dm
Select-String .\.env -Pattern AKKE_DM_SCRIPT
Get-ScheduledTask *akke* | Select TaskName,State
Get-Content .\akke-start.ps1 -TotalCount 5

2先停两台待迁机的派单(也顺手静音心跳告警)🗄️ DB

给饭粒和零星的 accounts.dispatch_paused_until 设一个未来时刻(迁移窗口 + 缓冲)。

这个字段是一改双职:设了未来时刻后,① 每轮派单直接 paused_skip 不派单; ② wuying-heartbeat-watch cron 看到它在未来就跳过、不会报「无影 agent 没在轮询」。 所以停机迁移期间不用另外关告警,改这一个字段就够。 迁完记得清空,否则新机器起来了也一条不派 —— 06-14 野荞被自己静音一整天、06-29 零星把人为静音误读成「软封自愈冷却」,都是栽在忘了清这个字段。

3备份两台待迁机的 .env这是整个迁移最关键的一份资产🖥️ 饭粒机 / 零星机

每台各跑一遍,把 base64 结果回传:

cd C:\akke-wuying\wuying-dm
[Convert]::ToBase64String([IO.File]::ReadAllBytes(".\.env"))
account_id 和各把 key 必须原样搬,一个字符都不要手打。 从错的快照恢复 / 手打错一位 → 「按 A 号 claim 却在 B 号前台发」, 这类事故在 DB 里看起来完全正常,只有肉眼核私信气泡才发现得了。
传文件一律走 curl.exe + paste.rs 或 base64,不要用 Invoke-WebRequest(会转码把文件搞坏)。 paste.rs 实测阈值已降到 <96KB(旧记的 384KB 别信)。base64 别贴回 PowerShell 提示符,写进文件再解。

4野荞机上建两套新目录 + 拉脚本🖥️ 野荞机

# 以饭粒为例,零星把 -yizhu 换成 -xiaoxing
mkdir C:\akke-wuying\wuying-dm-yizhu
cd C:\akke-wuying\wuying-dm-yizhu

# ① 先单独拉一次 update.bat 本身(它不在自己的下载列表里,机器上那份可能停在几个月前)
curl.exe -fsSL -o update.bat "https://raw.githubusercontent.com/upioai/wiki/main/public/akke/wuying-dm/update.bat"
.\update.bat
验收看行数,不看「成功」。update.bat 跑完 [2/3] 段打出的 OK 行数, 应该等于仓里 $files 的长度(当前 12)。只打 1-2 行 = 机器上是远古版更新器, 它自己不更新自己,会让整台机静默停在旧代码上 —— 07-19 饭粒机就是这么让捕获腿挂了很久没人发现的 (douyin_dm_grounded.py 是几个月前的截断版,IndentationError 把整条 import 链炸掉, 但 DM 发送腿照常工作,所以没人察觉)。
update.bat 的下载列表里没有任何 douyin_dm_web_*.py(只有 6 个 PC 客户端脚本)。 DOM 通道的发送 / 捕获脚本必须单文件 curl 补拉: curl.exe -fS "https://raw.githubusercontent.com/upioai/wiki/main/public/akke/wuying-dm/<file>.py" -o <file>.py
脚本源永远是公共镜像 raw(token-free,就是 main)。 绝对不要拿本地 checkout 的 feature 分支工作树去 paste.rs host —— 07-08 亲踩过: host 了个跟 DM 毫无关系的分支版本,比 main 少了 _leave_thread(发完离开会话让对方回复产生红点,红点捕获全靠它), 差点把「回复漏读」bug 带上生产机。部署后按字节数 + 关键函数命中数双校验。

5写三份 .env🖥️ 野荞机

把 Step 3 备份的原 .env 解出来放进对应目录,然后Add-Content 追加下面这段到文件末尾 (dotenv 后者覆盖前者,所以追加即生效;别手改文件中间 —— 这些 .env 里常有重复行,手改中间那行会被后面的覆盖掉):

# 饭粒目录 wuying-dm-yizhu\.env 追加
AKKE_CDP_PORT=9223
AKKE_EDGE_PROFILE=C:\akke-edge-debug-yizhu

# 零星目录 wuying-dm-xiaoxing\.env 追加
AKKE_CDP_PORT=9224
AKKE_EDGE_PROFILE=C:\akke-edge-debug-xiaoxing

AKKE_ACCOUNT_ID 用备份里的原值,不要新填。三份对照一遍:

目录AKKE_ACCOUNT_ID 应为
wuying-dm81cc9678-9b53-413b-9f40-7964341f4af1
wuying-dm-yizhuc5d236e1-fd80-4cff-b349-506dfd09699b
wuying-dm-xiaoxing8af08f10-6db5-4d83-8942-b908349efbda
二触归属别配重:零星原本是「route-B 走独立客户端 watch+consume」的变体,poll agent 必须 AKKE_SECOND_TOUCH_ENABLED=0 —— 留 =1 会和 consume 同时驱动、把同一批人二触两遍。 起来后看 agent banner 的 second_touch=on/off 就是验证点。

6三个 Edge 各自登一个抖音号🖥️ 野荞机

# 饭粒(9223)
start msedge --remote-debugging-port=9223 --user-data-dir="C:\akke-edge-debug-yizhu" https://www.douyin.com
# 零星(9224)
start msedge --remote-debugging-port=9224 --user-data-dir="C:\akke-edge-debug-xiaoxing" https://www.douyin.com
三个 profile 目录必须各自全新建、各自手动扫码登录。 绝对不要复制现成的 C:\akke-edge-debug 目录再改名 —— 复制 profile = 连浏览器指纹和登录态一起复制,就是 06-23 那个「克隆镜像共用设备指纹 → 集体软封」的坑换了个皮。 每个 profile 第一次启动时自己生成,才拿得到独立指纹。
Edge / Chrome 136+ 在默认 user-data-dir 上禁用了远程调试,所以必须用专用目录(这也是 C:\akke-edge-debug 存在的原因)。 验证端口通:浏览器开 http://127.0.0.1:9223/json/version,返回 Edge 版本 JSON 即 OK。

7三套 akke-start.ps1 + 三个开机任务🖥️ 野荞机

每个目录一份 akke-start.ps1,内容就是原来那套(kill 残留 → 拉 Edge → 轮询等 CDP 通 → 暖机 → 起 poll agent), 只是把端口 / profile / 目录换成本号的。注册成三个登录触发任务,错开延时避免同时抢资源

任务名延时拉起
AkkeDomDmStart(野荞,已有)30swuying-dm\akke-start.ps1
AkkeDomDmStart-Yizhu90swuying-dm-yizhu\akke-start.ps1
AkkeDomDmStart-Xiaoxing150swuying-dm-xiaoxing\akke-start.ps1
暖机那 15 秒别省。poll agent 一等到 CDP 端口通就起,但抖音私信面板 JS 还没渲染完 → 首轮捕获报 conversation-item=0(面板没开/DOM变了)。 判别:by_name N>0 但 conversation-item=0面板没加载好(时序问题)不是登录过期 (真过期是连 by_name 都读不到)。无害但污染日志,Start-Sleep 15 + 先跑一次 capture 暖机即可。
akke-start.ps1 里那段自更新(起 poll agent 前先从镜像拉最新 wuying_poll_agent.py,带 >20KB 体积校验防截断) 要三份都保留。少了它,机器会永远跑缓存的旧版 —— 症状是「改动明明合了 main 和镜像,云电脑行为却不变」。 另外:给云电脑加任何自动化前,先跑诊断确认真实启动入口 (列启动文件夹 + Get-ScheduledTask *akke* + 看 akke-start.ps1 内容), 别默认是 start.bat —— 07-26 就把自更新焊进了 start.bat,而 DOM 机开机根本不过它,白干一轮。

5验活清单 · 六项全绿才算迁完

#检查项怎么看合格标准
1三个端口各自活着 浏览器开 127.0.0.1:9222/9223/9224/json/version 三个都返回 Edge 版本 JSON
2三个 agent 各绑对号 看每个 agent banner 的 v= / account= / second_touch= / rc= account 值与第 ③ 节表格逐一对上
3交叉验证:agent 的号 = 它那个 Edge 里登的号 逐台把 banner 里的 account 和对应 Edge 窗口里抖音登录的账号肉眼对一遍 三对三一致
这是 wrong-account 事故唯一测得出来的地方
4捕获腿真的活着 各目录跑 py douyin_dm_web_capture_dom.py web capture[DOM]conversation-item N>0COMMIT 写回,无报错
5DB 侧心跳 查三个号的 accounts.last_poll_at 三个都在 5 分钟内刷新(超过就判离线、零派单)
6肉眼核私信气泡 三个号各发一条真单后,人工翻抖音私信列表 对方会话里真有气泡
第 6 项不能省,也不能用日志代替。云电脑 GUI / DOM 这条链的 sent 只代表「点了发送」, 抖音的陌生人私信限流(status_code 7911,约 24h 冷却)是静默丢弃的 —— HTTP 200、success:true、 日志一片绿,消息根本没送到。迁移后的第一批必须人工核气泡
「捕获腿挂了但 DM 照常发」是这套架构的固有盲区(两条腿在同一个 poll agent 进程里但互不影响)。 所以判「捕获活着」只认第 4 项那三个字样,别拿「DM 在发」当捕获正常的证据

6回滚预案

7本手册没法替你确定的三件事

现场确认
野荞机 DM 腿现在是 DOM 还是 PC 客户端 GUI
手上资料只记录了 07-03 给饭粒 + 零星切 DOM,没有野荞的记录。Step 1 的命令跑一下就知道。如果还是 GUI 版,必须先切 DOM 才能合并。
需实测
6 核 12G 跑得动 3×Edge + 3×agent 吗
这台机原本是按单号配的。跑起来后看任务管理器,内存吃满就得升配,或者这个方案只放两个号。
无先例
三个 Edge 同机同 IP 登三个抖音号,web 端风控怎么表现
我们有的是 PC 客户端侧的软封实证(06-23 / 06-26),浏览器是另一套 surface、指纹不走客户端那份缓存。同机三号在 web 侧会不会同样触发关联,没有数据,只能上线后盯着搜人是否返回空。