我在之前那个 tweet 里提到,Jev 这项工作的意义比我想象的要大一些。一方面,它的输出范式引导我们把决策与生成分离,经过这一轮验证评估,我们发现这种抽象在一些场景下本身就有价值,即使不引入新的模型。在 Nowledge Mem 里,比如记忆审核这样的环节,仅仅把决策和生成分离,我们就已经能观察到审核效果的改善了。
另一方面,我很看好 Jev 这类有泛化和上下文学习能力的协处理、system-one 模型。对于那些需要智能、但不需要生成内容的任务,模型往往需要理解完整的上下文,最后却只需要做几个判断。如果这些能力可以交给不同的子系统,我们就有机会把一部分工作 offload 到“大脑”之外,像我们把习得的能力交给反射、小脑、植物神经这些生物子系统那样。
当然,更显然的是,Jev 本身作为一个 prompt based 的低延迟分类器,无论是用来替代一些原本靠启发式实现的判断,还是用到过去因为延迟和 cost 而无法引入智能的环节,都有很大的价值。
这些想法贯穿了我们这一周多的探索。现在接入 Jev 的 Nowledge Mem 也已经发布了,我们可以把一些观察和实际接入的情况放在一起讨论了。
记忆系统中的语义判断
Nowledge Mem 是我们在做的 context layer 基础设施软件与服务,Mem 帮助个人和团队保存、组织 AI 工作中的上下文,让不同的 agent 能用上之前积累的知识。在这样的系统中,从对话里提炼记忆、整理已经保存的知识,到搜索时选择合适的上下文,很多环节都涉及需要理解语义才能做出的判断。
比如“这次命令执行成功了”和“以后部署前都要做这项检查”,都是刚出现的信息,前者记录一次操作的结果,后者可能是一条以后仍要遵守的工作约定。光看字数、关键词或时间戳,我们很难判断这些信息在时间维度上的含义,以及它们以后还有没有用。
再比如,在准备保存一条记忆时,我们还要检查它有没有来源依据,是否超出了原文的意思,之前有没有保存过,以及它是不是对某个旧决定的更新。这些判断决定了以后 agent 会读到什么样的上下文,一条错误的记忆可能被反复检索和引用,甚至成为其他结论的依据。我们需要在很多地方做这样的判断,但如果每一步都调用一次 LLM,整个流程的开销和等待时间也会随之增加。
Jev 是 TypeSafe 团队做的决策模型(decision model),调用时接收一份材料 state 和一组问题 questions,返回指定范围内的答案和相应的概率。这些问题可以是判断某件事是否成立、从固定选项中选择答案,也可以是按给定标准评分。
有了这样的接口,我们可以把记忆系统里的判断单独定义出来,围绕同一份材料一次问多个问题,再让不同的模型来回答。判断标准可以独立整理和测试,记忆正文、摘要、实体名称这些需要生成文字的工作,则仍然交给 LLM。
先在同一个模型上分离决策与生成
受 Jev 的启发,我们最先在候选记忆的审核环节做了一组优化实验。LLM 从对话里提炼出内容以后,在正式保存之前,还要检查它是否值得长期保留、有没有来源依据,以及是否存在过度解读。原来的实现也有这些审核要求,不过模型要在同一次调用里做几件事:判断候选是否保留,必要时修改标题和正文,最后把整理好的记忆作为 JSON 返回。而这次为了尝试接入 Jev,我们先把各项判断整理成独立的问题,分别说明判断标准和可以选择的答案,让模型只回答这些问题。
在实现的时候,我们把这套接口放进了 DecisionClient,这样 Jev 和 chat 模型都可以用来回答同一组问题。这也让我们能先保持模型不变,只比较任务的组织方式,看看收益究竟从哪里来。
我们让同一个 Kimi k3 用两种方式分别审核了 40 条候选记忆,一组沿用原来的审核方式,另一组只返回问题清单的答案。两组都是每条候选调用一次,结果如下:
模型在判断长期保留价值、识别过度解读这两件事上都有了改善,类型分类的准确率则没有变化。早期的对照实验里,类型分类也曾有过很大的提升,但这次没有复现,所以还不能把那次提升当成稳定的收益(类型分类只统计标注为值得长期保留的 19 条候选)。
这里的满分只是在这 40 条样本上的结果,而且在把审核拆成独立问题的时候,我们也把一些判断标准说得更清楚了。也就是说,前面的对照还不能严格区分改善是来自任务形式的变化,还是标准本身变得更明确。为此,我们又在同一轮消融实验里比较了五种写法,也试了让模型为每个答案补充理由:
| 写法 | 过度解读 F1 | 长期保留价值 F1 | 相对费用 |
|---|---|---|---|
| 原审核方式 | 0.27 | 0.83 | 1.10 |
| 保留原写法,点明容易混淆的情况 | 0.42 | 0.86 | 1.19 |
| 问题清单,每题加一句理由 | 1.00 | 1.00 | 1.41 |
| 问题清单,只给答案 | 1.00 | 1.00 | 1.00 |
| 问题清单,一题一次调用 | 0.82 | 1.00 | 2.83 |
最后一列比较的是完整审核一条候选记忆的费用,按 Kimi 当时的 API 价格计算,并把“问题清单,只给答案”这一组的费用记作 1。
从这组结果来看,只在原来的 prompt 里补充容易混淆的情况,已经能改善审核结果,但还没有达到把每项判断、标准和答案范围单独列出来的效果。而在问题清单的基础上,再要求模型为每个答案写一句理由,审核的分数没有继续提高,费用却增加了。
我们还在写入质量检查和独立的记忆类型分类上做了同样的实验,结果也类似:与只给答案相比,要求模型写出理由,并没有提高质量检查的分数,类型分类的表现也没有变好。三个任务的费用合计增加了约 35%,每次调用的中位延迟也大约翻了一倍:
在这些环节里,程序实际使用的是模型给出的判断,而生成理由会增加费用和等待时间。这几组对照没有观察到相应的质量收益,也让我们有理由重新考虑,哪些文字确实需要模型生成。当然,这里主要测试的是写出理由有没有帮助,不输出理由并不意味着模型内部没有 reasoning。
把每个判断定义成独立的问题以后,具体怎么组织调用,也会影响开销。比如审核一条候选记忆需要回答六个问题,这些问题用的是同一份材料。如果每道题分别调用一次,按照顺序全部完成,审核耗时的 p50 大约是 50 秒,而一次回答六道题只需要 11.6 秒。平均到每道题,就是从 8.4 秒降到了 1.9 秒,费用也减少了约 65%:
这几组实验里,我们一直没有更换 chat 模型,而是分别比较了任务的表达、是否生成理由,以及如何组织调用。为了接入 Jev 而做的抽象,让我们有机会把这些选择单独拿出来评估,并在其中找到一部分收益,这也是我在 tweet 里想分享的第一个观察。
哪些生成工作可以省掉
在评估判断本身的效果之外,我们也把整个后台的模型调用整理了一遍,按每天处理 20 个对话线程、60 条记忆的使用量,估算一个重度用户的月度费用,看看决策模型在整个流程里能影响多少开销。
按这个使用场景计算,判断任务占了一半以上的调用次数,费用却只占约四分之一。主要的开销来自提炼对话、抽取图谱、回填等生成工作,其中有些工作在确认是否有必要之前,就已经开始执行了:
从这个分布来看,只替换判断所用的模型,能直接省下的钱是有限的。但有了 Jev 这类能够理解上下文、调用成本和延迟又比较低的模型,我们就可以更积极地在生成之前增加判断,给昂贵、缓慢的生成任务剪枝。比如对话有了更新之后,先看其中有没有尚未保存、值得长期保留的知识,再决定是否让 LLM 开始提炼。
按前面的使用量估算,如果把原流程的开销记作 100,先不换模型,只把判断放到生成之前,再把可以批量完成的工作合在一起,开销就大约能降到 37。如果进一步把这些判断交给 Jev,按 Jev 团队当时的价格计算,开销约为 26:
按这组假设拆分,约 85% 的节省来自流程调整,包括与 Jev 无关的批处理,另外 15% 来自模型价格的差异。所以,前面估算的收益也很依赖使用方式:实际有多少内容可以跳过、多少工作可以合并处理,都需要用真实流量来验证。
在实际服务上做的小样本集成测试中,我们观察到每个对话线程的费用下降了约 10%–19%,没有前面估算的幅度那么大。这组测试里,候选审核仍由原来的模型负责,我们只记录决策模型的回答,其他几个环节则会根据它的回答决定后续工作。生产用户整月账单的 A/B 对照,我们还没有足够的时间去做。
这里还需要考虑判断之后的处理方式。如果大部分内容仍然需要提炼,或者决策模型的答案还要再交给 chat 模型复核,新增的调用就可能变成额外开销。而那些被跳过的内容,也需要回头检查,确认里面没有本来应该保存的知识。
判断结果怎样影响记忆的写入
在记忆提炼之前做这样的筛选,我们需要同时确认两件事:新增的内容值得长期保留,而且还没有保存过。如果只是一次操作的结果、临时状态,或者已经保存过的知识,就没有必要继续交给 LLM 提炼。
判断知识是否已经保存时,用什么材料来比较也很关键。摘要里提到过某个决定,并不代表它已经写入记忆库。如果上一次写入失败,这次再拿摘要作比较,模型即使正确理解了内容,也可能跳过这条一直没存下来的知识。所以,提供给模型的比较依据,必须来自真正写入成功的记忆。
同样,“没能完成判断”和“没有新增知识”也需要区分。决策调用超时或失败时,我们仍然继续原来的提炼流程,不能因为没拿到答案,就跳过这段内容。
在提炼之后的候选审核里,错误放行的内容,后面还有去重和写入质量检查的机会;而被错误拒绝的内容,就不会再进入保存流程。我们需要根据这两种后果分别确定采用答案的条件,不能让所有判断共用一个 confidence 阈值。
我们也试过一种保守的做法,只有模型足够确定应该放行时,才采用它的答案;拒绝或不确定的情况,仍交回原来的审核。三轮小样本对照中,虽然没有看到错误放行,最终保存的正确知识却有时比原流程更多、有时更少,费用也没有下降。所以候选审核目前仍然以 shadow 的方式运行:记录决策模型的回答,实际审核仍由原来的流程负责。
对于这样的剪枝,我们最后要检查的,是生成工作减少之后,本来应该保存的知识有没有留下来。模型读到的材料、程序采用的答案和最终写入结果,都需要连起来看,才能判断少一次调用究竟是省掉了不必要的工作,还是漏掉了一条记忆。
记忆检索
记忆检索是我们第一次看到 Jev 时,就觉得它会有帮助的一个场景。我们之前介绍过 Mem 的搜索 pipeline,其中有不少需要理解查询之后才能做好的判断:不同查询应该怎样分配多路检索的权重,是否值得使用 HyDE,查询里有没有时间条件。但受限于 latency,我们很难把这些都交给 chat 模型,再放进默认的快速搜索里。
我们也测试了能不能通过输入缓存来缩短这部分等待时间。测试时,我们向同一个 reasoning chat 模型连续发送六次前缀相同的判断请求,后五次约 88% 的输入命中了缓存,但单次模型调用仍然需要 6 到 33 秒。这里测的是实验中单独运行的模型判断,不是 Mem 的记忆检索耗时;默认快速搜索没有加入这一步。
这次接入 Jev,我们先补充了对查询中时间信息的理解。我们在之前关于记忆时间维度的文章里写过,事情发生的时间和记下来的时间是两回事,查询里的“去年”“上次迁移之后”也需要结合上下文理解。
原来的通用意图分析仍由 chat 模型完成,决策模型补充时间判断。在已配置决策服务的深度搜索(Memory Deep Search)里,如果决策模型及时识别出了查询中的时间意图,而且结果可用,我们也会尝试由它来做 rerank,否则继续原来的 rerank。
在快速搜索里,我们试着让检索和时间意图分析同时开始,只在排序前限定的时间内等待分析结果,超时就继续使用原来的检索结果。但实际测试时,检索结束得更早,决策模型的回答没能及时参与排序,所以目前快速搜索默认不使用决策模型。这部分能力的实际接入,先留在了深度搜索里。
即使拿到了时间判断,我们也只把模型推断的范围用于排序,并作为过滤建议返回,只有用户明确给出的过滤条件才会实际执行。一旦推断错了时间,直接过滤可能让一部分证据从结果里消失,后面的 agent 未必还有机会发现问题。
本地模型能不能做这些判断
Laya 这一类工作让我特别兴奋。像提炼前的筛选、检索时的意图理解,如果能交给常驻本机后台的模型,就可以直接在用户的电脑上处理,不必每次都等待远端调用。这次我们也评测了几个社区里的开放权重模型,看看它们在能力、延迟和资源占用上,能不能承担 Mem 中的这些任务。
我们先测试了 Laya、Von、Verdict 三个 encoder 模型,把问题清单固定下来,用同一批中英文样本分别测试,每个模型各完成了 290 次调用,机器是 8 核 CPU,没有 GPU。
我们事先把接入要求定为,每项任务在中文和英文上的结果,与 chat 基线的差距都不能超过 0.05,具体指标按任务使用准确率或 F1。结果这三个模型在七项任务中,没有一项达到这个要求,调用延迟 p50 在 0.2 到 3.3 秒之间,进程峰值内存为 1.7 到 4.1 GB,距离我们希望在用户电脑上长期运行的状态,也还有一些差距。
我们的朋友 PsiACE 是 Bub 的作者之一,他做的 Dohnuts 也很有意思。它用 Qwen3.5-0.8B 作为基座,通过 LoRA 和一个专门的打分 head 学习决策任务,训练过程中并不改动基座模型的权重。
用同一套题测试,Dohnuts 在七项任务中的五项,超过了这三个 encoder 在对应任务上的最佳成绩。比如写入质量判断,最佳 encoder 的 F1 是 0.17,Dohnuts 达到了 0.74;记忆类型分类,最佳 encoder 的准确率是 0.48,Dohnuts 达到了 0.70。
写入质量和记忆类型都涉及一些 Mem 特有的概念,Dohnuts 在这些任务上的表现明显更好,但对于需要读完整段上下文、再与其他内容比较的任务,我们还没有看到类似的改善,整体上也没有达到接入要求。这些提升有多少来自 Qwen 基座,又有多少来自训练数据和训练方法,还需要分别做实验才能知道。
接下来,我们把范围缩小到六个看起来更简单的任务,比如判断标签能不能复用、网页结果是否相关、页面是不是空壳。每个任务总共准备了 40 条样本,覆盖中文、英文和日文,但仍然没有一项能让本地模型在中文和英文上都达到前面的要求。最接近的是 Dohnuts 的网页相关性判断,中文 F1 为 0.94,chat 基线是 1.00。
其中一些任务最后只需要回答“是”或“否”,模型却仍然要理解具体内容和上下文。这也是为什么我会关注,更大的基座和不同的训练数据能不能让这些模型承担更多这样的判断。
用模型改进启发式判断
除了模型,我们还把词表、字数下限、文字脚本检测等常见规则放进了同样的六项测试。规则在六项任务上的结果都落后于 chat,其中四项还落后于最小的本地模型。比如根据页面长度来判断有没有实质内容,就会把一些很短、但确实有用的页面也排除掉。
权限、预算、日期运算、范围校验这些事情,当然还是应该由代码处理。但页面有没有实质内容,需要理解内容才能判断,页面长度只是我们用来近似它的一个指标。把规则和模型放进同一套测试以后,就能比较它们各自会在哪些内容上误判。
所以评估这些模型时,也需要看它们将要替代什么。接替已有的 chat 调用,要对照原来的质量要求;改进启发式判断,则要看模型能不能在可接受的开销下,减少现有规则的误判。前面测试的本地模型还没有达到我们的接入标准,不过,这组规则对照让我们看到了继续尝试的理由。
目前的接入情况
现在,大家可以在设置里的“快速判断”中配置决策服务。自带 API key 的用户可以添加 TypeSafe,使用托管 AI 的账号则会获得托管服务提供的配置。启用以后,桌面端和 Cloud 会在下面这些环节使用决策模型,两边的处理流程不完全相同:
| 环节 | 现在怎么用 |
|---|---|
| 判断对话是否值得提炼 | 桌面端和 Cloud 都已使用决策模型 |
| 检查新增对话里有没有尚未保存、值得长期保留的知识 | 桌面端根据判断结果决定是否继续提炼 |
| 去重、写入质量检查、类型分类 | 桌面端已使用决策模型完成这些判断 |
| 审核候选记忆的长期价值和来源依据 | 桌面端只记录决策模型的结果,仍由原来的审核流程决定 |
| 时间理解、rerank | 桌面端深度搜索启用时间判断,识别到时间意图且结果可用时尝试决策 rerank;快速搜索默认关闭 |
| 图谱抽取前的筛选 | Cloud 已使用决策模型进行筛选,实体和关系的抽取仍由 LLM 完成 |
除了替换已有的模型调用,我们也在尝试用决策模型识别宿主工具注入的内容,判断标签能不能复用、页面是不是空壳,以及一段描述使用的是哪种语言。目前这些判断都只记录结果,还没有实际影响后续处理,我们会继续把它们和现有的处理方式做比较。如果没有配置决策服务,也不会新增这些调用。
至于最终保存的记忆有没有更准确,用户整月的费用有没有下降,搜索有没有变快,还需要在生产环境里做覆盖完整流程的 A/B 测试,我们目前还没有这些结果。
如果大家也在做类似的工作,我很建议保留原来的实现作为对照,先在同一个模型上测试拆分后的判断,再保持问题不变换用新模型,最后看实际接入以后,完整流程的结果有没有改善。这样比较,我们才能知道哪些收益来自任务本身的拆分和重新组织,哪些来自模型,以及这些收益有没有体现在最后的结果里。如果准备改进的是启发式判断,也把现有规则放进对照。
接下来的一些想法
这两天,我们还看到了 UT Dallas 的 Jev-Mem 论文。他们也把决策模型放进记忆构建和检索的过程,让 LLM 负责复杂推理和答案生成,和我们在做的事情很接近。他们在 LoCoMo 上评估最终的问答效果,我们这次更多在研究每一道判断该怎么提问、模型的答案能不能直接采用。我觉得两份工作正好可以互相补充。
这次工作之后,我自己对“子神经系统”这个方向的期待也更具体了。把判断从生成任务中拆出来以后,我们就可以单独去考虑,这些判断到底需要多强的模型,能不能在本机完成,什么时候更适合放在云端,以及后续流程需要多快拿到答案。如果这些 system-one 模型能以足够低的开销,持续理解和判断新进入的上下文,我们也就有机会做一些过去很难频繁执行的工作。
以后我们还会继续测试本地的 Jev-like 模型,也会尝试把决策模型用到实时频道、Feed 卡片和跨语言标签的判断中。还有一些更贴近个人的能力,比如判断“什么值得为这个人长期保留”,我也很想知道专门训练以后能做到什么程度。目前我们做的还是问题设计和阈值校准,还没有训练出这样的模型。
同时,我也不觉得这些协处理模型都应该越小、越快越好。我在 tweet 里提到过,Jev-like 模型如果有更大规模的预训练、更强的泛化能力,即便延迟高一些,也应该会有很多超出简单反射的应用场景。Mem 中这些需要理解完整上下文的判断,就让我很期待这个方向。至于这样的能力能不能通过给开放权重 LLM 做决策式后训练获得,还是需要其他训练方法,也是我很想继续探索的问题。
机器人和具身智能也是我很感兴趣的方向。比如把几个不同的 Jev-like 模型和一个 frontier LLM 通过特制的 harness 组合起来,其中至少有一个模型能够理解视觉信息,我认为就有机会让这些模型参与机器人的反馈决策。我不熟悉机器人各个系统的接口,不过我猜测,这样的组合可能让一些过去需要昂贵训练才能获得的能力更容易实现。
沿着这个想法,LLM 和 harness 怎样低延迟地协调多个子模型,也很值得研究。如果把这些模型作为一个整体来设计,和通过 harness 编程调用它们相比,在能力和延迟上会有什么差别?一个不太恰当的类比,是端到端的 voice model 和组合起来的 voice agent framework。
回到神经系统的类比,我们在 AI 这里似乎先有了“大脑”级别的模型,然后才开始探索通用的子神经系统,这个顺序让我觉得非常有趣。欢迎做 memory、agent 和模型的同学一起来讨论,也期待看到更多围绕这些想法展开的工作。
实验说明
上文的 chat 消融实验使用 Kimi k3,每个任务 40 条样本,图表采用的是同一轮运行的结果,小幅差异还需要通过重复实验来确认。
chat 模型的费用按 Kimi 当时的 API 价格计算,方便在同一套价格下比较不同做法的成本。实验实际使用的是订阅,所以这些数字并不是我们实际支付的账单。
按照 Jev 团队的要求,这里不能公开 Jev 本身的性能数据,所以文中的模型评测数字来自 chat 模型和开放权重模型。