DocFinder 是一个跨平台的本地文档搜索应用,可为 PDF、DOCX、PPTX、OpenDocument、HTML、EPUB、Markdown 和纯文本建立语义索引。它使用 SentenceTransformers 或 ONNX 在本机生成嵌入,将文档元数据、分块和 float32 向量保存到 SQLite,并支持用自然语言描述内容来找文件。当前版本还加入了本地 Qwen3.5 文档问答。
原始项目首先解决“记得内容但忘了文件名”的问题:把查询和文档片段映射到同一向量空间,再按相似度排序。后续版本才增加本地 GGUF 模型问答。
仅需要找文件时,语义搜索更轻量;需要综合答案时,再启用本地聊天。两者都不要求云端 API,但首次下载嵌入和聊天模型需要网络。
项目为 macOS、Windows 和 Linux 提供 DMG、安装程序和 AppImage。开源构建可能触发 Gatekeeper 或 SmartScreen 提示,应从官方 Release 下载并核对版本。
源码运行需要 Python 3.10 或更高版本及 make:
git clone 项目仓库地址
cd DocFinder
make setup
make run
若需要浏览器界面,可运行 make run-web,默认只在本机 8000 端口提供服务。不要将无认证的本地界面直接暴露到公网。
图形界面中选择一个资料目录后,DocFinder 会递归扫描支持的文件、解析文本、分块、生成嵌入并写入数据库。第一次先选择小目录,观察模型下载、处理速度和磁盘增长。
命令行也可指定路径、数据库、嵌入模型、分块长度和重叠量。索引完成后应保存处理统计,确认跳过和失败文件。
| 格式 | 解析方式 | 重点检查 |
|---|---|---|
| PyMuPDF 按页面提取 | 扫描页、阅读顺序和页码 | |
| DOCX | python-docx 提取段落及结构 | 表格、文本框和标题层级 |
| Markdown | 直接读取文本并按内容切分 | frontmatter、代码块和编码 |
支持某种扩展名不等于完整保留视觉格式。语义搜索依赖提取后的文字,图表、图片和复杂版面可能无法参与检索。
文本以句子感知的重叠窗口切分。重叠可以保留跨边界上下文,但也会增加索引大小和重复结果。
SQLite 中分别保存文档和分块记录,向量以 float32 BLOB 存储。检索时将查询嵌入与已存向量比较,并返回文件路径、分块序号和元数据。
系统会根据资源调整解析并发和嵌入批量。若索引时内存耗尽,应降低批量或缩小目录,而不是强行提高并行度。
查询可以描述概念而不必复现原文,例如“去年关于供应商延期风险的报告”。系统先生成查询向量,再取回相似片段,并可使用 cross-encoder 重排候选。
验收时准备三类查询:包含原文关键词的精确题、只有同义概念的改写题、知识库完全不包含的无关题。第三类用于观察低相关结果是否仍被展示。
RAG 可选依赖使用 llama.cpp 运行 GGUF 模型。系统根据内存选择 Qwen3.5 2B、4B 或 9B 量化模型,并在缺少缓存时自动下载。
小文档最多约 20 个分块时可加载完整正文;大文档则围绕命中分块扩展上下文窗口。最终上下文仍受字符预算限制,长文跨章节问题可能需要缩小范围或拆分问题。
不同嵌入模型的向量不可直接比较。DocFinder 会在数据库中记录当前模型;发现模型变化或旧索引来源不明且已有向量时,会清空文档和分块索引,以便重新嵌入。
切换模型前必须确认原文件仍可访问并备份数据库。否则自动清理后无法恢复旧搜索状态。
文档、模型和向量都保存在本机,不使用账号或云端搜索服务。但本地数据库仍可能包含大量可还原的文本片段和路径。
| 现象 | 优先检查 |
|---|---|
| 首次启动很慢 | 嵌入或 Qwen 模型是否正在下载 |
| PDF 搜不到内容 | 是否为扫描件、页面能否提取文本 |
| DOCX 结果缺少表格 | 解析器是否提取目标结构 |
| 搜索排序不稳定 | 嵌入后端、重排器和分块参数 |
| 索引突然为空 | 嵌入模型是否发生变化 |
DocFinder 的核心价值是用完全本地的嵌入和 SQLite,把文件搜索从“记住关键词”提升为“描述意思”。可靠使用它需要先验证格式解析和索引生命周期,再决定是否启用更耗资源的本地 Qwen 问答。