把判断从贵模型里剥出来:给你的 Agent 装一层能测、能调、能回滚的决策层
我给自己的内容系统做了一件事:把里面所有「判断」从贵模型里剥了出来,搬到另一个只做判断、不写字的模型上,再把阈值写进我自己的代码。
不是优化提示词。是承认一件事:判断本来就不该住在提示词里。
事情起因是 TypeSafe 那个叫 Jev 的模型。给它一段素材加一组问题,它返回类型化答案加校准概率,70 到 500 毫秒,输入每百万 token 四毛二分、输出免费。
但真正让我动手的不是价格,是 LangChain 那篇里点破的一件事:coding harness 早就内置了「执行前先判断这个动作危不危险」的分类步,但那一步一直锁在闭源 harness 内部。现在这层公开了,它就变成了你自己代码里的一个阈值。
这篇把「搬」这个动作落地成可复现的步骤,最后再附上社区已经做出来的 8 个项目。全部步骤我自己跑过,判断侧成本 0。
一、先搞清它是什么:三个原语,不说话
最容易搞混的一点:它没有「回复」这个概念。你给它一个 state(一段文本,或者一个 JSON 对象),再给它一组问题。每个问题只能是三种之一:
| 原语 | 问的是什么 | 返回什么 |
|---|---|---|
choice | 从几个选项里选一个 | 选中的项 + 每个选项的概率 |
score | 在一条有序刻度上打分 | 位置 + 每个档位的概率 |
noul | 这个条件成不成立 | 一个 0–1 的数 |
三种可以混在一次请求里。同一个 state 上的所有问题并行评估——加问题几乎不增加响应时间,也不会互相干扰(官方叫「不产生 context rot」)。这一点很关键:它意味着判断的边际成本极低,你可以放心把一个问题拆成十个。
它不能生成文本,所以也编不出文字。官方说它「不会幻觉」——这是架构决定的,不是跑出来的分数。
二、为什么这层以前做不了
这是我觉得最值得带走的一段框架。
Claude、Codex、Cursor 这些 coding harness,早就内置了「执行前先判断这个动作危不危险」的分类步。你在用的时候能感觉到它在拦你:某个命令它不让你跑,某个操作它要你确认。
但那一步一直在闭源 harness 内部。你改不了它的判断依据,看不见它给出的概率,也没法把它挪到你自己的流程里——比如「这条选题能不能写」「这份稿子该不该拦」「这个请求该走哪条路」,这些判断以前只能靠一段提示词,塞进贵模型的上下文里让它顺带想想。
现在一个便宜、快、专门做判断的模型公开了,这层就从「厂商的私有权重」变成了「你自己代码里的一个阈值」。
所以真正可迁移的问题不是「Jev 好不好用」,而是:
你的 Agent 里有多少判断,现在是靠一段提示词糊在贵模型的上下文里的?
三、哪些判断该搬,哪些别搬
不是所有判断都值得剥出来。先过这张表:
| 该搬(交给判断层) | 别搬(留给贵模型) | |
|---|---|---|
| 1 | 分类:这条属于哪一类 | 需要长链推理的复杂决策 |
| 2 | 路由:这个请求该走哪条路、哪个模型 | 需要生成文字本身的活 |
| 3 | 守门:这个动作执行前该不该拦 | 需要多因素权衡后给一个结论 |
| 4 | 打分:按一条固定标准给分 | 标准本身还没想清楚的时候 |
| 5 | 抽取:把非结构化内容转成字段 | 一次性、只跑一遍的判断 |
右边那列的判据只有一句话:
如果这个判断你自己都说不清标准,那它还不该被写成代码——先想清楚,再搬。
四、怎么接进去:四步
搬一层判断 · 四步
- STEP 01拿到通路
官方 API / 免费位先备一条回退通道,再上生产 - STEP 02准备 state
文本 或 JSON判断需要的上下文一次塞全,它只计费一次 - STEP 03拆成原子问题
noul / choice / score一个问题只问一件事,别让它在脑内做长推理 - STEP 04阈值写进代码
if / elif判断归模型,决定归你,改口径只改一个数
判断归模型,决定归代码 —— 提示词里的一句话,变成一个能回滚的系数。
第 1 步:拿到一条通路。 官方 API 需要申请早期访问;另外有免费位可以用(我用的就是免费位,跑完整批判断成本 0)。⚠️ 免费位是限时的——我写这篇时就吃到一次 503。先给自己留一条回退通道再上生产。
第 2 步:把 state 准备好。 一段文本,或者一个 JSON。原则是:把判断需要的全部上下文塞进去,因为 state 只计费一次、所有问题共用它。 我的做法是把一条选题的全部证据(标题、钩子、市场数据、缺的一手)拼成一段,一次送进去。
第 3 步:把问题拆成原子的。 这是全篇最重要的一步,官方文档专门写了一节,原则是:
每个问题只问一件具体、边界清楚的事——就像「一个懂行的人看几秒就能给出的判断」。如果一个问题需要长推理、或者同时在权衡多个独立因素,拆开它。
举例,不要问「这个选题好不好」,而是分开问:
能不能迁移 (noul) 把产品名换成别的,这篇还成立吗
撞不撞负面清单 (noul) 属于随笔/泛热点/合规处罚类吗
够不够级别 (choice)S / A / B / 都不够
市场信号强度 (score) 5 档
请求的形状就是这样,一次问全:
{
"model": "jev-latest",
"state": "(一条选题的全部证据,拼成一段文本)",
"questions": {
"transferable": { "type": "noul", "instructions": "换掉产品名后,核心判断仍然成立" },
"tier": { "type": "choice", "instructions": "该选题能支撑的最高级别",
"options": { "s": "半天级实测", "a": "快反", "b": "碎片", "none": "不足以成文" } },
"market": { "type": "score", "instructions": "市场信号强度",
"levels": ["几乎没有", "弱", "中", "强", "多源共振"] }
}
}
拿回来的是一组概率,不是一段话。然后在你自己的代码里用公式合起来。 官方那句话说得比我好:
当优先级变了,改代码里的一个系数,而不是重写提示词。
第 4 步:阈值写在代码里。 这是「搬」这个动作的落点。判断层给你概率,决定权在你代码里的一行:
# 阈值是代码,不是提示词
READY = 0.30*P_transferable + 0.20*(1-P_news_recap) + 0.20*market + 0.10*whitespace \
+ 0.10*(1-P_negative) + 0.10*P_firsthand
if P_negative >= 0.5 or P_transferable < 0.4:
kill(topic) # 闸门:直接判死
elif READY >= 0.70:
queue(topic) # 进生产
else:
review(topic) # 交给人看
改口径 = 改一个数字,跑一遍回归就知道有没有坏别的。这就是「可讨论」的意思。
五、中文工作量的坑:阈值必须按语言分别标定
这条是我翻过的最大的车,也是最该先看的。
官方文档里有一句很不显眼但很关键的话:
其他语言(包括中日韩)能处理,但不等同英文的表现;拿非英文工作量上生产前,先在自己的内容上测,并且重点看 confidence。
说得很对,但「不等同」是多少?没人给数。我量了。
同一批 8 条真实选题,同一个 state,同一套问题语义,只换提问语言(英文问题 vs 中文问题),各跑 2 次取中位:
| 素材 | 英文提问 | 中文提问 | 差 |
|---|---|---|---|
| 跑分篇 | 0.67 | 0.33 | −0.34 |
| 榜单篇 | 0.76 | 0.53 | −0.23 |
| 成本单位篇 | 0.56 | 0.41 | −0.14 |
| 去 AI 味篇 | 0.77 | 0.56 | −0.21 |
| AI 味篇 | 0.77 | 0.52 | −0.24 |
| Loop 篇 | 0.70 | 0.61 | −0.09 |
| skills 横评 | 0.60 | 0.34 | −0.26 |
| Claude Code 篇 | 0.55 | 0.38 | −0.18 |
英文中位均值 0.671,中文 0.460,平均差 −0.211。8 条里 8 条都是负的,没有一条例外。
这个模型的抖动只有 ±0.02 量级(我重复跑过),所以 −0.21 且 8/8 同向不是噪声。
后果比数字重要:假设你按英文调好「概率 > 0.6 就算可迁移」,这套阈值搬到中文素材上会系统性误杀你自己的内容——而你看不出是语言造成的,只会以为「这批选题质量不行」。
正确做法不是记住 0.21,是让阈值按语言分开标定,并且在换语言时重跑一遍回归。
还有一个我自己踩到的边界,一并说清:这个差不是「语言」一个变量造成的。 我先前测的时候,中文问题写得很简略(省掉了判据说明),结果反而是中文更高(0.81 vs 英文 0.79)。只有把完整的问题语义原样换成中文,才稳定复现出 −0.21。所以真正要盯的是两件事:问题写得够不够完整,以及阈值是不是按语言分开标定的。
六、我踩过的另外六个坑
都是实操里的,照抄能省时间:
noul返回的就是概率,没有 true/false 标签。 所以别拿「p 小于阈值」当「低置信」——p=0.1是很自信地答「否」。判低置信要取max(p, 1-p)。choice/score返回的是下标键({"0":0.07, "1":0.35, ...}),标签要按你传入的选项顺序映射回来。顺序错了,结果全错但看起来正常。score的最后一个档位别放「unknown」这类非序数项——归一化时它会被当成最高档。- 喂 state 时别把「自评」放进去。 我在素材里写了「级别 A / 不需要 S」这类自我声明,结果判断被带偏了。只喂客观素材,别喂结论。
- 同一 state 重跑有 ±0.02 抖动。 只有跨过阈值的差异才当信号——0.38 vs 0.86 有意义,0.71 vs 0.73 没有。
- id 生成别用「已收集条数」当序号。 我用
len(已收集)+1生成 id,因为筛选条件带日期后缀永不匹配,40 条全拿到同一个 id、互相覆盖。用enumerate。
七、搬完之后,判断变成了什么
给你一个前后对照,这是我自己的真实场景。
我以前有个发布前的关键词扫描脚本,跑出来是「✅ 无命中」。但那份扫描器自己文档里就写了:它只做关键词与结构匹配,不做语义判断,零命中 ≠ 安全——它读不懂落点,分不清「教你做」和「别做」。
我拿一篇真实稿件两层都跑了一遍:
第 0 关 关键词扫描 → ✅ 无命中
语义层(判落点) → B 方法清单形态 P=0.45 [边缘]
最可能命中层级 → L4_semantics (0.37)
同一个文件,词表说干净,语义层说「边缘」。 词表读到的是词,语义层读的是这段话让读者去做什么。
它不是替我做决定,是把我原来根本看不见的那一档风险摆到了台面上。
同一套东西我也用在选题上:40 条候选,每个维度一个原子问题,直接出概率。以前这一步是我拍脑袋,或者写一段提示词让聊天模型给我个意见——它给我一段话,我看完还得自己再判断一遍那段话。
八、社区已经走到哪一步了
Jev 发布才几天,生态已经长出来了。我顺着这个话题翻了一圈,把还在活跃的项目按方向归了个类:
| 项目 | 干的事 | star | 最近提交 |
|---|---|---|---|
| fast-jev-compaction | 用 Jev 替掉 Claude Code 的压缩摘要:每次工具调用和结果都在一次快请求里打分,过期的丢弃或截断,留下的原样保留 | 6,326 | 09-18 |
| NanoJev | Jev 的轻量复现:并行决策、动态候选项、端到端训练流程 | 2,009 | 09-21 |
| reticle | 给 Web / 桌面应用加机器可读的运行时感知,让 Agent 看懂自己刚建出来的东西 | 818 | 09-22 |
| hermes-jev-skills | 把 Jev 接进 Hermes / Claude Code / Codex:模型路由、记忆、上下文压缩、Skill 选择、浏览器操作 | 592 | 09-22 |
| jev-search | 用 Jev 做搜索:信源选择、查询理解、相关性排序 | 415 | 09-20 |
| pi-jev | 给 Pi coding agent 加工具调用闸门,外加 jev_ask 类型化问答 | 140 | 09-22 |
| jev-browser | LLM 负责规划,Jev 负责浏览器里的具体选择(Library / CLI / MCP) | 75 | 09-22 |
| open-alternative-jev | 用开源权重模型复现 System One 决策层,附 benchmark | 51 | 09-22 |
这张表该怎么读:它们全都在干同一件事——把「判断」从贵模型里搬出来。压缩、路由、搜索、浏览器操作、界面理解,每一个都落在第三节那张表「该搬」的栏里。这不是我一个人的用法,是这层被公开之后必然会发生的事。
说明一句:表里的 star 数和最近提交时间,是我写这篇时逐个查过的(2026-09-22),但我没有逐个跑过这些项目。把它们当线索,别当背书。
九、交付清单
搬一层判断,你手上应该留下这四样:
- 一张原子问题表——每个问题只问一件事,边界清楚
- 一段阈值代码——判断归模型,决定归你,系数写在代码里
- 一套回归脚本——换语言 / 换模型 / 改阈值后能重跑
- 一条回退通道——判断层挂了,你的流程还能走
第 4 条最容易漏,也最容易出事。别把判断层建在一个没有兜底的免费位上。
边界
这篇不是推荐信,所以边界一起写。这些数字与限制都来自官方文档和发布文,你可以自己核一遍:
- 价格是不是长期价,它自己也不确定。 官方发布文里自己承认了一句,大意是他们无法证明这个价格不是补贴出来的。这话我尊重,但它意味着做成本模型时别把这个单价当常量。
- 它的评测比的是「一致」不是「对」。 官方那组「快 193 倍、便宜 444 倍」的工作流评测,参考答案用的是两个大模型输出的平均,不是真值;发布文里也写了「可能存有偏见」。它证明的是「判断风格接近前沿模型且便宜得多」,不是「判断更正确」。
- 「0% 幻觉」是构造保证,不是实测。 因为不能生成文本,它没法编造文字——这是架构决定的,不是跑出来的分数。
- 它不能看图。 只有文本,没有图像、音频、视频。要做视觉判断的,这条直接出局。
- 免费位是限时的,而且会挂。 我写这篇时就吃到一次 503。别把判断层建在一个没有兜底的免费位上。
- 这不是说它在造假。恰恰相反:把「我没算进去的部分」写在明处的项目,比只给你看一个漂亮数字的项目可信得多。
判断搬走之后,最大的变化不是省了钱,是判断变得可以讨论了。
以前我说「我觉得这个能上」,那是一个感觉。现在它是一列概率、一张阈值表、一段能重跑的脚本。感觉不能被检验,系数可以。
这件事跟用哪个模型无关。今天可以是任何一个判断模型,明天它下架了换一个就是——因为你搬走的是判断这件事本身,不是某家的服务。
提示词里的一句话,应该是一个能调、能测、能回滚的系数。
#Jev #Agent #AI工作流 #模型选型 #判断层 #SystemOne