184 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 知微 · 微信知识需求分析工具
一个本地运行的 Python + SQLite 工具。从群聊和私聊里发现反复提问、风险/事故、重复踩坑、后续复用线索,将其整理为带原文证据的知识需求卡,对应 CREATES 的 Choose → Retrieve → Extract / Validate。
## 页面连接 Mac 微信(v0.4)
新增“连接 Mac 微信”向导:扫描账号 → 读取本机密钥 → 退出微信后备份、解密、解析并导入。密钥仅存运行内存;权限不足或版本不匹配会显示具体失败原因。首次仍需在 Mac 启动本地服务,之后通过页面操作。
v0.3 将进程访问失败细分为签名阻塞、未运行和多进程等情况,管理员模式也保留诊断。新增需要用户预览并明确同意的临时调试副本路径:完整备份账号及登录配置后,只对独立副本添加调试权限,不改原版或 SIP。副本可能访问同一账号数据,且仍可能无法启动或取钥;操作影响和限制均在页面展示。页面标题同时移除重复的英文标签,统一中文。
v0.4 将“仅完成签名检查”和“实际读取被拒绝”分开显示。检查结果直接给出下一步按钮:未尝试时先读取一次、普通读取被拒后可主动尝试管理员、管理员仍被签名拒绝时预览临时副本。只检查到限制不会显示绿色成功或暗示已取得密钥;任务阶段和结果以中文说明,不再直接展示 JSON。
**接入属于实验性功能,尚未在目标 Intel Mac 微信 4.1.0.18 实机验证,不保证系统允许读取密钥。** 使用流程、权限与格式限制见 [Mac 接入说明](docs/mac-connection.md)。
## 交付状态
- 已实现:可读文件导入、明文 SQLite 表导入、去重和错误行报告、覆盖统计、时间与会话筛选、本地规则分析、脱敏预览、兼容模型 API、后台任务、原文回溯、人工修正、主题合并/拆分、CSV / Markdown 导出。
- 已验证:Windows / Python 3.11 的自动化测试;浏览器端样例操作;本机模拟 API 的完整脱敏与证据校验流程。
- 已实现实验性 Mac 原生接入:本机密钥读取、备份、SQLCipher 4 raw-key 解密、WAL 回放与部分微信 4.x 结构解析。**尚未完成:目标 Intel Mac 微信 4.1.0.18 实机验收。** 系统拒绝读取密钥或格式不匹配时会停止,不能承诺任意版本均可一键获取全部聊天。
- 已提供 Mac 只读诊断脚本,帮助确认版本、CPU、数据位置、SQLite / 加密文件头与 WAL 状态;不获取密钥,不修改微信数据或系统保护设置。
- Intel / Apple Silicon 使用相同 Python 分析代码;基础分析与原生 AES 无需 pip 依赖;压缩微信正文需要在页面安装可选 Zstandard 支持。
## 在 Mac 上启动
需要 **Python 3.10 或以上**。将整个项目目录或发布 ZIP 复制到 Mac 并解压,在终端进入目录:
```bash
python3 --version
python3 run.py
```
浏览器会打开 <http://127.0.0.1:8765>。关闭终端或按 Ctrl+C 停止服务。也可在目录内运行:
```bash
bash start-mac.command
```
如果希望以后双击启动,可先执行 `chmod +x start-mac.command`。Python 版本过低时,先安装新版 Python。端口被占用则运行 `python3 run.py --port 8766`。不要通过 `file://` 打开 HTML,也不要换成 `localhost`,服务校验 Host,只接受启动时的 `127.0.0.1:端口`。
Windows 开发环境:`python run.py` 或双击 `start-windows.cmd`。
## 第一次体验
1. 在“数据概览”点击“体验虚构样例”:13 条文字/媒体占位记录、两个群聊和一个私聊。示例中的人名、客户与业务都是虚构的,不是用户真实记录。
2. 进入“发现知识需求”,时间留空、会话类型选“全部会话”、勾选“跨会话汇总相似问题”,点击“本地发现线索”。无需密钥,不调用网络。
3. 会得到 4 张候选主题卡,其中“测试比例怎么确定”包含 3 次讨论、跨群聊与私聊。点击“查看证据与审核”查看原文、修改摘要、记录边界或审核。
4. 多张卡片可勾选后合并。单卡包含多个事件时,可在详情勾选部分事件拆出新主题。合并/拆分会重新标为待审核,旧摘要或备注保留在新卡备注。
5. 导出 CSV(Excel 可打开)或 Markdown。导出包含本地会话名与分析内容,**不是对外分享的脱敏报告**;分享前请检查。
## 从 Mac 获取接入诊断
请在目标 Mac 的项目目录运行:
```bash
python3 scripts/mac_probe.py
```
生成 `mac-wechat-diagnostic.json`(如果已存在,拒绝覆盖)。报告仅包含本机路径、大小、修改时间、文件头判定、应用版本、CPU 与访问错误,不包含消息正文。
若微信数据在自定义位置,可明确指定目录:
```bash
python3 scripts/mac_probe.py --root "/你的微信数据目录" --output mac-diagnostic-2.json
```
默认检查微信沙盒 Documents、Application Support 和用户 Documents/xwechat_files,最多 8 层、300 个候选数据库,不跟随符号链接,不扫描整块磁盘。路径可能因版本与设置不同而变化;未找到文件不代表没有记录。权限受限会写入 warnings,不会自动提升权限。报告含本地路径,分享前自行检查。
`sqlite_header` 仅代表有普通 SQLite 文件头;`encrypted_or_unknown` 不是对加密算法的确认。原生数据库中的联系人关联、XML、压缩文本与 BLOB 等仍可能需要版本适配。不要为了运行本工具关闭 SIP 或安装来路不明的提取器。
当前版本明确不依赖 chatlog 原仓库。2026-10-22 核查时,[原仓库](https://github.com/sjzar/chatlog)仅保留项目移除通知,不能据旧教程假设它仍可安装或支持 4.1.0.18。
## 导入真实记录
支持 JSON、JSONL / NDJSON、CSV、TSV、约定格式的 TXT、明文 SQLite(`.db` / `.sqlite` / `.sqlite3`)。浏览器单文件上限 45 MB,单次上限 50 万条。超限需分文件;每次分析最多选择 20 万条。
标准 JSON 为对象数组,或包含 `messages` / `items` / `data` 数组的对象:
```json
[
{
"id": "消息唯一ID",
"conversation": "测试项目群",
"conversation_id": "project@chatroom",
"kind": "group",
"sender": "张三",
"sender_id": "user_a",
"timestamp": "2026-10-01T09:00:00+08:00",
"content": "测试比例怎么确定?",
"message_type": "text",
"quote": ""
}
]
```
CSV 表头使用同名字段,见 `examples/template.csv`。导入界面可填写实际列名映射;时间、发送人、内容必须可解析。单会话文件缺少会话信息时,填写默认会话名称和类型;混合会话记录须在每行提供会话字段。
- `kind` 为 `group` / `private`。支持“群聊”/“私聊”。缺失时,ID 以 `@chatroom` 结尾识别为群,其余为私聊;请核对分类。
- `timestamp` 支持 ISO 8601、常见年月日时间、10 位秒或 13 位毫秒 Unix 时间戳。
- 无时区时间按设置中的源时区解释,默认中国时间 `+08:00`,**不使用运行电脑的时区猜测**。统一以 UTC 保存。筛选和界面显示按同一设置的固定 UTC 偏移。跨夏令时数据请使用带时区的源时间;更改设置不会重新解释已导入数据。
- 唯一消息 ID 按会话去重。没有消息 ID 时,用会话、发送人、时间、内容、类型、引用去重;真实同秒同内容消息可能合并,结果会提示。不要混合多个账号但复用同样的会话/消息 ID;如需多账号,请使用不同 `--data-dir`。
- 发送人缺失、文本内容为空、时间无效、BLOB 等会拒绝对应行,并返回错误行号,其他有效行仍会导入。
- 非文字内容保留类型与占位文本,不自动 OCR、转写语音或解析附件。
- 文件导入页不支持未经转换的 HTML、任意 TXT 布局、微信官方备份包或加密数据库;原生加密库请使用“连接 Mac 微信”向导。拒绝未知格式,避免把乱码当消息。
TXT 支持:
```text
[2026-10-01 09:00:00] 张三: 测试比例怎么确定?
这一行仍属于张三的消息。
[2026-10-01 09:02:00] 李四: 请先确认型号。
```
### SQLite 与 WAL
上传数据库时只会读取你选中的文件,浏览器不会自动附带 `-wal`。**不要直接复制运行中微信的 `.db` 文件然后视为完整导出。** 对已经明文、字段可读的数据库,可在 Mac 本地用只读 SQLite backup API 导出表(会包含已提交的 WAL 内容):
```bash
python3 scripts/export_sqlite.py "/路径/可读数据库.db" "消息表名" "/路径/messages.jsonl"
```
脚本不修改源库、不覆盖已有输出。输出保留源列名,可在导入页面配置字段映射。压缩/二进制内容会拒绝导出,避免误导。数据库没有 sender、conversation 等完整字段时,仍需先关联联系人/群成员信息;本版不对未知微信原生 schema 做猜测。
## 分析与覆盖范围
时间段可覆盖全部已导入的群聊和私聊;也可指定会话类型、包含/排除会话。包含列表不选代表全部。时间起止均包含边界;填到分钟时边界精确到该分钟的第 0 秒。不填时间即全部时间。结束日期若通过接口只提供日期,则包含当天 23:59:59。
关键词筛选会剔除不匹配的消息,因此可能破坏上下文。希望分析完整讨论时请留空。
本地分析先找提问、失败、风险、返工、未来任务等词语,再在同会话内按 30 分钟间隔、最多 30 条消息形成事件候选;用中文二元词片段与英文词相似度合并问题。**规则是可审查的起点,不是准确语义理解**:会漏掉隐含问题、延迟回复和未记录的背景,也可能混入交错话题。模型模式基于相同事件候选进一步提炼,不代表读懂了全部未入选闲聊。原文图片/语音没有转写时,结论可能缺证据。
“独立事件数”是窗口分段估计,“回答者”只是可能提供经验的人,“重复踩坑”是文本线索,都不能直接作为事故因果、专家能力或个人绩效结论。
本地优先级为启发式:每个事件 15 分、风险 20 分、返工 15 分、未来复用 10 分,上限 100。模型可调整分类与策略,但分数仍来自本地事件和关键词;仅供排序,不是业务损失评估。人工审核不等于实践验证。
分析时冻结事件与消息快照,后续导入不会改写历史卡片证据。新增记录须新建分析任务。历史状态、人工编辑和卡片保存在 SQLite,刷新或重启后仍可从分析历史打开。
## 配置模型 API 与脱敏
在“模型与脱敏”填写完整兼容接口地址(以 `/chat/completions` 结尾)、模型名和 API Key。本工具不绑定特定供应商;需要支持常规 `messages` 请求并返回 `choices[0].message.content`。模型须能遵守 JSON 与 ID 引用要求;响应不合规时整个任务失败,不保存部分卡片。
- 远程接口必须 HTTPS;本机 `localhost` / `127.0.0.1` 可用 HTTP。
- API Key 仅在 Python 进程内存;重启后重新输入。也可通过 `WECHAT_MODEL_API_KEY` 环境变量提供。不会写入 SQLite、浏览器 localStorage、日志或导出。
- 保存接口、预览均不发外部请求。点击“发送这些内容”才把预览的请求体发送给配置的服务;服务商的数据保留政策由你选用的服务决定。
- 脱敏覆盖全库已知发送人名/ID、会话名/ID、常见电话号码/邮箱/身份证/IP/网址/凭据与自定义词。代号由本地随机盐生成并保持稳定,映射不发送。时间、消息类型、证据数字 ID 和未替换正文会发送。
- **这不是可证明不可逆的匿名化**。自然语言中未知的人名、地址、业务秘密和组合身份线索可能残留;请补充敏感词并检查完整预览。预览最多 30 分钟有效,配置变更后失效,一份预览只能发送一次。
- 每批最多约 48000 JSON 字符、30 个事件;超大单事件拒绝发送而非截断。字符数不是精确 token/费用估计,服务商较小上下文窗口可能报错。
- 多批串行发送;**不会自动跨批语义合并**,结果中可人工合并。后台页面可等待;关闭浏览器不停止任务,停止 Python 服务会中断。重启后把未完成任务标记失败,不自动重新发送。
- 不自动重试、跟随 HTTP 重定向或读取系统代理,避免重复计费与转发脱敏数据。单次 API 等待最长 120 秒。需要代理的环境可使用明确配置的本地兼容网关。
- 模型只获得脱敏事件,没有本机文件/命令/网络工具。响应必须引用当前批次存在的事件和消息,事件不能重复或遗漏,证据必须属于该卡的事件;否则拒绝整次结果。
## 本地数据与备份
默认数据在项目下 `data/workbench.sqlite3`,包括原文、配置(不含 API Key)、代号盐、分析快照和人工修正。目录在支持 POSIX 权限的系统上设置为 0700。数据库本身未做静态加密,建议放在你的受保护 Mac 用户目录。
仅绑定 `127.0.0.1`,校验 Host/Origin 和写入令牌,不加载外部 CDN 或遥测。聊天/模型输出以纯文本 DOM 渲染,CSV 中以 `= + - @` 开头的内容会转义以避免公式执行。该工具是单用户桌面工作台,不是多人服务。
备份:先 Ctrl+C 停止服务,再复制整个 `data` 目录(包含可能存在的 WAL/SHM),或用 SQLite backup API。恢复时停止服务后放回原目录。用 `python3 run.py --data-dir "/其他/数据目录"` 建立独立工作空间;不要在两个进程中同时打开同一数据目录。
## 开发与验证
```bash
python3 -m unittest discover -s tests -v
python3 -m compileall -q wechat_tool scripts run.py
```
测试使用临时数据目录与本机模拟 API,不调用真实模型、不读取用户微信数据。覆盖时区、去重、错误行、跨会话聚类、媒体缺口、脱敏、完整批次、模型虚构证据拒绝、WAL 快照、只读诊断、CSRF、导入 HTTP、历史快照固定、人工合并/拆分/审核和导出。
源码结构:
```text
run.py 启动入口
wechat_tool/store.py SQLite 与筛选
wechat_tool/importer.py 文件解析、字段映射、去重
wechat_tool/analysis.py 事件、聚类、脱敏与模型结果校验
wechat_tool/server.py 本机 HTTP 服务、任务与导出
wechat_tool/static/ 无构建依赖的界面
scripts/mac_probe.py Mac 环境与数据库头诊断
scripts/export_sqlite.py 明文 SQLite / WAL 完整表导出
examples/ 虚构样例与导入模板
tests/ 无网络依赖的自动化测试
```
后续真实 Mac 验收仍需:确认 4.1.0.18 的可读数据来源,核对所选时间段的消息数/首尾/随机样本,确认群成员身份和引用解析,使用你选择的真实模型 API 验证响应,再扩大到半年的多群数据。这个接入限制是待完成事项,不是已通过的兼容性声明。