Skip to content

About

Windows 微信回复助手(非官方修改版):本地离线 OCR 读屏 + 模型起草候选回复 + 一键填入微信输入框,可选自动发送。不 hook、不注入、不读微信数据库。

Topics

Resources

Stars

10 stars

Watchers

0 watching

Forks

Latest commit

 

History

9 Commits

Folders and files

Repository files navigation

jev-chat-windows(非官方修改版)

Windows 上的微信助手悬浮窗:截自己屏幕上自己的微信窗口 → 本地离线 OCR 读对话 → 生成候选回复 → 一键填入输入框(可选自动发送)。 非官方修改版,基于 jev-chat-windows 二次开发。

An unofficial modified fork of jev-chat-windows: a Windows overlay that reads your own WeChat window with local OCR and drafts replies for you.


⚠️ 先说清楚三件事

一、这是第三方非官方修改版。

  • 本仓库不是 jev-chat 的官方发行版,与原作者无隶属关系, 也未获得原作者背书。上游明确要求:不得用「jev-chat-windows」「Jev 聊天助手」「jev-chat」名称或 chatjevs.com 域名暗示由原作者出品或背书——所以这里第一句就写明白。
  • 原始项目:
  • 本仓库在上游基础上做了修改与增补,改了什么见 NOTICE 与 docs/CHANGELOG.md。 想要上游原版请直接去 github.com/jev-chat/jev-chat-windows。

二、免责声明。

  • 仅供个人学习与自用。 请遵守微信的用户协议与当地法律法规,不要用它做群发、营销、骚扰或 任何形式的自动化滥用。用坏了、被封号、发错消息,都由使用者自己承担。
  • 自动发送是不可撤回的:微信没有撤回接口,本工具也不碰。最坏的情况是它替你回了一句你不想发的话, 而对方已经看到了。想彻底避免就保持默认关——出厂状态就是关的,装了它也只把文字填进输入框。
  • 本项目按 MIT 协议「按原样」提供,不附带任何形式的担保。
  • 本工具不逆向微信协议、不 hook 或注入微信进程、不读微信数据库、不解密聊天记录。 它只截自己屏幕上、自己本来就有权查看的微信窗口,然后做本地离线 OCR。

三、发布包里的界面组件是 GPLv3。

Windows 发布包(PyInstaller 打的 zip)打包了 PySide6-Fluent-Widgets,该组件是 GPLv3: 非商用免费,商用需要另外购买商业授权。因此发布包整体受 GPLv3 约束;只从源码运行不受这条影响 (源码本身仍是 MIT)。详见 NOTICE。


30 秒看懂

一个常驻桌面、置顶可拖动的小悬浮窗。它做的事只有三件:

  1. 看:截取你自己的微信窗口,本地离线 OCR 认出当前会话名和消息区里的对话(谁说的、说了什么)。
  2. 想:对方来了新消息,就把最近若干条对话发给模型,生成 1~3 条候选回复。
  3. 填:你点一下「填入微信」,文字进微信输入框,光标留在那儿——发送你自己按。

装完不改任何设置,它就是上面这个样子:只给建议,绝不替你发。想让它更进一步,按需开:

你想要 打开什么 一句话
让它自己回消息 自动发送 单聊 / 群里 @我 / 群里不@我也回,三条路分别开关,默认全关
记住这个人是谁 知识库 手写笔记 + 给会话建联系人,分析时自动带上
把聊天存下来 聊天记录导出 按 会话名/日期.csv 落在本机
同时盯好几个会话 多独立窗口 在微信里把几个会话开成独立窗口,程序自动发现

下面每一节都从「怎么开」讲起。

快速开始

方式一:下载打包好的版本(推荐)

普通使用直接下载,不用装 Python、不用碰源码。

👉 下载最新版

  1. 在 Releases 页下载 jev-chat-windows-vX.Y.Z.zip
  2. 解压到一个固定目录(整个文件夹一起,exe 要用旁边那堆文件)
  3. 双击 jev-chat-windows.exe

exe 没签名,SmartScreen 会拦一下:「更多信息」→「仍要运行」。 介意就往下看自己打包,自己打的更踏实。

方式二:从源码运行(开发者)

git clone https://github.com/caizili999/jev-chat-windows.git
cd jev-chat-windows
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt
python main.py

PyCharm / VS Code 里直接 Run main.py 也行。

环境要求

下载 exe 的只看前三条;Python 只有源码运行 / 自己打包才需要。

  • Windows 10 1903+ 或 Windows 11(Windows Graphics Capture 的最低要求)
  • 微信 Windows 4.x(Weixin.exe)
  • 一个起草服务的 API key:DeepSeek(推荐,国内直连)/ OpenRouter / 任意 OpenAI 兼容地址,三选一。判断那一步默认也用它
  • Python 3.10+(自己打包的话)
  • OpenRouter API key(选填):填了才有校准过的胜出概率(完整模式);不填走自判模式, 照样有摘要和推荐排序

Win10 上 WGC 会在微信窗口外画一圈黄框,系统不给关;Win11 才能关掉。 嫌碍眼就把标题栏的采集开关拨到「已暂停」,黄框立刻消失。

第一次启动(3 步)

  1. 设置页第一张卡「起草服务」:选「起草模型来源」并填对应的 key。
    • 推荐国内用户选 DeepSeek 直连,最省事也最快。
    • 选 OpenRouter 就要填 OpenRouter key(跟下面第二张卡共用同一把)。
    • 选「自定义」就填基础地址 + 模型名 + 自己那把 key。
  2. 第二张卡「判断与排序」→「判断引擎」,三档选一个:
    • OpenRouter(有胜出概率):走 Jev 内核(typesafe/jev-1.13,只在 OpenRouter 上有)。 这是唯一会给校准概率的一档。
    • 用起草模型判断(默认,无概率):拿你刚配好的起草模型再做一次调用,给摘要、紧张度和推荐顺序。 两个地址留空 = 跟起草完全一样,不用额外配任何东西。
    • 不判断:只要候选回复,最省钱。
  3. 选「你们的关系」(恋人 / 朋友 / 同事 / 家人 / 自定义),保存。可以用了。

