Jev 的边界

Jev 发布以后,很快出现在了一批看起来有些反常的 Demo 里。

有人用它控制浏览器,有人让 UI 根据用户状态动态变化,也有人把它放进游戏里,实时决定下一段地形应该怎么生成。

这些 Demo 和过去几年常见的大模型应用不太一样。

大语言模型习惯把很多问题都改写成 Generation。分类可以生成一个标签,路由可以生成一个模型名,工具调用可以生成一段 JSON。即使最终的软件动作只有三种:

continue
ask_human
stop

常见做法仍然是把当前状态交给模型,然后要求它生成:

{"action":"ask_human"}

Jev 省掉了中间这段。

它接收当前状态和有限候选,直接返回候选上的概率。TypeSafe 把这种模型称为 System One Model。

大致可以理解成:

State + Candidates
        ↓
      Jev
        ↓
Typed Decisions

第一次看到这个结构时,我很快想到了 Free4Chat。

过去几个月,Free4Chat 花了不少时间在 Agent Task 上。Agent 可以进入 Room,在自己的机器上执行一个长时间任务。Human 可以离开,之后再用手机回来查看进度、继续对话、Interrupt,或者把任务交给另一个 Agent。

这些 Agent 背后基本还是 Claude、Codex、Pi 这一类完整的大模型。

如果 Agent 只是偶尔做一次复杂判断,这没有问题。

但如果一个 App 希望 Agent 每隔几百毫秒做一个小决定,情况就不一样了。

给 Agent 加一个反射层

一个很自然的设计是把 Agent 分成两层。

System Two 负责理解目标、制定策略和处理复杂情况;System One 负责大量小而频繁的决策。

比如一个 Agent 进入 Room App 后,System Two 每隔一段时间决定一次:

保护 Human
优先攻击 healer
生命值过低时撤退

底下的 System One 根据实时状态不断选择:

move
attack
heal
defend
wait

这和我之前做 Domain Harness 时形成的思路很接近。

一个通用模型直接面对开放世界,通常很难稳定工作。更好的办法是先把领域整理成明确的 State、Action 和 Validation,让模型只处理真正需要模型的部分。

既然 Harness 已经把 Action Space 压缩成几个合法动作,再让一个完整的大语言模型为每一次小决策生成 JSON,看起来确实有些浪费。

于是我在 Free4Chat 的 Lab 里做了一个 Arena。

Arena 本身没有什么产品意义,它只是一个便宜的实验环境。

我们把游戏状态整理成结构化数据,把 Agent 可以执行的动作限制在一个很小的集合里。Jev 只负责选择 Semantic Action,真正的状态修改仍然由 App 的确定性逻辑完成。

从机制上看,这套设计可以工作。

结果却没有想象中好。

Scripted Bot 更稳定

Arena 里除了 Jev Bot,还有一个非常普通的 Scripted Bot。

后者没有模型,只是几条根据距离、生命值和目标状态编写的规则。

最后记录下来的行为指标里,Scripted Bot 反而更稳定。

延迟也没有最开始想象得那么低。

为了排除 Cloudflare AI Gateway 的影响,后来又直接测了一次 TypeSafe API。同一个 bounded Choice 请求,官方 API 的端到端 p50 大约是 344ms;经过当时的 Cloudflare Gateway,warm p50 大约是 635ms。

这已经明显快于 Frontier LLM,但离我一开始想象的「Agent 反射层」还有距离。

更重要的是,几百毫秒到底算不算快,取决于它处在什么 Control Loop 里。

300ms 用来决定下一块地图应该长什么样,可能完全够用。

300ms 用来决定角色现在应该向左还是向右,已经很慢了。

如果一个动作最终只是:

if (enemyDistance < 3 && health < 0.3) {
  defend()
} else {
  attack()
}

那么增加一次网络请求和一次概率模型推理,本身就是额外复杂度。

这里的问题已经不是 Jev 能不能做,而是为什么要让它做。

Free4Chat 最后没有增加一个通用的 System One Layer。高频 Movement、Aim、Fire Timing、UI Local Interaction 继续留在确定性代码里,相关的 Research Issue 也被关闭了。

为什么别人的 Demo 又很好看?

Arena 的结果很容易把人带到另一个极端:Jev 也不过如此。

但继续看最近那些效果不错的 Demo,会发现事情没有这么简单。

Sprite Fusion 有一个用 Jev 实时生成横版游戏地图的实验。

游戏引擎并没有让 Jev 自己生成整个世界,而是提前规定了一组参数:

Surface Type
Width
Gap
Height

Jev 根据玩家当前位置和已有地图,从这些合法参数里选择下一段地形。

他们公布的 API latency 也在几百毫秒。

和 Arena 看起来都属于「实时游戏 AI」,实际上两个系统对实时的定义完全不同。

Arena 是持续控制。

地图生成是 Ahead-of-time Decision。

只要玩家跑到下一段地图以前把结果算出来,300ms 和 30ms 对体验可能没有区别。

Browser Use 也是类似的问题。

表面上看起来是模型直接控制网页,但真正进入 Decision Model 以前,Browser Harness 往往已经处理了大量工作:

DOM
Accessibility State
Focused Element
Clickable Elements
Inputs
Current URL
Legal Operations

到了 Jev 面前,开放的网页已经变成了一组比较干净的状态和候选动作。

模型只需要回答:

CLICK element_17
TYPE element_23
SCROLL
WAIT

这些成功案例有一个共同点:

有人已经替模型把世界整理好了。

这和直接让模型理解一个开放环境不是同一件事。

