< 返回版块

egolearner 发表于 2026-11-06 15:06

Tags:RAG, agent, LLM

zg(zvec-grep)把 向量语义检索、BM25 关键词检索和 ripgrep 精确匹配装进了同一个本地命令行工具,同时通过 MCP 提供给 Claude Code、Codex、Cursor 等 AI Agent 使用。0.3.0 版本用 Rust 完整替换了原来的 Node.js 实现:安装包体积减少 79.5%,CLI 启动耗时减少 82.5%,索引构建耗时减少 64.5%,构建期峰值内存降低 53.2%。

项目地址:https://github.com/zvec-ai/zvec-grep


一、zg 是什么

zg(zvec-grep)是阿里巴巴开源的本地检索工具,面向人和 AI Agent,把向量语义检索、BM25 关键词检索和 ripgrep 精确匹配整合到同一个入口。

zg 演示:安装 Agent 集成、为工作区建立索引,再让 Agent 用 zg 检索

rg 是很多 Rust 开发者每天都在用的工具。函数名、配置项、报错信息这类明确目标,用 rg 查又快又准,而且能搜全。

但现在越来越多的检索请求来自 AI Agent,输入也从明确的符号变成了自然语言:“启动时怎么恢复主题偏好?”“用户权限在哪里校验?”。代码里对应的实现可能叫 hydratePreferences,文档里可能写成“账号授权与审批”,和问题本身没有一个相同的词。这种时候只用文本匹配,要么漏掉,要么把范围放得很大,得到一堆没有排序的匹配行。Agent 只能反复换关键词、搜索、读文件,工具调用次数、耗时和 Token 都会上去。

zg(zvec-grep) 就是为这个问题做的本地检索工具。它保留 rg 精确、快速、可以穷尽匹配的优点,再补上语义发现、相关性排序和上下文组织:

  • 一个入口,多种检索:向量语义检索、BM25、二者混合检索(RRF 融合排序),以及 rg 风格的精确/正则匹配。可以先按语义找方向,再按关键词收窄,最后用正则精确核对。
  • 理解代码结构:借助 tree-sitter 解析 C/C++、Go、Java、JavaScript/TypeScript、Python、Rust 等语言,按符号、签名和层级切分;Markdown 按标题和章节切分;JSON、TOML、YAML、CSV 等文本数据也能参与检索。
  • 结果紧凑、来源可查:默认返回排序后的紧凑预览,每条结果带文件路径和行号,需要时再读全文,避免无关内容塞满 Agent 的上下文。
  • 默认本地运行:文件扫描、Embedding、索引和检索默认都在本机完成。内置多种端侧模型,远程 Embedding 必须经过用户明确授权才会启用。
  • 人和 Agent 共用一份索引:zg 底层用 Zvec 嵌入式向量数据库同时存放向量索引和 BM25 索引,不用另外部署数据库服务。CLI 和 MCP 读写的是同一份索引,并支持增量更新和自动刷新。

在代码仓库问答 SWE-QA-Bench 和深度研究问答 BrowseComp-Plus 的配对 A/B 评测中(同一 Agent、同一模型、同一 Prompt,只比较是否接入 zg):

  • SWE-QA-Bench:工具调用减少一半以上,输入 Token 减少近一半,评审得分提高 1.50 分;
  • BrowseComp-Plus:准确率从 98.67% 提高到 99.00%,输入 Token 减少 37.56%,工具调用减少 43.52%,Agent 耗时减少 38.58%。

二、从 Node.js 到 Rust:重写带来了什么

为什么重写

zg 的前几个版本(0.2.x)用 TypeScript/Node.js 实现。对一个高频调用的命令行检索工具来说,这个运行时有几个绕不开的成本:

  • 每次单独调用 CLI 都要启动 Node.js 运行时并加载 JS 模块,Agent 连续调用时,这部分时间会累积起来;
  • 部分索引路径要在 JavaScript 普通数组和 TypedArray 之间转换,还要在 worker 线程之间传数据,带来额外的复制和临时内存分配;
  • 安装包要带上整套 JS 依赖和原生插件,体积很大。

大型工作区和 Agent 工作流对索引耗时、查询延迟和资源占用都很敏感,所以我们用 Rust 重写了整条核心执行链路。

性能对比

测试环境:Apple M3 Pro、18 GB 内存、macOS 27.2,Node.js v24.16.0。索引数据集使用 BEIR 中的 SciFact、NFCorpus、ArguAna 和 FiQA 四个公开语料,共 75,128 篇文档。两个版本使用同一个本地 Embedding 模型,都走 CPU 推理,Embedding 并发设为 4。

指标 Node.js 0.2.2 Rust 0.3.0 改善
安装包体积(含依赖) 167.5 MiB 34.3 MiB 减少 79.5%
CLI 启动耗时 153.1 ms 26.8 ms 减少 82.5%
索引构建总耗时 219.13 s 77.84 s 减少 64.5%
平均构建峰值内存(RSS) 4,210.26 MiB 1,968.61 MiB 降低 53.2%
平均检索耗时(MCP) 20.93 ms 14.88 ms 减少 28.9%