保存时如果还缺东西,设置页会直接说清缺哪一格,但不会拦着不让你存——已经填好的地址、模型、密钥照旧写进去。

功能一览

「默认」那一列就是装完不动任何设置时的状态。想用哪个,照着「怎么开」那列做就行。

功能 默认 说明 怎么开
回复建议(核心) 开 截微信窗口 → 本地 OCR → 生成 1~3 条候选,点一下填进输入框 配好起草服务就有
跟着微信切会话 开 你在微信里点开哪个会话,悬浮窗就跟到哪个;记录、上下文、候选按会话分开存 自动
群聊认发言人 开 群里每条消息前面的发言人名一起喂给模型,它知道哪句是谁说的 自动
判断与排序 用起草模型 给「建议动作 / 可能意图 / 对方可能需要 / 紧张度」,并排序;OpenRouter 档还有校准过的胜出概率 设置页「判断引擎」;标题栏也有个一键开关
群聊指定回复对象 关 群聊里可以选回复给谁,三条候选都按 TA 写,填入时可带「@名字 」前缀 设置页「回复偏好」
自动发送 关 生成完等 N 秒自动替你按发送键,N 秒内可点「取消发送」 设置页「自动发送」,三条路分别开关
焦点护栏 自动 自动发送前先看你多久没碰键鼠;8 秒内碰过就不发,不抢你的焦点 跟着自动发送走,不用配
一次只发一个 自动 多个会话同时来消息时排队发,不并行(并行会互相抢窗口) 跟着自动发送走,不用配
按会话授权(多独立窗口) 关 每个独立窗口单独允许/不允许自动回复;新窗口默认不允许 首页会话框旁边那个「允许自动回复」开关
多独立窗口 自动发现 在微信里把几个会话开成独立窗口,程序自动发现、各自识别、各自的标签页 在微信里右键会话 →「在独立窗口中打开」
聊天记录导出 关 把看过的对话按 会话名/日期.csv 落在本机,区分「对方 / 我 / 程序」 设置页「保存聊天记录到本地」
知识库:笔记 + 联系人 可用(空) 手写笔记、给会话建联系人(关系/备注/别名),分析时命中就带上 设置页「知识库」→「知识库与联系人」
知识库:聊天历史 关 把聊天按会话存进 知识库/logs/,分析时回注最近 N 条 设置页「记录聊天历史(只存本机)」
起草模型来源 OpenRouter OpenRouter / DeepSeek 直连 / 自定义(任意 OpenAI 兼容地址) 设置页「起草服务」
说话风格 / 参考上下文 空 / 10 条 一句话描述自己的口吻;上下文 3~30 条可调 设置页「回复偏好」
生成几条候选 3 1~3。调小能真变快(模型输出短了、也不用在几个版本间权衡) 设置页「起草服务」
失败自动重试 再试 2 次 5xx / 429 / 连接被掐会重试;4xx 和超时会超时不重试 设置页「起草服务」
采集开关 开 标题栏一拨就停,WGC 会话一起停掉(Win10 的黄框跟着消失),已有候选照样能用 标题栏右上角
实时聊天记录面板 — 底部展开,看 OCR 到底读出了什么;接口报错的详情也打在这里 底部按钮
新版本提示 开 启动时查一次 GitHub 最新版本号 设置页可关
响应式悬浮窗 — 置顶、可拖可缩,最小 320×360,窄于 400 自动进紧凑模式 自动

日常怎么用

只想要候选回复(默认状态)

  • 微信开着、别最小化(用别的窗口盖住没事),把要聊的会话点开
  • 对方来一条消息 → 悬浮窗几秒后给候选回复;开了判断还会带判断摘要和推荐顺序
  • 嫌慢就拨标题栏那个「判断」开关关掉判断(只给候选),或者去设置里把「生成几条候选」调成 1
  • 点「填入微信」→ 文字进微信输入框 → 你自己看一眼、改一改、按发送。没开自动发送时程序不碰发送键
  • 你在微信里切到哪个会话,悬浮窗就跟到哪个;群聊会带上发言人名
  • 暂时不想让它读微信:标题栏开关拨到「已暂停」

想让它记住人和事 → 知识库与联系人(可选)

想同时盯好几个会话 → 多独立窗口(可选)

国内用户建议:起草切到 DeepSeek 直连

起草候选默认走 OpenRouter,但从国内过去要等好几秒、还时不时抽风。DeepSeek 官方 API (api.deepseek.com)国内直连,起草基本就是一次 HTTP 请求的时间,体感差好几倍:

  1. 去 platform.deepseek.com 申请一个 key(很便宜,起草一次几厘钱)
  2. 设置页「起草服务」→「起草模型来源」选 DeepSeek 直连,填 DeepSeek key,保存

花多少钱

只有对方来新消息才调模型:完整模式是一次起草 + 一次 Jev 判断;自判模式也是一次起草 + 一次判断, 只是判断用的是起草那把 key;选「不判断」就只有起草那一次。十分钟没人说话就是十分钟零调用。 思考模式默认关,别开——起草三句话用不上,慢好几倍还贵。

自动发送(可选,默认关)

上面那句「发送由你确认」是出厂状态。如果你就是想让它替你发,设置页第三张卡「自动发送」可以打开。 这一节把边界写清楚——开了之后程序手里就有你微信的发送键,值得先读完再决定。

怎么开

  1. 设置页 →「自动发送」卡 → 三个独立开关,默认都关:
    • 「单聊里对方直接找我」:对方给你发消息 → 自动回。
    • 「群里 @我」:群里有人 @ 你 → 自动回。这个要填 「我在群里的昵称」——群昵称跟微信昵称 经常不一样,程序只认你填的这一个,没填就不发(宁可漏认,不可错认)。
    • 「群里不@我也回」:群里任何新消息都回,包括别人之间的对话。误判面最大, 所以它不认 @、也不需要群昵称;开了它,@你的消息当然也回,不用再开上面那个。
  2. 「生成完等几秒再发」默认 5 秒,范围 0~30。三条路共用这一个值,这几秒是给你的后悔时间。
  3. 「群里不@我时先安静几秒」默认 8 秒,只对第三个开关生效:群里连着聊的时候它一直往后等, 只在话题停顿处动手——不然就成「群里每有人说话都插一句」的刷屏机器人。填 0 = 不等安静。
  4. 「按哪个键发送」默认 Enter(微信默认)。必须跟你微信设置里的发送键一致。
  5. 保存。

