xerj 本地 AI 检索索引上手与编程助手接入实战

工具概述

xerj 是一个用 Rust 写的本地检索引擎,Apache-2.0 授权,仓库在 GitHub 的 xerj-org 组织下。它解决的痛点很具体:编程助手在代码库里找东西时,习惯用的是 grep 和 sed,一遍遍把整段文本读进上下文,token 烧得飞快,还常常找不准。xerj 的思路是把目录先索引一遍,之后让助手去「查」而不是「读」。

它有几条关键设计。一是 autoindex,零配置一条命令索引任意文件夹,代码、文档、日志、PDF 都能吃,索引完就能被助手检索。二是混合检索,支持 BM25、kNN 以及两者混合,另外提供 signature 模式,官方称比返回完整函数体少 74.7% 的字节数——这对上下文预算紧张的助手意义很大。三是 reference coding,它会下载并索引最接近的开源仓库,让助手在写代码前先看看别人怎么解决的。四是内置 agent memory,通过 /__memory 之类的端点给助手一个跨会话的持久记忆层。五是 MCP 原生,开箱就能接 Claude Code,另外还有 llms.txt 端点。

关于效果,需要把两个数字分清楚。仓库简介里写的是「比 grep 少 40 倍 token」,但 README 自己给出的实测数据要保守得多:参考编码场景 8 个任务、每个分支各跑 16 次,纯记忆方案输出 token 260916、成本 11.18 美元、16 次里解出 11 次;grep 驱动方案 26477 token、3.27 美元、16/16;xerj 方案 9982 token、1.58 美元、16/16。也就是说,相对 grep 是 2.7 倍,相对纯记忆是约 26 倍,README 还提到用户日常体感约 5 倍。用 2.7 倍这个数去评估,比用 40 倍靠谱。

Elasticsearch 兼容是它另一个实用点:实现了 ES 的 API,通过 1369 项一致性用例中的 1366 项,现有 ES 客户端和 Kibana 可以直接指过来。作者特意说明它「兼容 API,但不是 ES 内部实现的分支或重写」。

环境准备

最小依赖非常轻,这也是 Rust 单二进制的优势。

项目最小要求说明
操作系统Windows 10+ / macOS 12+ / 主流 Linux提供静态二进制
内存2 GB 起大仓库索引时按文件量增长
磁盘视索引规模--data-dir 指定,建议 SSD
Rust 工具链仅源码构建需要stable 即可

默认只绑定 127.0.0.1,也就是只监听本机回环,这点对开发者机器是友好的默认。默认词法检索不需要任何 API Key,完全离线可用——但有一个例外,开启可选的 rerank 会把文本发到远端服务器,这一点后面单独讲。

如果你打算索引的是公司代码库,先确认两件事:一是索引目录里有没有 .env、密钥文件这类敏感内容,autoindex 是「整个目录」级别的,不会自动帮你跳过;二是你准备让哪台机器上的助手来连它,默认回环绑定意味着远程机器连不上。

安装部署

三个平台各有官方安装脚本,另有一条源码构建路线适用于所有平台。

Windows

# 官方安装脚本(PowerShell)irm https://xerj.org/get.ps1 | iex# 校验xerj --version

irm ... | iex 是把远端脚本喂给 shell 执行的写法,方便但有风险。机器上存着凭据的话,建议先 irm https://xerj.org/get.ps1 | Out-File get.ps1 把脚本落盘看一眼再执行,或者直接走源码构建。

macOS

# 官方安装脚本curl -fsSL https://xerj.org/get | sh

xerj --version

Linux

# 官方安装脚本curl -fsSL https://xerj.org/get | sh# 或源码构建(稳定版 Rust 工具链)git clone https://github.com/xerj-org/xerj.gitcd xerj
cargo build --release -p xerj-server
./target/release/xerj-server --version

容器化部署的话,把 --data-dir 挂到宿主机卷上,避免重建容器后索引丢失:

services:  xerj:    image: xerj-server:local    command: ["--insecure", "--data-dir", "/data"]    ports:      - "127.0.0.1:9200:9200"    volumes:      - ./xerj-data:/data

快速上手

先把服务跑起来,再索引一个目录,然后发一条查询验证。Windows 与 macOS/Linux 的命令基本一致。

# 1) 后台启动服务,数据落在当前目录的 ./dataxerj --insecure --data-dir ./data &# 2) 一条命令索引整个项目目录xerj autoindex ~/my-project# 3) 自然语言查询xerj search "where do we validate webhooks"# 4) 查看定义xerj def validate_webhook# 5) 查看这次流程省了多少 tokenxerj gain

索引完成后,xerj search 返回的是命中的文件与行号,助手据此拉取精确的上下文片段,而不是把整个文件读进来。想走 Elasticsearch 兼容路线的话,直接用你熟悉的 ES 客户端指到本机端口即可,查询 DSL 不用重写;现有的 Kibana 也能连。

# 用 ES 客户端验证连通性curl -s "http://127.0.0.1:9200/_cat/indices?v"

编程助手接入实战

