VRPA(Vision RPA)通用 RPA 框架底座 + 微信参考实现 · MIT License 状态:V1.0 收口 checkpoint(微信 4.x / Windows;618 项测试全绿 · 覆盖率 85.39% · ruff / mypy strict 全绿 · 默认
dry_run· 真实发送默认关闭) M4:队列/拟人延迟/限流/状态机熔断/--simulate/接管;M5:OpenAI 兼容客户端(重试+用量)、Prompt 预算裁剪、后处理安全过滤、人设热加载、llm-ping。
目标:先跑通 dry-run,不真实发送。不要一上来就开真实发送。
- Windows 10/11,微信 PC 4.x,Python 3.11+(当前验证 3.14.7);
- dry-run 普通 PowerShell 可跑;真实发送需要管理员 PowerShell;
- 微信窗口保持打开,分辨率/DPI 与校准 profile 一致。
git clone https://github.com/ergjk/vrpa.git
cd vrpa
python -m venv venv
.\venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt
copy .env.example .env
notepad .env # 填入 DEEPSEEK_API_KEY
python -m wechat_agent first-run按 NEXT: 提示补齐。最常见的两项:
# 没有 profile 时:微信窗口打开后校准
.\venv\Scripts\python.exe -m wechat_agent calibrate --warmup 10 --elements main_window,chat_title,search_box,message_area,input_box,send_button
# 补齐后重新检查,直到 RESULT: READY
.\venv\Scripts\python.exe -m wechat_agent first-runREADY 后:
# 先离线模拟(不触发微信)
.\venv\Scripts\python.exe -m wechat_agent run --simulate --scenario tests/fixtures/simulation/01_basic_flow.json
# 真机 dry-run:真实采集/入库/LLM,但不发送
.\venv\Scripts\python.exe -m wechat_agent run --real --chat 目标会话 --warmup 8 --settle 3 --ticks 1 --json
# 可选:打开 GUI 控制台
.\venv\Scripts\python.exe -m wechat_agent guifirst-run输出RESULT: READY;- 模拟场景
ok=true; - 真机 dry-run
failures=0,有采集/入库,且没有任何真实发送。
真实发送必须同时满足:
config.yaml的app.dry_run=false;safety.allow_real_send=true;- 目标会话在
real_send_allowlist; - 显式
--i-understand-risk; - 管理员 PowerShell;
- 设置
--max-sends 1或单条send --real。
首跑只验证 dry-run;真实发送请按 §6.1 的灰度流程,先发 1 条、确认收到、再恢复双锁。
GUI 的“临时解锁并发送 1 条”会在系统临时目录生成一次性配置,进程结束立即删除;主 config.yaml 始终保持双锁。发送结束会弹出“是否收到”确认,失败统一显示 NEXT: 动作。
2026-11-07 实测:message_id=103 发送成功,临时配置清理后主配置仍为 dry_run=true / allow_real_send=false。
.\venv\Scripts\python.exe -m wechat_agent first-run --json
.\venv\Scripts\python.exe -m wechat_agent doctor
.\venv\Scripts\python.exe -m wechat_agent report日志:data/logs/agent.log;报告:data/reports/。
本项目不是一个"微信专属脚本",而是一个可以复用的 Vision RPA 框架 + 参考实现:
| 层 | 包 | 定位 | 依赖 |
|---|---|---|---|
| 通用框架底座 | vrpa |
把 RPA 场景中的通用能力沉淀为平台无关的框架:双库记忆存储引擎、异常与退出码契约、拟人化调度队列、视觉锚点匹配、配置/日志/审计、平台适配器契约与合规测试套件 | Python 标准库(视觉子系统需 numpy + opencv-python) |
| 微信参考实现 | wechat_agent |
基于 vrpa 接入微信 PC 的真实实现:假 UIA 树视觉定位、框选 + 剪贴板采集、状态回写去重、LLM 推理、HITL 控制台与插件 |
vrpa + RPA/LLM 第三方库 |
┌──────────────────────────────────────────────────────────────┐
│ wechat_agent —— 微信参考实现 │
│ 假 UIA 树视觉定位 · 剪贴板采集 · 状态回写去重 · 控制台/插件 │
│ (QQ / 钉钉开发者:在你的应用包里写同位置的适配器即可) │
└───────────────────────────┬──────────────────────────────────┘
│ 只依赖 vrpa 的公共契约
┌───────────────────────────▼──────────────────────────────────┐
│ vrpa —— 通用 RPA 框架底座(Vision RPA) │
│ 双库存储引擎 · 异常/退出码契约 · 拟人化调度队列 · 视觉锚点匹配 │
│ 配置内核 · 日志审计 · 平台适配器接口 · 适配器合规测试套件 │
└───────────────────────────┬──────────────────────────────────┘
│ 标准库(视觉:numpy/opencv)
Python stdlib
依赖方向是单向的:wechat_agent → vrpa → stdlib。第三方平台(QQ / 钉钉 / 飞书)只需实现 vrpa 的适配器契约,不需要修改底座;微信实现可作为参考样板。
状态图例:已实现(M0)/规划中(已设计,按 M1~M6 里程碑交付,任务与 DoD 见 docs/行动清单-V1.0.md)
| 你是…… | 建议入口 |
|---|---|
| 只想跑一个微信机器人 | §6.1 WeChat 快速开始 |
| 想开发 QQ / 钉钉机器人 | §6.2 VRPA 适配器快速开始,完整指南见 docs/writing-an-adapter.md |
| 想理解分层与依赖规则 | docs/architecture.md(含 ADR 决策记录 docs/ADR/) |
| 想参与实现 / 验收 | docs/行动清单-V1.0.md(M0~M6 任务、DoD、阶段门禁) |
| 想先看技术细节 | docs/技术方案-V1.0.md(含 M0 已落地部分 + M1~M6 设计) |
| 能力 | 说明 | 状态 |
|---|---|---|
| 双库存储引擎 | 流水库(历史上下文)+ 核心档案库(长期记忆)双库分离;WAL、幂等迁移、预迁移备份、FTS5 全文检索、软删 | 已实现 M0-06;M0-F-05 引擎已上提 vrpa.memory(应用仅保留薄适配) |
| 异常与退出码契约 | 统一异常家族 + 进程退出码(0/1/2/3/4/5/6/7/8/130),to_dict/to_audit 结构化、自动脱敏 |
已实现 M0-04 |
| 日志 / 审计 / 脱敏 | RotatingFileHandler、trace_id 贯穿、JSONL 审计、API Key / 手机号 / 身份证 / 邮箱打码 | 已实现 M0-03 |
| 配置内核 | 通用配置加载、校验、环境变量覆盖(VRPA_*);通用段(app/uia_tree/capture/llm/humanize/ratelimit/safety/control/plugins/display)已上提 vrpa.config.schema,平台字段由适配器插件校验 |
已完成 M0-F-03 / F-06 |
| 拟人化调度队列 | 优先级 FIFO、跨会话轮转、限流 / 静默时段、可打断的拟人延迟(思考 / 打字 / 发送节奏) | 已实现 M4(queue / delay / scheduler / machine / loop);人手化节奏为 V1.0 启发式,V1.2 计划学习真人节奏 |
| 视觉锚点匹配 | 元素树 profile + 多尺度模板匹配定位(失败即中止,禁止坐标兜底),供各平台适配器复用 | 已实现 M1(vrpa.vision:profile / matcher / locator / calibration) |
| 平台适配器契约 | PlatformAdapter 协议 + AdapterRegistry + 适配器合规测试套件(vrpa.testing.contracts,第三方实现必须全绿才能接入) |
已实现 M0-F-04(微信适配器 M0-F-05 全绿接入) |
| 能力 | 说明 | 状态 |
|---|---|---|
| 假 UIA 树视觉定位 | 微信 4.x 无原生控件树,自建 JSON 元素树 + 锚点图匹配定位点击目标(只服务"操作界面") | 已实现 M1-01~06(calibrate / validate-tree / locate 可用) |
| 剪贴板纯文本采集 | 消息流唯一来源:鼠标框选 + Ctrl+C,禁止对消息做图像识别(红线 R3) |
已实现 M2-01~06;微信 4.x 三段式格式已适配(wechat_block) |
| 状态回写去重 | 发送后立即以 assistant 写库;下轮抓屏按文本哈希去重;无前缀消息识别为主人多端发送,入库不回复 |
已实现 M3-01~07(去重/多端/回写/档案/job/回放) |
| LLM 推理 | Persona + 长期记忆 + 最近 N 轮上下文,Token 预算裁剪、输出清洗与安全过滤 | 已实现 M5 |
| 发送三重校验 | 会话 / 焦点 / 内容三校验通过才回车;失败清空重试,绝不重发 | 已实现 M6(真实发送默认关闭) |
| HITL 控制台 | 状态、dry-run 启停、真实发送锁定、日志;暂停/托盘待后续 | 已实现 M6-02 / M6-07(首版) |
| 可插拔插件 | 插件协议 + #发圈 示例(默认关闭) |
已实现 M6-04 |
| 微信适配器装配 | WeChatAdapter 实现 PlatformAdapter 并注册到 ADAPTER_REGISTRY;create_ports() 组装记忆 / 元素树 / 感知 / 执行 / 推理五端口(记忆已可用,其余按 M1/M2/M5/M6 就绪) |
已实现 M0-F-05 |
vrpa/ # 通用框架底座(可独立发布/复用)
__init__.py # 框架版本 + 契约版本 INTERFACE_VERSION
logging.py # 日志 / 审计 / trace_id / 脱敏(命名空间可配置)
errors.py # 平台无关异常族 + 退出码契约
element_tree.py # 通用 profile 元素树(严格失败语义,M0-F-05)
memory/ # 双库引擎 / SQLite MemoryStore(M0-F-05)
# HistoryStore / 尾部去重 / 档案库 / 异步 job(M3)
knowledge/ # 只读知识块 / Provider 协议 / 检索门面 / 文件热加载(M5-02)
llm/ # client / prompt 预算 / postprocess / persona / policy(M5)
plugins/ # 插件协议与故障隔离管理器(M6-04)
runtime/ # 失败自保 / 崩溃恢复快照(M6-03)
scheduling/ # 队列 / 拟人延迟 / 限流调度 / 状态机与熔断 / 编排循环(M4)
vision/ # profile schema / 多尺度匹配 / 定位缓存 / 校准核心(M1)
# 窗口后端(win32 优先)/ DPI 感知 / 输入驱动 / 校准包(M2-M6)
parsing/ # 解析策略分发器(StrategyDispatcher,M2-04)
config/ # 配置内核:env / validators / plugin / loader / schema(通用段)
ports.py # 五端口协议 + 跨层 DTO(M0-F-04)
platform.py # PlatformAdapter 协议 + AdapterRegistry(M0-F-04)
testing/ # Fakes + contracts 合规测试套件(M0-F-04)
tests/ # 618 项测试(配置/日志/异常/接口/双库/CLI/端口/契约/兼容 shim)
docs/ # 技术方案、行动清单、架构、ADR、适配器指南
scripts/quality.ps1|.bat # 一键质量门禁(ruff + mypy strict + pytest + coverage)
scripts/mouse_record.py # 真机调试:记录手动拖选鼠标轨迹(用于校准 capture.drag)
scripts/input_check.py # 真机调试:检查鼠标注入/剪贴板是否可用(无需微信)
scripts/soak_real.ps1|.bat # 真机浸泡循环(只读 dry-run,JSONL 日志 + 汇总,失败即停)
wechat_agent/ # 微信参考实现(六层模块见 §5.1)
main.py # CLI 入口 / 子命令注册 / 退出码映射
adapter.py adapters.py # WeChatAdapter(五端口装配)+ ADAPTER_REGISTRY(M0-F-05)
core/ # 配置、日志、异常 shim、接口契约(与 vrpa.ports 统一)
memory/ # 双库门面 shim + Config 薄适配(引擎已上提 vrpa.memory)
perception/ # ProfileElementTree 绑定 + 剪贴板采集 Perception(M1-M2)
brain/ act/ # 推理 Brain(M5);执行 Executor(M6,干跑已可用)
control/ plugins/ tools/ # 控制台(M6);插件(M6);calibrate / locate / validate-tree / probe / replay / run / llm-ping / send / plugin / report / soak / acceptance / db-check 工具
personas/ # 人设文件(mtime 变化自动热加载,M5-04)
data/knowledge/ # 静态只读知识(global/ 与 chats/<chat_id>/,绝不写入记忆库)
perception/ # ElementTree / 窗口 / 会话切换 / 采集 / 解析器(M1-M2)
| 层 | 组件 | 职责 | 状态 |
|---|---|---|---|
| 感知层 | pywinauto + 假 UIA 树 + pyperclip |
定位界面元素、框选并复制消息文本 | 已实现 M1-M2(ElementTree / 窗口 / 会话切换 / 采集) |
| 记忆层 | SQLite 双库 + 去重对齐 | 流水去重、长期记忆提炼与召回 | 已实现 M3(HistoryStore / 尾部对齐 / LongTermMemory / 异步 job) |
| 推理层 | DeepSeek / OpenAI 兼容 API | 上下文组装、回复生成与清洗 | 已实现 M5(客户端/预算/后处理/人设热加载/llm-ping) |
| 执行层 | pyautogui + 三重校验 |
粘贴、校验、回车、状态回写 | 已实现 M6-01(内容/目标/回读三重校验;默认 dry_run,真实发送需显式授权 + 真机验收) |
| 控制层 | CLI + Tkinter 控制台 | 运行/记忆/危险区/开发者四页签;worker 自动提炼;临时解锁发送;失败 NEXT;紧急停止 | 已实现 M6-02 CLI 与 M6-07 GUI(临时解锁灰度已通过 message_id=103;托盘/暂停待后续) |
| 扩展层 | 插件协议 + Task Scheduler | #发圈 等 RPA 指令 |
已实现 M6-04(Plugin 协议 + 故障隔离 + moments 示例);Task Scheduler 待后续 |
完整设计见 docs/技术方案-V1.0.md §4.3 / §6。本节只保留适配器作者需要遵守的要点。
- 定义:用本地 JSON 描述界面元素树("假 UIA 树"),替代微信 4.x 缺失的原生控件树;它只回答"点哪里/输到哪",不读取消息内容。
- 元素结构:相对比例坐标(0~1,相对父元素)+ 特征截图(Anchor Image,可多张按序匹配)+
role(container / region / anchor)+purpose(click / input / drag / guard / plugin)。 - 定位原理:取顶层窗口客户区 → 沿父链裁剪屏幕 → OpenCV 多尺度模板匹配(
TM_CCOEFF_NORMED)→ 比例换算绝对坐标。 - 失败语义(硬性):匹配低于阈值即
ElementNotVisible,立即中止并重试,绝不复用旧坐标、绝不用比例坐标兜底;分辨率/DPI/窗口矩形变化时ProfileMismatch,要求重新校准。 - 边界(红线 R3):假 UIA 树仅用于操作界面;消息流只准走「鼠标框选 +
Ctrl+C剪贴板」,禁止对消息做图像识别 / OCR。 - 校准:
calibrate逐元素框选 → 存锚点图 → 立即回验;validate-tree --strict现场自检(M1-04/05 已交付)。
- 触发:定时器 tick;假 UIA 树切到目标会话并定位消息区。
- 采集:框选消息区 →
Ctrl+C→ 剪贴板文本(唯一消息来源)。 - 清洗与路由:解析为结构化消息;与流水库尾部锚点对齐:
- 已入库 → 忽略(去重);
- 无前缀且不在库 → 判定为主人多端发送,入库不回复;
- 有前缀(他人)→ 合并入 FIFO 队列。
- 上下文:核心档案库召回 + 会话摘要 + 最近 N 轮流水 + Persona。
- 推理:LLM 生成回复,施加拟人化随机延迟(拟思考 / 拟打字)。
- 执行:假 UIA 树定位输入框 → 粘贴 → 三重校验 → 回车 / 点发送。
- 回写:发送成功即以
assistant写库,闭合去重与自指识别。
适合:已有微信 PC 4.x、想直接跑微信机器人的开发者。
# 1) 安装依赖(Python 3.10+,当前验证环境 3.14.7)
pip install -r requirements.txt
# 2) 配置
copy .env.example .env # 填入 DEEPSEEK_API_KEY
# 编辑 config.yaml(schema v2:platform.kind / platform.options;
# 若沿用 v1 的顶层 wechat 段,加载时会自动升级并打印迁移提示)
# 目标会话、限流、拟人延迟、dry_run 保持 true
# 3) 环境自检 + 双库初始化
python -m wechat_agent doctor # 依赖/DPI/微信窗口/写权限体检
python -m wechat_agent selftest
python -m wechat_agent db-check
# 4) 视觉校准与自检(微信 4.x)
python -m wechat_agent calibrate --warmup 10 --elements main_window,chat_title,search_box,message_area,input_box,send_button
python -m wechat_agent calibrate --append --warmup 10 --elements drag_start_area # 追加鼠标起点区(优先使用)
python -m wechat_agent calibrate --append --warmup 10 --elements bubble_avatar_area # 可选:追加气泡-头像区求补集
python -m wechat_agent validate-tree --strict # 现场自检(真实截屏)
python -m wechat_agent locate input_box --json # 打印坐标/分数/缩放
python -m wechat_agent probe --chat 目标会话 --warmup 5 --debug --dump data/probe_raw.txt # 真实采集诊断(只读,不落库不回复)
python -m wechat_agent probe --text 样例.txt --json # 离线解析诊断
python -m wechat_agent replay --scenario tests/fixtures/dedup_scenarios/01_basic_overlap.json # 去重回放
python -m wechat_agent run --simulate --scenario tests/fixtures/simulation/01_basic_flow.json # 全链路 dry-run 模拟
python -m wechat_agent run --real --chat 目标会话 --warmup 8 --settle 3 --json # 真机 dry-run(真实采集/入库/LLM,不真实发送)
python -m wechat_agent run --real --chat 目标会话 --warmup 8 --settle 3 --multi --json # 多条采集:中心起点→终点越界自动滚动(不要先回底)
python -m wechat_agent run --real --chat 目标会话 --warmup 8 --settle 3 --history --json # 历史诊断:底部中心→向上越界自动滚动(测试用,不保证入库)
python -m wechat_agent first-run # 新用户首跑向导
python -m wechat_agent memory-extract # 处理异步记忆提炼任务(LLM 筛选)
python -m wechat_agent gui # Tkinter 控制台:临时解锁 1 条,结束自动清理
scripts\soak_real.bat -Iterations 20 -IntervalSeconds 20 # 真机浸泡(管理员;不真实发送;日志在 data/soak_real/)
# run --real 输出 timing(warmup/activate/switch_session/capture/ingest/reply/ticks/total 毫秒)
python -m wechat_agent llm-ping # LLM 连通性(需 DEEPSEEK_API_KEY)
python -m wechat_agent send --chat 张三 --text 你好 # 控制台发送(默认 dry_run)
python -m wechat_agent report # 运行报告(只读)
python -m wechat_agent soak --iterations 5 # 浸泡测试(simulate,纯 Fake)
python -m wechat_agent acceptance # 生成真机验收清单
# 4.1) 分享/复用校准包(可选)
python -m wechat_agent calibrate --export ./share/wechat-1280x720@1 # 导出
python -m wechat_agent calibrate --import ./share/wechat-1280x720@1 # 导入(目标已存在需 --force)
# 或直接用外部路径(无需复制):config.yaml -> uia_tree.profile_path / anchors_root 填绝对路径
# 详见 docs/calibration-package.md
# 5) 真机联调说明
python -m wechat_agent run --simulate --scenario <场景.json> # Fake 全链路(不触发真实键鼠)
# 真实 dry-run 已可用:采集→解析→去重入库→LLM→dry_run 三重校验→回写
# 真实发送:send --real(默认关闭,需 dry_run=false + safety.allow_real_send=true + --i-understand-risk)首次真实发送前必须完成:M1 校准通过 + M2 采集验收 + M6 三重校验;
dry_run: true期间不会发出任何消息。
已完成验证
- 环境体检
doctor:Python/依赖/分辨率/微信窗口/写权限全部 PASS(微信未启动时窗口项为 WARN); - 视觉校准:
calibrate --warmup 10交互框选 6 个元素;main_window/message_area为容器静态矩形(窗口位置必须固定),其余 4 个控件走锚点匹配; validate-tree --strict全绿;真实probe --chat 会话成功采集并解析微信 4.x 三段式文本(发送者 / 日期时间 / 内容)。
微信 4.x / 本机适配要点
- 进程名为
Weixin.exe(配置已加入platform.options.process_names);窗口枚举 win32 优先、UIA 兜底,规避 UIA 枚举为空/阻塞; - 启用 Per-Monitor DPI 感知,截图与鼠标坐标统一为物理像素;
- 采集剪贴板加 防伪哨兵:
Ctrl+C未生效时直接报错,不会把终端/旧剪贴板内容当消息; - 部分 Windows 环境下
pyautogui需要管理员 PowerShell 才能注入鼠标;可用scripts/input_check.py自测; - 微信窗口位置/大小/DPI 必须与校准时一致(容器为静态坐标)。
- 身份映射(可选):
data/identity.toml(示例identity.example.toml,手写 TOML、支持注释)。有备注时会话名=备注、昵称写入nicknames用于切会话校验;无备注时会话名=昵称,此时可不配映射,但昵称变更会改变会话主键,建议常用联系人设置备注。 - 机器人自身身份:在
data/identity.toml增加[self] nicknames = ["王"]。这样即使采集到“王”前缀的消息,也会按assistant入库、不排队回复;Prompt 会明确“你是王、对方是三”,避免把自己当第三方。
当前边界
- 消息流只支持文本(含 Unicode emoji 字符);原生表情包/图片/语音/文件/引用回复不在 V1.0 范围(
text_only,红线 R3 禁止图像识别); - 真实 dry-run 已接为命令:
run --real --chat 会话 --warmup 8 --settle 3(真实采集/入库/LLM,不真实发送;单次--ticks 1只处理 1 条回复,队列剩余属正常);切会话每个操作间隔由capture.switch_delay(默认 0.5s)控制;--multi多条模式会先滚轮向下 +PageDown×5 +Ctrl+End回底,并按message_area - (message_area ∩ bubble_avatar_area)求起点区后向下越界采集;采集后会对比“解析最新时间 vs 库内最新入向时间”,窗口陈旧则回底重采最多 3 次;终点按住停留 3/5 秒随机(普通模式 2~3s),输出capture_info(planned_attempts/attempt_used/start_point/end_point);首次失败会回底并换轨迹重试一次;去重允许跳过库尾部不在本次窗口内的消息(如 dry-run 未发送的 out); - 人手化拖拽/停留为 V1.0 启发式(时长、抖动、泊松停留),仅作节奏过渡;V1.2 计划用授权采样学习真人节奏(不记录消息内容)。
- 运行:单轮/多条/历史 dry-run、停止、日志;
- 记忆:
worker自动开关、间隔、每次上限、立即提炼一次;- worker 只跑
memory-extract,不发送微信; - 主任务运行时自动让路;默认关闭;
- worker 只跑
- 危险区(红):真实发送临时解锁、确认短语、发送内容;
- 主配置双锁始终保留,临时配置结束自动删除;
- 开发者模式:
first-run/doctor/validate-tree/report/memory-extract;- 打开 config/identity/日志;
- 只读展示
history_turns、memory_top_k、allowlist; - 不提供绕过
dry_run、allowlist 或管理员检查的按钮。
- 流水库(chat_history):全量逐字保存,只做监控/回溯,不直接全量注入 LLM;
- 核心档案库(memory):由异步
memory_extractjob 提炼,只保留情绪、约定、偏好、关系变化等长期价值内容; - 提炼不使用规则硬提取;
LLMMemorySelector用“像人一样回忆”的 Prompt 调 LLM,输出 JSON 候选; - 主循环只负责把新增消息入队(
memory_queued),不阻塞回复; - 单独运行
python -m wechat_agent memory-extract消费任务; - M5 Prompt 只注入:
- 召回的核心记忆(top_k);
- 最近
llm.history_turns条流水(按status='ok'过滤); - 绝不注入全量历史。
适合:想复用 VRPA 底座做新平台机器人的开发者。不要改
vrpa底座,只写适配器。
- 阅读 docs/writing-an-adapter.md(适配器契约、能力矩阵、校准规范、常见坑);
- 实现 5 个端口(Ports):
ElementTree/Perception/Executor/Brain/MemoryStore; - 提供平台配置校验器(
PlatformAdapter.config_schema())与元素树 profile 规范; - 提供消息解析策略包(输入=采集通道原始文本,输出=
IncomingMessage列表,附 ≥15 份真实样例); - 实现
PlatformAdapter并注册到AdapterRegistry; - 跑合规测试套件
python -m vrpa.testing.contracts --adapter <模块>:<类> --json(M0-F-04 已交付)与scripts\quality.bat,全绿即接入成功。
参考实现:本仓库微信适配器即样例——
python -m vrpa.testing.contracts --adapter wechat_agent.adapter:WeChatAdapter(M0-F-05 起 10/10 全绿),可对照wechat_agent/adapter.py+wechat_agent/adapters.py实现。
- A 离线浸泡:100 + 500 轮,
failures=0; - B 真机 dry-run:20/20 轮,
captured=4 / duplicates=4 / failures=0,无真实发送; - C memory worker:100 个合成 task,
processed=100,失败重试通过; - D GUI worker:启动/停止正常,停止后无残留;
- E 真实发送:临时解锁
live 1 条,sent_count=1,真实回复message_id=117,failures=0;- 临时配置自动删除;
- 主配置保持
dry_run=true / allow_real_send=false。
- 操作系统:Windows 10 / 11(RPA 依赖 Win32 窗口与键鼠模拟)
- Python:3.10+(当前验证:3.14.7;3.11/3.12 为兼容性推荐)
- 微信:PC 版 4.x(假 UIA 树按该版本校准)
- 核心依赖:
pyautogui/pywinauto/pyperclip(RPA)、opencv-python+numpy+Pillow(锚点匹配)、openai(LLM)、PyYAML(配置)、pytest(测试) - 权限:dry-run 普通用户即可;真实发送需要管理员 PowerShell(否则合成输入可能被系统丢弃)
.\scripts\quality.bat # 一键:ruff check → ruff format → mypy strict → pytest+coverage
python -m pytest tests -q # 单元测试(当前 618 passed)
python -m mypy # vrpa 框架包 strict| 门禁 | 工具 | 当前状态 |
|---|---|---|
| 静态检查 | ruff(E/F/I/UP/B/SIM) | 全绿 |
| 格式 | ruff format | 全绿 |
| 类型 | mypy strict(vrpa) |
0 error |
| 测试 | pytest | 618 passed |
| 覆盖率 | pytest-cov | 85.39%(门禁 ≥85%) |
| 一键 | scripts\quality.bat |
QUALITY GATE: PASS |
| 文档 | 内容 | 状态 |
|---|---|---|
| README.md | 分层定位、能力矩阵、受众导航、微信实现说明、红线 | 本文件 |
| docs/architecture.md | 目标架构:双包分层(vrpa + wechat_agent)、依赖规则、M0-F 迁移路线 |
Accepted |
| docs/writing-an-adapter.md | VRPA 适配器指南:QQ / 钉钉等平台接入步骤 | 定稿 v1.0(M0-F-06) |
| docs/calibration-package.md | 校准包分享指南:profile/anchors 包结构、导出/导入/外部路径 | 新增(M1) |
| docs/ADR/ | ADR-0001 框架分层 / 0002 配置 schema v2 / 0003 接口稳定与适配器契约 | Accepted |
| docs/技术方案-V1.0.md | 详细技术设计:假 UIA 树算法、双库、去重、队列/延迟、控制台、异常、测试策略 | M0 框架底座已完成 |
| docs/行动清单-V1.0.md | 施工图:M0~M6 全量任务(任务描述 / 输入输出 / DoD)、阶段门禁 | M0 框架底座已完成 |
| CHANGELOG.md | 版本变更记录(Keep a Changelog) | 维护中 |
| LICENSE | MIT License(版权人:ergjk) | 生效 |
- 当前只做 V1.0 核心架构;V1.1(表情/语音/撤回)与 V1.2(行为克隆/生图)不得出现具体实现代码;
- 最多只允许在
vrpa的接口文件中保留空 Protocol,不实现、不接线、不加测试。
- 版本控制、分支管理与推送由 Agent 执行,主控官监督与验收;
- 每次里程碑 DoD 通过后原子提交并推送,提交信息可回溯;
- 破坏性操作(force push / 历史重写 / 删除远端分支)必须获得主控官明确指令。
- 假 UIA 树只服务"操作界面";消息流只准走「鼠标框选 +
Ctrl+C剪贴板」; - 禁止用图像识别 / OCR / 模板匹配读取、判断、推断消息内容;
- 由
tests/test_boundary.py(M2)与selftest --redlines(M0-09)在 DoD 中强制。
- 独占限制:RPA 运行期间抢占鼠标键盘;建议副屏/虚拟机隔离运行。当前首版 GUI 只有停止/紧急停止,暂停与系统托盘待后续,运行中不要操作 GUI。
- 分辨率 / 主题依赖:元素定位依赖锚点图;窗口大小、DPI 缩放、深色/浅色主题变化后需重新校准。校准失效时系统中止动作而非猜测(表现为"暂时不回复")。
- 富文本局限:只处理纯文本,不解析图片 / 语音 / 视频 / 复杂富文本。
- 平台突变:客户端大版本更新可能导致 UI 不可匹配,需重录锚点图或升级适配器。
- 账号风险:采用零注入 + 低频拟人化降低风险,但第三方自动化仍有平台规则风险;仅用于个人合规场景,勿用于营销群发、自动加好友。
- 平台无关性:以上局限中,1/2/4 属于通用 RPA 约束;3/5 中的平台规则部分由各适配器自行声明。
以下功能在 V1.0 阶段仅保留空接口,需主控官立项后再开发。
| 类别 | V1.0 现状(启发式) | V1.2 目标(学习型) |
|---|---|---|
| 鼠标操控 | 固定 0.9s / 24 步拖拽、±6px 抖动、0.15s 按下停顿、终点 0.3/0.6/0.9 泊松停留 | 从授权轨迹学习路径曲率、速度、停顿分布;按人设/场景/对象自适应 |
| 字符串输入 | 剪贴板 + Ctrl+V + 回车;会话切换每步 0.5s |
学习输入节奏、改写频率、粘贴/键入混合策略;仍以剪贴板为唯一消息来源 |
| 路径与时间 | switch_delay、settle、warmup、copy_wait 等固定/区间参数 |
用 UI 状态反馈 + 时序模型动态决定等待,去除固定秒数 |
| 人设 | Prompt 人设文本 + 固定回复后处理 | 人设参与操作策略(回复长度、打字节奏、表情使用)与口癖/常用语学习 |
不变的安全边界(V1.2 也不得替换):消息流只走「框选 + Ctrl+C」剪贴板(红线 R3)、dry-run 三重校验、去重与审计、限流/熔断。
- V1.1:动画表情(本地表情截图库 + 情绪标签匹配)、语音/TTS(虚拟声卡 + RPA 长按)、消息撤回与情绪模拟(二次审查 + 右键菜单 RPA)、开放插件生态(
#红包/#拍一拍)。 - V1.2:学习型操作策略(鼠标/输入路径与时序,由 V1.0 启发式取代)、行为克隆(回复节奏 / 口癖 / 常用语学习)、生图等多模态扩展。
项目治理:SECURITY.md(安全边界与私密报告) · 真实环境压力测试方案 · ADR 0005 远程控制边界 · V1.0 复盘 · CHANGELOG.md(变更记录) · CONTRIBUTING.md(开发与提交规范) · .github/labels.yml(标签定义)
| 阶段 | 状态 |
|---|---|
| M0 框架底座(含 M0-07 doctor) | ✅ 已完成 |
| M1 假 UIA 树与视觉定位 | ✅ 已完成 |
| M2 框选 + Ctrl+C 采集与解析 | ✅ 已完成(微信 4.x wechat_block 已适配) |
| M3 去重对齐与记忆提炼 | ✅ 已完成(新增跳过窗口外尾部消息) |
| M4 编排调度与 dry-run 全链路 | ✅ 已完成 |
| M5 LLM 推理层与 Prompt 预算 | ✅ 已完成 |
| M6 执行层/控制台/插件/报告/验收清单 | ✅ 已完成(真实发送默认关闭,灰度入口可用) |
| 真机联调(当前) | ✅ 单轮 dry-run、受控 live(max-sends 1)、GUI 首版均已通过 |
| 切会话提速(验证采集合并/去掉重复采集) | ✅ 已关闭重复采集校验 |
| 多回复/队列消化(ticks 连续运行) | ✅ ticks 可连续消化;未提供独立 --max-replies 参数 |
| 真实浸泡 + 真机验收清单逐项确认 | ✅ 单轮 dry-run、R5 3/3 受控发送;R6 2h 长时浸泡未跑(可选) |
| 群聊身份映射与联调 | ⛔ 不在 V1.0 范围(V1.1+) |
| GUI 控制台 | ✅ Tkinter 首版;系统托盘/暂停恢复待后续 |
真实发送入口(send --real,默认关闭) |
✅ 两条灰度已通过:message_id=86(手动聚焦)、87(自动直接粘贴 + 静态输入区);默认仍关闭 |
受控真实发送循环(run --live,默认关闭) |
✅ 首轮实跑通过:--max-sends 1、sent_count=1、message_id=100;失败即停,默认仍关闭 |
| GUI 临时解锁发送 | ✅ 已通过:live 1 条、message_id=103;结束自动删除临时配置并弹窗确认收到 |
| A–E 压力测试 | ✅ A 500 轮离线 / B 20 轮真机 dry-run / C 100 memory tasks / D GUI worker 启停 / E 真实发送 1 条 / R5 真实发送 3/3(message_id=124/125/126) |
| V1.1 / V1.2 | ⬜ 仅规划 |
当前位置:V1.0 本地收口完成;真实发送默认关闭,仅保留受控灰度入口。R2-5 旧窗口与 R2-3 无前缀真机样本仍有限;R6 长时浸泡、群聊归档、GUI 托盘/暂停恢复不在 V1.0 范围。
- 本项目的大量代码与文档由大语言模型(如 DeepSeek 等)辅助生成,并经主控官审阅、测试与验收后提交。
- 本项目遵循 MIT 开源协议(详见 LICENSE 文件);AI 生成内容不代表任何平台(包括但不限于微信、QQ、钉钉、飞书等)的官方立场,也不构成任何平台授权或背书。
- 使用本项目进行自动化操作时,请自行遵守目标平台的服务条款与当地法律法规;因使用本项目产生的风险与责任由使用者自行承担。
MIT License © 2026 ergjk