开着的时候长什么样

每次自动发送前,候选卡片上方会出现一条橙色倒计时条:「5 秒后自动发送」+ 一颗「取消发送」按钮。 点一下就能拦下,回复留在候选里不会消失。如果你为了提速关掉判断,倒计时条、页脚和设置页会明确写 「判断关着,发第一条候选」——它仍然会发,但不会假装那是判断过的推荐。

它不会替你做这些(代码里逐条拦死的)

情况 为什么
程序刚启动时的第一批消息 你不在的时候微信攒了一批,开程序就替你回一条几小时前的消息太危险。从第二批起才生效
你在手动看别的会话 / 浏览旧会话 界面正显示的不是微信当前开着的会话 → 发出去就串会话了
输入框里已经有内容 你可能正在打字,或者上一条回复还没删。宁可漏发这一次,也不覆盖你正在写的东西
正在生成新的回复 / 微信切了会话 这条回复对应不上当前状态了
这一档没有判断结果(选了「不判断」,或判断那一步失败) 发第一条候选,倒计时条会写明「没有判断结果,直接发第一条」,不假装它是推荐回复
群里这条没 @ 你 只认「@你填的昵称」,裸昵称不算(会被「他说我今天……」这类句子误伤)
你 8 秒内碰过键盘或鼠标(多独立窗口) fill() 要抢前台 + 挪鼠标,会打断你正在打的字。走开一会儿它才发
那个独立窗口关掉了 / 换成别的会话了(多独立窗口) 发送前重读窗口标题跟生成候选时的会话名比对——这是「往错群发消息」的唯一防线
这个独立窗口还没授权(多独立窗口) 新窗口默认不允许。在首页那个「允许自动回复」开关上打开它

任何一条没满足,都不会静默跳过——状态栏和日志会写清是哪个条件拦下的,你能一眼看出是配置没对还是设计如此。

多独立窗口下多出来的三条

同时开着几个独立窗口时,自动发送还多三道闸(只对独立窗口生效,单窗口的老用户完全不受影响):

  1. 按会话授权:每个窗口单独允许/不允许,新窗口默认不允许。为什么:独立窗口一直在屏幕上, 「群里不@我也回」在单窗口时代靠「窗口被盖住 / 你没在看」天然有个刹车,独立窗口把这层刹车拿掉了。
  2. 窗口还在 + 标题没变:发送前重新枚举句柄、重读窗口标题,跟生成候选时那个会话名对一遍。
  3. 你不在电脑前:8 秒内碰过键鼠就不发(见上面那张表)。

授权只是一层、全局那三个开关是另一层,两层都开才会真发。只拨了授权那一层时日志会提醒你。

误判的后果,以及怎么自查

自动发送是不可撤回的(微信没有撤回接口,本工具也不碰)。所以:

  • 程序发完 2.5 秒会回看一眼输入框。如果里面还有内容,说明发送键跟你微信设置里的不是同一个—— 文字没发出去,还堆在输入框里。状态栏会直接告诉你,看到就立刻去对一下微信 「设置 → 通用 → 快捷键」。这是唯一能自查「发送键填错」的手段。
  • 判不准一律往「有字」的方向判(宁可漏发,不可乱发)——所以偶尔会看到「输入框里已经有内容了」这种 其实框是空的情况。这是刻意的。
  • 群里靠文本匹配认 @,OCR 漏一个字就认不到,会漏发。@ 的识别只在「@昵称」连在一起时成立。

聊天记录导出(可选,默认关)

设置页第一张卡里有个 「保存聊天记录到本地」 开关(默认关)。打开后,程序看过的对话会写进 程序目录下的 聊天记录/,按 会话名/日期.csv 分层:

聊天记录/
  示例群/
    2026-09-24.csv

每个 CSV 四列:

时间 方向 发送者 内容
2026-09-24 14:15 对方 张三 今天天气不错
2026-09-24 14:16 我 那我们去哪
2026-09-24 14:16 程序 去爬香山

「方向」分 对方 / 我 / 程序——程序替你自动发出去的那条会单独标出来,事后翻记录才分得清 哪句是你自己打的、哪句是它替你发的。

细节:

  • 时间是聊天时间,不是「你看到它的时间」:从微信里那行灰色时间戳认出来的 (14:15 / 昨天 14:15 / 星期二 14:15 / 9月20日 14:15),认不出一律留空并继承上一条已知时间—— 宁可留空也不猜,猜错会把消息归到错的日期里。一条都认不到才退回当前时间,并会在聊天记录面板里说破。
  • 去重是「宁可漏掉,不可写错」:最近 50 条内查重,连 OCR 抖动认错一个字也算同一条; 程序重启后会读回已写的文件接着查,不会把整屏重报的旧消息写第二遍。窗口外的同内容照记—— 同一个人两次说「好的」是两条真实消息,不该被吞。
  • 切换会话就以进入那个会话的时刻为新起点;切进去时屏幕上已经显示的那几条会一起记下来 (程序分不出它们是不是刚到的)。
  • 攒批落盘:攒够 20 条或满 5 秒写一次,退出时再写一次,所以被强杀最多丢最后几秒。
  • 写盘失败只在「聊天记录」面板报一行,绝不影响采集、生成和自动发送。
  • 会话名会转义成合法目录名(Windows 非法字符、CON 这类保留名、超长名字带哈希防撞名)。
  • 只在本机写文件,不联网。 关掉开关时会先把攒下的那批写完再停。那个目录已在 .gitignore 里, 你自己的对话内容不会被误提交。

知识库与联系人(可选)

上游 Jarvis 的那套「记住这个人是谁、记住这些事实」。Windows 这边整块都是可选的: 什么都不建就跟以前完全一样。

下面这段是它是什么。想知道该怎么用(每个字段建议填什么、常见踩坑、完整示例), 看 docs/USAGE_KB.md。

设置页「知识库」那张卡里有两个入口:「知识库与联系人」打开管理窗口,「清空知识库与历史」一次删干净。

