DigUp 五分钟速览:这个1146星的项目解决什么问题?
【免费下载链接】DigUpSearch your computer by what's in your files: photos, PDFs, documents, recordings, videos and code. On-device on Mac, Windows and Linux, built on Google DeepMind's EmbeddingGemma 2.项目地址: https://gitcode.com/gh_mirrors/di/DigUp
在 macOS 上,你仍然会为「找不到文件」而恼火:你记得一张截图里有一行报错,记得一段播客里主持人聊到了睡眠,记得一份 PDF 的某一页写着你签过的宠物条款——但 Spotlight 只能按文件名和已索引文本匹配,编辑器里的 grep 只能在你知道搜什么关键词时才有用。DigUp 要解决的,正是「我记得它长什么样 / 说了什么,但记不得它叫什么」这个本地搜索世界里最古老的痛点。
DigUp 是一个开源的 macOS 菜单栏应用:它读取你指定文件夹里的图片、PDF、录音、视频和代码,然后用 Google DeepMind 的多模态嵌入模型 EmbeddingGemma 2 把「内容」变成向量。你用自己的话描述要找的东西,它按语义找出匹配——并且直接把你带到 PDF 的那一页、视频出现斑马的那一刻、音频谈到某个话题的那一分钟、代码定义某个函数的那一行。整条链路都在本机完成。
项目主页的口号是"Describe it. Dig it up."。截至写作时,仓库在 GitHub 上已收获 1146 颗星,属于典型的「小而锋利」的个人效率工具:SwiftUI 写的约 20 MB 的壳 + 一个 865 MB 的本地模型 + 一个 SQLite 向量索引。
它"挖"的到底是什么:内容,而不是文件名
先说结论:DigUp 挖的是文件"里面有什么",而不是"文件叫什么"。它的全部能力都建立在一个关键选择上——用多模态嵌入模型把文字、图片、音频、视频放进同一个向量空间(768 维),于是"沙滩上的一条狗"这张照片的向量,会落在"a dog on the beach"这句话的向量旁边;一段谈论睡眠的录音,会落在"where they talk about sleep"旁边。
这个选择直接决定了它能搜什么。项目 README 给出了几类有代表性的查询:
"zebra in a video"—— 打开视频,跳到斑马出现的那一刻;"where they talk about sleep"—— 跳到播客谈到睡眠的那一分钟;"the clause about pets in the lease"—— 显示 PDF 那一页,并把命中词标出来;"a dog on the beach"找到照片,"payment declined error"找到截图;- 用英文搜,能搜出用孟加拉语、阿拉伯语写的笔记(模型支持 100+ 语言,跨语言检索);
"code: retry a failed call with backoff"找到项目里那个函数,无论它叫什么名字。
底层模型是 EmbeddingGemma 2:2026 年 10 月由 Google DeepMind 发布,Apache 2.0 开源,740M 参数,小到能在笔记本上流畅运行。DigUp 通过 llama.cpp 的 Metal 后端把它跑在 Mac 的 GPU 上,索引进程用完即退,查询时只加载约 250 MB 的文本编码器。
值得一提的是,语义匹配之外精确词匹配同样重要。发票号、错误码、人名这类字符串对 embedding 毫无意义,但对用户至关重要。DigUp 为此维护了一个 SQLite FTS5 全文索引:文件名、文档正文、截图的 OCR 文本都会进去。在 Sources/DigUpKit/Searcher.swift 里可以看到这套混合检索的设计:语义分数(z-score 归一化)与关键词覆盖率的加权融合,查询由纯代码/数字构成时自动加重关键词权重、压低语义权重——因为"K7Q2LM"这种订单号没人能靠语义找到。测试集 evals/synthetic.json 里有专门的exact标签覆盖这类场景。
从按下 ⇧⌘Space 到打开文件:一次搜索的旅程
上手流程非常像 Spotlight,但结果形态完全不同。安装后首次启动,引导页会让你勾选要索引的文件夹(可以精确到子文件夹),并对每个文件夹给出首次索引的耗时估算——这一步由 Sources/digup/main.swift 里的digup estimate命令支撑,它只做元数据爬取,不读文件内容。之后在任何 App 里按⇧⌘Space呼出搜索面板,输入自然语言描述即可。
一次搜索在代码层面是这样的:
- 每个按键先走关键词搜索(
Engine.search(text, vector: nil, prefixLast: true),见 Sources/DigUpApp/Engine.swift),末词按前缀匹配,结果毫秒级出现; - 停顿约 120 ms 后,查询文本被送入独立的查询编码进程(text-only 的模型,冷启动约 0.35 s),得到 768 维查询向量;
- Sources/DigUpKit/Searcher.swift 用一次矩阵-向量乘法(vDSP_mmul,分块 1024 行)对索引里所有向量打分,按模态(文字/图像/音频)各自做 z-score 归一化,再与关键词排名融合;
- 结果按类型分组展示,按 ↩ 打开:视频和录音跳到命中时刻(通过 QuickTime 定位),PDF 带关键词进入 Preview 搜索,代码在编辑器里打开到定义行。Space 是 Quick Look,⌘↩ 在 Finder 里显示,⌘C 直接复制文件。
索引侧,Sources/DigUpKit/Indexer.swift 展示了"读取与嵌入流水线化"的设计:提取(ImageIO 解码图片、PDFKit 读页、Vision 做截图 OCR、AVFoundation 解码音视频)与模型嵌入在两个线程上重叠进行,图片每 8 张一批。音频按 30 秒重叠窗口切分(模型单输入上限 30 s),视频则每几秒抽一帧并做 8×8 平均哈希去重(同一镜头内只保留一帧),再叠加音轨窗口。长 PDF 先读前 30 页,其余在首轮结束后补读(上限 5000 页)——所以一本 100 页的航海日志,前 30 页立刻可搜,后面的页随后到位,evals/synthetic.json 里tag: "long"的查询验证的就是这条路径。
一个反直觉的工程选择:它没有用任何向量数据库。索引就是 Sources/DigUpKit/IndexStore.swift 里的一个 SQLite 文件(index.sqlite),向量以 float16 存成 BLOB,与描述它们的行在同一个库、同一个事务里——崩溃也不会让向量与元数据脱节。在 ~2 万个向量、约 30 MB 的规模下,对内存中的向量做暴力搜索只需几毫秒(源码注释原话:"no vector database needed")。向量矩阵用 mmap 映射,释放时能真正归还内存。
和 Spotlight、ripgrep、向量数据库分别是什么关系
这是阅读这个项目时最容易混淆的一点。DigUp 的 FAQ 里自己回答了与 Spotlight 的差异:Spotlight 按文件名、文本和元数据找文件;DigUp 按"内容展示了什么、说了什么"找文件,并把你带到那一页/那一刻。两者可以并行共存,互不干扰。换句话说,Spotlight 是"我知道它叫什么/里面含哪些词"的检索,DigUp 是"我记得它长什么样"的检索。
与编辑器和 ripgrep 的关系则更微妙:代码搜索默认是关闭的,需要显式开启(code:前缀)。开发者的判断很务实——普通编辑器 + ripgrep 本来就能精确搜代码,DigUp 的差异化在于按意图搜:"code: refreshAccessToken"会跳到定义它的那一行,而不是所有调用它的地方;"code: plot how many examples each class has"能命中 notebook 里做这件事的单元格。为了做到这一点,Sources/DigUpKit/CodeExtractor.swift 把代码按完整行切成 ~1800 字符的 stretch(尽量在块边界断开),每个 stretch 以"仓库路径 + 文本"为输入嵌入,Sources/DigUpKit/Model.swift 里的Prompts.codeQuery使用模型卡上专门为代码检索设计的 prompt("task: code retrieval | query: ..."),命中行还做了"定义还是使用"的启发式判定。结果可以打开进 Zed、VS Code、Cursor、Xcode、Sublime Text、JetBrains 全家桶等编辑器(见 Sources/DigUpApp/CodeEditors.swift,每种编辑器都有独立的定位方式)。索引会尊重 git:被 .gitignore 忽略的文件、vendor/ 和构建产物一律不读。
至于"为什么不用 Milvus/FAISS 这类向量数据库"——前面已经说过:本地几万个向量的暴力检索毫秒级搞定,引入向量库只会增加运维复杂度。这是个人工具与工业级搜索引擎在规模上的本质区别,也是 DigUp 值得学习的取舍:在能暴力破解的规模里,优先做简单的架构。
隐私是它的另一个卖点:被索引的任何内容都不离开 Mac,联网只有两次——首次下载模型和每天一次更新检查(可关闭)。无账号、无遥测。它也只读不写,绝不会修改、移动或上传文件;密钥、证书、密码文件、隐藏目录(如~/.ssh)、App 包和缓存一律跳过,仅存在于 iCloud 云端的文件不会被下载。首次全量索引在几百个文件的规模下只需几分钟,之后的每个新文件在落盘一两秒后即可搜到。
适合谁关注
如果你是macOS 用户,且满足 Apple Silicon + macOS 14+:DigUp 解决了"我记得内容、记不得名字"这一真实高频痛点,尤其是截图、PDF 合同、播客/录像这类 Spotlight 无能为力的文件。它免费、开源(MIT)、无账号、本地推理,与 Spotlight 并存使用没有成本。
如果你是开发者,值得关注的不只是它的功能,更是实现方式:
- 单文件索引的设计:向量与元数据同库同事务、float16 存储、mmap 释放,Sources/DigUpKit/IndexStore.swift 里的 schema 迁移(版本化 PRAGMA user_version、逐条重建 FTS5)几乎可以作为"个人级本地检索"的范本;
- 混合检索的调参方法论:Searcher 源码注释里记录了每一次权衡的实测依据——z-score 按模态归一化的效果、word-weight 取 2.0 的理由、用三个 eval 文件(evals/synthetic.json、evals/multilingual.json、evals/code.json)度量每次改动,这是很难得的数据驱动开发痕迹;
- 大模型本地化的工程边界:模型常驻的独立 helper 进程随用随退、查询编码器约 250 MB 的文本模型单独起停、跨语言检索(英文查孟加拉语/阿拉伯语文档)的真实落地,都值得做端侧 AI 的团队参考。
一句话收尾:DigUp 把"多模态嵌入模型 + 本地文件系统"这件事做成了 macOS 上体验最顺滑的样子——它挖的不是文件名,是你记忆里的画面和声音。
【免费下载链接】DigUpSearch your computer by what's in your files: photos, PDFs, documents, recordings, videos and code. On-device on Mac, Windows and Linux, built on Google DeepMind's EmbeddingGemma 2.项目地址: https://gitcode.com/gh_mirrors/di/DigUp
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考