Featured image of post Agent 里那些 if/else,该从 prompt 里搬出来了:不用等 Jev 的模型,一张 3090 加冻结的 4B 就能复现这套接口

Agent 里那些 if/else,该从 prompt 里搬出来了:不用等 Jev 的模型,一张 3090 加冻结的 4B 就能复现这套接口

TypeSafe 的 Jev 把「让模型判断」从生成一句话再解析,改成运行时定义 schema、直接读选项概率。24 小时内两个开源复刻证明这套接口模式用一张 3090 加冻结的 Qwen3.5-4B 就能跑:777 次判断从 2.33 提到 20.03 decisions/s。本文拆开这套接口,并给出哪些 if/else 该搬、搬到哪一层、自己跑要接受什么代价。

你让模型判断「这单该不该转人工」。它先写一段话——「根据客户描述,账户无法访问,属于技术问题,建议转技术支持」——你再写个正则或者 json.loads 把它解析回一个布尔值或者一个枚举。

这段文字没有任何人读。它存在的唯一理由是:模型只会吐字符串。

延迟、成本、解析失败、类型错误,全花在这段没人读的文字上。TypeSafe 的 Jev 想干的事就是把这层砍掉:判断不再以「生成一句话」的形式存在,而是变成运行时定义的 schema + 直接读选项概率。更值得关注的是,发布后 24 小时内出现了两个开源复刻,证明这套接口模式不需要等它的闭源模型——一张 3090 加一个冻结的 4B 模型就能跑。

本文写给正在把 LLM 塞进生产链路的后端工程师。下面所有 TypeSafe 的性能与价格数字都是官方自评,两个复刻的数字是各自本地 fixture 的实验结果,我会逐条标清楚边界。

判断被写成一句话再解析回来,这三笔开销都花在没人读的文字上

先算账。官方对比表里,前沿 LLM 的输出 token 大约是输入 token 的 5 倍价格;端到端响应时间引用 llm-benchmarks 的数据是 3 到 329 秒。这个量级对聊天够用,但嵌进代码就是瓶颈——你的接口 P99 被一个「判断」拖到秒级。

更直观的证据来自 openjev(一个复刻项目)的对照实验。同一张 RTX 3090、同一个冻结的 Qwen3.5-4B、同一份 state、同样 21 条二元判断:

同一张 3090 上,直接读选项概率用 1.023 秒输出 0 个 token,自回归写 JSON 数组用 5.332 秒输出 111 个 token

  • 直接读选项 logits:1.023 秒,输出 0 个 token
  • 自回归写一个 JSON 数组:5.332 秒,输出 111 个 token(其中 0.489 秒才出第一个 token)

5.21 倍的差距,全部来自那 111 个没人读的 token。而且注意:这个生成式基线已经是最省的写法了——只输出有序的 "yes"/"no" 值,没有 key、没有 confidence 对象、没有解释。openjev 还试了更极端的「压缩到无空白」请求,模型在 21 个值之后继续重复输出,三次全部撞上 128 token 上限——被记为失败,没有拿来放大倍数。

所以问题不在模型不够聪明。21 条判断它答对了 18 条,和直接读概率的 argmax 一致。问题在接口形状:你为了拿一个布尔值,被迫让模型先写一段散文。

Jev 的接口只有三个原语,而且 schema 是跟着请求走的

那「接口模式」到底是什么?官方 API 是 POST https://api.typesafe.ai/v1/systemone,请求体就三样:statemodelquestions。问题只有三种类型:

  • Choice:从若干选项里选一个,返回 choice + probabilities + confidence
  • Score:给一个连续打分,返回 score + legend + confidence
  • Noul:判断一个命题成立与否,返回 0–1 的 noul

官方 quickstart 的真实响应长这样(照抄文档,未改动字段名):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{
  "model": "jev-latest",
  "answers": {
    "department": {
      "type": "choice",
      "choice": "technical",
      "probabilities": { "billing": 0.159, "technical": 0.84, "sales": 0.001 },
      "confidence": 0.596
    },
    "is_urgent": { "type": "noul", "noul": 0.999 }
  },
  "usage": { "input_tokens": 312, "output_tokens": 48 }
}

关键在 questions 这个对象。它是随请求到达的——criteria 和选项描述不写死在 prompt 里,而是每次调用时定义。这意味着改判断逻辑是改代码里的系数,不是重写 prompt。官方文档的原话是:把复合判断拆成原子问题,再用代码里的公式组合。

官方还明确了两点:所有问题并行且相互隔离地针对同一份 state 评估,「增加问题几乎不改变响应时间」;而且「每个问题独立评估,所以增加问题不会产生 context rot」。这两句话是这套接口真正的卖点——它把「判断」从一次对话变成一次函数调用