这一步是 xerj 真正的价值所在:把索引暴露给 Claude Code 或 Cursor。下面按执行顺序走一遍,先讲接入,再讲怎么用好。

第一步,确认服务在跑且索引已完成。用 curl -s http://127.0.0.1:9200/_cat/indices?v 看到你刚建的索引名,再往下走。

第二步,一行接入编程助手。xerj init 会把 xerj 以 MCP server 加一个 skill 的形式装进 Claude Code 或 Cursor,装完在助手里就能直接调用检索能力,不需要手工拼命令。

# 接入 Claude Code / Cursor(MCP server + skill)xerj init# 其他 MCP 客户端,用 mcp 子命令暴露工具(共 13 个)xerj mcp

第三步,验证接入是否成功。在 Claude Code 里问一句与代码库相关的问题,观察它是否调用了 xerj 的工具而不是去 grep。如果它还在 grep,通常是 skill 没被加载,检查 xerj init 输出里写到的配置文件路径是否落在助手实际读取的位置。

第四步,把 reference coding 用起来。这是省 token 最猛的一项:助手写代码前先检索相似开源实现,复用成熟解法再动手,官方数据显示这一步能显著降低输出 token 与错误率。用法上建议在项目开始时让它先检索一轮,把参考实现作为上下文锚定,再进入编码。

第五步,用 xerj gain 做量化复盘。它会报告本次流程的 token 节省情况。建议的做法是:挑一个你熟悉的任务,分别用「纯 grep」和「接了 xerj」各跑一次,对比你自己环境下的比值,再决定要不要推广到整个团队。别人的 2.7 倍不一定是你的 2.7 倍。

进阶用法

混合检索的取舍。 纯 BM25 对精确标识符、错误信息、日志关键字最快最准;kNN 语义检索适合「这段逻辑大概在哪」这类模糊描述。代码库问答建议开混合,日志与事故分析用 BM25 更稳。

signature 模式省上下文。 检索函数时只返回签名而不是整个函数体,官方称比返回完整 body 少 74.7% 字节。让助手先扫签名定位,再按需展开具体几个函数,是控制上下文的实用手法。

Agent 长期记忆。 内建的 memory 端点可以给助手一个跨会话的持久记忆层,适合把「这个项目的约定」「上次的结论」沉淀下来。注意记忆是命名空间隔离的,多项目并行时别共用同一个命名空间。

安全审计场景。 跨文件类型查询危险模式和密钥泄露,是 README 列出的用例之一。因为它索引的是全量文件,比逐个 grep 更容易发现散落在配置、日志、文档里的凭据。

离线环境。 默认词法检索用离线 embedding,无云依赖,气隙环境可用。这是它相对托管 RAG 服务的硬优势。

常见问题与排查

坑一:--insecure 模式没有 TLS 也没有鉴权。 这是最大的风险点——在这个模式下,任何能访问到端口的调用者都是超级用户,可以读写全部索引数据。开发机上回环绑定问题不大,一旦你把端口暴露到局域网或容器外部,就等于开了一个无认证的全文数据接口。正确做法是保持默认只监听 127.0.0.1;确实需要远程访问时,套一层反向代理做 TLS 与鉴权,不要直接暴露。

坑二:开启 rerank 会把文本发到外部服务器。 默认词法检索不需要 API Key 也不外发,但可选的 rerank 功能会把文本送到远端。处理涉密代码或合规数据时,确认 rerank 处于关闭状态,或者明确接受这个外发行为后再开。

坑三:autoindex 把不该索引的文件也吃进去了。 它索引的是整个目录,不会自动跳过 .env、密钥、大型二进制。索引前先确认目录内容,或者在索引后检查索引条目。已经索引了敏感内容的,清理对应索引并重新索引。

坑四:索引用了默认的 data 目录,重装后找不到。 用 --data-dir ./data 显式指定位置,并把它挂到稳定路径或卷上。容器部署尤其容易踩这条——容器删了索引也没了。

坑五:ES 兼容性不是 100%。 官方自述通过 1366/1369 项一致性用例,也就是说有 3 项不通过。如果依赖了冷门的 ES 特性,迁移前先跑一遍你的查询集验证,不要假设完全等价。

总结与选型建议

xerj 的定位清晰:给编程助手一个本地的、可查的、省 token 的检索层,顺带兼容 Elasticsearch 让存量工具链能直接复用。它不是通用搜索引擎,也不是向量数据库替代品,而是「助手读代码」这件事的一个更便宜的入口。

建议采用的情况:代码库规模已经大到助手 grep 起来明显吃力;团队想控制助手的 token 成本;需要在气隙环境里给助手配检索能力;或者已有 ES 客户端/看板想换掉 JVM 这个重依赖。

建议观望的情况:只有小项目,grep 完全够用,引入一层索引属于额外运维成本;或者你对远端 rerank 的数据外发有硬性合规限制,而你的场景又强依赖语义 rerank。

落地建议从小范围开始:先索引一个你最熟的项目,用 xerj init 接进 Claude Code,跑一个真实任务,用 xerj gain 看节省比例。数据站得住再推广,别先被「40 倍」这个仓库简介里的数字带跑。