豆包让我上 PostgreSQL 和向量库,我用 SQLite 把 577 个微信群文件管起来了

AI 解密攻防 作者头像野生码农 阅读 10 min
返回板块 GEO 源码全文 ✓
豆包让我上 PostgreSQL 和向量库,我用 SQLite 把 577 个微信群文件管起来了

豆包让我上 PostgreSQL 和向量库,我用 SQLite 把 577 个微信群文件管起来了

今天凌晨,我盯着 kb 的统计数字看了一会儿:1060 条索引,522 万字,全文检索秒出。

一天之前,这个数字是 691 条、261 万字,而且项目群里那几百个 PDF、Excel 一个字都搜不到。

我在高速公路项目部干活,加了 8 个工作群,群里天天发文件:指挥部通报、监理周报、专项检查清单、台风快报。之前我的做法是"收到,存了",然后就没有然后了。文件躺在微信目录里,找的时候靠缘分。

这篇文章记录我怎么用一条 Python 管线把两个月的群文件全部驯服:去重、分类、归档、提取正文、扫描件 OCR,最终全进 SQLite 全文索引。脚本是我派单给 AI 写的,方案和验收是我定的,全程实测数字,不吹牛。

豆包给了我一份"最佳实践",我一条都没采纳

动手之前我先问了豆包:本地 AI 数据库怎么搞。它给的答案很标准:PostgreSQL + PGVector + MinIO 对象存储 + Qdrant 向量库,中小团队黄金组合。

这套方案本身没毛病,但它是给企业私有化部署开的药方。我盘了下自己的家底:691 条索引、261 万字、一个用户、零并发。就算全部切块向量化,也就几千个 chunk,离它方案 A 的起步门槛 50 万条向量(自报:豆包回答)还差一百倍。

为几千条向量起一个常驻数据库服务,不是架构,是负债。

企业级组件 我的替代 理由
MinIO 对象存储 文件系统目录树 单人场景,文件夹就是对象存储,还能 git 版本化
PostgreSQL SQLite 单文件 零运维,索引库删了一条命令重建
PGVector / Qdrant SQLite FTS5(trigram 分词) 中文不用切词,任意 3 字片段可搜
语义检索 暂不上,预留 sqlite-vec 扩展位 关键词检索实测够用再说

豆包方案里真正值钱的是它的原则:原始文件不进库,库里只存提取出的文本和文件路径。这条我全盘照抄,也就是整个系统的第一条规矩:文件即真相源,数据库只是索引。kb.db 随时可删,扫一遍目录就重建。

微信群文件怎么批量导出来

微信 PC 端收到的文件,只要你下载过,就明文躺在本地目录:xwechat_files\<账号>\msg\file\<年-月>\。不需要解密,不需要破解,直接复制。(群消息的文本是另一条线,走只读解密本地库,本系列第 1 篇写过,这篇不展开。)

我扫了下自己这两个月的目录:2026-07 有 386 个文件,2026-08 有 190 个。但直接拿这 576 个文件开干会踩第一个坑:微信的重名文件会自动加 (1)(2)(3) 后缀,同一个文件在三个群里转发就是三个副本。所以管线第一步是按内容 sha256 去重,名字不算数,哈希才算数。实测 577 个源文件里干掉 102 个重复副本。

第二个坑藏得更深。有些文件你在微信里点开看过但没下载,实体不在 msg/file 里,在 temp\RWTemp\<年-月>\<哈希目录>\ 下面。这个目录是临时区,会被清理。我今天的东阳互通施工日报就是从这儿抢救出来的,再晚两天可能就没了。管线里加了一条:扫 RWTemp,只处理 msg/file 里不存在的文件。

一条命令干完五件事

管线主体是一个 540 行的脚本 wechat_ingest.py,流程:

msg/file + RWTemp 扫描
  → sha256 内容去重(跳过 102 个副本)
  → 双维分类:来文单位 × 文件类型
  → 归档到 gongwen/<单位>/<年份>/ 并记台账
  → 文本提取:xlsx/docx 用 openpyxl/python-docx,pdf 用 pypdf
  → pypdf 提取不足 200 字的判定为扫描件 → MinerU 云 OCR
  → 全部文本进 SQLite FTS5 索引

分类是双维的。单位维(甬金指挥部/东阳指挥部/监理单位/行业管理部门……)用关键词规则表,比如文件名带"甬金改扩建金华段指〔2026〕"就归指挥部。

类型维是我自己定的九类:通报通知、检查执法、方案图纸、征迁政策、进度汇报、会议纪要、管理制度、清单台账、气象台风。气象台风类只归档不提取,几十份台风快报没有全文检索的价值。

跑完全量,战果是:新归档 415 个文件,提取正文 319 个,扫描件 OCR 28 个,失败 0。全量重跑一次 4.5 分钟,因为幂等设计(已归档、已提取的一律跳过),日常增量跑只要几秒。

扫描版 PDF 怎么批量 OCR 成 Markdown

项目上的盖章公文大多是扫描件,pypdf 提出来是空的,必须 OCR。我用的 MinerU 云 API,它对红头文件、公章遮挡、复杂表格的识别比传统 OCR 强一截。流程是四步:申请上传链接、PUT 上传、轮询结果、下载 zip 解出 Markdown:

