1. 从一次线上事故说起:为什么大家都在聊 Jev
上个月我们团队做了一次 Agent 系统的成本复盘,结果挺扎心的。一个日均调用量在 40 万次左右的客服 Agent,光 LLM 推理费用一个月就烧掉了将近六位数,而其中真正需要"动脑子"的请求,按事后抽样统计,不到 18%。剩下的 82% 是什么?是意图分类、参数抽取、路由判断、格式校验、简单问答、状态确认——这些活儿,用一个大模型去干,就像请一位资深架构师去贴发票,能力过剩得离谱。
这就是 Jev 突然火起来的背景。它想干的事情非常直接:把 Agent 里那些高频、低复杂度、模式固定的 LLM 调用,替换成一个更轻、更快、更便宜的决策模型。热搜里出现的 Jev、RLCD、Decision Model 这几个词,其实指向的是同一件事——用强化学习式的决策机制,去接管 Agent 编排中原本由 LLM 承担的那部分"判断"工作。
我第一次看到 Jev 这个概念的时候,第一反应是"这不就是规则引擎换皮吗"。但仔细看完它的思路之后,我改主意了。规则引擎的问题是写死的,遇到边界情况就崩;而 Jev 这类 Decision Model 是从数据里学出来的,它能处理模糊输入,还能随着使用不断调整。它和 LLM 的关系不是替代,而是分工:LLM 负责开放域理解、复杂推理、长尾生成,Jev 负责高频决策、快速路由、确定性判断。
这篇文章适合三类人看。第一类是在做 Agent 开发、被 LLM 调用成本压得喘不过气的工程师;第二类是在设计 Agent 框架与编排层、需要做架构取舍的技术负责人;第三类是刚接触 agent 智能体、想搞清楚"为什么不能什么都丢给大模型"的入门者。我会把 Jev 的核心逻辑、RLCD 的机制、Decision Model 的落地方式,以及我自己踩过的坑,全部摊开讲。
2. Jev 到底解决的是什么问题:Agent 里的 LLM 浪费
2.1 一个 Agent 请求的生命周期里,LLM 被调了多少次
先别急着聊 Jev 本身,我们得先看清楚问题在哪。一个典型的 Agent 处理一次用户请求,内部会发生什么?我拿我们自己的客服 Agent 举例,拆解一下调用链:
- 用户输入进来,先做意图识别——调一次 LLM
- 根据意图决定走哪条工具链,做路由决策——调一次 LLM
- 抽取工具调用需要的参数——调一次 LLM
- 工具返回结果后,判断结果是否可用、是否需要重试——调一次 LLM
- 生成最终回复——调一次 LLM
- 回复前做安全与格式校验——调一次 LLM
一次请求,六次 LLM 调用。其中第 1、2、3、4、6 步,本质上都是分类问题或结构化判断问题,输入输出空间是有限的、可枚举的。只有第 5 步是真正的开放域生成。
我做过一个统计,在我们系统里,这六步的 token 消耗占比大概是:意图识别 8%、路由 6%、参数抽取 15%、结果判断 10%、生成 55%、校验 6%。也就是说,45% 的 token 花在了决策类任务上,而这些任务的准确率要求其实并不高——意图识别做到 92% 就够用了,路由做到 88% 就能跑,但为了这 45% 的消耗,我们付的是和生成任务一样的单价。
提示:你可以自己跑一遍统计,把 Agent 里每一次 LLM 调用的输入输出长度、任务类型、是否可枚举输出记录下来。大部分团队做完这个统计都会发现,决策类调用占比在 35% 到 55% 之间。
2.2 为什么不能直接用规则或者小分类模型
看到这里你可能会说,那用规则引擎或者训个小 BERT 不就行了?我试过,都试过。
规则引擎的问题在于维护成本随复杂度指数上升。我们最早用 if-else 写意图路由,一开始 20 条规则很清爽,三个月后变成 200 条,规则之间开始互相冲突,改一条崩三条。而且规则处理不了"用户说了一半又改口"这种模糊情况。
小分类模型(比如微调一个 BERT)的问题是每个任务都要单独训一个模型。意图识别一个、路由一个、参数抽取一个、结果判断一个,四个模型四套训练流程四份维护成本。而且这些模型之间不共享上下文,路由模型不知道意图模型的置信度,判断模型不知道路由走了哪条路。
Jev 这类 Decision Model 的思路是:用一个统一的决策模型,接管所有决策类任务,输入是当前 Agent 的完整状态(对话历史、工具返回、中间变量),输出是下一步动作。它不生成自然语言,只做决策。这就把四个小模型合并成了一个,而且因为共享状态,决策质量反而更高。
2.3 RLCD 在这里扮演什么角色
热搜里的 RLCD,我理解是Reinforcement Learning from Decision Comparison或者类似的决策对比学习机制。它的核心思想是:不依赖人工标注每一步决策的对错,而是通过对比不同决策路径的最终结果来学习。
举个例子。用户问"帮我查一下上个月的订单",Agent 面临两个决策:直接调订单查询工具,还是先调用户信息工具确认身份。如果最终用户满意,那这条路径上的决策就是正样本;如果用户中途说"不对我要查的是退款",那这条路径就是负样本。RLCD 通过大量这样的路径对比,让 Decision Model 学会在什么状态下该做什么决策。
这比传统监督学习强在哪?强在不需要标注每一步。你只需要知道最终结果好不好,模型自己反推中间哪一步决策出了问题。这对 Agent 场景特别友好,因为 Agent 的最终结果(任务完成没完成、用户满意不满意)是天然可获取的,但中间每一步的标注成本极高。
3. Decision Model 的核心机制拆解
3.1 状态表示:Agent 的"当前局面"怎么编码
Decision Model 要做的第一件事,是把 Agent 的当前状态编码成一个向量。这个状态包括什么?根据我的实践,至少要有这几块:
- 对话历史摘要:不是原始对话,是压缩后的意图序列和关键实体
- 当前任务进度:已经完成了哪些子任务,还剩哪些
- 可用工具列表及其状态:哪些工具当前可用,上次调用返回了什么
- 中间变量:已经抽取的参数、已经确认的信息
- 约束条件:超时限制、权限限制、格式要求
这里有个坑我踩过:状态表示不能太细,也不能太粗。太细的话,模型会被噪声干扰,比如对话历史里用户的一句"嗯"其实不影响决策,但如果编码进去,模型可能会过度关注。太粗的话,关键信息丢失,决策质量下降。
我的经验是,状态向量控制在256 到 512 维比较合适。对话历史用滑动窗口加摘要的方式压缩,工具状态用 one-hot 加最近一次返回的 embedding,中间变量直接拼接。具体维度要根据你的任务复杂度调,但别超过 1024,超过之后收益递减明显。
3.2 动作空间:Decision Model 能做什么决策
Decision Model 的输出是一个动作,这个动作空间是预定义、可枚举的。常见的动作类型包括:
| 动作类型 | 说明 | 示例 |
|---|---|---|
| 调用工具 | 选择某个工具并传入参数 | 调用订单查询,参数 order_id=123 |
| 请求澄清 | 向用户追问缺失信息 | 追问"您说的是哪个订单" |
| 路由跳转 | 切换到另一个处理流程 | 从售前流程跳到售后流程 |
| 终止 | 结束当前任务 | 任务完成或无法完成 |
| 重试 | 重新执行上一步 | 工具返回超时,重试 |
| 降级 | 切换到 LLM 处理 | 决策置信度低,交给大模型 |
动作空间的设计直接决定了 Decision Model 的能力边界。我建议动作数量控制在 20 到 50 个之间。太少的话覆盖不了场景,太多的话模型学不好,而且每个动作的训练样本会被稀释。
注意:动作空间一旦确定,后期修改成本很高。因为修改动作空间意味着所有历史训练数据都要重新映射。所以前期设计的时候,宁可多留几个动作位,也不要后期频繁增删。
3.3 决策置信度与 LLM 兜底
Decision Model 最关键的机制之一是置信度阈值。模型对每个动作输出一个概率分布,如果最高概率超过阈值(比如 0.85),就直接执行;如果低于阈值,就把这个请求升级给 LLM 处理。
这个机制是 Jev 这类方案能落地的核心。因为 Decision Model 不可能覆盖所有情况,遇到没见过的、模糊的、高风险的请求,必须有一个兜底。LLM 就是那个兜底。
我实测下来,阈值设在0.8 到 0.9之间比较合适。设太低,错误决策变多;设太高,大量请求被升级给 LLM,省不了钱。具体数值要根据你的业务容错率调,金融类场景可以设到 0.92,一般客服场景 0.85 就够。
3.4 训练数据的来源:从 LLM 日志里挖金矿
Decision Model 的训练数据从哪来?最实际的来源就是你现有的 LLM 调用日志。
你现在的 Agent 每次调 LLM 做决策,输入是什么、输出是什么、最终结果好不好,这些日志里全都有。把这些日志整理成(状态,动作,结果)的三元组,就是天然的训练数据。
我整理数据的流程是这样的:
- 从日志里提取每次决策类 LLM 调用的输入(状态)和输出(动作)
- 追踪这次调用之后的最终任务结果(成功/失败/用户满意度)
- 用最终结果给每个决策打标签
- 对于结果好的路径,路径上的决策标为正样本;结果差的,标为负样本
- 用 RLCD 的方式做对比学习
这套流程不需要额外标注,全部从现有日志里挖。我们大概积累了 3 个月的日志,整理出 12 万条有效决策样本,训出来的 Decision Model 在意图识别上做到了 94% 的准确率,路由做到了 89%。
4. 实操:把 Jev 接入现有 Agent 的完整流程
4.1 第一步:盘点你的 LLM 调用,找出可替换的决策点
别一上来就想着全量替换。先做盘点。把你 Agent 里所有 LLM 调用列出来,按这个表打分:
| 调用点 | 输出是否可枚举 | 调用频率 | 单次 token 消耗 | 准确率要求 | 可替换优先级 |
|---|---|---|---|---|---|
| 意图识别 | 是(8类) | 极高 | 低 | 92% | 高 |
| 路由决策 | 是(5条路) | 极高 | 低 | 88% | 高 |
| 参数抽取 | 部分 | 高 | 中 | 95% | 中 |
| 结果判断 | 是(3类) | 高 | 低 | 90% | 高 |
| 最终生成 | 否 | 极高 | 高 | 高 | 低 |
| 安全校验 | 是(2类) | 高 | 低 | 99% | 中 |
优先级高的先做。我的建议是从意图识别和路由决策入手,这两个任务输出空间小、频率高、容错率高,最容易看到效果。
4.2 第二步:定义状态编码和动作空间
这一步是纯设计工作,但决定了后面所有事情。我拿意图识别举例。
状态编码:取最近 5 轮对话的摘要 embedding(每轮 64 维),拼接当前用户输入的 embedding(128 维),拼接上一轮决策的动作 one-hot(16 维),总共 5×64+128+16 = 464 维。
动作空间:8 个意图类别,加上一个"不确定"动作,共 9 个动作。
置信度阈值:0.85。
这套配置我们跑下来,意图识别的 Decision Model 推理延迟在8ms 左右(CPU 上),对比 LLM 的 800ms 到 2s,快了两个数量级。成本更是可以忽略不计。
4.3 第三步:从日志生成训练数据
这一步是体力活,但有几个技巧。
第一,负样本要平衡。如果你的日志里 90% 的决策都是对的,直接训会得到一个"永远输出多数类"的模型。我的做法是对负样本做 3 倍过采样,让正负比例接近 1:1。
第二,要标注决策的"关键性"。有些决策错了无所谓,有些决策错了整个任务就崩了。我在数据里加了一个权重字段,关键决策的权重是普通决策的 5 倍。这样模型会优先学好关键决策。
第三,留出验证集。我一般留 15% 的数据做验证,而且验证集要按时间切分——用前 3 个月的数据训练,用第 4 个月的数据验证。这样能真实反映模型在新数据上的表现。
4.4 第四步:训练与调参
Decision Model 本身不大,我用的是一个 4 层 MLP,隐藏层 512 维,参数量在 200 万左右。训练在单张消费级显卡上跑 2 小时就能收敛。
关键参数:
- 学习率:1e-3,用 cosine 衰减
- Batch size:256
- 优化器:AdamW
- 损失函数:交叉熵 + RLCD 对比损失,权重 0.7:0.3
- 训练轮数:50 轮,早停 patience=5
RLCD 对比损失的实现思路是:对同一个状态下的不同决策路径,让好路径的决策概率高于坏路径。具体来说,取一个 batch 里的正负样本对,计算它们的决策概率差,用 margin loss 拉大这个差距。
4.5 第五步:灰度上线与置信度校准
别一次性全量切。我的做法是:
- 先切 5% 的流量给 Decision Model,同时 LLM 也跑一遍,对比两者决策
- 统计 Decision Model 和 LLM 决策一致的比例,以及不一致时谁对谁错
- 如果一致率超过 90%,且不一致时 Decision Model 不差于 LLM,扩大到 20%
- 逐步扩大到 50%、80%、100%
置信度校准也很重要。模型输出的概率往往不是真实概率,需要做 Platt scaling 或者 isotonic regression 校准。校准之后,阈值 0.85 才真正代表"85% 的情况下这个决策是对的"。
5. 常见问题与排查技巧实录
5.1 Decision Model 准确率上不去怎么办
这是最常见的问题。我遇到过的原因和排查思路:
| 现象 | 可能原因 | 排查方法 | 解决 |
|---|---|---|---|
| 训练准确率高,验证低 | 过拟合 | 看训练/验证 loss 曲线 | 加 dropout、减参数量、增数据 |
| 训练验证都低 | 状态编码信息不足 | 检查状态向量是否包含关键信息 | 补充特征、增大维度 |
| 某些类别准确率特别低 | 样本不平衡 | 统计各类别样本数 | 过采样、加类别权重 |
| 置信度普遍偏低 | 校准问题 | 画 reliability diagram | 做概率校准 |
| 上线后效果差 | 训练数据与线上分布不一致 | 对比训练集和线上数据的特征分布 | 用近期数据重新训练 |
我踩过最大的坑是状态编码里漏了"上一轮决策"这个特征。结果模型不知道上一轮做了什么,导致在多轮对话里反复做同一个决策。补上这个特征之后,多轮场景的准确率从 76% 提到了 91%。
5.2 置信度阈值怎么定才合理
阈值不是拍脑袋定的,要用验证集算。具体做法:
- 在验证集上跑 Decision Model,得到每个样本的置信度和是否正确
- 画一条曲线:横轴是阈值,纵轴是"被 Decision Model 处理的请求中错误的比例"
- 找到你业务能接受的错误率对应的阈值
比如你能接受 5% 的错误率,那就在曲线上找错误率 5% 对应的阈值。我们业务能接受 8% 的错误率,对应的阈值是 0.83。
提示:不同动作类型可以用不同阈值。高风险动作(比如涉及金额、权限)用高阈值,低风险动作用低阈值。我们系统里,查询类动作阈值 0.8,修改类动作阈值 0.92。
5.3 遇到 Decision Model 没见过的状态怎么办
这是必然发生的。我的处理策略是三级兜底:
第一级,Decision Model 置信度高于阈值,直接执行。
第二级,置信度低于阈值,但状态在训练分布内(用马氏距离判断),交给一个轻量 LLM(比如 7B 模型)处理。
第三级,状态在训练分布外,交给完整 LLM 处理,同时把这个样本记录下来,加入下一轮训练数据。
这套机制跑下来,大概 70% 的请求走第一级,25% 走第二级,5% 走第三级。整体 LLM 调用量下降了 70% 以上。
5.4 怎么衡量省了多少钱
别只看调用次数下降,要算综合账。我的计算方式是:
- 原来:每次决策 LLM 调用平均消耗 800 token,单价按 0.002 元/千 token 算,单次成本 0.0016 元
- 现在:Decision Model 推理成本忽略不计,但 30% 的请求升级给 LLM,单次成本 0.00048 元
- 节省比例:70%
但还要算上 Decision Model 的训练成本、维护成本、以及错误决策带来的业务损失。我们算下来,综合节省在 55% 到 60% 之间。这个数字已经很可观了。
6. 我对 Jev 这类方案的真实看法
Jev 火起来不是偶然。Agent 开发走到今天,大家都过了"什么都丢给 LLM"的兴奋期,开始算账了。算账的结果就是,LLM 应该用在它真正擅长的地方——开放域理解、复杂推理、长尾生成,而不是用来做那些本来就不需要它的决策。
Decision Model 加 RLCD 这套组合,本质上是在 Agent 架构里加了一层"快思考"系统。LLM 是"慢思考",负责难的部分;Decision Model 是"快思考",负责高频的部分。这跟人脑的工作方式其实很像——大部分日常决策是直觉性的、快速的,只有遇到复杂问题才启动深度思考。
我自己的体会是,这套方案的门槛不在技术,在数据。你得有足够多的历史日志,才能训出可用的 Decision Model。如果你是个新项目,没有历史数据,那前期还是得靠 LLM 跑,边跑边攒数据,等数据够了再切。
另外,别指望 Decision Model 能覆盖所有场景。它的定位就是处理高频、模式化的决策,长尾的、复杂的、高风险的,该给 LLM 还是得给。把这两者的边界划清楚,比追求 Decision Model 的覆盖率更重要。
最后分享一个小技巧:Decision Model 上线之后,别停止记录 LLM 的决策。让 LLM 在后台继续跑,和 Decision Model 的决策做对比。这样你既能监控 Decision Model 的表现,又能持续获得新的训练数据。我们系统里这个"影子模式"跑了大半年,积累了 30 多万条对比样本,模型迭代了 4 个版本,准确率从最初的 82% 提到了 94%。