注意:本文采用原生 HTTP 调用方式实现与 Ollama 的交互,不依赖任何第三方 SDK(如 Spring AI、LangChain4j 等)。这种方式可以让你更好地理解底层实现原理,并且可以根据实际需求自由选择是否使用其他 SDK。
为什么选择结构化输出?
在实际应用中,我们经常需要将 LLM 的输出集成到现有的系统中。这时,结构化的输出格式(如 JSON)就显得尤为重要:
- 易于解析:JSON 是一种标准的数据交换格式,可以轻松地转换为编程语言中的对象
- 结构清晰:相比于纯文本输出,JSON 的层次结构更加清晰
- 便于集成:可以轻松地集成到现有的系统和工作流程中
技术实现
1. 环境准备
首先,我们需要在本地环境中安装并运行 Ollama。
macOS 安装
# 使用 Homebrew 安装 brew install ollama
Linux 安装
# 使用官方脚本安装 curl -fsSL https://ollama.com/install.sh | sh
启动 Ollama 服务
安装完成后,在终端运行:
# 启动 Ollama 服务 ollama serve
拉取并运行模型
打开新的终端窗口,运行以下命令拉取通义千问2.5模型:
# 拉取通义千问2.5 32B参数量模型 ollama pull qwen2.5:32b
你可以通过以下命令测试模型是否正常工作:
# 测试模型 ollama run qwen2.5:32b "你好,请做个自我介绍"
验证 API 服务
确保 Ollama API 服务正常运行:
# 测试 API 服务是否正常 curl http://localhost:11434/api/version
如果返回版本信息,说明服务已经准备就绪。
2. Java 代码实现
我们将使用 Spring Boot 框架来实现一个简单的示例。首先创建必要的 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; }
接下来,实现调用 Ollama API 的服务类:
@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(""); } }
实践示例
让我们通过一个具体的例子来说明如何使用这个系统。假设我们想要获取一款车型的推荐信息:
String prompt = """ 请生成问界M9车型的推荐信息,返回JSON格式,结构如下: { "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 会返回类似这样的 JSON 响应:
{ "model": "问界M9", "brand": "问界AITO", "priceRange": "50-70万元", "powerType": "增程式混动", "scenarios": [ "商务接待", "家庭出行", "长途旅行", "城市通勤" ], "advantages": [ "华为智能座舱", "超大空间", "豪华舒适", "智能驾驶", "低油耗" ], "recommendation": { "trim": "旗舰版", "color": "星际银", "options": [ "全自动泊车辅助", "行政座椅套件", "全景天幕" ] } }
最佳实践
在使用 Ollama 生成结构化输出时,有以下几点建议:
- 明确的提示词:在提示词中明确指定你期望的 JSON 结构,并指定format json
- 错误处理:添加适当的错误处理机制,因为 LLM 的输出可能不总是完全符合预期
- 输出验证:使用 JSON Schema 验证输出的格式是否符合要求
- 性能优化:考虑添加缓存机制,避免重复请求相同的内容
结论
Ollama 的结构化输出功能为我们提供了一种强大的方式来集成 AI 能力到现有系统中。通过使用 JSON 格式,我们可以更容易地处理和使用 AI 生成的内容。本文提供的 Java 实现方案可以作为一个起点,帮助你开始使用 Ollama 的结构化输出功能。