笔记(管理窗口第一个页签)

  • 标题 + 正文 + 标签,另有「启用」和「常驻」两个开关。
  • 命中规则:任一标签或标题出现在会话标题里、或出现在最近 6 条消息里,这条笔记就带上。 最多带 5 条命中的,越新的越优先。 ⚠️ 正文不参与匹配——只有标签和标题参与。所以「聊天里真会出现的词」要写进标签, 否则写了等于没写(正文只是给模型看的内容)。
  • 常驻的笔记不看关键词,每次都带上——适合「我自己的固定情况」这类前提。
  • 「从文本导入」可以一次贴一段:按空行分段,每段第一行当标题、其余当正文。

联系人(管理窗口第二个页签)

  • 名字 + 别名(每行一个)+ 关系 + 备注。
  • 命中规则:会话标题等于名字或任一别名即算命中,忽略大小写、忽略群人数后缀、忽略零宽字符。 所以 测试群(12)、测试群(12)、 测试群 会认成同一个人。别名可以填别的写法或群名。
  • 关系填了会作为「关系:…」带进分析,跟设置页那个全局「关系背景」同时存在(两行都会出现在 提示词里,谁也不覆盖谁——所以别在联系人里填跟全局冲突的关系词);备注当作关于这个人的事实。
  • 联系人只由你建立,程序不会自动创建。想快速建一个:在回复建议页点「存为联系人」, 把界面上正看着的会话一键存下来(已存在就并入)。
  • 每个联系人可以单独「清空此人历史」,删联系人的话历史一起删。
  • 管理窗口第二个页签顶上还会有一栏 「当前看到的窗口」(只在开着独立窗口时出现): 把窗口标题配到联系人。见多独立窗口那一节。

聊天历史(默认关)

  • 设置页「记录聊天历史(只存本机)」打开后,才会把聊天按会话存进 知识库/logs/,并在分析时回注 最近 N 条(N 在下面那格填,0~100,默认 30)。
  • 0 是合法值:只记录、不注入。这种组合界面会明确提示一句,不然两个控件各自看都正常, 凑一起才「记了却永远不带」。
  • 回注时会把已经显示在屏幕上的那几条去掉——它们本来就在上下文里,重复带一份只是白占预算。 所以如果一个会话的历史全都还显示在你当前屏幕上,这一轮就一条都不会带(这是正常的,不是坏了; 把聊天往上滚一屏,或者等新消息把旧的顶出去,历史就会开始生效)。
  • 首页那行报的是这一轮实际注入了几条,不是日志里存了多少。它会随着聊天慢慢涨, 涨到上面填的那个数(默认 30)就封顶不再涨——那是注入上限,不是又卡住了。日志本身最多留 300 条。
  • 每个会话只留最近 300 条。

预算与边界

  • 笔记 + 历史加起来不超过 1500 字。超了先丢最旧的历史,再整条丢笔记(绝不截半条); 常驻笔记不参与裁剪。
  • 全是精确匹配 + 纯子串,没有 embedding、没有打分,不出网、不调模型。
  • 内容只存在程序目录下的 知识库/,跟 config.json 同级——整个文件夹拷走知识库也跟着走。 那个目录在 .gitignore 里。
  • 设置页那张卡里还有个低调的「自检」按钮:用临时数据跑一遍匹配、命中和去重,跑完把自己造的东西删掉。 它是排查用的,不是功能。
  • 首页状态栏下面那行会写「本轮已带上:N 条笔记、M 条历史」(带上了联系人关系/备注时会再补一句「、联系人背景」)—— 开了知识库之后,这是唯一能当场确认「真的用上了」的地方。什么都没识别到时写「本轮未使用知识库」; 识别到联系人了、但这一轮确实没有可补的内容(比如那些记录全都还显示在你当前屏幕上,见上面「聊天历史」那段), 写的是「本轮已识别到联系人,但没有可补的内容」——不会说成「未使用」,免得你以为功能坏了。

出网范围会变:知识库命中时,联系人关系 / 备注 / 笔记正文 / 历史会随对话一起发给模型—— 它们就在 prompt 里(详见隐私与边界)。所以笔记里别写密钥、密码、身份证号这类东西。

多独立窗口(可选)

想同时盯好几个群 / 好几个人,用微信自带的「独立聊天窗口」。

怎么开

不需要任何设置,只要在微信里动手:

  1. 微信版本 4.0.5 或更高
  2. 在会话列表里右键一个会话 → 「在独立窗口中打开」
  3. 想盯几个就开几个,摆到屏幕上(别最小化)
  4. 悬浮窗会在 1 秒内自动发现它们,每个窗口算一个独立会话

为什么必须是这种方式:微信同一时刻只渲染「当前点开的那个会话」,别的会话根本没有画面可截。 另外两条路都走不通——主动去点会话列表会清掉你的未读红点还抢鼠标;读本地数据库已经被 律师函和 DMCA 1201 封杀。独立窗口是微信官方功能,副作用只有一个:不清红点。

开了之后有什么不一样

  • 每个窗口各自识别消息、各自生成候选,互不干扰
  • 首页会多出一行会话标签页(只在真的有两个以上独立窗口时出现),点一下切换看哪个, 当前在看的那个高亮。切换只改悬浮窗显示什么,微信那边一个都不动
  • 每个窗口多一行「允许自动回复」开关,新窗口默认不允许——要自动发就逐个打开
  • 自动发送一次只发一个,同时来消息就排队

⚠️ 有一件事必须做一次:把窗口标题配到联系人

如果你用了知识库,第一次开独立窗口时一定要做这一步。

原因很实在:以前会话名是从微信窗口头部 OCR 出来的,现在是窗口标题。两者对不上——

窗口标题 知识库里存的名字 为什么不一样
1群 1群(4)Q 那个 Q 是 OCR 把搜索图标 🔍 认成的字
程序员烧烤🦞技术交流群v3.0 程序员烧烤技术交流群v3.0 存的时候 🦞 丢了

不配一次,你原来那些聊天历史会静默对不上——首页只是从「本轮已带上…」变成 「本轮未使用知识库」,看起来就像功能坏了。

