用 Jev 打德州扑克
Jev 一个字都不生成。不能聊天,不能写代码,只返回带类型的判断和一个校准过的概率。我把一个真实牌局的翻牌圈喂给它,只问一个决策点:第一遍它建议跟注,自己只有 32% 的把握;我往局面描述里补了一句话,它翻转成弃牌,把握涨到 63%,而弃牌才是数学上正确的答案。那句话是「我手里没有方块」。这篇讲的是它为什么推不出来,以及为什么这比结论更值得记。
Jev 是什么
2026 年 9 月 15 日,一家叫 TypeSafe AI 的公司放出了第一个模型 Jev。创始人 Diogo Almeida 是前 OpenAI 研究员,RLHF 的共同发明人之一,也就是 ChatGPT 背后那套方法的作者之一。
他们给 Jev 的定位叫 System One Model,对应卡尼曼那套「系统一是快速直觉判断,系统二是慢速推理」。
它和你熟悉的所有大模型有一个根本区别:
它完全不生成文字。
不能聊天,不能写代码,一个字都吐不出来。你给它一段材料和一组带类型的问题,它返回带类型的答案:一个选择、一个分数、一个概率,每个都附带置信度。
和大模型的四个差别
一、架构上不解码。 大模型是逐个 token 往外吐,结构化输出是把吐出来的字符串再解析成 JSON。Jev 没有语言模型头,直接用决策头输出概率分布,中间没有「先写一段话再转结构」这一步。
二、答案空间由你定义。 你给它三个选项,它只能在这三个里选。「输出了一个不存在的分类」在架构层面就不可能发生,这不是靠提示词约束,是靠结构。
三、概率是校准过的。 这是最值钱的一条,也是它整个训练方法的目标。TypeSafe 管这套训练叫 RLCD(Reinforcement Learning for Calibrated Decisions):不用人类偏好打分,而是用可验证的真实答案配上严格评分规则来算奖励。目标不是「让人觉得好」,而是「说 70% 的时候,真的就该有 70% 会中」。
四、便宜和快。 输入 $0.042 / 百万 token,输出免费,因为它根本不产出 token。延迟在几十到几百毫秒量级。
为什么「校准」是重点
我在本地做过一个对照。用 Ollama 跑本地模型,把候选映射成字母,直接读 token 的 logprob 再归一化,这样拿到的是模型真实的输出分布,不是问它「你有多确信」。
然后问它一个原理上不可知的问题:
一枚硬币已经抛出但尚未揭晓,是正面吗?
本地模型给的是 99.9%。温度调到 0、1、2 都一样,因为那是未经温度缩放的原始分布。
同样的问题给 Jev:51%。
差别不在于谁更聪明。本地那个模型当然知道硬币是五五开,你在聊天里问它,它会告诉你 50%。缺的不是知识,是那个数字没承载知识。 被迫选一个 token 的时候,它就是会给 99.9%。
RLCD 教的不是「硬币是公平的」,是让那个数字有意义。
注册
好消息:TypeSafe 在 9 月 21 日取消了等待名单,现在 console.typesafe.ai 直接注册就能用,新账号送 $5 额度,按 $0.042 / 百万 token 算大约一亿两千万 token。玩起来基本等于无限。
注意是 console 子域名,主站 typesafe.ai 是产品页。API Key、Playground、用量面板都在 console 里。
Playground 长这样:左边上方填 State,左边下方写 Questions(JSON),右边出结果。
把一手牌翻译成 State 和 Questions
拿来做实验的是一场直播现金局里的一手牌。说清楚范围:我没有让它打完一局,只截取了翻牌圈上的一个决策点,问它此刻该弃该跟还是该加。
翻牌 Q♦ 10♣ J♦,底池 29,000。三个人:PAMPAGE 在大盲位拿 A♣7♣,HANDZ 在枪口位拿 QQ,PAV 在按钮位拿 K8。
我要做的是:站在 PAMPAGE 的位置上,让 Jev 给一个决策。
第一个设计决定:不能给它上帝视角
直播画面是上帝视角:三家的底牌全亮着,HANDZ 的 QQ、PAV 的 K8 都一目了然。这些绝对不能进 State。
因为 PAMPAGE 坐在桌上时看不见对手的牌。放进去会得到一个「正确但毫无用处」的建议,它在用上帝视角做决策,而真实场景里你没有那份信息。
这是设计这类系统最容易犯的错:State 里只能有决策者当下真的能观察到的东西。
第二个设计决定:能算的别问
跟注赔率是确定的算术:
下注前底池 29,000 + 按钮下注 15,000 + 我跟注 15,000 = 59,000
15,000 ÷ 59,000 = 25.4%
意思是我至少要有 25.4% 的胜率,这一跟才不亏。这个数我用计算器算好写进 State,不问模型。 模型该做的是判断,不是计算。
最终的 State
Six-handed cash game. Blinds are 500/1000 with a 2000 ante from every player.
I am in the big blind holding A♣ 7♣ (the ace and seven of clubs).
The flop is Q♦ 10♣ J♦ (queen of diamonds, ten of clubs, jack of diamonds).
Preflop: the UTG player raised to 5,500, the button called, I called from the
big blind, and the small blind folded. Three players saw the flop and the pot
was 29,000.
Flop action so far: I checked, the UTG player checked, and the button bet
15,000.
It is now my turn. Calling costs 15,000. If I call, the pot will be 59,000,
so I am getting 25.4% pot odds.
The UTG player still acts after me, so calling does not close the action and
I could still face a raise.
Stacks: me 1,100,000, the UTG player 843,000, the button 940,000.
I have no diamonds in my hand, so I have no flush draw. My only draw is a
gutshot to Broadway, needing a king.
最后那两句是这次实验的关键,后面说。
Questions:三种类型,分四层
Jev 有三种问题类型:
| 类型 | 答案空间 | 返回 |
|---|---|---|
| Noul | 固定:真 / 假 | 一个概率 |
| Choice | 你定义的选项 | 每个选项一个概率 + 总置信度 |
| Score | 你定义的等级 | 一个数值(可小数)+ 置信度 |
criteria 就是你定义答案空间的地方。Choice 用对象,键是选项;Score 用数组,下标就是分数。Noul 没有 criteria,因为答案空间天然固定,没什么可定的。
我把六个问题拆成四层:
{
"currently_best_hand": {
"type": "noul",
"instructions": "Right now on this flop, is my hand most likely the best hand among the players still in the pot?"
},
"made_hand_strength": {
"type": "score",
"instructions": "How strong is my made hand right now, ignoring any drawing potential?",
"criteria": [
"No pair and no showdown value at all",
"High card only, or bottom pair",
"Middle pair, or a weak top pair",
"Strong top pair",
"Two pair or better"
]
},
"draw_quality": {
"type": "score",
"instructions": "How good is my potential to improve to a winning hand on the turn or river?",
"criteria": [
"No draw at all",
"Gutshot straight draw only, roughly four outs",
"Open-ended straight draw, or a flush draw",
"Strong combination draw with many outs",
"Drawing to the effective nuts with a very large number of outs"
]
},
"opponent_range_is_strong": {
"type": "noul",
"instructions": "Given the preflop action and this flop, does the betting player's range look strong here?"
},
"utg_likely_to_raise": {
"type": "noul",
"instructions": "If I call the 15,000, is the UTG player behind me likely to raise?"
},
"action": {
"type": "choice",
"instructions": "Facing a 15,000 bet with one player still to act behind me, what should I do?",
"criteria": { "Fold": null, "Call 15,000": null, "Raise": null }
}
}
为什么不直接问一句「我该怎么打」?
因为那样你只得到一个答案和一个置信度,模型在哪一步出的错你完全不知道。拆开之后,每一环都能单独验证,而这正是后面救了我的东西。
前两条尤其重要:它们的正确答案我已经知道,所以可以用来检验模型到底读懂牌面没有。先用已知答案的问题做验证,再去信那些你不知道答案的问题。
Jev 的回答
| 问题 | 回答 | 置信度 |
|---|---|---|
| 我现在是最大的吗 | 17% 为真 | — |
| 成牌强度 | 1.04 / 4 | 69% |
| 听牌质量 | 1.08 / 4 | 93% |
| 对手范围强吗 | 65% 为真 | — |
| 身后会被加注吗 | 30% 为真 | — |
| 我该怎么打 | 弃牌 75% / 跟注 22% / 加注 3% | 63% |
逐条解读
我现在是最大的吗 → 17%。只有 A 高牌,没成对。牌面 Q-J-10,对手手里只要有 Q、J、10 中任意一张就成对了。要赢必须两家同时落空、高牌还都比我小。17% 甚至偏乐观。
成牌强度 → 1.04 / 4。落在第 1 档「只有高牌」。没落到第 0 档(毫无摊牌价值),是因为 A 高终究还能赢下对方的 K 高、Q 高。返回 1.04 而不是整数,是因为它给的是整个分布的期望值。
听牌质量 → 1.08 / 4,置信度 93%。落在第 1 档「只有卡顺,约四张出牌」,完全正确。我的 A 配上牌面的 Q-J-10,只差一张 K 就成 A-K-Q-J-10,全副牌四张 K。牌面那两张方块在公共牌上不在我手里,所以没有同花听牌。93% 是全屏最高的置信度。这一条是整篇文章的转折点。
对手范围强吗 → 65%。按钮位在两家都过牌之后才下注。要么真有牌,要么看两家示弱来偷池。65% 偏向「真有牌」,留三成多给诈唬,分配合理。
身后会被加注吗 → 30%。UTG 翻牌前加注、翻牌后却过牌了,过牌这个动作通常削弱范围。但过牌加注是真实存在的打法,所以不能给 0。
这里有个值得玩味的地方:实际上 HANDZ 手里是 QQ,在这个牌面上是三条,他大概率真的会加注。 但 Jev 不该知道,PAMPAGE 在桌上看不见。从那个座位上能拿到的信息看,30% 就是诚实的答案。这正是一开始坚持不泄露底牌的意义。
我该怎么打 → 弃牌 75% / 跟注 22% / 加注 3%,置信度 63%。弃牌为什么对:
需要的胜率 25.4%
卡顺,下一张牌 4 ÷ 47 = 8.5%
就算能看两张牌 ≈ 16.5%
而且 UTG 在我后面,这 15,000 买不断两张牌,连 16.5% 都拿不到。
跟注那 22% 不是噪声,它对应隐含赔率:万一真来了 K,对手会付我一个大底池。Jev 认可这个理由存在,只是判断它不够补上缺口。
加注 3%:对着一个 65% 偏强的范围诈唬,身后还有人可能反加,几乎永远是错的。约等于零,判断准确。
一个结构上的细节
你会注意到 Noul 那三条没有单独的置信度,而 Choice 和 Score 有。
因为对判断题来说,概率本身就是答案,「17% 为真」已经把不确定性说完了。而 Choice 和 Score 的答案是「选了哪个」「落在哪档」,这个选择本身有多可靠是另一个问题,所以需要额外一个数。
真正的发现
前面跳过的那件事:第一次跑的时候,State 里没有最后那两句。
它把牌面上的两张方块当成了我的同花听牌。
这个推理对人来说是零成本的:我拿 A♣7♣,牌面 Q♦J♦,一眼就知道我没方块。但它做不了这个减法。补上一句「我手里没有方块」,听牌评估立刻落到正确档位,置信度从全屏最低变成全屏最高,最终建议也跟着翻转了。
于是这次实验真正回答的不是「这手牌该怎么打」,而是:模型能不能自己推出归属关系。
答案是不能。所以:
凡是「X 属于 A 不属于 B」这类归属关系,必须显式写进 State,不要指望模型自己推。
三条可复用的东西
一、错误传播链是可见的。 它之前建议跟注,唯一原因就是高估了听牌。上游一修正,下游立刻反转。如果我只问一句「我该怎么打」,我看不到这条链,只会觉得模型反复无常。
二、置信度精确地指向了 bug 的位置。 第一次跑的时候 39% 是全屏最低,那正是坏掉的那一环。按置信度升序排,修最低的那个,重跑。 这是一套可以直接拿去用的排查流程,不需要懂扑克。
三、置信度是诚实的。 它错的时候说自己没把握,对的时候说自己有把握,两次都说对了。这就是校准的全部意义,也是本地那个玩具永远做不到的事,它在两种情况下都会给你 100%。
最后
Jev 不是扑克求解器,别指望它替代 solver。GTO solver 给的是数学上可证的最优解,Jev 给的是判断,这是两件事。
它也不是「最终答案」,而是一个部件。这个局面真正的结论来自三样东西的汇合:确定的算术(需要 25.4%,实际 8.5%)、模型的判断(弃牌 75%)、位置的事实(跟注不能封顶)。三条指向同一个方向,才是该行动的时候。
反过来说:如果模型说跟注而算术说亏,听算术的。算术是确定的,模型是判断,这个优先级不能反。
还有一句和牌桌无关的:我们不知道这手牌实际怎么走的,截图只到翻牌。但即使跟注之后真的来了一张 K、赢下一个大池,弃牌仍然是当时正确的决策。8.5% 的事情会发生,发生了也不代表当初该跟。
结果好,不等于决策对。