这几天 Jev 到处都是。TypeSafe 管它叫 System One 模型:不生成文本,你给它一段内容和一道有固定选项的题,它直接给每个选项的概率。输入 0.042 美元一百万 token,输出免费。
这种模型正好能拿来做 grep。
grep ERROR app.log 干的事,是对每一行问同一个问题:这行有没有 ERROR?把问题换成“这行是不是在说磁盘出了问题”,grep 就变成了按意思搜。想法不新,llm-grep、mgrep、grepai 都做过。以前的麻烦是,要么让大模型慢慢生成一个 yes,要么先把目录切块算 embedding 建索引。Jev 的接口正好就是“一行文本加一个问题,返回一个概率”,一次请求能塞几十行一起答,按输入算钱。
于是有了 jevgrep。Go 写的单个二进制,命令行照抄 grep,只是 PATTERN 换成一句话。下面的输出都是在这个仓库上实际跑出来的。
翻日志
仓库里有一份 10 行的示例日志:
2026-09-18 03:11:07 INFO GET /healthz 200 3ms
2026-09-18 03:11:41 INFO user 4182 signed in from 10.0.0.7
2026-09-18 03:12:02 WARN retrying upstream payments-api (attempt 2)
2026-09-18 03:12:19 ERROR write /var/lib/pg/base/16384: input/output error
2026-09-18 03:12:19 INFO cache warm: 12840 keys
2026-09-18 03:13:44 WARN smartd: 1 uncorrectable sector on /dev/nvme0n1
2026-09-18 03:14:02 ERROR payment 9931 declined by issuer
2026-09-18 03:15:10 INFO nightly backup finished in 4m12s
2026-09-18 03:16:33 ERROR no space left on device while flushing WAL
2026-09-18 03:17:01 INFO GET /healthz 200 2ms
假设想看磁盘相关的问题。grep ERROR 会给三行,支付被拒那行跟磁盘没关系;第 6 行 smartd 报告 NVMe 有坏扇区,这行最该看,但它是 WARN,grep 找不到。
$ jevgrep -np "a disk or filesystem error" examples/app.log
4:0.96:2026-09-18 03:12:19 ERROR write /var/lib/pg/base/16384: input/output error
6:0.78:2026-09-18 03:13:44 WARN smartd: 1 uncorrectable sector on /dev/nvme0n1
9:0.89:2026-09-18 03:16:33 ERROR no space left on device while flushing WAL
-n 是行号,-p 会把模型给的概率一起打出来,默认 0.5 以上才算匹配。
排查问题时更常见的情况是,不知道要找什么,只知道健康检查、正常请求这些不想看。这时用 -v 反选,描述一下噪音长什么样就行:
$ jevgrep -vn "routine noise: a health check, a successful request, or a progress message" examples/app.log
2:2026-09-18 03:11:41 INFO user 4182 signed in from 10.0.0.7
3:2026-09-18 03:12:02 WARN retrying upstream payments-api (attempt 2)
4:2026-09-18 03:12:19 ERROR write /var/lib/pg/base/16384: input/output error
6:2026-09-18 03:13:44 WARN smartd: 1 uncorrectable sector on /dev/nvme0n1
7:2026-09-18 03:14:02 ERROR payment 9931 declined by issuer
9:2026-09-18 03:16:33 ERROR no space left on device while flushing WAL
healthz、cache warm、备份完成这些都被过滤掉了。也可以正着问,值班的人该看哪几行:
$ jevgrep -np "something an on-call engineer should look at" examples/app.log
3:0.82:2026-09-18 03:12:02 WARN retrying upstream payments-api (attempt 2)
4:0.95:2026-09-18 03:12:19 ERROR write /var/lib/pg/base/16384: input/output error
6:0.94:2026-09-18 03:13:44 WARN smartd: 1 uncorrectable sector on /dev/nvme0n1
7:0.67:2026-09-18 03:14:02 ERROR payment 9931 declined by issuer
9:0.95:2026-09-18 03:16:33 ERROR no space left on device while flushing WAL
支付被拒那行 0.67,不高不低。这行本来就说不清是用户的卡有问题还是支付网关挂了,有个概率比硬给一个是或否更有用。
找代码
比如想知道一个仓库里的配置对象是哪个类型,但不知道它叫 Config、Options 还是 cfg。拿 jevgrep 自己的代码试一下:
$ jevgrep -rn -t 0.9 -g '*.go' -g '!*_test.go' "a struct type definition for a configuration or options object" internal/
internal/apikey/login.go:51:type LoginOptions struct {
internal/cli/options.go:50:type Option struct {
internal/cli/parse.go:30:type config struct {
internal/jev/jev.go:47:type Config struct {
internal/output/output.go:52:type Options struct {
internal/search/search.go:69:type Options struct {
internal/walk/walk.go:46:type Options struct {
7 行,全是 struct 定义,一个没漏。注意这里加了 -t 0.9。搜代码时默认的 0.5 太松,struct 的字段和上面的注释也会跟着进来,同一条搜索在 0.5 下有 41 行。好在抬阈值不花钱:分数缓存在本地,比较也在本地做,第一次跑完之后随便调。
有一种问法不管用,就是直接问“重要的类定义”。试过 "an important class definition",回来 84 行,基本把所有 type 声明列了一遍,没有一行超过 0.9。原因是 jevgrep 一次只看一行,一个类重不重要,一行里没有这个信息。管用的问法是说这个类型是干什么的:装配置的、表示一次请求的、管缓存的。你描述用途,它去找名字。
另外它对注释和代码一视同仁,注释写得清楚的仓库更好搜。
结果也可以喂给别的工具。--json 每行输出一个对象,带文件、行号、原文和分数,给 coding agent 当检索工具正合适:按描述找代码,不用猜标识符。
跨语言
问题和被搜的行不必是同一种语言。上面那份英文日志,直接用中文问:
$ jevgrep -np "磁盘或文件系统出了问题" examples/app.log
4:0.93:2026-09-18 03:12:19 ERROR write /var/lib/pg/base/16384: input/output error
6:0.86:2026-09-18 03:13:44 WARN smartd: 1 uncorrectable sector on /dev/nvme0n1
9:0.91:2026-09-18 03:16:33 ERROR no space left on device while flushing WAL
和用英文问的结果一样。搜代码也行,用 "配置或选项对象的 struct 定义" 加 -t 0.9,前面那 7 个 struct 找到了 6 个,漏掉的 type config struct { 得了 0.89,就差一点。跨语言要注意的就是这个:TypeSafe 自己说中文准确率比英文低,实际用下来是阈值附近的分数会飘。觉得结果不对,先加 -p 看看分数,再决定是改措辞还是改 -t。
多少钱,数据去哪
搜的每个非空行都会发到 TypeSafe 的 API,每一行都计费。这是它和 grep 最大的区别,下面几个设计都是围绕这一点。
--dry-run 什么都不发,也不需要 key,只告诉你会发多少行、大概多少钱。搜一遍 jevgrep 自己的整个仓库,100 个文件、16,315 个非空行,报价 0.031 美元。
分数缓存在本地,同一个搜索第二次跑一个请求都不发,改阈值也不发。缓存里只有哈希和概率,没有内容。
递归搜索永远不会碰 .git/、.env、*.pem、*.key、id_rsa 这类文件,也没有任何选项能打开它们。真要搜一个 .env,只能在命令行上把它的路径写出来。理由很简单,凭据一旦发到远程 API 就收不回来了。
和同类工具怎么选
| 原理 | 建索引 | 数据去哪 | 适合 | |
|---|---|---|---|---|
| grep / ripgrep | 正则 | 不用 | 不出机器 | 知道要找什么字的时候,先用它 |
| semgrep / ast-grep | AST 模式 | 不用 | 不出机器 | 代码结构:调用、定义、类型 |
| mgrep | 向量检索 | 要,持续同步 | 云端 | 大代码库、Agent 集成 |
| grepai / ai-grep | 本地 embedding | 要 | 不出机器 | 隐私优先、离线 |
| jevgrep | 每行一道判断题 | 不用 | TypeSafe API | 日志、工单、管道里的一次性文本;跨语言 |
区别主要在要不要建索引。向量方案先切块、算 embedding、存下来,之后查询在本地做。jevgrep 每次现问现答,每行都发、都计费,换来的是任何文件、任何管道都能直接搜,不用先建索引。日志和工单这种一次性、不断变化的东西适合 jevgrep;几十万行的大仓库天天搜,建索引更划算。
它也替代不了 semgrep。一次只看一行,没有上下文,跟不了调用链。找到 struct 定义之后想看它被谁用,还是得靠 LSP。
局限
要花钱,要联网,没有离线模式。一次只看一行,不看上下文。阈值附近的分数不稳,跨语言时尤其明显。还是 0.x 版本,选项可能会变。
安装
curl -fsSL https://sijiaoh.github.io/jevgrep/install.sh | sh
也可以 go install github.com/sijiaoh/jevgrep/cmd/jevgrep@latest,Windows 用户从 Releases 下载。装好后运行 jevgrep --login,贴上 TypeSafe 的 key 就能用。
会 grep 就会用:-r -l -c -q -A -B -C -n 这些都有,退出码也一样,if jevgrep -q … 照常写。
仓库在 github.com/sijiaoh/jev…,MIT 协议。