怎么配:悬浮窗会自己弹一条提示(非模态的,飘一下就走,不会卡住程序), 点上面的「去配对」直接跳到知识库窗口的联系人页。也可以自己去: 「知识库与联系人」→ 联系人页 → 顶上那栏「当前看到的窗口」→ 选一个联系人 → 点「配到…」。 它会把窗口标题写进那个联系人的别名,之后主窗口和独立窗口两条路就统一到同一个 key 了。

回退:不开独立窗口 = 跟以前一模一样

一个独立窗口都不开时,程序的行为和没有这个功能时一个字节都不差:

  • 还是只盯那个标题叫「微信」的主窗口,会话名还是从头部 OCR 出来的
  • 没有会话标签页、没有「允许自动回复」那一行、没有「当前看到的窗口」那一栏
  • 自动发送的判据还是全局那三个开关,一个字都没变

也就是说:你不用这个功能,就完全感知不到它存在。

设置说明

设置项 说明 存在哪
关系背景 决定说话的分寸。恋人 / 朋友 / 同事 / 家人,或自己填一句 config.json → relationship
说话风格 一句话描述自己的口吻,补在「照着你最近发的消息模仿」之上 config.json → style
参考上下文条数 3~30,默认 10,起草和判断都按它取最近 N 条 config.json → context
群聊指定回复对象 开了以后群聊里可以选回复给谁,候选针对 TA 写,填入时可带「@名字 」前缀 config.json → reply_target
起草模型来源 OpenRouter / DeepSeek 直连 / 自定义(任意 OpenAI 兼容地址) config.json → draft_provider
基础地址(自定义) 填到 /v1 即可,程序自己补 /chat/completions config.json → draft_base_url
模型名(自定义) 留空用该地址的默认模型 config.json → draft_model
判断引擎 完整(OpenRouter,有校准概率)/ 自判(用起草模型,有摘要和排序、无概率)/ 不判断 config.json → judge_engine
判断服务地址 / 模型(可选) 走哪条协议跟着引擎变:完整模式只能填 OpenRouter 兼容代理;自判模式填任意 OpenAI 兼容地址 config.json → judge_base_url / judge_model
起草时开启思考模式 开了模型先想再写,慢好几倍、贵一些 config.json → thinking
失败后最多再试几次 0~5,默认 2。5xx / 408 / 429 / 连接被掐 / 响应体格式不对才重试,4xx 和超时都不重试 config.json → retries
启动时检查更新 开了才在启动时查一次 GitHub 最新版本号 config.json → check_update(默认开)
保存聊天记录到本地 开了才把看过的对话写进「聊天记录」目录。默认关:它要长期往磁盘写文件 config.json → save_history(默认关)
起草超时 / 判断超时(秒) 5~120,默认 20 / 15。判断超时不丢候选,只是没有摘要和排序 config.json → draft_timeout / judge_timeout
生成几条候选 1~3,默认 3。调小能真变快 config.json → candidate_count
单聊里对方直接找我(自动发送) 单聊里对方给你发消息 → 生成完等 N 秒自动发送。默认关 config.json → auto_send_dm
群里 @我(自动发送) 只有明确 @你填的昵称的消息才自动发送。默认关,且必须填下面的群昵称 config.json → auto_send_group
群里不@我也回(自动发送) 群里任何新消息都自动发送,包含上面那个开关。默认关 config.json → auto_send_group_any
生成完等几秒再发 自动发送前的可取消倒计时,0~30,默认 5。三条路共用这一个值 config.json → auto_send_delay
群里不@我时先安静几秒 只对「不@我也回」生效,0~30,默认 8;填 0 = 不等 config.json → auto_send_any_wait
按哪个键发送 Enter(微信默认)/ Ctrl+Enter。必须跟你微信「设置 → 通用 → 快捷键」里的选择一致 config.json → send_key
我在群里的昵称 判断「有没有 @我」用的名字,要填群里显示的那个 config.json → my_name
允许某个会话自动回复(多独立窗口) 每个独立窗口单独一条授权,新窗口默认不允许;关掉就把这条删掉 config.json → auto_chats(形如 {"1群": true})
记录聊天历史(知识库) 开了才把聊天按会话记进 知识库/logs/ 并回注。默认关:它要长期往磁盘写聊天内容 config.json → kb_history_enabled(默认关)
注入最近历史条数(知识库) 0~100,默认 30。0 是合法值(只记录、不注入),界面会明确提示这种组合 config.json → kb_history_count
API 密钥 四个 key 都只进注册表 HKCU\Environment,任何文件里都不出现,也绝不进日志;注册表里存的是 DPAPI 密文(只有同一个 Windows 用户能解开) 注册表 → OPENROUTER_API_KEY / DEEPSEEK_API_KEY / CUSTOM_API_KEY / JUDGE_API_KEY