不过账得算全。官方承认无法证明定价未被补贴,需要长期验证可持续性;首页那个 193.6x faster / 444.6x cheaper 来自他们自己的 4 个 workflow eval,官方自己注明「我们预期这是真实世界收益的高位」,而且 workflow 由自家 model capabilities 团队构建,「可能存在 bias」。这些数字可以引用,但必须带「官方自评」这个前缀。

不用等 Jev——两个复刻把「读概率」和「训一个 head」两条路都走了一遍

这是全文信息量最大的部分。Jev 是闭源 early access,要 waitlist。但 9 月 16 日一天之内,GitHub 上出现了两个独立复刻,走的是完全不同的两条路。

openjev 走免训练路线。 它直接读冻结 Qwen3.5-4B 的选项 logits,不做答案句、不做 JSON 修复、不写解码循环。核心工程点是 --mode shared:如果所有行的 state 完全相同,就只 prefill 一次,然后并行评估多条 criteria。效果是:

777 次判断下,每次重新打分 2.33 decisions/s,串行复用 state 10.75,并行评估 20.03,原生 reranker 1.86

在 37 个 state × 21 条 criteria = 777 次判断的工作量上,每次重新打分是 2.33 decisions/s(333.1 秒),串行复用 state 提到 10.75,并行评估多条 criteria 到 20.03 decisions/s(38.8 秒)。同一个 4B 模型,只是换了 state 的复用方式,吞吐差 8.6 倍

质量上它给了诚实的数字:自有 144 行判断集 balanced accuracy 0.813,外部 WANLI 数据集 0.637,在 TypeSafe 公开的 102 行可对齐子集上 modal agreement 0.845,而官方记录的 Jev 是 0.883

jevlike 走训练路线。 它冻结一个 encoder(比如 Qwen2.5-0.5B),只训练一个小的 scorer head,--rank 控制宽度。自述实验里,合成菜单约 98% 准确率;在 target-disjoint 的 Wikispeedia next-click 任务上,冻结 Qwen2.5-0.5B + head 达到 26%,而 shuffled / random-encoder 对照组约 8%;从零训练的小模型在 40,000 次点击上达到 29%。8 个选项时,一次 pass 比被迫写 400 token 的小 decoder 快约 100 倍

两条路的取舍很清楚:免训练零成本上手,但精度天花板取决于基座模型;训练要数据和算力,但能把判断能力压进一个很小的 head。 如果你只是想验证「我的判断能不能改成读概率」,openjev 那条路当天就能跑;如果你有标注数据且判断模式稳定,jevlike 那条路更省推理成本。

必须说清楚:这两个项目都明确否认复现了 Jev 的模型与训练。 openjev 的 README 原话是「复现的是接口模式,不复制 Jev 未公开的模型或训练」;jevlike 写的是「这是一个研究起步项目,不是 Jev 的复制品」。而且 openjev 的 Jev 对比数字是从 TypeSafe 公开记录里读的,作者没有跑实时 endpoint,对比只覆盖 102 行可对齐数据,不是官方报告的 711 行聚合。别把它写成「开源版 Jev」。

搬哪些判断、搬到哪一层、自己跑要接受什么代价

回到你手上的代码。不是所有 if/else 都值得搬,判断标准是三个条件同时成立

  1. 判断本身不需要开放式推理——分类、路由、打分、判断证据是否支持结论,这些是「给定选项做选择」,不是「想清楚再回答」
  2. 选项可以预先枚举——jevlike 明确把「一次 pass 打分要求预测前给全选项列表」列为限制;选项都列不出来,就别搬
  3. 错了能兜底——低置信度能回退到人工或前沿模型,而不是直接写进数据库

三条都满足,才值得改成读概率。

具体怎么开始,openjev 的 quickstart 可以直接照抄(注意 --revision 固定了模型版本号,这是可复现的关键):

1
2
3
4
5
6
CUDA_VISIBLE_DEVICES=0 openjev-score \
  --mode direct \
  --model Qwen/Qwen3.5-4B \
  --revision 851bf6e806efd8d0a36b00ddf55e13ccb7b8cd0a \
  --input examples/decisions.jsonl \
  --output results.jsonl

输入格式就是一行一个 JSON,你可以直接套自己的工单或日志:

1
2
3
4
5
6
7
8
9
{
  "id": "route-1",
  "state": "Customer cannot access an account after a password reset.",
  "question": "Which queue should handle this request?",
  "options": [
    {"id": "access", "description": "Account access support."},
    {"id": "billing", "description": "Billing support."}
  ]
}

