AI端侧应用、氛围编程
开源jevcache:Jev的决策缓存,省下重复调用
#Jev分类模型
#缓存教程
#GitHub工具库推荐
2026-09-21
4K
banq
jevcache 把 TypeSafe Jev 返回的类型化决策存进一个本地文件,让第二次同样的决定不用再问模型!
这件事听着小,但它触到了一个所有用 AI 做判断的人都会碰到的麻烦!
jevcache 是一个命令行工具,它围绕 TypeSafe 推出的 Jev 模型工作。Jev 不写文字,只接收一段状态和几个预设问题,返回类型化答案——从选项里选一个、给一个分数、或者给一个是或否,每个答案带一个校准过的概率。jevcache 做的事是:把 Jev 已经做过的决定,按照脱敏后的状态指纹存下来,下次遇到同样指纹,直接返回缓存里的答案,不再调用 Jev,也不调用任何模型。这个工具用 Rust 写成单个二进制文件,体量在两到三兆之间,没有运行时依赖。它把自己描述成一份决策账本,而不是一个模型代理。
Jev 把生成文字的活儿砍掉了,只留下选择
TypeSafe Jev 在 2026 年 9 月 15 日进入早期访问,创始人是前 OpenAI 研究员 Diogo Almeida,他参与过 InstructGPT 论文和 RLHF 训练流程的早期工作。TypeSafe 把 Jev 叫做 System One 模型,用丹尼尔·卡尼曼那套快思考与慢思考的区分来定位自己:前沿大语言模型走的是慢的、逐步推理的路线,Jev 走的是快的、直接判断的路线。
Jev 接收一段非结构化状态——一封邮件、一条日志、一张工单、一段 JSON——外加一组类型化问题。你让它从三个工具里选一个,它只会返回那三个里的一个,不会自己编出第四个。这个设计换来的是一个很窄但很硬的性质:Jev 不能幻觉出一个不存在的选项,因为它根本不生成文字。它仍然可能选错,但选错和编出一个不存在的选项是两回事。
TypeSafe 公布的数字说,Jev 在自家工作流评测里比对照的大语言模型快 193.6 倍,便宜 444.6 倍,端到端延迟在 70 到 500 毫秒之间,输入价格是每百万 token 收 0.042 美元,输出不收钱。这些是发布方的说法,独立验证还没有大规模出现。
jevcache 缓存的东西,和你见过的缓存都不一样
常见的 AI 缓存分两种。一种是精确匹配缓存,同样的提示词字符串回来,直接返回上次的响应。另一种是语义缓存,把提示词转成向量,找最近邻,判断“差不多意思”就复用结果。LangChain 的 RedisSemanticCache 走的是第二条路,它把提示词文本存成可搜索文本,用向量嵌入做语义相似度查找。
jevcache 走的是第三条路。它不存提示词,不存向量,也不存模型生成的文本。它存的是 Jev 返回的类型化决策:选了什么选项、打了多少分、布尔值是真是假,外加那个决策对应的状态指纹。指纹的生成方式是先对状态做脱敏和规范化——去掉邮箱、、长串数字,去掉 ID 和时间戳——然后对处理后的内容做哈希。jevcache 的说法是,个人信息和易变字段永远不会进入缓存键。
这个区别可以亲手试出来。你拿一段客服工单的 JSON,问 Jev 三个问题:该走退款流程吗?该升级给人工吗?该标记为高风险吗?第一次运行,jevcache 把 Jev 的三个答案和工单脱敏后的指纹写进本地账本。第二次运行,你把工单里客户的邮箱改掉,把时间戳更新,jevcache 算出的指纹不变,直接返回缓存里的三个答案,一次模型调用都不发生。语义缓存做不到这一点,因为改了邮箱和时间的文本,在向量空间里会漂移。精确匹配缓存也做不到,因为字符串已经变了。
Jev 自己都不是确定性的,那 jevcache 凭什么说确定性
这里要引入一个让 jevcache 的叙事变得微妙的事实。有一个开发者拿自己博客的 183 篇文章,每篇附上四个相同的问题,总共 732 个判断,跑三遍 Jev,然后对比三次结果。三次完全相同的答案只有 177 个,占比 24%。另外 555 个都发生了移动。移动幅度不大:中位数漂移 0.010,p90 是 0.030,p99 是 0.050,最坏的一个案例漂移了 0.070。flagged-post 的数量三次分别是 56、56、57。
这个测试的作者写了一句很精确的话:Jev 不是“同样输入给出同样答案”,而是“同样输入给出误差在十分之一以内的答案”。漂移不是均匀分布的,它集中在概率的中间地带。一个打 0.03 的帖子三次都是 0.03,一个打 0.72 的帖子下一次变成了 0.68。Jev 在它确定的时候几乎不动,在它不太确定的时候会晃。
这件事直接撞上 jevcache 的宣传语。jevcache 说自己提供“确定性重放”,说“同样的决定,更少的账单,在 CI 里可以确定性回放”。但 Jev 本身并不是确定性的。如果 Jev 每次返回的概率值都在漂移,jevcache 缓存的到底是什么?
关键在于 Jev 返回的是一个类型化答案加一个概率。类型化答案是离散的:退款或不退款,高优先级或低优先级,风险是或否。概率是连续的,会漂移。jevcache 缓存的是那个离散答案,不是概率值本身。只要 Jev 在一个状态下连续两次都选“走退款流程”,即使第一次置信度是 0.72,第二次是 0.68,缓存里存的都是同一个选项。
但这里有一个没有被 jevcache 的公开文档明确处理的边界。如果 Jev 的概率漂移恰好把一个决策从“是”推过了阈值变成“否”,或者从“高优先级”推到了“中优先级”,那么缓存的决策和重新调用 Jev 得到的决策就会不一致。漂移中位数 0.010 意味着大部分情况下不会跨过阈值,但 p99 的 0.050 和最坏情况的 0.070 意味着,在一个足够大的决策集里,总会有一部分答案处于阈值附近,漂移会把它们推到另一边。jevcache 不解决这个问题,它只是把这个问题从“每次调用都会遇到”变成了“只在缓存未命中时遇到”。
分享缓存文件的动作,把决策的责任也一起分享了
jevcache 有一个 publish 命令。它把你本地账本里已经缓存的决策打包成一个 JSON 文件,一个 schema 一个文件,里面只有指纹和答案,没有原始状态。你可以把这个文件托管在任何地方,别人用 jevcache add 加进来,他们的 recall 就开始命中你的决策。
这个机制在工程上很干净。两个团队做同一种客服工单分类,一个团队跑了一千两百多条工单,把缓存发布出来,另一个团队直接加载,不用重新调用 Jev,不用付钱,不用等延迟。缓存文件是纯 JSON,可以打开看,可以审。jevcache 还支持发布到 gist,或者发布到它自己的托管索引。
但这里面有一个需要想清楚的事。你发布的缓存里,每一个决策都是 Jev 在某个时刻、对某个脱敏后的状态、返回的一个类型化答案。别人加载了这个缓存,他们的 recall 命中时,拿到的答案不是他们的 Jev 算出来的,是你的 Jev 算出来的。如果 Jev 的漂移恰好让你的那个决策处于一个不稳定的位置,你缓存了“是”,别人却会一直拿到“是”,直到他们遇到一个未命中的状态。jevcache 的 salt 机制可以让别人无法枚举你的状态空间,但 salt 防的是逆向工程,不防决策漂移。
还有一个更安静的张力。jevcache 说“recall 只查本地账本,从不调用后端”。这句话在操作上是准确的,但在语义上会给人一个印象:缓存里的决策是确定的。实际上缓存里的决策是“某一次 Jev 运行的结果被冻结了”。冻结带来确定性,但冻结的是那个历史时刻的输出,不是 Jev 本身的性质。如果 TypeSafe 更新了 Jev 的权重,或者调整了某个内部采样参数,你缓存里的旧决策不会自动失效。它们会一直命中,直到你手动清掉账本。
一个缓存文件解决了一个问题,同时把另一个问题藏进了指纹里
jevcache 的核心动作可以概括成一个很短的流程。状态进来,脱敏器抹掉身份信息和易变字段,规范化器把结构理顺,哈希器产出一串指纹,指纹去账本里查,命中就返回,未命中就交给 Jev,然后把答案和指纹写回去。分享的时候,只导出指纹和答案的那一层。
这个流程的干净之处在于它把“状态”和“决策”切开了。状态留在本地,决策可以流动。对于隐私敏感的场景,这个切割本身就是价值。一封客服邮件里的客户姓名和订单号永远不会离开你的机器,但“这封邮件应该走退款流程”这个决策可以分享出去,让另一个运行同样流程的人直接命中。
但是指纹的生成方式决定了这个系统能命中什么。jevcache 把脱敏和规范化做在哈希之前。这意味着两个内容不同但决策相关的结构,如果脱敏和规范化之后落到了同一个指纹上,就会命中。反过来,两个决策相同但结构化方式不同的状态,可能落到不同的指纹上,就不会命中。jevcache 没有公开它的规范化算法细节。指纹的粒度和语义等价性的边界,是这套系统里最需要自己动手测的部分。
现在回到那个 732 个判断里只有 24% 完全相同的测试。它测的是概率值,不是类型化答案。类型化答案的稳定性没有在那个测试里被单独报告。有可能类型化答案的稳定率远高于 24%,因为大部分决策的概率值虽然漂移了,但没有漂过分类的边界。也有可能有一些决策恰好坐在边界上,漂移把它们推来推去。这个数据缺口决定了 jevcache 在实际生产里的命中质量和答案一致性。在有人把类型化答案的跨运行一致性单独测出来之前,你只能自己拿自己的 schema 和状态去试。先拿二十条真实状态跑三遍,看看你的类型化答案有多少是稳定的,再决定要不要把缓存分享给别人。