最新版本的 Ollama 原生加入了对决策模型的支持,新增了一个专用的 /v1/systemone 接口。只要把本地的 Ollama 升级到 0.35 及以上版本,就能直接调用这项能力。
这个接口走的是 TypeSafe 发起的 Jev API 规范。它和我们平时调的 /api/generate 或 /api/chat 完全是两套逻辑。客户端在一次请求里发过去一段文本状态,同时带上几个具体的问题。模型在一次推理里把这些问题全算完,直接给强类型的结果和精确的小数概率。
因为模型跑在本地机器上,省掉了公网请求来回跑的时间,延迟压得很低。在本地跑这种决策模型,单次判定常常只要几十毫秒,拿来做高频意图分流或者安全拦截才跑得起来。

Cloudflare 开源的 Clef 决策模型

规范出来之后,开源社区很快跟进了专用模型,其中很受关注的是 Cloudflare 开源的 Clef 系列。
Clef 采用 Apache 2.0 协议开源,目前主要有两个尺寸。一个是偏向高精度的 Clef,参数量 27 B,基座基于 Qwen3.8-27 B 微调。另一个是偏向低延迟的 Clef-flash,参数量 9 B,基座基于 Qwen3.5-9 B。
从计算过程来看,Clef 和普通的自回归语言模型差别很明显。
普通的语言模型算下一个词时,必须依赖前面已经吐出来的词。Clef 走的是非自回归路线,在骨干网络把输入内容算完一遍之后,直接用两阶段注意力路由,让输入内容和候选选项做交叉计算,直接算出每个选项的概率分布。整个过程不用逐字生成任何中间文本。
除了算得快,Clef 还带了视觉编码器,可以直接接收图片并给出分类概率,同时保留了 64k 的上下文长度。在处理长工单或者图片审核时,这些设计省去了很多外围拼接的工作。
在本地 Ollama 中跑起 Clef
在本地跑 Clef 不需要复杂的配置。先把机器上的 Ollama 升级到最新版本。
升级好之后直接拉取模型。日常本地开发和测试,9 B 的 clef-flash 速度快而且占资源少。
拉完模型,可以用 cURL 往本地 Ollama 的 /v1/systemone 接口发一个请求。下面是一次针对技术工单的多问题判定。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| curl http://localhost:11434/v1/systemone \ -H 'Content-Type: application/json' \ -d '{ "model": "clef-flash", "state": "系统从上午9点开始一直报500错误,请尽快安排退款并修复!", "questions": { "team": { "type": "choice", "instructions": "该工单应指派给哪个团队处理?", "criteria": { "billing": "支付、账单与退款问题", "technical": "系统故障、接口报错与运维问题", "sales": "售前咨询与升级方案" } }, "need_refund": { "type": "noul", "instructions": "用户是否明确要求退款?" }, "urgency": { "type": "score", "instructions": "该问题的紧急程度评分", "criteria": ["常规", "一般", "紧急", "致命"] } } }'
|
接口返回的是结构清晰的答案,每个问题都带上概率。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| { "answers": { "team": { "type": "choice", "choice": "technical", "probabilities": { "technical": 0.68, "billing": 0.31, "sales": 0.01 } }, "need_refund": { "type": "noul", "answer": true, "probability": 0.94 }, "urgency": { "type": "score", "score": "紧急", "probabilities": { "常规": 0.02, "一般": 0.08, "紧急": 0.72, "致命": 0.18 } } } }
|
拿到具体的概率值,控制分支条件会踏实很多。比如最高选项的概率如果低于 0.6,代码可以直接把工单转给人工坐席,避免系统在没把握的时候乱选。
用 LangChain4j 接入本地决策模型
在 Java 生态里,最新版本的 LangChain4j(1.21.0)正式引入了实验性的 DecisionModel 接口。
这个接口主要用来支持那些对延迟敏感的环节,比如模型路由器 DecisionModelChatModelRouter、输入安全检查 DecisionModelInputGuardrail 和工具过滤器 DecisionModelFilteringToolProvider。
因为 Ollama 的 /v1/systemone 端点遵循了 Jev 规范,Java 这边可以直接用 LangChain4j 的 TypeSafeDecisionModel 驱动连上去。
在 Maven 项目里引入依赖。
1 2 3 4 5 6 7 8 9 10
| <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-core</artifactId> <version>1.21.0</version> </dependency> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-typesafe</artifactId> <version>1.21.0</version> </dependency>
|
接着在 Java 代码里把请求地址指向本地 Ollama。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import dev.langchain4j.model.decision.DecisionModel; import dev.langchain4j.model.decision.request.ChoiceQuestion; import dev.langchain4j.model.decision.request.DecisionRequest; import dev.langchain4j.model.decision.request.YesNoQuestion; import dev.langchain4j.model.decision.response.ChoiceAnswer; import dev.langchain4j.model.decision.response.DecisionResponse; import dev.langchain4j.model.decision.response.YesNoAnswer; import dev.langchain4j.model.typesafe.TypeSafeDecisionModel;
public class DecisionModelExample {
public static void main(String[] args) { DecisionModel decisionModel = TypeSafeDecisionModel.builder() .baseUrl("http://localhost:11434") .modelName("clef-flash") .build();
DecisionRequest request = DecisionRequest.builder() .input("系统从上午9点开始一直报500错误,请尽快安排退款并修复!") .question("team", ChoiceQuestion.builder() .text("该工单应指派给哪个团队?") .option("billing", "支付、账单与退款问题") .option("technical", "系统故障、接口报错与运维问题") .option("sales", "售前咨询与方案升级") .build()) .question("urgent", YesNoQuestion.of("该工单是否属于紧急故障?")) .build();
DecisionResponse response = decisionModel.decide(request);
ChoiceAnswer teamAnswer = response.choice("team"); YesNoAnswer urgentAnswer = response.yesNo("urgent");
System.out.println("分配团队: " + teamAnswer.value()); System.out.println("分配团队概率分布: " + teamAnswer.probabilities()); System.out.println("是否紧急: " + (urgentAnswer.isYes(0.7) ? "是" : "否")); System.out.println("紧急判定概率: " + urgentAnswer.probability()); } }
|
除了直接调用 DecisionModel,LangChain4j 还支持通过 Java 接口定义判定规则的 DecisionService。写一个普通接口并配上注解,框架会在底层自动完成参数打包和类型转换。把本地运行的 Ollama 和非自回归决策模型配合起来,系统的第一道分流就能在毫秒级内跑完。