保存时只校验格式(地址要 http:// / https:// 开头),不拦「还没填 key」——不然刚填的地址和模型会一起丢掉。 缺什么由保存后那条提示统一说。

界面说明

  • 当前会话:顶部下拉框,自动跟着微信走(右边标「跟随微信」)。聊天记录、喂给模型的上下文和候选 都按会话分开,切来切去不串味。也可以自己选另一个会话翻它的记录和上次的建议(标「浏览中」)—— 那会儿只能看不能填,微信当前开着的不是它,填进去就串会话了。
  • 会话标签页(多独立窗口):下拉框下面一行,每个有独立窗口的会话一个按钮,当前在看的那个高亮。 点一下切换看哪个,微信那边不动。只在两个以上独立窗口时出现。
  • 自动回复(多独立窗口):会话标签页下面一行「允许自动回复」开关,只对独立窗口的会话出现。 新窗口默认「不允许」。
  • 回复对象(群聊,可选):设置里打开「群聊指定回复对象」后,群聊的「当前会话」下面会多一行下拉框, 选回复给谁,三条候选就都按 TA 来写(换一个人会立刻重生成)。旁边的「填入时带 @」默认勾着,填入时会 在开头加「@名字 」——那只是普通文字,微信不会认成真正的 @(真 @ 得用微信自己的选人面板)。
  • 采集开关:标题栏右上角。拨到「已暂停」就完全不读微信(WGC 会话一起停掉,黄框也没了), 已经生成的候选照样能填入、能复制。
  • 判断开关:标题栏上、紧挨着「采集开关」。拨一下立刻生效(不用进设置页、不用点保存)。 它跟设置页的「判断引擎」是同一个设置,两处显示永远一致。
  • 填入微信:点候选卡片上的「填入微信」,文字进微信输入框,光标留在那儿,发送你自己按。
  • 自动发送倒计时条:开了自动发送时,候选上方会出现橙色条「N 秒后自动发送」+「取消发送」。 倒计时结束前你手动点「填入微信」,也会自动取消这一次自动发送。
  • 复制:卡片右上角的复制按钮。
  • 聊天记录:底部按钮展开,看 OCR 到底读出了什么。接口报错的详情也打在这里 (和 OCR 文本同一个面板,这是已知的将就之处)。
  • 状态栏的失败提示:认得出 HTTP 状态码就给一句能照做的,例如 403 被该地址的防护拦下了(不是密钥问题)、 401 密钥被拒,检查这个地址对应的 key、404 地址路径不对,确认要不要带 /v1;重试过还会带上次数。 失败时「聊天记录」面板会自动展开,真因就在第一行。

几个注意:

  • 微信别最小化。 Windows 不渲染最小化窗口,什么截图法都拿不到画面。程序发现被最小化会无激活还原 再压到最底下(不抢焦点),但直接用别的窗口盖住微信是更省心的做法——被遮挡不影响 WGC。
  • 群聊和单聊各算一个会话(群名后面的成员数「(422)」会去掉,只拿名字当 key)。
  • 判断题的口径是按一对一写的,群里多人混说时结论会偏。

截图

界面全部是合成演示数据(tools/preview_ui.py 生成,不含任何真实聊天内容)。

回复建议 自判模式 设置 采集暂停
回复建议(完整模式):「当前会话」跟随微信、群聊多一行「回复对象」,3 条候选带 Jev 概率百分比,推荐那条置顶 回复建议(自判模式):有摘要和推荐顺序,卡片不带百分比,并写明「自评未经校准」 设置:关系背景、说话风格、参考上下文条数、群聊指定回复对象 采集暂停:不再读微信,已有候选照样能填入、能复制
自动发送设置 发送前倒计时 保存聊天记录到本地 判断与排序
自动发送:三个开关 + 共用的倒计时秒数 +「不@我也回」专属的安静窗口 橙色倒计时条:「5 秒后自动发送」+「取消发送」 保存聊天记录到本地:开关 + 存放位置(只读,可直接复制) 「判断与排序」卡:完整 / 自判 / 不判断三档
关闭判断时的自动发送设置 关闭判断时的倒计时条
关掉判断后的自动发送设置:「发第一条候选」写死在卡片上 关掉判断后的倒计时条:同样写明「没有判断结果,直接发第一条」,不假装它是推荐回复

判断关闭时,设置页和倒计时条都会明确写「发第一条候选」——它仍然会发,但不假装那是判断过的推荐。

知识库设置 知识库与联系人
知识库:记录聊天历史的开关 + 注入条数,两个入口和一个低调的「自检」 知识库与联系人:笔记(标签 + 启用开关)和联系人两个页签,点条目编辑

知识库整块是可选的:不建任何东西时,设置页这张卡、首页那行计数和「存为联系人」按钮都不会出现, 行为跟没有这个功能完全一样。(上面两张图用 tools/preview_ui.py --kb / --kb-window 生成, 演示数据建在临时目录里。)

多独立窗口 窗口配对
多独立窗口:首页多一行会话标签页(当前在看的那个高亮),每个窗口单独授权是否自动回复 知识库与联系人:把每个窗口标题配到联系人(写进它的别名),配好之后两边的历史和关系备注是同一份

上面这一组是多独立窗口那条线(微信 4.0.5+ 的「在独立窗口中打开」)。 不开独立窗口的话,界面和请求跟没有这个功能时一模一样——会话标签页整行不出现, 授权那一行也不出现,会话名还是从微信窗口头部 OCR 来的。 (用 tools/preview_ui.py --multi-window / --multi-window --kb --kb-window 生成。)

隐私与边界

这是个人自用工具,下面几条是硬约束,代码里就是这么写的:

  • 只读自己电脑上、自己本来就有权查看的对话。 不代替任何人查看别人的聊天。
  • 只截自己的微信窗口 + 本地离线 OCR(RapidOCR)。 不 hook、不注入、不读微信数据库、不解密、 不碰微信进程内存。
  • 枚举微信窗口只是本机的事。 为了知道该盯哪几个窗口(多独立窗口),程序会枚举自己屏幕上 微信进程的顶层窗口,读它们的标题和大小,用标题当会话名。全程只用 Windows 本地 API, 不联网、不写盘、不发给任何服务。
  • 截图只在内存里。 捕获到的帧是 numpy 数组,全程不写磁盘、不进日志、不上传,程序里没有 .save()。 唯一的例外是「保存聊天记录到本地」(默认关):打开后写出去的是 OCR 认出来的文字,不是截图, 而且只落在你自己机器上的 聊天记录/ 目录里,不上传、不发给任何服务。那个目录也在 .gitignore 里。
  • 知识库只存在本机,但命中时会随请求发出去。 你手写的笔记、联系人备注、别名,以及(默认关的) 聊天历史,都存在程序目录下的 知识库/,不上传、不同步、不发给任何服务。但要清楚:命中时它们 会作为 prompt 的一部分发给模型——这跟对话文本本身是同一条通道。所以笔记里别写密钥、密码、身份证号 这类东西。那个目录也在 .gitignore 里。
  • 默认不自动发送。 出厂状态下只把文字粘进输入框就停手,不发回车、不点发送按钮;页脚一直写着 「发送由你确认」。只有你在设置页显式打开「自动发送」之后才会替你按发送,而且默认只对单聊里直接找你的 消息、以及群里 @ 你的消息生效——别人的群聊闲话不会替你回(「不@我也回」是单独的开关,默认关)。 用了多独立窗口还要再逐个窗口授权一次,新窗口默认不允许。
  • 不碰钱。 转账、红包、收款相关的界面元素一律不碰,起草的 system prompt 里也禁了这几个话题。
  • 只有对方的新消息到来(或你在群里换了回复对象)才调一次模型。 静默期零调用——十分钟没人说话 就是十分钟零 token。
  • API key 只进环境变量,且注册表里是密文。 四个 key 都写进注册表 HKCU\Environment (跟 setx 同一个地方),任何文件里都不出现 key,也绝不进日志(报错文本一律脱敏)。 注册表里存的值是 Windows DPAPI 加密后的密文(CryptProtectData),只能被同一个 Windows 用户解开——注册表快照、备份、截图、别的账户都读不出明文。诚实说清边界: 它挡的是「密钥以明文躺在那里被顺手拿走」,挡不住「已经以你的身份在运行的恶意程序」 (那种情况下它本来也能读注册表)。进程内存里仍然是明文,因为 core/ 那层只认环境变量。
  • 自定义地址会改变出网范围。 地址本身不是密钥,落在 config.json;但填了它,对话文本就发到那里。 两个地址都留空时,出网范围跟以前完全一样。
  • 启动时查一次版本号(可关)。 只向 GitHub Releases API 发一个 GET,带的只有 UA 和当前版本号, 不夹带任何聊天内容。

什么会出网:core/ 那两次调用(起草 + 判断/排序;选「不判断」时只有起草这一次),加上启动时(可关) 一次到 GitHub 查版本号。自动发送、聊天记录导出、多独立窗口都不新增任何出网调用—— 它们分别只是按发送键、写本地文件、枚举本地窗口。

core/ 送出去的是最近 N 条对话文本(N = 设置里的「参考上下文」,默认 10;群聊带发言人名)、 关系设置、你自己最近 12 条 60 字以内的短消息(当口吻样本,链接和长段不送)、你填的说话 风格,群聊指定了回复对象的话再加一个对象名。判断那一步只看最近 6 条。 建了知识库的话,再加上命中的笔记正文、命中的联系人关系与备注、以及(打开历史时)回注的那几条 历史——加起来不超过 1500 字。没建知识库时,这一项一个字节都不多。 请求头里固定带一个 User-Agent: jev-chat-windows(不伪装浏览器,就一个自家标识)。除此之外没有别的。 OCR 全程离线。

但你在设置里填了自定义地址,这条承诺就变了:起草的对话文本会发到你填的那个地址,「判断服务地址」 填了的话判断文本也会发到那里。两个都留空时,出网范围就还是上面那三处。改地址等于改承诺, 请自己确认那个地址是你信任的。

调用失败怎么办(自动重试)

中转站、网关、家宽抖动,这些都不是你的错,也不该让你手忙脚乱地点第二次。所以起草和判断这两次出网调用 都会自动重试:

  • 会重试:5xx、408、429、连接被掐断、响应体不是预期格式。退避 1s / 2s / 4s,最多 4 秒一次。
  • 不会重试:4xx(密钥错、地址错这类——重试一百次也是同样的错),以及我们自己等待超时。 超时的含义是「对端已经慢到超过我们愿意等的上限」,立刻再打一次几乎必然还是超时,中间那几秒退避等的是空气。
  • 次数在设置里改(0~5,默认再试 2 次),起草和判断共用。

失败时状态栏给一句能照做的提示(认得出状态码就写具体原因,认不出才退回笼统的「请检查网络和服务设置」), 完整详情永远打在「聊天记录」面板第一行,那个面板会自动展开。

已知限制

  • 自动发送是不可撤回的:最坏的情况是它替你回了一句你不想发的话,而对方已经看到了。 想彻底避免就保持默认关。
  • 自动发送的发送键必须与微信设置一致:设置页选了 Ctrl+Enter 但微信里是「按 Enter 发送」, 文字就只会堆在输入框里发不出去(不会误发别的东西)。程序发完 2.5 秒会回看输入框并当场提示。
  • 多独立窗口下,「填入微信」一次只服务一个会话。 悬浮窗沿用单窗口时代那条规则——只有它当前跟随的 那个会话的按钮是可点的,点标签页切到别的独立窗口时按钮会变灰、提示「只看不填」。 自动发送不受这条影响:它是按会话查自己的窗口、直接往那个窗口发的,三个窗口都能各发各的。
  • 多独立窗口的授权按会话名存:改了群名要重新授权一次(换来的是「不用每次重启都重新授权」)。
  • 多独立窗口必须真的把窗口开着:独立窗口关掉、最小化、或者被微信自己收起来,那个会话就停了。 受屏幕大小限制,摆不下太多。
  • 多独立窗口的会话名就是窗口标题,跟知识库里按 OCR 存下的名字可能对不上, 第一次要在知识库窗口里配一次(见多独立窗口),否则那些历史用不上。
  • 焦点护栏是 8 秒:你 8 秒内碰过键盘或鼠标,自动发送就会让路。这是刻意的——fill() 要抢前台、 挪鼠标,正打字的时候抢走焦点会把你那几个字打飞。
  • 群里认 @ 靠文本匹配,会漏认:只认「@你填的群昵称」连在一起出现,且 OCR 漏一个字就认不到。 这是刻意的(宁可漏认,不可错认)。
  • 输入框内容检测判不准时一律当「有字」:所以偶尔会在框其实空着的时候报「输入框里已经有内容了」 而不发。漏发可以补,覆盖你正在写的字不行。
  • 导出的 CSV 是「程序看到的东西」,不是微信原文:OCR 认错的字会原样落盘(所以它同时是排查 OCR 的 样本);时间戳只在屏幕上出现时才有,滚过去的那些靠继承上一条。
  • 同一人连发两句一模一样的会吞一条:去重按文本相似度做的。对「要不要触发分析」没影响, 但导出的 CSV 会跟着少一条——这是「宁可漏掉,不可写错」的代价。
  • 群聊里名字行被 OCR 漏识,这条消息会挂到上一个人头上;「填入时带 @」加的 @名字 也只是纯文本, 微信不会把它变成真正的 @ 提醒。
  • 主窗口的会话名靠头部标题认:OCR 抖一个字会按相似度归到已知会话(不然一抖就多出一个会话), 代价是名字只差一个字的两个会话会被并成一个。头部一直认不出就先挂在「当前会话」名下。 (独立窗口不用这套——它的会话名是精确的窗口标题。)
  • Win10 黄框:WGC 的采集提示框,系统不给关,Win11 才行。
  • 输入框拉高超过面板一半会认错消息区:消息区靠「面板 45% 高度以下第一根分隔线」定位。
  • OCR 的「文字必须落在平底色上」规则只对精确像素的帧成立:缩放或压缩过的图(比如拿预览窗再截一次) 底色会糊成几百种颜色,整屏都会被当成图片。
  • fill 靠点击输入框坐标:算的是消息区底线下方 40px、左边界右侧 60px,微信改布局就得跟着调。
  • 没有托盘:关窗口就是退出(标题栏的「最小化」是收到任务栏,不是后台常驻)。
  • 校准概率没有替代品:typesafe/jev-1.13 只在 OpenRouter 上,走的是它私有的 decisions 协议。 没有 OpenRouter key 就是自判模式——摘要、紧张度和推荐顺序都有,但没有胜出概率: 普通模型自评的百分比没有校准依据,给出来就是假信息。
  • 自判模式的结论比完整模式糙:判断比起草难得多,用一个小模型去判断,结论会偏。
  • 有些中转站会拦「不是浏览器」的请求:Cloudflare 的默认规则里有 Python-urllib 这一条,所以 Python 的 urllib 如果不显式设 User-Agent 会被直接 403(body 是 error code: 1010)——同一个请求 用 curl 却是 200,很容易误判成「密钥/地址填错了」。程序现在所有出网请求都固定带 User-Agent: jev-chat-windows。

自己打包

双击 build.bat(走 uv:没有 .venv 会自己建一个,依赖从清华镜像装、顺带装上 PyInstaller, 最后调 PyInstaller,一路到底),或者手动:

uv venv .venv --python 3.11
uv pip install --python .venv\Scripts\python.exe -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt pyinstaller
.venv\Scripts\python.exe -m PyInstaller --noconfirm --clean jev.spec

推 v* tag 会触发 GitHub Actions 在 windows 上全新构建并挂到 Release (见 .github/workflows/release.yml)。那条流水线会先把下面那批离线检查 跑一遍,再打包,最后体检发布包——确认里面没有 config.json / 聊天记录 这类你自己的东西, 而且 OCR 模型、windows_capture、界面资源都在。发布包只从 CI 出:本地 dist/ 是你自己跑过的目录, 里面有你的设置,别手动压了往上传。

本地想自己过一遍同一套体检:

python tools/check_release_bundle.py            # 体检 dist/jev-chat-windows
python tools/check_release_bundle.py --expect-version 1.2.3   # 顺带断言版本号盖过章

开发者

  • docs/DESIGN.md —— 工作原理(截图 → 定位 → OCR → 去重 → 调用链的完整流程图)、 模型与判断三档、为什么走 OCR、为什么起草不那么像 AI、项目结构与每个模块的取舍

  • docs/DESIGN_MULTIWINDOW.md —— 多独立窗口那条线的设计: 为什么只有这条路走得通(另外三条的排除证据)、会话名对齐、自动发送的六道闸、向后兼容怎么守

  • docs/USAGE_KB.md —— 知识库与联系人怎么用(每个字段填什么、常见踩坑、示例)

  • docs/CHANGELOG.md —— 完整迭代记录

  • docs/KICKOFF.md —— 最初的需求与硬约束

  • tools/ 里有一批离线回归检查(不需要 Qt、不联网、不碰真实微信),跑全部:

    # 发现式:tools/check_*.py 全部跑一遍。新增检查脚本不用改任何清单。
    # check_release_bundle.py 要读 dist/ 构建产物,单独跑(见下)。
    for f in tools/check_*.py; do
      case "$f" in */check_release_bundle.py) continue ;; esac
      QT_QPA_PLATFORM=offscreen python "$f" || echo "FAIL $f"; done

    其中 check_ui_layout / check_overlay_runtime / check_kb_ui 需要 PySide6,其余不需要。

  • tools/check_release_bundle.py 体检发布包(没有你的 config.json / 聊天记录,关键载荷齐全); tools/set_version.py 把版本号写进 app/version.py(CI 打包前用它盖章,本地也能跑)。

  • tools/preview_ui.py 用合成数据预览界面,不采集不联网不碰微信;--screenshot 出图(README 里那几张就是它出的)。 --multi-window 演多独立窗口那一组(配 --kb --kb-window 还能截知识库的「当前看到的窗口」那栏)。

  • probe/ 是一次性技术探针(结论已写进 docs/DESIGN.md),留着是为了可复现。

