☰
Everything 式秒搜回潮:从 Agent 技能到 GitHub 新星,本地搜索生态正在重排
2026/10/10 11:48:49 网站建设 项目流程

Everything 式秒搜回潮:从 Agent 技能到 GitHub 新星,本地搜索生态正在重排

【免费下载链接】fsearchWhole-disk file search for macOS: fuzzy names, typo tolerance, indexed content grep. ~1 ms over 8M files.项目地址: https://gitcode.com/gh_mirrors/fsea/fsearch

"全盘搜索、毫秒返回"——这个自 Everything 诞生以来被反复验证过的需求,在 2025 到 2026 年之交突然又站上了聚光灯:Cursor 在官方博客讨论"为 agent 工具构建文本索引",Cloudflare 发文把搜索定义为"智能体的搜索原语",社区里出现"开源 Everything 搜索技能让 AI Agent 文件检索速度翻倍"的实操分享,连 Windows 11 都在酝酿搜索框的重大改版,ClickHouse 则忙着在对象存储上重构全文索引。本地搜索不再只是桌面效率工具的存量话题,而是正在成为 Agent 时代的基础设施。

在这波回潮中,一个面向 macOS 的全新 fsearch 仓库(Cargo.toml 中即名为 fsearch)带着 "Whole-disk file search for macOS: fuzzy names, typo tolerance, indexed content grep. ~1 ms over 8M files." 的自我介绍出现。它与中文社区里教程饱和的 Linux GTK3 版 FSearch 同名同理念,却走了一条完全不同的工程路线。本文结合社区舆情与仓库源码,拆解这次"秒搜回潮"的信号、fsearch 的实现细节,以及本地搜索生态正在发生的重排。

回潮信号:秒搜正从桌面工具变成 Agent 的"搜索原语"

把近期舆情中的线索并排放在一起,能清楚看到一条共同的暗线:

  • Cursor发布《快速正则搜索:为 agent 工具构建文本索引》,直接面向"给 agent 一个可快速正则检索的文本索引"这一场景——agent 要在一个大型代码库或文档库里找到指定符号,本质就是在做"索引 + 秒级命中";
  • Cloudflare提出 "AI Search:智能体的搜索原语",把搜索视为 agent 与本地/云端数据之间最基础的接口原语之一;
  • 社区流传的"开源 Everything 搜索技能"教程,宣称把 AI Agent 的文件检索速度"直接翻倍",说明在实操层面,agent 的文件查找已经慢到成为瓶颈;
  • AnySearch v2.1.0这类"搜索中枢"工具迭代,方向同样是"提升 Agent 搜索质量";
  • 传统大厂与基础软件也没闲着:Windows 11 搜索迎来重大改版,ClickHouse 重构全文索引以在对象存储上跑出高性能 Full-Text Search。

这些信号指向同一个判断:当 AI 需要"读文件、找文件、理解代码库"时,一切又回到了搜索最朴素的定义——先建索引,再以毫秒级延迟命中。而 Everything 式的"文件名秒搜 + 全文内容检索",恰好就是这一需求最成熟的形态。于是,本地搜索赛道出现了一次明显的"回潮":既有存量工具被重新审视,也有新实现带着更现代的工程手段入场。

同名不同路:CSDN 教程饱和与 GitHub 新星起量

舆情快照里最显眼的一组矛盾,是中英文社区在"FSearch"这个名字下的节奏差。

在 CSDN 上,"FSearch"相关教程自 2024 年起密集产出,且多数围绕 Linux 平台的 GTK3 版本:安装 PPA/AUR/COPR/Flatpak 的方式、添加搜索路径、更新数据库、正则与多条件组合语法、快捷键与筛选器自定义……标题从"5 分钟快速上手"到"终极指南"层层加码,部分文章收藏数达数十次,形成典型的"教程饱和"形态。这些内容解决的是使用问题:怎么装、怎么配、怎么搜得更好用。

而 GitHub 上起量的这个 fsearch,解决的则是性能与集成问题:Cargo.toml 显示它是一个 Rust 项目(edition 2024),README 的第一句话就是能力宣言——macOS 全盘搜索、约 1 毫秒按名找到任意文件、容忍拼错、带索引的内容检索。它没有把力气花在"教用户怎么配索引",而是把索引、增量更新、模糊匹配、内容检索全部做进了引擎内部,用户拿到的是一个开箱即用的服务(CLI + 常驻守护进程 + Rust crate)。

这两个同名项目恰好演示了生态位的分化:中文社区教程饱和的,是"GUI 秒搜工具的使用方法";GitHub 新星瞄准的,是"搜索作为一个可以被 CLI、应用、Agent 共用的基础服务"。前者是存量需求的教程化消化,后者是新需求的工程化回应。

源码解剖:一个毫秒级全盘搜索引擎的工程答卷

fsearch 的 README.md 给出了硬指标:M4 Max 上 770 万文件与文件夹,按名全盘查找 p50 1.3 ms,内容检索 p50 9 ms,文件新增/改名/删除约 0.1 秒可见,首次全盘爬取约 20 秒(仅一次),守护进程内存 30–135 MB。这些数字背后是一整套环环相扣的工程决策,逐一拆开看。

一次扫描 + 事件增量:索引永不整体重建

全盘索引的第一步是"怎么把磁盘读完"。 src/walk.rs 的注释写得很直白:用getattrlistbulk(2),一次系统调用返回数百个条目,名字、类型、大小、mtime、flag 一次到手,"没有逐文件的 stat";目录在 rayon 线程池上扇出并行,挂载点不跨越、firmlink 照走(这正是 /Users 等在数据卷上的目录以 / 为根恰好出现一次的原因);子目录用openat()相对父目录 fd 打开,路径永不重建,PATH_MAX永远不会咬人。

首次建索引后,日常更新完全交给 FSEvents:src/fsevents.rs 以目录粒度监听/,事件按 id 可重放;src/engine.rs 中的 apply 循环对每个目录事件"只列这一个目录再 diff",diff 是幂等的,所以历史重放、重复事件、与压缩竞争的竞态都无害。重启后只重放上次保存点以来的增量——这也是"首次爬 20 秒、此后永远秒级新鲜"的来源。

把全盘文件名压进一个 mmap 文件

索引的物理形态在 src/index.rs 里是点睛之笔:整个索引就是一块可 mmap 的扁平 blob。关键布局技巧是"按目录块 DFS 序排放条目":于是每个目录的子节点天然连续,每个目录的整棵子树是单一区间dir_start..dir_end——in:范围搜索在 fsearch 里不是过滤器,而是一个区间边界。

更狠的是名字去重:750 万条目只共享约 200 万个不同名字,每个名字只存一次,附带它的字符位掩码;查询对"去重后的名字"打分,而不是对 750 万个条目逐个打分(src/query.rs 注释明确写着"per distinct name (~2M) rather than once per entry (~7.5M)")。一个 64 位的char_mask把名字的字符类压缩成位图,预筛阶段"每个条目一次 AND"就能拒绝磁盘上的绝大多数名字,且完全无分支、保持向量化。

位掩码预筛 + 模糊打分 + 拼错容忍

名字打分在 src/query.rs 里是 fzf-v1 风格的实现:leftmost-ending 匹配、从右侧收缩、边界/驼峰/连续命中加分。模糊匹配之上叠加了拼错容忍:5 个字母以上的词容忍一个拼写错误(错字、多字、漏字、换位均可),代价是固定的 TYPO_COST 扣分,所以同质量的干净命中永远排在前面;数字永不被"纠错"(hat_18 不是 hat_98 的 typo);typo 的候选起点通过name_mask高位的"词首位图"预筛——一次 AND 排除掉所有不可能的名字,不必真的读它。

查询语言本身也直接落到解析器里:'exact、^prefix、suffix$、!exclude,以及ext:、type:、kind:、in:、size:、mtime:、re:、path:、grep:、regex:、sym:、limit:等过滤器。README 中的示例:

fsearch 'readme in:~/Developer' # inside a folder fsearch 'type:image size:>5mb mtime:<7d' fsearch 'ext:rs regex:fn\s+\w+_dir' # regex inside files fsearch 'sym:apply_dir' # where it's defined

内容检索:trigram 索引与"永不 stale 的结果"

文件名之外,fsearch 还做内容检索,实现见 src/content.rs:一个针对文本文件的三元组(trigram)索引。段(segment)是不可变的 mmap 文件,内含文档表 + 每个 trigram 的 posting list(delta varint 编码,命中超过 1/8 文档时自动退化为位图)。

最值得称道的是它的新鲜度设计:trigram 只负责挑选候选文件,命中匹配总是"现读磁盘真验证"——注释里写明 "Results therefore never show stale content; only candidate selection can trail a file written in the last couple of seconds"。也就是说,索引可以稍滞后,但展示的结果永远来自当前磁盘内容。同步方式与名字索引一致:按目录 diff,重索引变化的、墓碑删除的;而 node_modules、.git、target、各类 cache 等目录被显式跳过(src/content.rs 中的 SKIP_DIRS 列表)。

内存治理:从 1 GB 到 30–135 MB

最后一块拼图是内存。 src/main.rs 里有一段很典型的 macOS 工程经验:索引构建和内容批处理会产生大量大块缓冲,而 macOS 的 malloc 会把释放的大块保持 mapped 且 dirty,导致守护进程在构建后滞留约 1 GB 占用、实际存活数据只有约 2 MB。fsearch 的做法是自定义全局分配器:大于 1 MB 的分配直接走mmap、释放即munmap,让大块内存用完立刻归还内核。同一文件里还有setiopolicy_np的调用——永远不让搜索触发 iCloud 占位文件物化(dataless 文件打开/列举快速失败,而不是联网下载)。

实测:与 fff 的同机对比