换算成实际体验:四个语料的首次建索引时间从约 3 分 39 秒缩短到约 1 分 18 秒;构建期峰值内存从约 4.11 GiB 降到约 1.92 GiB,而且四组测试每一组都下降了。本机同时开着编辑器、Agent 和其他开发工具时,这部分内存节省很明显。

性能从哪里来

  • 原生启动:直接运行编译好的原生程序,不再需要初始化 Node.js 运行时和加载 JS 模块。CLI 冷启动从 153 ms 降到 27 ms。
  • 计算路径更直接:文本编码和向量计算在原生代码中完成,使用明确的数值类型和连续内存数组,编译器更容易优化计算循环。
  • 减少中间转换:计算结果一直以原生数值数组的形式存在,不再在 JS 普通数组和 TypedArray 之间来回转换,数据复制和临时分配都少了。
  • 共享资源、统一调度:在支持的本地推理路径上,各计算线程共享已加载的分词器和模型数据,避免重复初始化,任务由原生线程池统一调度。

三、上手:安装与使用

1. 安装

zg 目前通过 npm 分发(后续会支持其他安装方式),运行时直接执行原生程序,不依赖 Node.js。支持 macOS、Linux 和 Windows。

npm install -g @zvec/zvec-grep --allow-scripts=@zvec/zvec-grep
zg --version

安装依赖 npm 的 postinstall 脚本把原生程序放入合适位置和按需下载CUDA,所以要加上 --allow-scripts 允许它运行。

2. 接入 AI Agent(可选)

# 自动发现本机已安装的 Agent 并配置 MCP
zg --install

# 也可以指定目标,例如 Claude Code / Codex / OpenCode
zg --install --target claude --yes
zg --install --target codex --yes

目前支持的目标包括 claude、codex、opencode、cursor、qwen、qoder、copilot、vscode、grok、pi。配置完成后重新连接 Agent,Agent 会根据问题自己判断什么时候调用 zg。

3. 建立索引

cd your-repository

# 默认使用面向代码的轻量本地模型 local/potion-code-16m-v2
zg --index

# 查看索引覆盖范围、Embedding 模型和存储状态
zg --status

索引保存在工作区根目录下的 .zvec-grep/。之后文件有变化时只做增量处理,内容没变的文件不会重新计算 Embedding。如果要换模型,用 zg --index --rebuild --embedding <model> 重建索引。

在交互式终端里,即使跳过这一步直接搜索,zg 也会先引导你选模型并建好索引。脚本或 CI 这类非交互环境不会自动建索引,需要先显式执行 zg --index。

4. 检索

# 自然语言 / 语义检索(默认混合检索:向量 + BM25,RRF 融合排序)
zg "where is the connection pool timeout configured"
zg "用户权限在哪里校验"

# 只走 BM25 关键词检索,或只走向量检索
zg --fts "AuthService"
zg --vector "retry with exponential backoff"

# 同时执行多个查询,--fuse 把多组结果合并后统一排序
zg --hybrid "connection pool" --hybrid "socket timeout" --fuse

# 用 rg 风格做精确/正则匹配(不需要索引)
zg --rg -n "AuthService" src
zg --rg -F "fn main(" crates

# 限定范围:文件类型、glob、条数
zg "error handling for invalid config" -t rust -g 'crates/**' --limit 5

# 调整预览详细程度:none / short(默认)/ full / detail
zg --preview detail "how indexing jobs are scheduled" --limit 3

5. 示例:用小说测试一下

mkdir zg-mystery && cd zg-mystery
curl --retry 3 --retry-all-errors --progress-bar -fL \
  -o alice-in-wonderland.txt https://raw.githubusercontent.com/GITenberg/Alice-s-Adventures-in-Wonderland_11/master/11.txt \
  -o sherlock-holmes.txt https://raw.githubusercontent.com/GITenberg/The-Memoirs-of-Sherlock-Holmes_834/master/834.txt

# 语料是英文小说,换用面向文本检索的本地模型
zg --index --embedding local/potion-retrieval-32m

zg --preview detail "An unseen creature left a few marks. What did the detective infer?" --limit 3

查询里没有出现 Holmes、weasel、foot-marks 这些原文用词,zg 依然会把《福尔摩斯回忆录》中《驼背人》里根据脚印推断动物的段落排在最前面,并给出具体行号。


四、写在最后

zg 0.3.0 是 Rust 版的第一个正式版本。接下来我们会继续推进图检索与重排、PDF/Office 等更多内容格式、更高的上下文效率,以及本地模型和索引的性能优化。

欢迎 Rust 社区的朋友试用,也欢迎提 Issue、PR,或者分享你在大型代码库、知识库和 Agent 工作流里的使用情况:

如果觉得有用,欢迎给项目点个 Star。


Ext Link: https://zvec.org/zh/blog/2026-11-03-zvec-grep-rust/

评论区

写评论

还没有评论

1 共 0 条评论, 1 页