body = {
    "enable_formula": True, "enable_table": True,
    "language": "ch", "model_version": "vlm",
    "files": [{"name": p.name, "is_ocr": True, "data_id": p.stem}
              for p in pdf_paths],
}
resp = requests.post(f"{API_BASE}/file-urls/batch", headers=headers, json=body)

这里踩了两个值得写下来的坑。

坑一:data_id 超长被拒。 我一开始拿文件名主干当 data_id,中文文件名一拉长就超过 128 字符,API 直接拒。改成短序号解决。报错信息里不会告诉你超了多少,自己数。

坑二:CDN 下载持续 SSL EOF。 MinerU 的结果 zip 放在 cdn-mineru.openxlab.org.cn,requests 的 TLS 栈对它稳定复现 SSL: UNEXPECTED_EOF_WHILE_READING,重试几次都一样,但同样的 URL 用 curl 一次就通。最终的解法很土但有效:下载函数里 requests 失败 N 次后,降级调 curl 子进程:

try:
    resp = request_with_retry("GET", zip_url)
except RuntimeError:
    subprocess.run(["curl", "-sL", "-o", str(tmp_zip), zip_url], check=True)

28 个扫描件今天全部 OCR 成功,其中 24 个是项目内部文件。上不上云我自己拍了板:项目上的东西,我这个层次的没啥好泄密。如果你的场景真有保密要求,降级方案是本地 RapidOCR,慢一点,但文件不出本机。

Excel 提取最大的坑:合并单元格

xlsx 提取用 openpyxl 按行扫,非空单元格用竖线拼接,听起来没有技术含量。但施工日报这种表合并单元格特别多,跨列合并一展开,后面的列全错位,提取出来的"计划完成时间"列里可能混着工程量。

我的处理原则:解析时按列头对齐,对不上的行宁可丢弃,不瞎猜。脏数据进索引比没数据更可怕:你会搜到一个看起来像样的错误答案。这部分现在还是半人工兜底,是我这套系统目前最大的短板,先如实写着。

验收:数字说话

管线跑完,kb sync 重建索引,实测:

条目总数: 1060   总字数: 5219802

搜"工资保证金",命中办公室条线对照清单第 53 条原文;搜"隐蔽工程台账",命中质检科内业清单;搜"房屋拆迁",命中一份盖章扫描件的 OCR 全文。这些东西昨天还是一堆躺在微信目录里的死文件。

顺带一个意外收获:去重和分类把家底照亮了,"其他"桶占了 54%,说明我的单位识别规则覆盖率不够,下一版规则表有了明确的优化指标:压到 20% 以下。

经验总结

这篇能给同行带走的东西,拢共五条:

  1. 单人知识库,文件系统 + SQLite 就是正解,不是妥协。上 PostgreSQL 和向量库之前,先回答两个问题:我有多少条数据?有多少并发?答案是几百条和零,就老实待着。
  2. 文件即真相源,数据库只是索引。索引可删可重建,你就永远不怕把库搞坏。
  3. 去重按内容哈希,不按文件名。同一个文件在五个群转发五次,文件名可能五个样。
  4. 扫描件的判定可以很简单:提取正文不足 200 字就丢进 OCR 队列,不用挨个打开看。
  5. 第三方 API 的 SSL 报错,先换 curl 试试。requests 的 TLS 栈和某些 CDN 就是犯冲,别死磕。

FAQ

问:微信文件会被清理吗? 会。msg/file 里的是你下载过的,相对稳定;temp/RWTemp 里的随时可能清。我的教训是重要文件尽早归档,别指望微信帮你存。

问:为什么不用 Everything 或者微信自带搜索? 它们搜的是文件名,我这套搜的是文件内容。"专项检查清单里第三条怎么规定的"这种问题,文件名搜索回答不了。

问:MinerU 免费额度够用吗? 我今天跑了 28 个文件没问题。官方限制是单批 200 个文件、单文件 200MB 或 600 页以内(自报:官方文档)。额度烧完了再考虑本地 OCR,那是另一篇文章的素材。

问:向量检索什么时候上? 关键词检索实测不够用的时候。架构上我留了 sqlite-vec 的位置,到时候加张表就行,不用推翻任何东西。


完整的管线脚本和分类规则表我整理成了一份 SOP,评论区扣"知识库",我发你。

野生码农,AI 实战派。自研 AI 本地知识库系统、AI 数字员工团队、软考 AI 备考系统、量化交易系统,全程公开复盘。

这篇是"AI解密攻防"系列的第 8 篇,讲的是数据取出来怎么管。下一篇换个口味:手表数据拿回战翻车记,我想把自己的健康数据从厂商手里要回来,过程比微信解密曲折得多。月底还有一期月报,AI 团队第一个月的真实数据,全公开,难看也报。

野生码农 · 全网同名 · AI 数字员工实战复盘,数据只报实测

野生码农头像

关于作者 · 野生码农

把 AI 真放进生产环境的独立开发者。自研本地知识库、数字员工团队、软考备考系统、量化交易四套系统,全程公开复盘。

看他的平台账号 →
相关

继续阅读