许可与致谢

本项目以 MIT 协议开源,见 LICENSE。

致谢(上游)

本仓库是在下列项目基础上修改而来,版权与许可声明均已原样保留(详见 NOTICE):

  • jev-chat/jev-chat-windows —— Windows 版本体, 本仓库的直接上游。MIT,Copyright (c) 2026 rezoch340 and the jev-chat contributors。 本项目基于它二次开发。
  • jev-chat/jev-chat-jarvis —— 安卓原版, Jev 判断内核与题目口径都来自这里。MIT,Copyright (c) 2026 Finderchangchang and the jev-chat contributors。

感谢两个项目的作者和贡献者。再次说明:本仓库是第三方修改版,不代表上游,也未获得上游背书。

第三方组件

组件 许可证
PySide6-Fluent-Widgets GPLv3(非商用免费,商用需另购授权)
PySide6 LGPL-3.0
RapidOCR Apache-2.0
windows-capture MIT
numpy BSD-3-Clause
pillow MIT-CMU
PyInstaller GPL-2.0-or-later(含 bootloader 例外)

发布包整体受 GPLv3 约束(因为打包了 PySide6-Fluent-Widgets);只从源码运行不受这条影响。 完整说明见 NOTICE。

About

Windows 微信回复助手(非官方修改版):本地离线 OCR 读屏 + 模型起草候选回复 + 一键填入微信输入框,可选自动发送。不 hook、不注入、不读微信数据库。

Topics

Resources

Stars

10 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages