Java AI 實(shí)戰(zhàn):本地模型JSON結(jié)構(gòu)化輸出
在人工智能和機(jī)器學(xué)習(xí)領(lǐng)域,大語言模型(LLM)的應(yīng)用日益廣泛。Ollama 作為一個(gè)強(qiáng)大的開源 LLM 工具,不僅可以進(jìn)行自然語言對(duì)話,還能生成結(jié)構(gòu)化的輸出數(shù)據(jù)。本文將詳細(xì)介紹如何使用 Ollama 生成 JSON 格式的輸出,并提供完整的 Java 實(shí)現(xiàn)方案。
注意:本文采用原生 HTTP 調(diào)用方式實(shí)現(xiàn)與 Ollama 的交互,不依賴任何第三方 SDK(如 Spring AI、LangChain4j 等)。這種方式可以讓你更好地理解底層實(shí)現(xiàn)原理,并且可以根據(jù)實(shí)際需求自由選擇是否使用其他 SDK。
為什么選擇結(jié)構(gòu)化輸出?
在實(shí)際應(yīng)用中,我們經(jīng)常需要將 LLM 的輸出集成到現(xiàn)有的系統(tǒng)中。這時(shí),結(jié)構(gòu)化的輸出格式(如 JSON)就顯得尤為重要:
- 易于解析:JSON 是一種標(biāo)準(zhǔn)的數(shù)據(jù)交換格式,可以輕松地轉(zhuǎn)換為編程語言中的對(duì)象
- 結(jié)構(gòu)清晰:相比于純文本輸出,JSON 的層次結(jié)構(gòu)更加清晰
- 便于集成:可以輕松地集成到現(xiàn)有的系統(tǒng)和工作流程中
技術(shù)實(shí)現(xiàn)
1. 環(huán)境準(zhǔn)備
首先,我們需要在本地環(huán)境中安裝并運(yùn)行 Ollama。
macOS 安裝
# 使用 Homebrew 安裝
brew install ollama
Linux 安裝
# 使用官方腳本安裝
curl -fsSL https://ollama.com/install.sh | sh
啟動(dòng) Ollama 服務(wù)
安裝完成后,在終端運(yùn)行:
# 啟動(dòng) Ollama 服務(wù)
ollama serve
拉取并運(yùn)行模型
打開新的終端窗口,運(yùn)行以下命令拉取通義千問2.5模型:
# 拉取通義千問2.5 32B參數(shù)量模型
ollama pull qwen2.5:32b
你可以通過以下命令測(cè)試模型是否正常工作:
# 測(cè)試模型
ollama run qwen2.5:32b "你好,請(qǐng)做個(gè)自我介紹"
驗(yàn)證 API 服務(wù)
確保 Ollama API 服務(wù)正常運(yùn)行:
# 測(cè)試 API 服務(wù)是否正常
curl http://localhost:11434/api/version
如果返回版本信息,說明服務(wù)已經(jīng)準(zhǔn)備就緒。
2. Java 代碼實(shí)現(xiàn)
我們將使用 Spring Boot 框架來實(shí)現(xiàn)一個(gè)簡(jiǎn)單的示例。首先創(chuàng)建必要的 POJO 類:
@Data
@Builder
public class ChatMessage {
private String role;
private String content;
}
@Data
@Builder
public class ChatCompletionRequest {
private String model;
private List<ChatMessage> messages;
private String format;
}
@Data
public class ChatCompletionResponse {
private String model;
private String createdAt;
private ChatMessage message;
private String done;
}
接下來,實(shí)現(xiàn)調(diào)用 Ollama API 的服務(wù)類:
@Service
@Slf4j
public class ChatCompletionService {
private static final String API_ENDPOINT = "http://localhost:11434/api/chat";
private final RestTemplate restTemplate;
public ChatCompletionService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
public String generateStructuredResponse(String prompt) {
ChatCompletionRequest request = ChatCompletionRequest.builder()
.model("qwen2.5:32b")
.messages(List.of(ChatMessage.builder()
.role("user")
.content(prompt)
.build()))
.format("json")
.build();
ResponseEntity<ChatCompletionResponse> response = restTemplate.postForEntity(
API_ENDPOINT,
request,
ChatCompletionResponse.class
);
return Optional.ofNullable(response.getBody())
.map(ChatCompletionResponse::getMessage)
.map(ChatMessage::getContent)
.orElse("");
}
}
實(shí)踐示例
讓我們通過一個(gè)具體的例子來說明如何使用這個(gè)系統(tǒng)。假設(shè)我們想要獲取一款車型的推薦信息:
String prompt = """
請(qǐng)生成問界M9車型的推薦信息,返回JSON格式,結(jié)構(gòu)如下:
{
"model": string,
"brand": string,
"priceRange": string,
"powerType": string,
"scenarios": string[],
"advantages": string[],
"recommendation": {
"trim": string,
"color": string,
"options": string[]
}
}
""";
String response = chatCompletionService.generateStructuredResponse(prompt);
Ollama 會(huì)返回類似這樣的 JSON 響應(yīng):
{
"model": "問界M9",
"brand": "問界AITO",
"priceRange": "50-70萬元",
"powerType": "增程式混動(dòng)",
"scenarios": [
"商務(wù)接待",
"家庭出行",
"長(zhǎng)途旅行",
"城市通勤"
],
"advantages": [
"華為智能座艙",
"超大空間",
"豪華舒適",
"智能駕駛",
"低油耗"
],
"recommendation": {
"trim": "旗艦版",
"color": "星際銀",
"options": [
"全自動(dòng)泊車輔助",
"行政座椅套件",
"全景天幕"
]
}
}
最佳實(shí)踐
在使用 Ollama 生成結(jié)構(gòu)化輸出時(shí),有以下幾點(diǎn)建議:
- 明確的提示詞:在提示詞中明確指定你期望的 JSON 結(jié)構(gòu),并指定format json
- 錯(cuò)誤處理:添加適當(dāng)?shù)腻e(cuò)誤處理機(jī)制,因?yàn)?LLM 的輸出可能不總是完全符合預(yù)期
- 輸出驗(yàn)證:使用 JSON Schema 驗(yàn)證輸出的格式是否符合要求
- 性能優(yōu)化:考慮添加緩存機(jī)制,避免重復(fù)請(qǐng)求相同的內(nèi)容
結(jié)論
Ollama 的結(jié)構(gòu)化輸出功能為我們提供了一種強(qiáng)大的方式來集成 AI 能力到現(xiàn)有系統(tǒng)中。通過使用 JSON 格式,我們可以更容易地處理和使用 AI 生成的內(nèi)容。本文提供的 Java 實(shí)現(xiàn)方案可以作為一個(gè)起點(diǎn),幫助你開始使用 Ollama 的結(jié)構(gòu)化輸出功能。