Live View 的第二个边界

Arena 之后,我又考虑过另一个看起来更适合 Jev 的场景:Task Live View。

Live View 是 Free4Chat Task 里由 Agent 生成的一块临时交互界面。

它本身就是受限的 Declarative UI。Agent 不能随便执行 HTML 和 JavaScript,而是在一个有限的 Component Catalog 中组合界面。

假设系统已经提供:

Progress
ArtifactList
DiffView
ApprovalCard
TestResult
Retry
Cancel

Jev 完全可以决定哪些组件应该出现、怎么排序、哪个更重要。

Vercel 的 json-render 也提供了类似的思路:先定义 Component Catalog、State 和 Actions,再让模型在这个合法空间里组合 UI。

问题出现在更前面。

假设用户说:

分析这个 Repo,给我一个可交互的 Dashboard。

合理的界面也许应该包含:

Dependency Graph
Risk Table
File Explorer
Test Summary

但这些 Candidate 是谁提出的?

如果仍然需要 Claude 或 Codex 先理解 Repo,再判断应该有哪些信息和交互,那么 Jev 优化的只是最后一小段 UI Composition。

它可以从候选里选择。

它不能保证真正需要的东西已经出现在候选里。

这和 RAG 里的 Reranker 很像。Reranker 可以很强,但 Retriever 根本没有召回某篇文档,它也没有机会把那篇文档排到第一。

后来 Free4Chat 把这两条路线重新拆开了。

简单、受限、不需要执行环境的动态界面继续留在 Live View,并单独研究更丰富的 Declarative UI 和 json-render

当界面复杂到需要自定义业务逻辑、状态和数据处理时,与其不断扩充 UI DSL,不如让 Coding Agent 直接生成一个临时 Runtime App。

Jev 并不是两条路线中间必须存在的一层。

Jev 的位置

折腾一圈以后,我现在更愿意从问题本身来区分工具。

问题形态 更自然的实现
规则能够稳定表达 Deterministic Code
规则很难写死,但 Candidate Space 已经明确 Decision Model
连 Candidate 都需要发现、创造和解释 Generative / Reasoning Model

Arena 大部分动作其实落在第一类。

Live View 的复杂部分经常会滑向第三类。

Jev 真正有区别的地方,出现在中间这一层。

比如几十个告警里现在最应该看哪几个;一个请求应该路由给哪个 Agent;当前 Workflow 应该继续、重试还是交给 Human;一批内容应该 Ignore、Watch 还是 Deep Dive。

这些问题不太适合写很多规则,但答案空间又已经存在。

从这个角度看,Jev 更像一组非常便宜的 Fuzzy If Statements,而不是一个更快的小号 Claude。

这也解释了为什么 Routing、Classification、Scoring、Verification 这些场景天然适合 Decision Model。

这条边界和 Domain Harness 的关系也很直接。

Domain Harness 解决的是:怎么把一个开放世界整理成模型可以稳定处理的问题。

Jev 继续追问的是:当这个过程已经完成以后,剩下的判断还需要一个完整的 Generative Model 吗?

Decision Model 前面的工作

Jev 越专用,前面的 Harness 反而越重要。

一个完整的大模型可以直接接收一张 Screenshot,然后尝试自己理解页面。

Decision Model 更依赖系统提前做好 Representation 和 Candidate Construction。

网页要先变成 DOM、Accessibility State 和 Legal Actions。

游戏要先变成结构化 World State 和可执行动作。

Workflow 要先定义哪些状态允许哪些 Transition。

如果 Candidate Space 没有把正确答案暴露出来,模型再快也没有意义。

这也是我之前做 Domain Harness 时反复遇到的问题。

一个 Agent 能不能稳定进入某个领域,很多时候不取决于模型参数再增加多少,而取决于这个领域有没有被整理成机器容易消费的 State、Action、Constraint 和 Feedback。

当 Harness 已经把一个开放问题压缩成稳定状态和十几个合法动作以后,再调用一个完整的 Generative Model,本身可能就是一种过度计算。

过去几年大模型提供了一个非常方便的统一接口。

分类可以 Generation。

路由可以 Generation。

工具选择可以 Generation。

决策也可以 Generation。

统一接口当然很好用,但它也很容易让不同的问题看起来都应该经过同一条计算路径。

Jev 至少让这个假设重新变得可疑。

这次实验留下了什么

我现在还不知道 Jev 最后会不会成为一个独立的模型品类。

TypeSafe 所谓的 System One Model,也可能几年以后被 Foundation Model 吸收成一种新的 inference mode。底层可能仍然共享同一个 Backbone,只是在不同任务上走不同的计算路径。

对 Free4Chat 来说,这个问题暂时没有那么重要。

最后没有接入 Jev。

Arena 继续使用确定性控制,Live View 继续研究 Declarative UI,更复杂的界面准备交给 Runtime App。

从产品结果看,这甚至算不上一次成功的 Jev 实验。

但下一次再遇到一个需要「一点智能」的判断时,我大概不会再默认先调用 LLM。

先看看规则是不是其实能够写清楚。

如果规则写不清,再看看 Candidate Space 是否已经明确。

只有连 Candidate 都需要发现、创造和解释的时候,Generation 才重新变得自然。

大语言模型已经证明,很多问题都可以通过 Generation 表达。

但能用 Generation 表达,并不意味着一定要通过 Generation 计算。

Jev 最有意思的地方,也许不是它已经给出了一个新答案,而是它让「所有智能问题都应该变成 Generation」这件事重新变得可疑。

相关资料

更新时间: 今日 版本: cc1564c