README 与 demo/vs_fff.py 给出了可复现的对比方法(同一台 Mac、同一组查询、交替先后执行避免热端偏差),演示视频见 demo/fsearch-vs-fff.mp4。在 Chromium 源码库(约 50.9 万文件)上,实测结果如下(数据见 demo/vs_fff_chromium.json):

指标fsearchfff
按名查找(p50,1500 个查询)1.05 ms13.8 ms
内容检索(p50,67 个模式)5.6 ms53.4 ms
名字打错仍把目标排第一98%87.8%
启动后首个查询就绪0.05 s2.5 s
内存占用50 MB(全盘 828 万条目)358 MB(仅该文件夹)

有意思的是 Linux 内核目录(9.6 万文件)上的对照组(demo/vs_fff_linux.json):按名搜索打成平手(1.15 ms vs 1.04 ms),内容检索 fsearch 依然 4.3 ms vs 22.8 ms。README 也如实说明:fff 检索到的文件多约 9%,因为 fsearch 跳过了一部分文件类型和 build/vendor 目录——这是覆盖范围与速度之间的明确取舍,而非隐瞒。

生态位重排:GUI 秒搜、CLI 检索、索引服务三分天下

这波回潮真正的结构性变化,是"本地搜索"从单一形态裂变为三个生态位:

  • GUI 秒搜:Everything、Linux 的 GTK3 FSearch 们,面向桌面用户"手快于脑"的直觉查找,中文社区教程饱和的正是这一层;
  • CLI 检索:ripgrep、fzf 与 fsearch CLI 这一支,面向开发者在终端里的定位与跳转,强调查询语言表达力;
  • 索引服务:把"全盘索引 + 秒级查询"封装成常驻服务,让多个进程共享一份索引。fsearch 正是这一层的代表:fsearch serve跑一个守护进程,通过~/Library/Application Support/FSearch/fsearch.sock上的 JSON-lines 协议应答,fsearch stdio提供标准输入输出通道,任意进程都能以极薄客户端接入:
{"q": "fsearch main", "limit": 20} {"op": "grep", "pattern": "apply_dir", "in": "~/Developer"}

更关键的是多进程共享设计(src/engine.rs):索引文件有flock写锁,第一个进程拥有索引,其他进程作为 follower 加载同一份 mmap 索引、跟随 FSEvents 更新、在主人退出后自动接管——"一个应用和 CLI 共享同一份索引"。README 中甚至给出了直接内嵌为 Rust crate 的 API:

let engine = fsearch::Engine::start(fsearch::Options { dir: fsearch::default_dir(&home), home: home.clone(), skip: None })?; let hits = engine.search(&fsearch::Query::parse("fsearch main", &home)?)?;

这套"索引即服务"的形态,恰好就是 Agent 场景最需要的接口:不弹窗、不交互、毫秒级应答、可编程接入。开头提到的"Everything 搜索技能让 Agent 文件检索翻倍",本质上就是把这一类服务接进 Agent 的工具箱。

下一步看什么

基于现有信号与 fsearch 的技术路线,本地搜索生态的下一轮爆款大概率出现在这几个交叉点:

  • 跨平台落地:fsearch 深度绑定 macOS(getattrlistbulk、FSEvents、TCC 权限模型),但它的索引布局思想——DFS 块序、名字去重、位掩码预筛、mmap 扁平 blob——在 Linux/Windows 上同样成立。谁先把这套性能工程移植到 Linux(那里目前只有 GUI 教程饱和、缺一个现代 CLI/服务实现),谁就吃到第一波红利;
  • 内容索引的精度军备:trigram 候选 + 现读真验的方案证明了"索引负责召回、磁盘负责验证"的正确性,下一步是索引文件类型边界的扩展与索引延迟的进一步压缩;
  • Agent 原语标准化:Cloudflare 的"搜索原语"论述与 Cursor 的文本索引实践说明,搜索 API 的形态(JSON-lines socket、stdio、Rust 内嵌)会逐渐收敛为事实标准,谁能提供"单进程索引、多进程消费"的最省心方案,谁就更接近爆款;
  • 共享索引的生态化:"第一个进程拥有、其余跟随、主人退出自动接管"这种优雅的共享模型,如果配上 WebSocket/HTTP 网关,就是一个本地的、私有的、毫秒级的"知识检索基础设施"。

Everything 式秒搜在桌面时代解决的是"找不到文件"的焦虑;在 Agent 时代,它要解决的是"机器找不到文件"的瓶颈。当 Cursor、Cloudflare、Windows 11 与开源社区在同一时间把目光投向本地索引,而 fsearch 用 1.3 ms 的中位数和 30–135 MB 的内存给出了一份工程答卷时,可以确定:本地搜索不是回归,而是带着新的生态位重新出发了。

【免费下载链接】fsearchWhole-disk file search for macOS: fuzzy names, typo tolerance, indexed content grep. ~1 ms over 8M files.项目地址: https://gitcode.com/gh_mirrors/fsea/fsearch

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询