package com.xly.service; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.xly.util.OkHttpUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; /** * 直连 Ollama /api/chat 的**受约束 JSON**补全(constrained decoding)。 * *
为什么绕开 LangChain4j:Ollama 的 {@code format= 用于两处「窄而稳」的推理子任务:{@link IntentService}(意图+实体分类)与
* {@link SlotFillService}(按表单真实字段做受约束的槽位填充)。主对话/查询仍走 LangChain4j 工具循环。
*/
@Service
public class OllamaJsonClient {
private static final Logger log = LoggerFactory.getLogger(OllamaJsonClient.class);
private final ObjectMapper mapper;
@Value("${langchain4j.ollama.base-url}")
private String baseUrl;
@Value("${langchain4j.ollama.chat-model-name}")
private String model;
public OllamaJsonClient(ObjectMapper mapper) {
this.mapper = mapper;
}
/**
* 受约束 JSON 补全:think=false(快且稳定,实测无精度损失)、低温度、format=schema、非流式。
*
* @param system 系统提示(角色 + 抽取规则)
* @param user 用户话
* @param schema JSON Schema(Map 结构,直接序列化进 format)
* @return 解析后的 JsonNode;失败返回 null(调用方须降级处理,绝不因它中断主流程)
*/
public JsonNode completeJson(String system, String user, Map