7天假期生态全齐:Ollama原生支持决策模型,LangChain4j火速接入

最新版本的 Ollama 原生加入了对决策模型的支持,新增了一个专用的 /v1/systemone 接口。只要把本地的 Ollama 升级到 0.35 及以上版本,就能直接调用这项能力。

这个接口走的是 TypeSafe 发起的 Jev API 规范。它和我们平时调的 /api/generate 或 /api/chat 完全是两套逻辑。客户端在一次请求里发过去一段文本状态,同时带上几个具体的问题。模型在一次推理里把这些问题全算完,直接给强类型的结果和精确的小数概率。

因为模型跑在本地机器上,省掉了公网请求来回跑的时间,延迟压得很低。在本地跑这种决策模型,单次判定常常只要几十毫秒,拿来做高频意图分流或者安全拦截才跑得起来。

ollama 决策模型

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 升级到最新版本。

1
ollama --version

升级好之后直接拉取模型。日常本地开发和测试,9 B 的 clef-flash 速度快而且占资源少。

1
ollama pull 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 和非自回归决策模型配合起来,系统的第一道分流就能在毫秒级内跑完。