还在用 LLM 硬憋 JSON?Jev + ai4j:让 Java 系统直接拿到"能跑的决策"(附 Agent 编排实战)
关键词:Jev / System One / TypeSafe AI / ai4j / Java / Agent 编排 / 置信度路由
本文实操环境:JDK 8+、Maven、ai4j 2.7.0
一、先聊痛点:LLM 其实不适合"做决策"
如果你的系统里有这种代码,那你一定踩过坑:
// 让大模型判断工单该分给谁,然后祈祷它输出合法 JSON
String prompt = "请判断下面工单属于 billing/tech/sales 中的哪一类,只输出 JSON:{\"route\": \"...\"}";
String text = chatService.chat(prompt); // 返回的是一坨文本
// 然后开始漫长的兜底:剥 markdown 代码块、正则提取、JSON 解析、字段校验、幻觉重试……
问题在于:LLM 是"给人写话"的模型,不是"给程序做决策"的模型。RLHF 训练出来的模型天然追求"说得好听",于是带来了模式坍缩、过度自信、输出不可靠这些毛病——你让它选 billing,它可能给你来一段"根据我的分析……"。
今天要介绍的 Jev 走的是完全相反的路线,而且在 Java 圈现在就能用上。
二、Jev 是什么?一个"原生给机器用"的模型
Jev 是 TypeSafe AI 的第一个 System One 模型(名字致敬卡尼曼《思考,快与慢》里的"系统一"——快速、直觉式的判断)。
它和 LLM 的核心区别一句话概括:
| 普通 LLM | Jev (System One) | |
|---|---|---|
| 输出 | 给人看的文本 | 给程序用的类型化决策 |
| 结构化 | JSON mode 是"求"出来的 | 类型是协议的一部分 |
| 置信度 | 没有/靠嘴说 | 每个答案带校准过的概率分布 + confidence |
| 用法 | prompt 工程 + 解析兜底 | state + questions → 直接分支路由 |
| 定位 | 助手 | 自动化决策原语 |
官方宣称在 System One 类任务上比 LLM 工作流 快 193.6 倍、便宜 444.6 倍,输入价格约 $42 / 十亿 token(官方口径,量级感受一下就好)。它背后是新架构 + 新采样器 + 新训练算法(RLCD,Reinforcement Learning for Calibrated Decisions)。
三个 AI 原语
Jev 的 API 只有一个核心动作:你给它一个 state(案件材料)+ 一组 questions(问题清单),它并行评估所有问题,一次返回全部类型化答案。
| 问题类型 | 在问什么 | criteria 填什么 | 答案长什么样 | 什么时候用 |
|---|---|---|---|---|
choice | “从这几个选项里挑一个” | {选项名: 选项说明} 映射 | choice=胜出的选项名 + 每个选项的 probabilities + confidence | 路由、分类、意图识别——“这个工单给 billing / tech / sales 哪个组?” |
score | “按刻度给它评级” | 有序等级列表 ["不急","一般","紧急","致命"],下标即等级 | score=等级下标 + legend 映射 + probabilities/confidence | 紧急度、满意度、风险分级——选项之间有确定顺序时用 |
noul | “这个命题成立吗?给概率” | 可空;可选 {true: "什么算'是'", false: "什么算'否'"} 划边界 | noul="是"的概率 0..1 | 是/否判定:是否含隐私信息、是否违规、是否需要人工介入——天然适合当护栏阈值 |
一次真实调用的请求/返回长这样:
// POST https://api.typesafe.ai/v1/systemone
{
"state": {"text": "我的卡尾号4242被重复扣费了,请尽快退款!"},
"model": "jev-latest",
"questions": {
"route": {"type": "choice", "instructions": "分给哪个组?", "criteria": {"billing": "发票退款", "tech": "技术故障"}},
"urgency": {"type": "score", "instructions": "紧急程度?", "criteria": ["不急", "一般", "紧急"]},
"has_pii": {"type": "noul", "instructions": "含手机号身份证等隐私信息吗?"}
}
}
{
"answers": {
"route": {"choice": "billing", "confidence": 0.91, "probabilities": {"billing": 0.91, "tech": 0.09}},
"urgency": {"score": 2, "confidence": 0.81, "legend": {"0": "不急", "1": "一般", "2": "紧急"}},
"has_pii": {"noul": 0.97}
}
}
注意几个设计细节:
- 问题的 key(
route/urgency/has_pii)是你自己起的名字,只是用来取答案的标识,模型不看它 - 所有问题并行评估、互相隔离——加问题几乎不增加耗时,也不会互相污染上下文
- confidence 是校准过的:
confidence=0.91意味着"历史上这类置信度的判断约 91% 是对的"——这让置信度门控成为严肃的工程手段,而不是玄学
三、上手:5 分钟拿到 API Key
- 打开控制台注册/登录:https://console.typesafe.ai/
- 想先零代码体验?进 Playground,粘一段文本当 state,加几个问题直接看结果
- 在 Keys 页面 创建 API Key
- 设成环境变量(别写进代码/配置仓库):
# Linux / macOS
export TYPESAFE_API_KEY="sk-..."
# Windows PowerShell
$env:TYPESAFE_API_KEY="sk-..."
官方文档(https://docs.typesafe.ai/)目前只有 Python SDK(pip install typesafe-sdk)。Java 这边怎么办?往下看。
四、Java 接入:用 ai4j 两行配置搞定
ai4j 是一个 Java 8+ 的多平台 AI SDK(OpenAI / Claude / Gemini / DeepSeek / 豆包 / 通义 / Ollama 等几十家平台统一接口),2.7.0 版本刚发布了 Jev / System One 的一等公民支持——也是目前 Java 生态里第一条现成的接入路径。
4.1 加依赖
<dependency>
<groupId>io.github.lnyo-cly</groupId>
<artifactId>ai4j</artifactId>
<version>2.7.0</version>
</dependency>
4.2 初始化(纯 Java 方式)
TypeSafeConfig config = new TypeSafeConfig();
config.setApiKey(System.getenv("TYPESAFE_API_KEY"));
Configuration configuration = new Configuration();
configuration.setTypeSafeConfig(config);
ISystemOneService systemOne = new AiService(configuration)
.getSystemOneService(PlatformType.TYPESAFE);
4.2’ 初始化(Spring Boot 方式,推荐)
application.yaml:
ai:
platforms:
- id: typesafe-main
platform: typesafe
api-key-env: TYPESAFE_API_KEY # 凭证不落盘,装配时从环境变量解析
# api-host: https://api.typesafe.ai/ # 默认值,可覆盖
# system-one-url: v1/systemone # 默认值,可覆盖
引入 ai4j-spring-boot-starter 后,服务由自动装配注入:
@Resource
private AiService aiService;
ISystemOneService systemOne = aiService.getSystemOneService(PlatformType.TYPESAFE);
4.3 发一次求值:Builder 一把梭
// state:任意 JSON 形态 —— String / Map / List / null 都行
Map<String, Object> state = new LinkedHashMap<>();
state.put("message", "我的卡尾号4242被重复扣费了,请尽快退款!");
state.put("channel", "email");
// choice 的 criteria:{选项名: 选项说明}
Map<String, Object> routes = new LinkedHashMap<>();
routes.put("billing", "发票、退款、订阅扣费相关");
routes.put("tech", "功能异常、报错、集成问题");
routes.put("sales", "价格咨询、升级、新购");
SystemOneResponse response = systemOne.evaluate(
SystemOneRequest.builder()
.state(state)
.model("jev-latest") // 可省,缺省就是 jev-latest
.choice("route", "这个工单该分给哪个组?", routes)
.score("urgency", "紧急程度?",
Arrays.asList("不急", "一般", "紧急", "致命"))
.noul("has_pii", "内容含手机号/身份证/银行卡等隐私信息吗?")
.build());
String route = response.choice("route"); // → "billing"
Double urgent = response.score("urgency"); // → 2.0(等级下标)
Double pii = response.noul("has_pii"); // → 0.97("是"的概率)
Double conf = response.confidence("route"); // → 0.91
对比一下传统做法——不用拼 prompt、不用解析 JSON、不用正则兜底,拿到的直接是 String/Double,编译器帮你把关。
noul 需要更严格的判定边界时,可以加 criteria:.noul("has_pii", "含隐私信息吗?", new NoulCriteria("包含手机号、身份证、银行卡、住址", "只有昵称、订单号、时间戳"))。
五、重头戏:配合 Agent 编排使用
单个 evaluate 只是开胃菜。Jev 真正的威力在 Agent 工作流里当"决策节点"——ai4j-agent 模块直接内置了两个编排组件。
5.1 置信度门控路由:SystemOneRouter
场景:工作流跑到 “decide” 节点,要决定下一步走 billing 还是 tech 分支。置信度高就自动分流,置信度低就落到兜底分支(比如人工复核)——这是"机器原生智能"最经典的用法:
SystemOneRouter router = new SystemOneRouter(systemOne)
.instructions("这个请求该由哪个分支处理?")
.route("billing", "发票、退款、扣费问题")
.route("tech", "功能异常、报错、性能问题")
.minConfidence(0.7) // 置信度低于 0.7 不自动路由
.fallbackRoute("human"); // 兜底:转人工复核节点
Map<String, String> routeMap = new HashMap<>();
routeMap.put("billing", "billingNode");
routeMap.put("tech", "techNode");
routeMap.put("human", "humanReviewNode");
StateGraphWorkflow workflow = new StateGraphWorkflow()
.addNode("decide", decideNode)
.addNode("billingNode", billingNode)
.addNode("techNode", techNode)
.addNode("humanReviewNode", humanNode)
.start("decide")
.addConditionalEdges("decide", router, routeMap); // router 返回的 label → 节点 id
router 实现了 StateRouter 接口,直接把 Jev 的 choice 答案映射成条件边的目标节点——置信度不够自动走 fallbackRoute,这就是 calibrated confidence 的工程价值:你敢让它自动跑,因为你知道它什么时候"心里没底"。
5.2 合规护栏:SystemOneGuardrail
场景:用户输入进 Agent 之前,先问一句"这段内容含 PII 吗",概率超过阈值就拦截:
SystemOneGuardrail pii = new SystemOneGuardrail(systemOne)
.instructions("内容是否包含可识别个人身份的信息?")
.criteria(new NoulCriteria(
"包含手机号、身份证、银行卡、住址等",
"只有昵称、订单号、时间戳等非敏感内容"))
.threshold(0.8); // noul ≥ 0.8 判违规
// 作为工作流前置节点:命中即返回违规结果,不再往下走
workflow.addNode("piiGate", pii.asNode(blockedResult));
它实现的是 StateCondition 接口——既能当工作流节点用,也能挂到扩展体系的 GUARDRAIL 能力上,比如"模型调用前统一过一遍越权/涉敏检查"。
5.3 测试不烧钱:ScriptedSystemOneService
ai4j-testing 模块提供了录制回放式的夹具实现——编排逻辑的单元测试完全不用碰真实 API:
<dependency>
<groupId>io.github.lnyo-cly</groupId>
<artifactId>ai4j-testing</artifactId>
<version>2.7.0</version>
<scope>test</scope>
</dependency>
预先编排好"这个 state 该返回什么答案",CI 里随便跑,零 token 消耗。
5.4 一个完整的分工图景
用户消息
│
▼
[SystemOneGuardrail] noul ≥ 0.8 ? ──含敏感信息──→ 拒绝/脱敏节点
│ 安全
▼
[SystemOneRouter] choice + confidence ≥ 0.7 ? ──没把握──→ 人工兜底
│ 有把握
├──→ billingNode → 你的 Agent(LLM 干活:查单、生成回复)
└──→ techNode → 你的 Agent(LLM 干活:诊断、给方案)
这就是推荐的姿势:Jev 做"小而快的判断题"(路由、分级、合规),LLM 做"大而慢的问答题"(生成、推理、对话)。各干各擅长的活,延迟和成本同时降。
六、什么时候该用 Jev,什么时候还是用 LLM?
| 场景 | 选谁 |
|---|---|
| 工单分流、意图分类、内容审核开关 | Jev (choice/noul) |
| 紧急度/风险/满意度评级 | Jev (score) |
| 需要置信度门控的自动化决策 | Jev(confidence 是校准过的) |
| 高频、低延迟、大调用量的判断 | Jev(官方口径:快两个数量级) |
| 长文生成、复杂推理、多轮对话 | LLM(ai4j 里 IChatService/IResponsesService) |
| 需要创造性/开放性的输出 | LLM |
一句话:让 Jev 当 Agent 系统的"神经反射",让 LLM 当"大脑皮层"。
七、总结
- Jev 是 TypeSafe AI 的 System One 模型:输入
state+ 类型化questions,输出带概率分布和校准置信度的结构化答案——choice(选项路由)、score(等级评定)、noul(概率化是非题) - 注册:console.typesafe.ai → Playground 试玩 → Keys 页拿 key →
TYPESAFE_API_KEY环境变量 - Java 接入:ai4j 2.7.0,
ISystemOneService+ Builder API,Spring Boot 走ai.platforms[]+api-key-env - 编排:
SystemOneRouter(置信度门控条件路由)、SystemOneGuardrail(noul 阈值护栏)、ScriptedSystemOneService(离线测试夹具)
相关链接
- ai4j GitHub:https://github.com/LnYo-Cly/ai4j (⭐ 求 Star,2.7.0 已发布 Maven Central)
- System One 中文文档:https://lnyo-cly.github.io/ai4j/ → 能力 → System One
- TypeSafe 官网:https://typesafe.ai/ | 文档:https://docs.typesafe.ai/ | 控制台:https://console.typesafe.ai/
- DeepWiki(ai4j 架构导览):https://deepwiki.com/LnYo-Cly/ai4j
如果这篇文章帮你少写了 200 行 JSON 解析兜底代码,点个赞/收个藏吧 🙏 有问题欢迎评论区交流,也可以直接到 GitHub 提 issue。
190



被折叠的 条评论
为什么被折叠?