所有行 state 相同时换 --mode shared,prefill 一次、并行评估——就是上面那张图里 8.6 倍吞吐的来源。

然后是代价,这部分必须写实:

  • 概率是条件概率,不是校准置信度。 openjev 明确写了「返回的概率是条件于所给选项的」,必须在你自己的 workload 上验证校准。它自己的 36 行缺失证据测试里,直接读 logits 和 reranker 各有一个在分数 >0.8 时给出了非 insufficient 的选择——不能当操作阈值用
  • 快速复用路径是实验性的。 BF16 执行相对 fresh scoring 改变了 777 个 argmax 中的 5–6 个。省下来的时间,是用一点点判断漂移换的。
  • 选项顺序会影响结果。 openjev 的扰动测试里,把选项顺序反转,准确率仍是 0.813,但有 10 个判断翻转了。位置措辞和概率移动这个问题没解决。
  • Jev 本身不处理图像,Doom demo 的输入是结构化文本状态不是像素;选项基数上限 255,高基数走「先独立打分再显式选择」的两阶段,官方原文承认会有「偶发变慢」。
  • 「0% 幻觉」指的是类型/格式错误,不是判断准确率。 官方原文写得很直白:「我们的数字不是实测的。schema matching 是保证的,所以我们可以放心地把 0% 放进图里。」这是机制保证——schema 约束下不可能输出非法类型——不等于判断正确。

还有一条排查路径值得记住:如果直接读 logits 的 argmax 和生成式 JSON 的答案不一致(openjev 的 21 条里就有 3 条不一致),说明这条判断不适合走概率读法,回到生成式,或者把它拆成更细的原子问题。

至于什么时候不该动:如果你的判断调用量很低、或者本来就跑在便宜模型上,这套改造是过度工程——直接读概率省下的那几秒和几分钱,抵不上你重写判断层和验证校准的成本。这套东西的收益随调用量线性放大,量小的时候不值得。

先拿一条判断跑一遍,看 argmax 一致率和概率分桶

别急着改生产代码。先挑一条你已经在用 LLM 做、且满足那三个条件的判断——最典型的是工单路由或者内容分类——把它的输入导成 openjev 的 JSONL 格式,跑一遍 --mode direct,然后做两件事:

一是对答案:拿你现有的生成式实现跑同一批数据,看 argmax 一致率是多少。不一致的那几条,就是这条判断里真正模糊的部分,比任何 benchmark 都有信息量。

二是验校准:把返回的概率按区间分桶,看每个桶里的实际准确率。如果 0.8 置信度那一桶的实际准确率只有 0.6,那这个概率就不能直接当阈值用,得先在你的数据上做校准。

这两步做完,你就知道自己该不该搬了。TypeSafe 那套 200 倍的说法是不是真的,对你其实不重要——重要的是你自己的 workload 上,读概率比写文字省了多少、准了多少


本文引用的一手来源(访问日期均为 2026-09-18):

  • TypeSafe 官方博客《Introducing System One Models & Jev》(2026-09-15,Diogo Almeida):https://typesafe.ai/blog/introducing-system-one-models-and-jev —— 官方对比表、定价、193.6x/444.6x 及其限定语、「0% 不是实测」原文、基数上限 255、不处理图像
  • TypeSafe 官方 quickstart(API 形状、请求/响应 JSON、Python SDK):https://docs.typesafe.ai/introduction/quickstart
  • TypeSafe workflow evals 站点:https://evals.typesafe.ai/
  • openjev(MIT,TheoLeeCJ):https://github.com/TheoLeeCJ/openjev —— Speed 表、state 复用表、质量表、输入格式、quickstart 命令、--mode shared 说明、实验性复用路径与 5–6/777 argmax 漂移
  • openjev 详细结果与「复现了什么/没复现什么」:https://github.com/TheoLeeCJ/openjev/blob/master/docs/RESULTS.md
  • openjev 复现指南(环境、固定命令):https://github.com/TheoLeeCJ/openjev/blob/master/docs/REPRODUCE.md
  • jevlike(MIT,vinnylarouge):https://github.com/vinnylarouge/jevlike —— 架构说明、数据格式、Wikispeedia 26% vs 8%、8 选项快约 100 倍、明确局限声明
  • GitHub star 数(2026-09-18 经 GitHub API 实测):openjev 749 star / 51 fork(创建 2026-09-16);jevlike 655 star / 60 fork(创建 2026-09-16)
  • 配套生态(同公司项目,非独立验证):https://github.com/typesafe-ai/system-one-adapter-python ;https://github.com/typesafe-ai/skills