wechat-auto-reply-requirements.md
8.21 KB
微信自动回复 · 需求文档
日期:2026-07-09 设备:Pixel(
59171FDCG0009N),微信 8.0.74,LSPosed + Termux + Hermes Agent 定位:Pixel 上的 Hermes Agent 自动处理"别人发给小火子的微信"——私聊 / 群里 @ / 群里引用——判断要不要回、怎么回、自动发还是人工审核。
0. 目标
有人给小火子发微信(私聊、群 @我、群引用我)时,Hermes 能:
- 接收到这条消息
- 读取会话上下文
- 基于上下文 + SOUL.md 生成回复
- 判断"直接发"还是"进人工审核队列"
- 发送回复(含微信原生引用气泡)
约束:尽量低电量 / 低资源;纯端上(Hermes 在设备 Termux 内跑,模型走 Kimi 或本地 llama-swap)。
1. 设备现状(建这套的地基,2026-07 核对过)
| 能力 | 现状 | 备注 |
|---|---|---|
| 微信 DB 解密读 | ✅ 可用 | 主账号目录 ec4f423b316d41e9af5e8398155cf105,key 1986554(MD5("1234567890ABCDEF"+uin257966415)[:7]);参数 cipher_compatibility=1+page_size=1024。skill ~/.hermes/skills/wechat-db-decrypt/ 已就位 |
| 发送文本 | ✅ 可用 | LSPosed 内部 API(am broadcast com.hermes.wechat.SEND_MSG);WeChatHook.java 已打通文本/语音/图片 |
| 发送带原生引用气泡 | ❌ 未实现 | 见环节 5 |
| 通知接收 | 待搭 | NotificationListenerService / dumpsys,见环节 1 |
| lifelog 人物库 | 明文 SQLite | com.lemon.lifelog/databases/lifelog.db(4.8MB,Person 表),二期打通 |
| SOUL.md | ✅ 存在 | ~/.hermes/SOUL.md(Hermes 人格) |
⚠️ 过时提醒:旧文档
md/wechat-auto-reply-status.md(2026-05-23)里的 keye03ce81/ 目录653cdc…是次账号,已不是当前主账号;旧文档主推的 Frida daemon 发送已废弃(常驻注入微信触发反调试崩溃)。以本文件为准。
2. 五环节需求
环节 1 · 接收通知 —— ✅ 已实现并真机验证(2026-07-09)
落地:wechat_plain/scripts/auto-reply/wechat_reply_watcher.py(设备 ~/.hermes/wechat_reply/)。
- 触发:纯 ctypes inotify 监听当前账号 DB 目录(SELinux 放行,零轮询);建 watch 失败自动退回 stat mtime 轮询。真机验证
[inotify] +N事件驱动读取成立。 - 账号自适应:运行时
MD5("mm"+uin)定位当前登录账号(验证时账号已从 火星人 切到 小火子,daemon 自动跟上,无硬编码)。 - 增量+去重+基线:持久化
last_msgId;只isSend=0 且 msgId>last;首跑基线=当前最大 msgId,不重放历史。 - 分类:private / group_at_me / group_quote_me / group_other;群消息剥
wxid:\n前缀取 sender+body;自身 wxid/昵称从 userinfo 自动检测。 - 输出:
incoming.jsonl事件队列(供环节 2-5 消费)。自检--selftest、单读--once、--tail N。 - 常驻自启(已接):
wechat_reply_daemon.sh监督器(root + Termux 环境、单实例锁、等微信登录、看门狗崩溃重启);/data/adb/service.d/wechat-reply-watcher.sh开机拉起。真机验证:纯 root(boot 上下文) selftest 通过、单实例防重、杀 watcher 自动重启。已在设备常驻运行。 - 待接:env4 里过滤 gh_ 公众号与系统消息(撤回/拍一拍);daemon.log 无限增长需加轮转(ponytail:先不做,24/7 下每天几 MB)。
原始设计记录:
(原)环节 1 · 接收通知 —— 事件驱动,非定时轮询
根因:费电的不是 cron 循环,是"每次轮询都 su 拷 90MB 的 EnMicroMsg.db"。定 5s 紧循环拷 90MB → 电量扛不住。
- 主触发:常驻 NotificationListenerService。系统主动 push,空闲近零成本;微信来消息才被唤醒 → 这时才读库。没消息 = 不动。
- 兜底:Hermes cron 每几分钟扫一遍,捞免打扰 / 漏掉的消息。不要跑紧循环。
- 读库:优先只读 in-place 打开(immutable);锁住再拷。因为改成事件驱动,拷库只在真有消息时发生,频率极低,可接受。
- 消息源:主账号
ec4f…/EnMicroMsg.db的message表,WHERE isSend=0 AND msgId>last_processed_id。 - 分流(本环节难点):
- 私聊:直接是一条
- 群 @我:群消息 content 前缀
wxid:\n,需匹配我的昵称判 @ - 群引用我:看 refermsg 是否指向我的 svrid
环节 2 · 读取上下文 —— ✅ 不写模块,走 skill 配方(2026-07-09)
结论:Hermes 是有 shell+SQL 的 agent,已有 wechat-db-decrypt skill,环节2 无需新代码。
- 给 skill 补了「读会话上下文」一节(
~/.hermes/skills/wechat-db-decrypt/SKILL.md,仓库留档wechat_plain/scripts/auto-reply/skill/):一次拷库查齐 ①发送者身份rcontact(显示名优先级 conRemark>nickname>alias)②最近 N 条message历史(剥群wxid:前缀、type→占位符、只喂文本)③引用 refermsg 解析 + 群名;末尾给出喂 env3 的上下文骨架。 - 真机验证配方查询产出干净上下文(身份+时间正序历史)。
- 架构澄清:环节 3(生成)= Hermes 这个 LLM 本身;环节 4(策略)= 它的推理;只有环节 4/5 的「审核队列 + viewer 接发送」还需写代码。
- 二期加分:回链 lifelog
Person库做人物增强。一期不做。
环节 3 · 生成回复
- Hermes(Kimi / 本地 llama-swap):上下文 + SOUL.md → 回复。
- 建议一次结构化调用同时出
{should_reply, confidence, draft, risk_flags},别拆两次。 - ⚠️ 若回复要以"小火子本人"口吻发出,SOUL.md 里可能需加一段"小火子语气"约定(否则像 agent 替他说话)。
环节 4 · 自动 vs 审核 —— 白名单直发,其余进 viewer 待回复
- 白名单(联系人 / 群 / 群里某发言人)+ 生成成功 → 直接发送。
- 非白名单 → 写入 Pixel 本地 wechat viewer 的"待回复列表",人工点击"发送"才真正发出。
- 落地新增:①「待回复队列」存储(sqlite/json);② wechat viewer 的"发送"按钮接到发送链路。
- 安全红线(贯穿):涉钱 / 承诺 / 约时间 / 低置信 → 即使白名单也建议进审核。
环节 5 · 发送回复带引用(原生气泡)
需求 = 点原文→引用→发送后显示引用气泡。两条实现路:
- (a) A11y UI 自动化(一期推荐):长按目标气泡 → 点"引用" → 输入 → 发送。驱动微信自己 UI → 产出货真价实的原生引用气泡,零逆向。代价:需微信前台、脚本略脆、比 API 慢。已有 A11y 发送服务底子。
- (b) 内部 API 构造 refermsg(二期优化):微信引用 = type 49 appmsg + refermsg(type 57) 指向被引 svrid。一整块新逆向,量级同当初啃发图,重。留作提速。
3. 贯穿层(不做会出事)
- 防循环/去重:只处理
isSend=0;持久化 per-talkerlast_processed_msgId;绝不回自己发的、绝不重放。 - 限流:每人/每群回复冷却,防抖防刷屏。
- 安全红线:陌生人 / 涉钱 / 承诺 / 约时间 → 永不自动发,硬编码兜底。
4. 一期最小可跑(MVP)
通知触发(NotificationListener)
└→ 读库(主账号 ec4f/1986554, message 表, isSend=0 & msgId>last)
└→ 分流(私聊/群@我/群引用我) + 取上下文(近 N 条 + rcontact 身份)
└→ Hermes 生成(上下文 + SOUL.md → {should_reply,confidence,draft})
├→ 白名单 → A11y 发送(纯文本+@;引用气泡)
└→ 非白名单 → 写入 wechat viewer 待回复队列 → 人工点发送
二期:lifelog Person 人物增强;内部 API refermsg 引用提速;cron 兜底调优。
5. 待决策 / 待确认
- [ ] 白名单如何维护(配置文件 / viewer 里管理 / 从 lifelog 拉)
- [ ] 待回复队列 + wechat viewer 的具体形态(现有
wechat-web-viewerskill 扩展?) - [ ] SOUL.md 是否加"小火子语气"段
- [ ] 群 @我 / 引用我的判定用昵称还是 wxid(昵称易误判,wxid 更准)
- [ ] in-place 只读打开能否稳定绕过 WCDB 锁(否则回退拷库)
- [ ] 环节 2 lifelog join key:
Person里存的微信标识字段(二期确认)