你让 Claude Code 查一句“上个月这台机器为什么反复重启”,它 grep 了三轮,吐出几万行日志,上下文窗口直接撑爆,答案还没找对。这不是你不会用提示词,是路线从根上就错了。最近几天,GitHub 上冒出来一个叫 Leviathan 的单文件工具(github.com/elstongun/leviathan),上线不到一周攒了 698 星,思路简单粗暴:把你的数据先建成全文索引,agent 用大白话提问,每次只回一张约 450 token 的引用卡片。官方基准里,同样 100 万条记录,grep 最优策略一次要烧 107,122 token,它只要 436——差 245 倍。这篇文章把它的六个用法拆给你,每一招今晚就能抄。
Leviathan 是一个 Rust 写的单二进制程序(Apache-2.0 协议,Rust 1.88+),把 JSONL、JSON、CSV/TSV、SQLite,或者任何数据库命令行工具的输出,变成一个带排序的全文索引。作者在一份 678 MB、100 万条记录的合成运维日志上做了对比测试(注意:这是官方自测基准,数据集是合成的,方法论文档全部公开可复现):
| 100万条记录下 | Leviathan | 最优 grep 策略 |
|---|---|---|
| 每个问题的中位 token | 436 | 107,122(245倍) |
| 最坏情况 | 602 token | 970 万 token |
| top-5 命中率 | 99.0% | 96.0%(且要吞3万字符) |
| 中位延迟 | 33 ms | 92 ms |
看懂了吗?不是快 20% 的问题,是“能查”和“查不动”的区别。grep 路线下,数据涨到百万条,agent 的上下文就是不可能完成的任务;索引路线下,成本和数据量几乎无关。
cargo install leviathan-index
cd examples/tickets && leviathan index
leviathan search -g acme "sso login loop after password reset"
第三行的意思是:在 acme 这个分组里搜“密码重置后 SSO 登录死循环”。返回的不是一堆原始行,而是一张卡片:标题、状态、优先级、解决方案、命中片段、相关度分数,最后还有一行 shown 3 of 3——告诉 agent“一共 3 条命中,给你看了 3 条”。这个设计很关键:agent 能分清“没搜到”和“没数据”,不会瞎编。
还有一个容易被忽略的细节:退出码。0 是正常(包括零命中),3 是分组名有歧义——这时它列出候选让你选,绝不替你猜。对自动化脚本来说,这是天然的幻觉防火墙。
这是我最欣赏的设计哲学:Leviathan 永远不持有数据库凭据。数据怎么出来,用各家自己的命令行:
# PostgreSQL:psql 管道喂进去
psql "$DATABASE_URL" -At -c "SELECT row_to_json(t) FROM tickets t" | leviathan index - -c tickets.toml
# SQLite:直接 --sql
leviathan index app.db --sql "SELECT * FROM tickets" -c tickets.toml
# 连 Parquet 都行:duckdb 打头阵
duckdb -json -c "SELECT * FROM 'events/*.parquet'" | leviathan index - -c events.toml
构建是原子性的,数据没变就跳过,upsert 和 delete 做增量更新。懒的话跑一句 leviathan init ./export,它会自动推断字段、生成一份带注释的配置文件。不想装 Rust 工具链,Releases 页面有预编译二进制,零运行时依赖。
-g 分组检索是灵魂运维日志按机器分组、客服工单按客户分组、销售记录按地区分组——-g 接受主键、完整名或部分名。组内没命中时,它会自动回退到其他组并打上 OTHER CUSTOMER 标签,不会静默漏掉。中国的技术团队手里最多的就是这类“结构化记录”:Nginx 日志、工单系统导出、监控告警历史。把 group 字段映射到机器名或客户 ID,一个索引就是一个可对话的知识库。
leviathan search -g web-01 --where level=error --since 2026-09-01 "connection reset" -timeout
--where 按字段过滤(映射 filters 字段后可用)、--since/--until 卡时间窗(映射 date 字段后可用)、引号短语精确匹配、-xxx 排除词。另外两个暗门:title 字段在排序里权重是正文的两倍;rank.boost 能让字段更完整的记录排前面。跑一句 leviathan describe 可以自查索引里有哪些字段、分组、可过滤值,把这句塞给 agent,它自己就会拼查询。
这是对国内用户最实用的一招。leviathan wrap 能打印 Claude Code、Codex、Cursor、VS Code/Copilot、Gemini CLI、Windsurf、Cline、Zed、JetBrains 等 24 个 agent 的接入配置,加 --apply 直接写进配置文件:
leviathan wrap claude --memory --hooks --rules --apply
但作者更推荐的方式其实更轻:把仓库里的 skills/leviathan 复制到 ~/.claude/skills/,或者粘进 AGENTS.md/.cursor/rules——待机时零 token 消耗,agent 遇到查库任务才去调命令。不想走 CLI 也可以 leviathan mcp 起 stdio MCP 服务,四个只读工具每会话只占约 640 token。
leviathan serve --http 0.0.0.0:8080
同一套能力摇身变成 Streamable HTTP MCP + REST + OpenAPI 服务,支持 bearer token 或 OAuth 2.1 鉴权。这意味着 claude.ai、ChatGPT、Anthropic/OpenAI 的 API 都能远程连你这个索引。小团队把公共数据(工单、文档、资产清单)建成一个索引,全组的 agent 共用,不用每人本地建一份。
Leviathan 还带一个可选的记忆模块:agent 一次 remember 一条事实,凡是会变的内容都有 key 槽位,新值直接覆盖旧值,不会自相矛盾。官方跑了 300 个会话的对比:会话启动加载 736 token(整份 MEMORY.md 是 33,313),答案在上下文里的比例 100% 对 18%(只读前 200 行的方案),过期信息混入率从 73.8% 压到 0%。已有记忆不浪费,一条命令从 markdown 迁移:leviathan memory import ~/.claude/projects/*/memory/MEMORY.md。密钥类内容它直接拒收,历史版本可查。
flowchart TD
A["原始数据<br/>JSONL / CSV / 数据库"] --> B["leviathan index<br/>字段映射建索引"]
B --> C["一个SQLite文件<br/>FTS5全文索引"]
C --> D["agent用大白话提问"]
D --> E{"解析分组<br/>精确到模糊"}
E -->|命中| F["FTS5一次匹配<br/>BM25乘权重排序"]
E -->|歧义| G["列出候选<br/>exit 3不瞎猜"]
G --> D
F --> H["只解码前N条<br/>截成小卡片"]
H --> I["shown N of M<br/>约450token回灌"]
国内做“AI 查知识库”,第一反应往往是 LangChain + 向量库 + embedding 模型那一整套。两条路线各有地盘:
| Leviathan(BM25 路线) | 向量库 RAG 路线 | |
|---|---|---|
| 部署 | 单二进制,一个 SQLite 文件 | 向量库 + embedding 服务 |
| 成本 | 零模型调用,全离线 | 每次查询要跑 embedding |
| 可解释性 | 关键词命中,分数可追溯 | 相似度黑盒 |
| 弱项 | 语义改写查不准(问“登不上”搜不到“认证失败”) | 运维重,中文分词调优烦 |
工单、日志、表类记录这种“关键词基本会出现在原文里”的数据,BM25 又快又稳;自由的文档问答、同义改写多的场景,向量路线依然更合适。别拿锤子拧螺丝。
| 大多数人还在做 | 老手已经在做 |
|---|---|
| 让 agent 反复 grep 大日志 | 先建索引,agent 只读卡片 |
| 全量灌上下文,烧钱又爆窗 | 每问固定约 450 token |
| MEMORY.md 越滚越肥 | key 槽位记忆,启动只载 736 token |
| RAG 全家桶一步到位 | 结构化数据用 BM25 单文件就够 |
| 每个工具手写接入配置 | wrap 一条命令接管 24 个 agent |
cargo install leviathan-index,拿你手头一份 CSV 导出(工单、日志、账单都行)跑 init + index,用大白话搜三次,感受卡片式返回。skills/leviathan 复制进 ~/.claude/skills/,再跑一次 leviathan wrap claude --apply,让 Claude Code 自己学会查库。serve --http 挂到内网一台机器上,全组 agent 远程共用。一个上周才开源的单文件,解决的却是所有 agent 用户每天都在流血的伤口——这种窗口期,就是信息差最值钱的时候。
本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵爱卫生(微信ID: gprshome201101)维护。 聚焦5G/6G核心网、3GPP标准、AI工具实战。知识星球「51学通信」提供深度技术答疑和行业洞察。
[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。
