技术复盘|2026 年 11 月 9 日
本文由 ChatGPT 根据开发过程、M4 运行日志、已合并的 Git 代码和使用者的首次实发确认整理。文中联系人匿名,聊天正文、账户标识、解密密钥及私人路径均不公开。这不是微信官方提供的接入方案。
一台 Mac M4、一份微信本地加密数据库、一个本地 AI 模型和一个原本已经存在的微信发送控制器,最后被连接成了一个可以实际回复消息的系统。使用者确认了第一次真实回复成功。完成这件事的过程远比“接上模型,然后发送”复杂:我们经历了窗口采集失败、数据库读取桥接、只生成草稿的 Shadow 阶段、Live 安全切换、联系人配置校验,以及最后的代码入库。
开源专题 · 第 01 期|微信本地 AI 自动回复
本篇作为系列技术记录与交互样章持续更新。项目代码目前仍在私有仓库,技术记录和脱敏示例不等于已开放源码。
技术实验室 · 可交互样章
交互示例为脱敏的教学模拟,不读取微信、不发送信息。内容持续更新时,应以正文技术记录和实际仓库状态为准。
一、为什么不再依赖截图读取消息
早期的微信 Agent 通过窗口读取消息,曾出现 window-capture-failed、wechat-window-not-found 等错误。窗口被遮挡、应用未处于预期状态或桌面锁定时,这条路径容易失效。此次方案没有再堆叠 OCR、截图和坐标定位,而是重新划定职责:本地数据库负责接收,既有控制器负责发送。
读取器使用本地 SQLCipher 数据库及仅保存在设备上的密钥;接收桥调用读取器的 check/ack 接口。它并不修改微信数据库。桥接自身有独立的 SQLite 处理账本,以数据库名和本地消息 ID 组合识别已经处理的消息。
二、五个环节如何协作
读取:只处理读取器识别出的新记录。辨别:本人发出的消息记为 ignoredself,非文字记为 ignorednontext,避免 AI 对自己的回复再接一轮。去重:进入模型或发送环节前先看账本,重复消息不会重复处理。草稿:本机 Ollama 调用 lmn:light 输出简短中文回复;对空值、过长内容和推理标记进行检查。发送:只有 Live 模式,并且联系人、配置与显式发送授权同时满足条件,才调用已经存在的精确联系人发送控制器。
这套结构最关键的细节是:消息发送动作可能已经发生,但调用方却因为超时而不知道结果。此时不能一律自动重试,否则可能导致重复发送。因此账本区分 sendattemptedunverified 与 sendambiguousno_retry。“尝试发送”不是“送达确认”。
三、从 Shadow 到 Live 的真实证据
在禁止自动发送的 Shadow 阶段,状态记录里 AI 草稿累计从 1 增至 3,本人消息忽略计数为 1。当时守护进程运行,心跳约 0.3 秒,数据库接收错误为 null。这证明自动轮询能够经过入站读取、方向过滤和草稿生成,但这些计数是当时的快照,不能反推每条消息的完整来源。
进入 Live 的第一步并不顺利。一次切换报 livemodeguardanchormissing,原因是部署脚本按严格文本片段定位旧守护进程代码;我们改为依据实际结构定位,同时保留源码校验和失败回滚。另一轮报 contactorshadowmodemismatch,诊断工具后来读出了真实的配置名称和模式,确认配置文件之间一致,避免为追求方便而模糊匹配微信联系人。
最终的状态报告是 mode=live、sending=true、配置一致、守护进程正常、心跳约 0.5 秒、dbingresserror=null。随后使用者确认首条实际回复成功。可以确认单联系人首次端到端闭环成功;不能据此宣称全天候稳定或所有微信版本通用。
四、把运行成功和代码交付分开
第一次真实回复成功后,Git 检查发现四个相关 Python 脚本仍是未跟踪文件。它们随后被单独提交并推送;由于旧开发分支与主分支分叉,而且包含不相关改动,没有直接合并原分支。最终从最新 main 建立隔离分支,仅带入四个文件,经 PR #1470 Squash 合并,主分支提交为 6bba71e。随后对比结果为 identical。
这次主分支更新没有要求重启已经工作的微信守护进程,也没有把网站部署与本地消息系统混为一谈。程序已运行、Git 已归档、网站已部署,是三种不同的完成状态。
五、工程交付、测试边界与开源准备
后续首先应重新执行并完善自动化回归测试,观察多消息连续回复、模型超时、客户端升级和设备重启后的恢复。当前接收器对数据库目录结构及账户选择具有环境特定假设,不能宣称可直接复制到任意机器。单联系人许可与停止功能必须保持,回复内容的安全和私密日志也需要进一步审查。
目前代码所在的 LMN516 仓库是私有仓库。合入私有 main 不等于开源。若要开源,应该另建独立工程,排除解密密钥、个人路径、联系人备注和私有日志;以离线样例、只读与 Shadow 为默认模式,补齐测试、许可证、适用范围和微信平台规则说明后再公开。
六、回到真实代码:一条新消息究竟经过哪些判断
前面的五环节只是架构概览。要判断一个自动回复系统是否可靠,更值得看的是每条消息在什么位置被接受、丢弃、记账和发送。此次 M4 的数据库接入并没有另起一套与原系统竞争的微信控制程序,而是保留原有守护进程,把本地数据库读取桥接到它的定时入口。读取和发送仍由不同组件承担。
从当前入库脚本看,关键路径可以整理为:
微信本机消息数据库(SQLCipher,只读)
↓ wechat_db.py:check(携带游标)
单联系人入站桥接 wechat-db-bridge.py
↓ 核对消息方向、文本类型
本地 SQLite handled 处理账本
↓ 是否已处理?
本机 Ollama:lmn:light 生成文本
↓ 校验草稿、记录 send_started
lmn-wechat-mode --exact
↓ 在 M4 上操作微信客户端
更新结果状态 → wechat_db.py:ack 游标“只处理指定联系人”不是在生成回复时随便判断一下名字。初始化时,读取器会先将微信备注名称解析成内部聊天身份,并要求匹配结果唯一。它还会与此前核对过的聊天身份比对;不一致就拒绝初始化。后续读取器使用已绑定的聊天身份获取新消息。发送时,依旧使用完全相同的联系人名称,不自动替换成看上去相似的联系人。这是单联系人方案中的一条边界,而非“支持所有好友”的能力。
实际读取一次消息时,程序调用 check,返回一批新记录和下一位置的游标;处理完成后再调用 ack。这里有两个不同的“状态”:游标解决下次从哪里继续读,SQLite 处理账本解决同一条记录是否已经经过业务逻辑。只靠游标不能覆盖重启、重复扫描及异常中断时的全部去重情形;只靠账本又不能告诉数据库读取器下次该从哪里开始。
消息进入 AI 前至少要经过三次判断。第一,from_self 必须明确;如果读取器无法判定发送者,整批处理会报错,不会把身份不明的记录假装成联系人消息。第二,来自本人的消息记录为 ignored_self,避免出现“自己发一句、AI 回复一句、AI 再回复自己”的循环。第三,只有 local_type=1 且存在文本内容的记录才进入模型,图片、语音和其他非文字记录记为 ignored_nontext。这并不意味着未来不能支持多模态,只是这一版的自动回复入口尚未实现。
七、AI 实际看到什么,又看不到什么
这一节很容易被一笔带过:“消息交给本地模型处理。”但模型能拿到哪些信息,直接决定了它的回复上限。
代码向本机 127.0.0.1:11434 的 Ollama 接口发起请求,选用 lmn:light。正常路径使用 /api/chat、非流式生成、think=false,生成配置包含 num_predict=320 和 temperature=0.5。系统提示词要求输出一句简短自然的中文回复,不展示推理过程、不虚构发送状态、不替使用者作承诺。当前这一调用中的用户消息,是单独的一条新文本。
这就意味着,虽然程序可以连续处理三条新消息,但它还没有做到把连续消息合并成一个完整的对话场景。举一个仅供说明的合成例子:
联系人依次说:“在吗?”“明天晚上有空吗?”“想一起吃饭。”
如果每条分别进入模型,它可能分别产生三个短回复。读者能从上下文看出对方是在发出邀请,当前模型调用却没有自动附带前三轮聊天记录、既往约定、关系信息或日程安排。程序也没有“等对方输入完再答”的消息聚合窗口。模型会说话,与代理能理解这段关系和这次对话,是两件不同的事。
代码还做了输出校验:只接受非空文本,剔除两端空白,拒绝超过 1,800 字符的回复,并拒绝带有特定推理控制标记的内容。这不是简单的“越长越好”或“模型任意生成就发送”。对自动回复来说,短而合规的草稿往往比长篇解释更符合聊天场景,但仅靠字数和标记检查,仍然不能保证语义正确。
有一处较具体的模型兼容性处理:某些本地推理模型即使设置了 think=false,也可能把输出额度消耗在推理内容上,导致最终回答为空。代码只有在检测到这种情形时,才再尝试一次原始文本补救路径:调用 /api/generate,要求输出形如 {"reply":"好的,收到。"} 的 JSON,随后解析并再次校验 reply。正常聊天接口超时设置为 35 秒,补救请求为 65 秒;这不是承诺每条微信都在几秒内答复,而是为异常模型输出留出的上限。失败仍有可能发生,不应该在文章里描述为“自动解决了所有生成问题”。
当前尚未在这条桥接链中实现的能力包括:聊天历史检索、联系人专属语言风格、话题追踪、重要问题转人工、按日程决定是否作答、连续消息合并,以及对含糊或风险较高的问题主动保持沉默。以上属于下一阶段的产品逻辑,不能写成已经上线的功能。
八、去重策略背后的艰难取舍:宁可不重发,也不能盲目重发
发送链路的一个真实问题是:程序发出了最后一次 Enter,微信窗口可能已经接收消息,但本地控制器随后超时、退出或没拿到回执。对于远程 API,可以尝试用服务端幂等键解决;但我们这里操纵的是桌面微信客户端,一次键盘动作成功,不等于拥有一个可靠的送达事务。
目前每条消息的唯一性由“数据库名称 + 本地消息 ID”组成,保存在本机 SQLite 的 handled 表中。准备发消息时,先把记录写为 send_started 并提交,然后调用发送控制器。返回后,再把状态记成 send_attempted_unverified 或 send_ambiguous_no_retry。如果最终发送步骤可能已经执行,程序不会再次自动发送同一内容。
用缩短的伪代码展示这个顺序,比单说“有幂等去重”更准确:
# 结构说明,不是直接复制可执行的生产代码
if already_handled(database_name, local_id):
skip()
elif from_self:
record("ignored_self")
elif not_plain_text:
record("ignored_nontext")
else:
reply = generate_and_validate(message_text)
record_and_commit("send_started")
try:
send_exact_contact(reply)
record_and_commit("send_attempted_unverified")
except Exception:
record_and_commit("send_ambiguous_no_retry")
# 对已处理批次推进数据库读取游标这套实现侧重避免重复发送,但也有清楚的代价:如果在写入 send_started 之后、真正执行发送之前意外退出,下一轮可能因为账本已有记录而跳过。这意味着它不是“必达一次”的消息队列,而是趋近于“一条消息最多尝试一次”的处理策略。用户看到一次成功的真实回复,只能证明那次端到端路径通了;不能据此推断没有漏回或所有异常都能自动恢复。
另外要注意:模型生成失败发生在写入发送账本之前时,这条消息与发送已开始后的消息不是同一种失败状态。处理框架应分别统计模型错误、消息过滤、已生成草稿、尝试发送和结果不确定,而不是只展示一个“成功/失败”数字。
九、发送不是一个抽象 API:M4 上实际按了哪五步
这一版仍然使用 M4 上已经存在的微信发送控制器 lmn-wechat-mode,而非直接把文本写进微信数据库。实际操作约定为:⌘F 搜索精确联系人 → Enter 进入会话 → 在输入框 ⌘A、Delete → 粘贴生成文本 → Enter 发送一次。
这里特意省去了截图、OCR、窗口坐标和二次标题读取。我们此前的失败经验表明,这些依赖窗口可见状态的读取环节很脆弱。改成数据库读取消息之后,日常入站不需要依靠看见微信窗口;但出站仍依赖本机微信客户端和可操作的桌面会话。因此不能把“数据库可读”理解为“锁屏、退出微信、界面被其他程序抢占时都能稳定发送”。
执行发送前,桥接还会复核运行标志与绑定联系人是否一致。在调用 Live 路径时需要显式批准当前联系人和发送开关,且发送调用使用 --exact,不对一个找不到的联系人改发给近似名称。若某个键盘动作明确失败就停止;若最终 Enter 是否已经触发不确定,则记为结果不明,不能为了补救而自动重复一次。
我们还需要区分三件事:AI 草稿生成成功、控制器尝试发送、联系人实际收到消息。当前控制器记录的 send_attempted_unverified 只支持第二种说法,不是微信服务器的送达回执,更不是对方已读。文章中“首次实发成功”的依据来自使用者当时的人工确认,不能与程序自动证实投递混为一谈。
十、为什么有时一个接口显示 Live,另一个却显示 Shadow
11 月 9 日凌晨,M4 上的数据库桥接状态显示 mode=live、sending=true、联系人配置一致、守护进程运行。后来检查 MCP 的另一条微信接管状态接口时,却出现 enabled=false、shadow=true、active_send=false,同时它的较早状态还记录了 wechat-window-not-found。
看似矛盾,实际提醒我们:同一台机器可以存在不止一个“状态视角”。新数据库入站桥接有自己的配置、处理账本和守护进程心跳;较早的 MCP 接管接口也有自己的开关、许可名单及运行状态。不能把一条旧接口的 Shadow 直接判定成新数据库桥接已经停了,也不能看到数据库桥接的 Live 就宣称所有 MCP 接管通道都已开启。
要核对当前是否真的能自动回复,至少应该分别查看:① 新桥接的 Live/Shadow 配置是否一致;② M4 守护进程是否在运行、最近一次轮询有没有错误;③ 本地处理账本是否增加了真实新消息和发送尝试;④ 如需确认联系人收到,则依靠得到授权的真实端到端测试或联系人反馈。单凭一个 sending=true 不能代替第四项。
这里还要把历史快照和当前运行态分开。文章记述的“心跳约 0.5 秒”“首次回复成功”都是当时的观察结果,不表示读到本文这一刻仍是这些数值;也不是跨设备、跨微信版本的稳定性结论。
十一、下一阶段值得写进工程任务的验收清单
下表是尚需逐项验证的预期行为,不是已经全部通过的回归测试。其价值在于:以后系统变更时,可以拿同一批场景测试,而不是每次只发一句“你好”就宣布完成。
| 测试场景 | 应有行为 | 最重要的失败风险 |
|---|---|---|
| 联系人连续发送三条相关文字 | 不误发给其他人;未来应按上下文决定合并或分别回复 | 三条孤立回答造成误解 |
| 本人从微信发出一句话 | 记录 ignored_self,不触发 AI | 自我回复循环 |
| 联系人发送图片或语音 | 当前版本忽略非文字;以后需单独设计多模态路径 | 把二进制或占位符误当文本 |
| 同一条消息被读取两次 | 已存在处理账本记录时跳过 | 重复发送 |
| 本地模型超时或输出空白 | 如符合条件仅进行一次指定补救;记录失败 | 长时间阻塞或无效回复 |
| 已按下发送键但控制器超时 | 记录不确定状态,不盲目重发 | 连续两条相同消息 |
| M4 退出微信、锁屏或重启 | 明确报告可读与可发的边界,验证恢复流程 | 守护进程健康但无法操作客户端 |
| 联系人备注名称变化 | 精确身份校验失败时停止,而非猜测收件人 | 错发隐私内容 |
| 普通闲聊转为重要承诺 | 当前版本尚无完善人工升级规则,应作为优先设计项 | AI 替使用者作决定 |
如果继续建设,我会先补“读最近几轮对话 + 连续消息短时合并 + 重要问题人工接管”,而不是先追求更大的本地模型。现在的问题并不主要是模型参数不够,而是它拿到的上下文太少、回复许可过粗。与此同时,应该保留单联系人边界、最小日志留存、Shadow 测试和发送不确定时不重试这几项已经形成的安全约束。
十二、为什么我们一定要做到真实自动回复
最初要解决的并不是“能不能让 AI 写一句微信回复”,而是让一台自己的 Mac 在收到真实微信消息后,完成接收、理解和回发,不依赖使用者每次手工切换窗口、复制回复,也不把一条 HTTP 成功记录错认成微信消息送达。
这项工作在 2026 年 8 月已经遇到过一个反复出现的断点:模型确实生成了文本,但出站调度器没有把文本送入微信;即使有些接口返回类似 sent 的状态,客户端实际可见的结果仍不一定成立。8 月 24 日,使用者把验收标准说得很清楚:本人发出新问题,并在真实微信会话中收到自动回复,才算成功。 这比“模型能回答”“脚本 exit 0”严格得多。
到 9 月 13 日,目标又更明确了一步:希望 M4 上的本地模型承担实时回复,不让远程 ChatGPT 或远程桌面控制工具成为每条微信的必经路径。这是关于系统自主运行和执行链路的具体要求。早期方案依靠窗口及辅助功能识别消息,但只要锁屏、窗口状态改变或误判红点,就可能导致读取失败。后来转向本地数据库入站,正是针对这一瓶颈做的工程调整:让消息接收不再依赖窗口当前显示出来的内容,同时把发送动作继续交给已经存在的微信控制器。
需要保留一个边界:我们做的是个人微信客户端的非官方本地自动化,不是微信官方机器人接口;它不能自动享有官方消息投递保障,也不应该被包装成免维护、适用于所有人的成熟商业客服系统。
十三、技术路线是怎样选出来的
可以把实际探索分为四条路线,而不是只展示最后一张架构图。
| 路线 | 实际尝试或讨论 | 关键问题与取舍 |
|---|---|---|
| 微信渠道插件 / Agent 调度 | 2026 年 8 月围绕消息入站、AI 生成、出站分发进行调试 | 模型能回答不等于出站可达,插件版本、会话绑定和发送确认会形成断点 |
| macOS GUI / Accessibility | 9 月逐步统一微信控制器、监听、回复和发送;曾采用界面读取、OCR 等方式 | 优点是不直接依赖消息数据库;不足是窗口、焦点、锁屏和红点误判 |
| 本地模型与上下文试验 | 9 月在 M4 上测试本地模型、最近消息上下文及共享记忆 | 记忆与推理的可行性不等于真实发送已完成,需要分别验收 |
| 本地数据库入站 + 既有发送控制器 | 11 月把 SQLCipher 只读消息读取器、Python 桥接、Ollama 和精确联系人发送器接起来 | 降低入站对可见窗口的依赖;仍需要本机运行的微信客户端完成出站 |
最终选择的是混合路线:入站走只读本地数据库,判断与文本草稿走本地 Python 和 Ollama,去重走 SQLite,出站仍走 macOS 上的微信客户端五步键盘操作。这样没有建立第二套发送守护程序,也没有把客户端数据库误当成官方可写 API。
还有一个看起来不够漂亮、但必须写清的变化:9 月早期 GUI 方案曾验证过最近 12 条消息和共享记忆的使用;11 月首次打通的数据库桥接却先采用单条新消息生成草稿。 这并不是上下文问题已经被完美解决,而是在确保“读取—生成—发送”闭环时,先缩小功能范围。两个阶段的能力不能混写成“新方案同时完整具备历史上下文和真实回复”。
十四、我们参考过什么,哪些东西还没有学会
历史技术讨论中,2026 年 9 月 13 日曾参考过两个开源方向,而不是凭空设计所有流程:
WeChatAutoReply 展示了基于 macOS Accessibility API 读取微信界面、调用 AI 模型生成回复、再模拟键盘输入的方式。项目资料还提供了连续消息缓冲、工作时段、联系人专属提示词以及近期对话记忆等设计。它说明了完整自动回复产品除“识别—生成—发送”之外,还必须处理回复时机、上下文和联系人差异。对 LMN516 来说,这些属于有价值的设计参考;不能因为参考过就宣称相应功能已经实现。
WeReply 把界面、编排器与平台 Agent 分层,使用状态机、消息去重和模型调度。LMN516 的具体实现并没有因此采用它的全部框架;我们延续了既有 M4 控制器,在自己的数据库桥接中加入 SQLite 去重和发送结果状态。这两者可以作为架构上的对照,但当前材料没有证据证明复制了上述项目的源码。
此外,早期还研究过 OpenClaw、Ollama 的使用方式,以及微信作为 Agent 接入渠道的可能性。历史记录中确实存在插件兼容、调度器不出站等问题;这属于探索证据,而非 OpenClaw 官方承诺或某个开源方案必然失败的证明。
值得关注的一点是:其他工具已经提出过“短时间内连续消息聚合”“不同联系人不同语气”“人工确认后发送”等策略。我们现有数据库桥接虽然在入站可靠性上做了针对性优化,却尚未将这些交互层面的策略全面实现。写借鉴关系,既要承认外部项目给过启发,也要如实列出还没实现的部分。
十五、完整时间轨迹:哪一天才称得上成功
以下记录以当时的对话、运行报告与 Git 交付记录为依据。时间使用北京时间;有些阶段只有日期,没有精确事件时间,不能补造分钟数。
| 时间 | 当时已经做到的事 | 当时仍未解决的事 |
|---|---|---|
| 2026-08-24 | 真实入站消息能够到达 AI,AI 能生成回答;明确以实际微信收到回复作为验收标准 | 出站调度和真实投递未闭环 |
| 2026-08-25 | 排查旧微信插件与 Agent 框架兼容问题、发送调用和客户端回显问题 | 接口返回发送状态仍不等于客户端看到了消息 |
| 2026-09-10 | 讨论 OpenClaw、Ollama 与本地计算设备如何分工 | 讨论架构不代表已经完成自动回复 |
| 2026-09-13 | 确立 M4 本地模型实时回复方向,调研 macOS 相关开源项目;一次发送动作约耗时 8.5 秒 | 该次发送没有获得真实成功验收 |
| 2026-09-15 | 早期模型、最近 12 条消息上下文及共享记忆相关测试通过 | 自动接收和自动实发仍不能宣称完成 |
| 2026-09-18 | 修复 GUI 监听中红点二次 OCR 误判和过早解除发送授权等问题;部分回归测试通过 | 一次人工补发成功,并不等于新消息全自动闭环通过 |
| 2026-11-03 | 本地模型可用,继续尝试微信联系人托管 | 遇到 target-chat-not-active 与 wechat-window-not-found,未成功托管 |
| 2026-11-08 | 新数据库入站方案通过 Shadow 试验,草稿计数由 1 增至 3,未启用真实发送 | Shadow 只能证明读取和生成,并不能证明对方收到 |
| 2026-11-09 凌晨约 01:58 | 使用者在对话中确认首次真实自动回复成功;此前 Live 状态报告显示发送开关打开、守护进程正常 | 只证明指定联系人的首次真实闭环;长期稳定性尚未验证 |
| 2026-11-09 凌晨后续 | 微信桥接相关四个 Python 脚本通过 PR #1470 合并至私有 main,提交 6bba71e | 合并源代码不等于任意机器可直接部署,也不等于代码已经开源 |
这里最重要的分界是:“人工触发一次发送成功”与“新消息到来后自动读取、自动生成、自动发出并获得真实反馈”不是同一项验收。 11 月 9 日凌晨的用户确认,才是当前这条数据库自动回复路线第一次有依据称为真实端到端成功的节点。
十六、自动回复到底有多快:有证据的数字和不能乱写的数字
技术文章不应该拿缺失的性能统计来填漂亮结论。目前能找到的指标分为四类:
| 观察或配置 | 有什么数值 | 它真正说明什么 |
|---|---|---|
| 2026-09-13 的一次发送动作 | 约 8.5 秒 | 这是旧阶段单次发送动作耗时,且没有取得真实发送成功验收;不能作为新方案平均延迟 |
| 2026-11-08 Shadow 守护进程观察 | 最近心跳年龄约 0.3 秒 | 仅表示当时守护进程近期有活动,不是处理一条微信的耗时 |
| 后续 Live 守护进程状态 | 最近心跳年龄约 0.5 秒 | 仅表示状态检查时心跳新鲜,不能据此写“0.5 秒自动回复” |
| 当前数据库桥接模型请求配置 | 首次请求最多 35 秒;特定回退最多 65 秒 | 是调用超时限制,不是平均响应时间,也不是端到端延迟承诺 |
一条新微信的真实总耗时,至少包括:数据库中出现新记录与轮询发现之间的等待 + 本地模型推理 + 草稿校验 + M4 微信客户端切换与粘贴发送。模型冷启动、长回复、桌面焦点冲突、机器负载以及异常回退,都可能改变这个结果。目前尚缺少带统一时间戳的连续真实测试,因此不能提供可信的 P50/P95 回复延迟、每小时稳定吞吐、CPU/内存开销、失败率和长期可用率。
下一步衡量效率,应该在不保存私人聊天正文的条件下,为每一条已授权测试消息记录四个时间点:数据库消息时间、读取发现时间、模型完成时间、发送控制器返回时间,再另行记录真实接收反馈。这样才能区分究竟是消息发现慢、模型生成慢,还是 GUI 发送慢。如果不做这种分段测量,就不能得出“我们的方案比其他项目快多少”的结论。
十七、与其他自动回复路线相比,我们到底有什么不同
比较技术路线,要比较相同问题,而不是只比较谁的功能列表更长。
| 维度 | 官方企业客服接口 | 个人微信 GUI / OCR 自动回复 | LMN516 当前混合方案 |
|---|---|---|---|
| 接入对象 | 企业微信/微信客服等获授权业务场景 | 个人微信桌面客户端 | 指定个人微信桌面联系人 |
| 接收方式 | 平台提供的业务消息接口 | 可见窗口、辅助功能树或截图识别 | 本地 SQLCipher 数据库只读读取 |
| AI 推理 | 可用云端或自建模型 | 常见云端或本地模型 | 本机 Ollama lmn:light |
| 发送方式 | 官方业务 API | 模拟桌面客户端输入 | 既有 M4 发送控制器五步操作 |
| 对窗口状态的依赖 | 通常不依赖桌面微信 | 入站读取与发送常依赖 GUI 状态 | 入站较少依赖 GUI,出站仍依赖 GUI |
| 上下文和联系人策略 | 取决于具体客服产品 | 部分开源项目支持消息合并、记忆和个性化 | 新数据库回复桥接目前以单条消息、单联系人为主 |
| 最大优势 | 正式接口、可扩展业务集成 | 无需读取本地加密数据库,开发方式直观 | 沿用现有本地系统,减少入站截图/OCR 误判 |
| 最大限制 | 不等同于普通个人号自动操作 | 易受 UI 变化和窗口状态影响 | 非官方个人微信自动化,依赖本地数据库结构和桌面发送;真实运行指标未充分建立 |
这里还存在使用风险:个人微信客户端自动化不等于官方批准的 Bot 接入。与官方企业客服 API 相比,本地方案需要自己承担客户端变化、账号合规和维护风险。另一方面,数据库只读能降低读消息时的窗口依赖,但并不自动解决模型上下文、联系人判断或微信投递确认。
因此,我们当前可证明的不同之处,是“数据库负责入站、GUI 负责出站、本地模型负责生成、SQLite 负责去重”的组合,而不是已经比所有自动回复系统更快、更智能、更稳定。等到真实端到端数据积累后,才有资格做可量化的性能比较。
下面的交互演示完全使用合成消息。它不连接真实微信,不访问任何数据库,也不会发送消息。