Ollama Chat
通过 Ollama,我们可以在本地运行各种大型语言模型 (LLM) 并从中生成文本。 Spring AI 通过 OllamaChatModel
支持 文本生成。
前提条件(Prerequisites)
首先,您需要访问 Ollama 实例。有以下几个选择:
- 在本地机器上下载并安装 Ollama。
- 通过 Testcontainers 配置和运行 Ollama。
- 通过 Kubernetes Service Bindings 绑定到 Ollama 实例。
你可以从 Ollama 模型库中提取想要在应用程序中使用的模型:
ollama pull <model-name>
你还可以下载数千个免费的 GGUF Hugging Face 模型中的任何一个:
ollama pull hf.co/<username>/<model-repository>
或者,您可以启用自动下载任何所需模型的选项:自动拉取模型。
添加存储库和 BOM
Spring AI 工件发布在 Spring Milestone
和 Snapshot
存储库中。请参阅存储库部分将这些存储库添加到您的构建系统中。
为了帮助进行依赖管理,Spring AI 提供了 BOM(物料清单),以确保在整个项目中使用一致的 Spring AI 版本。请参阅依赖管理部分将 Spring AI BOM 添加到您的构建系统。
自动配置(Auto-configuration)
Spring AI 为 Ollama 聊天模型提供 Spring Boot 自动配置。要启用它,请在项目的 Maven pom.xml
文件中添加以下依赖项:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-ollama</artifactId>
</dependency>
或者,在你的 Gradle 构建文件 build.gradle
中添加:
dependencies {
implementation 'org.springframework.ai:spring-ai-starter-model-ollama'
}
基础属性(Base Properties)
前缀是 spring.ai.ollama
的属性,用于配置 Ollama 的链接。
属性 | 描述 | 默认值 |
---|---|---|
spring.ai.ollama.base-url | Ollama API 服务运行的基础URL | http://localhost:11434 |
以下是初始化 Ollama 集成及 自动拉取模型 的属性设置。
属性 | 描述 | 默认值 |
---|---|---|
spring.ai.ollama.init.pull-model-strategy | 启动时是否拉取模型及拉取方式 | never |
spring.ai.ollama.init.timeout | 等待模型拉取完成的最长时间 | 5m |
spring.ai.ollama.init.max-retries | 模型拉取操作的最大重试次数 | 0 |
spring.ai.ollama.init.chat.include | 是否在初始化任务中包含此类模型 | true |
spring.ai.ollama.init.chat.additional-models | 除默认配置外需要初始化的额外模型列表 | [] |
聊天属性(Chat Properties)
前缀 spring.ai.ollama.chat.options
的属性是配置 Ollama 聊天模型的属性。它包括 Ollama 请求 (高级) 参数,如 model
、keep-alive
和 format
,以及 Ollama 模型选项属性。
属性 | 描述 | 默认值 |
---|---|---|
spring.ai.ollama.chat.enabled (已移除且无效) | 启用Ollama聊天模型 | true |
spring.ai.model.chat | 启用Ollama聊天模型 | ollama |
spring.ai.ollama.chat.options.model | 使用的支持模型名称 | mistral |
spring.ai.ollama.chat.options.format | 返回响应的格式,目前唯一接受的值是json |
- |
spring.ai.ollama.chat.options.keep_alive | 控制模型在请求后保持在内存中的时长 | 5m |
剩余的选项属性基于 Ollama 有效参数和值以及 Ollama 类型。默认值基于 Ollama 类型默认值。
运行时选项(Runtime Options )
Ollamaoptions.java 提供模型配置,例如要使用的 temperature、maxToken、topP 等。
在启动时,可以使用 OllamaChatModel(api,options)
构造函数或 spring.ai.ollama.chat.options.*
属性来配置默认选项。
在运行时,您可以通过在 Prompt 调用中添加新的、特定请求的选项来覆盖默认选项。例如,为特定请求覆盖默认型号和温度:
ChatResponse response = chatModel.call(
new Prompt(
"Generate the names of 5 famous pirates.",
OllamaOptions.builder()
.model(OllamaModel.LLAMA3_1)
.temperature(0.4)
.build()
));
自动拉取模型(Auto-pulling Models)
当模型在 Ollama 实例中不可用时,Spring AI Ollama 可以自动拉取模型。这项功能在开发和测试以及将应用程序部署到新环境中时特别有用。
有三种拉取模型的策略:
- always (在 PullModelStrategy.ALWAYS 中定义) :始终拉取模型,即使模型已经可用。这对于确保使用的是最新版本的模型很有用。
- when_missing (在 PullModelStrategy.WHEN_MISSING 中定义): 仅在模型尚未可用时才拉取。这可能导致使用模型的较旧版本。
- never (在 PullModelStrategy.Never 中定义): 永远不要自动拉取模型。
通过配置属性和默认选项定义的所有模型都可以在启动时自动拉取。您可以使用配置属性配置拉取策略、超时和最大重试次数:
spring:
ai:
ollama:
init:
pull-model-strategy: always
timeout: 60s
max-retries: 1
您可以在启动时初始化额外的模型,这对于在运行时动态使用的模型很有用:
spring:
ai:
ollama:
init:
pull-model-strategy: always
chat:
additional-models:
- llama3.2
- qwen2.5
如果你只想将拉动策略应用于特定类型的模型,可以将聊天模型排除在初始化任务之外:
spring:
ai:
ollama:
init:
pull-model-strategy: always
chat:
include: false
这种配置将将拉取策略应用于除聊天模型外的所有模型。
工具 / 功能调用(Tool/Function Calling)
您可以使用 OllamaChatModel 注册自定义 Java 函数,并让 OllamaModel 智能地选择输出一个包含参数的 JSON 对象来调用一个或多个注册的函数。这是一种强大的技术,可以将 LLM 功能与外部工具和 API 连接起来。详细了解工具调用。
多模态(Multimodal )
多模态是指模型同时理解和处理来自不同来源信息的能力,包括文本、图像、音频和其他数据格式。
在 Ollama 中提供的一些支持多模态的模型包括 LLaVA
和 BakLLaVA
(参见完整列表)。有关更多详细信息,请参阅 LLaVA: 大语言和视觉助手。
Ollama 消息 API 提供了一个 “images ” 参数,用于将 base64 编码的图像列表与消息结合起来。
Spring AI 的消息接口通过引入媒体类型来促进多模态 AI 模型。这种类型利用 Spring 的 org.springframework.util.MimeType
和 org.springframework.core.io.Resource
来处理原始媒体数据,包含消息中与媒体附件相关的数据和细节。
下面是一个直观的代码示例,摘自 OllamaChatModelMultimodalIT.java, 说明了用户文本与图像的融合。
var imageResource = new ClassPathResource("/multimodal.test.png");
var userMessage = new UserMessage("Explain what do you see on this picture?",
new Media(MimeTypeUtils.IMAGE_PNG, this.imageResource));
ChatResponse response = chatModel.call(new Prompt(this.userMessage,
OllamaOptions.builder().model(OllamaModel.LLAVA)).build());
示例展示了一个模型将 multimodal.test.png 图像作为输入:
与文本信息 “解释一下你在这张照片上看到了什么?” 一起,产生如下回复:
The image shows a small metal basket filled with ripe bananas and red apples. The basket is placed on a surface,
which appears to be a table or countertop, as there's a hint of what seems like a kitchen cabinet or drawer in
the background. There's also a gold-colored ring visible behind the basket, which could indicate that this
photo was taken in an area with metallic decorations or fixtures. The overall setting suggests a home environment
where fruits are being displayed, possibly for convenience or aesthetic purposes.
结构化输出(tructured Outputs)
Ollama 提供自定义结构化输出 API, 确保您的模型生成的响应严格符合您提供的 JSON Schema。除了现有的 Spring AI 模型无关的结构化输出转换器外,这些 API 还提供了增强的控制和精度。
配置(Configuration )
Spring AI 允许您使用 OllamaOptions
构建器以编程方式配置响应格式。
使用聊天选项构建器
您可以使用 OllamaOptions 构建器以编程方式设置响应格式,如下所示:
String jsonSchema = """
{
"type": "object",
"properties": {
"steps": {
"type": "array",
"items": {
"type": "object",
"properties": {
"explanation": { "type": "string" },
"output": { "type": "string" }
},
"required": ["explanation", "output"],
"additionalProperties": false
}
},
"final_answer": { "type": "string" }
},
"required": ["steps", "final_answer"],
"additionalProperties": false
}
""";
Prompt prompt = new Prompt("how can I solve 8x + 7 = -23",
OllamaOptions.builder()
.model(OllamaModel.LLAMA3_2.getName())
.format(new ObjectMapper().readValue(jsonSchema, Map.class))
.build());
ChatResponse response = this.ollamaChatModel.call(this.prompt);
与 BeanOutputConverter 实用程序集成
你可以利用现有的 BeanOutputConverter 实用程序自动从域对象生成 JSON Schema, 然后将结构化响应转换为特定于域的实例:
record MathReasoning(
@JsonProperty(required = true, value = "steps") Steps steps,
@JsonProperty(required = true, value = "final_answer") String finalAnswer) {
record Steps(
@JsonProperty(required = true, value = "items") Items[] items) {
record Items(
@JsonProperty(required = true, value = "explanation") String explanation,
@JsonProperty(required = true, value = "output") String output) {
}
}
}
var outputConverter = new BeanOutputConverter<>(MathReasoning.class);
Prompt prompt = new Prompt("how can I solve 8x + 7 = -23",
OllamaOptions.builder()
.model(OllamaModel.LLAMA3_2.getName())
.format(outputConverter.getJsonSchemaMap())
.build());
ChatResponse response = this.ollamaChatModel.call(this.prompt);
String content = this.response.getResult().getOutput().getText();
MathReasoning mathReasoning = this.outputConverter.convert(this.content);
OpenAI API 兼容性
Ollama 与 OpenAI API 兼容,你可以使用 Spring AI OpenAI 客户端与 Ollama 通话并使用工具。为此,你需要为 Ollama 实例配置 OpenAI 基本 URL:spring.ai.openai.chat.base-url=http://localhost:11434
, 并选择其中一个提供的 Ollama 模型:spring.ai.openai.chat.options.model=mistral
。
HuggingFace 模型
Ollama 可以直接访问所有 GGUF 拥抱面对面聊天模型。你可以按名称拉取任何模型:ollama pull hf.co/<username>/<model-repository>
或配置自动拉取策略:自动拉取模型:
spring.ai.ollama.chat.options.model=hf.co/bartowski/gemma-2-2b-it-GGUF
spring.ai.ollama.init.pull-model-strategy=always
spring.ai.ollama.chat.options.model
: 指定要使用的 Hugging Face GGUF 模型。spring.ai.ollama.init.pull-model-strategy=always
: (可选) 启用在启动时自动模型拉取功能。对于生产,您应该预先下载模型以避免延迟:ollama pull hf.co/bartowski/gemma-2-2b-it-gguf
。
示例控制器(Sample Controller)
创建一个新的 Spring Boot 项目,并将 spring-ai-starter-model-ollama
添加到 pom (或 gradle) 依赖项中。
在 src/main/resources 目录下添加 application.properties 文件,以启用和配置 Hugging Face 聊天模型:
spring:
ai:
ollama:
base-url: http://localhost:11434
chat:
options:
model: mistral
temperature: 0.7
这将创建一个 OllamaChatModel 的实现,你可以将其注入到你的类中。下面是一个简单的 @RestController 类的示例,它使用聊天模型进行文本生成。
@RestController
public class ChatController {
private final OllamaChatModel chatModel;
@Autowired
public ChatController(OllamaChatModel chatModel) {
this.chatModel = chatModel;
}
@GetMapping("/ai/generate")
@Operation(summary = "文本生成")
public Map<String, Object> generate(@RequestParam(value = "message", defaultValue = "你好!") String message) {
try {
String response = chatModel.call(message);
return Map.of(
"success", true,
"generation", response,
"message", "Generated successfully"
);
} catch (Exception e) {
return Map.of(
"success", false,
"error", e.getMessage(),
"message", "Generation failed"
);
}
}
@GetMapping("/ai/generateStream")
public Flux<String> generateStream(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
return this.chatModel.stream(message).contextCapture();
}
}
手动配置(Manual Configuration)
如果不想使用 Spring Boot 自动配置,可以在应用程序中手动配置 OllamaChatModel。OllamaChatModel 实现了 ChatModel 和 StreamingChatModel, 并使用低级 OllamaApi 客户端连接到 Ollama 服务。
要启用它,添加 spring-ai-ollama
依赖到你的项目 Maven pom.xml
文件:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-ollama</artifactId>
</dependency>
或者,在你的 Gradle 构建文件 build.gradle
中添加:
dependencies {
implementation 'org.springframework.ai:spring-ai-ollama'
}
接下来,创建一个 OllamaChatModel
并将其用于文本生成:
var ollamaApi = OllamaApi.builder().build();
var chatModel = OllamaChatModel.builder()
.ollamaApi(ollamaApi)
.defaultOptions(
OllamaOptions.builder()
.model(OllamaModel.MISTRAL)
.temperature(0.9)
.build())
.build();
ChatResponse response = this.chatModel.call(
new Prompt("Generate the names of 5 famous pirates."));
// Or with streaming responses
Flux<ChatResponse> response = this.chatModel.stream(
new Prompt("Generate the names of 5 famous pirates."));
OllamaOptions 为所有聊天请求提供配置信息。
Low-level OllamaApi Client
OllamaApi 为 Ollama Chat Completion API 提供了一个轻量级的 Java 客户端。
下面的类图说明了 OllamaApi 聊天接口和构建块:
以下是一个简单的片段,展示了如何以编程方式使用 API:
OllamaApi ollamaApi = new OllamaApi("YOUR_HOST:YOUR_PORT");
// Sync request
var request = ChatRequest.builder("orca-mini")
.stream(false) // not streaming
.messages(List.of(
Message.builder(Role.SYSTEM)
.content("You are a geography teacher. You are talking to a student.")
.build(),
Message.builder(Role.USER)
.content("What is the capital of Bulgaria and what is the size? "
+ "What is the national anthem?")
.build()))
.options(OllamaOptions.builder().temperature(0.9).build())
.build();
ChatResponse response = this.ollamaApi.chat(this.request);
// Streaming request
var request2 = ChatRequest.builder("orca-mini")
.ttream(true) // streaming
.messages(List.of(Message.builder(Role.USER)
.content("What is the capital of Bulgaria and what is the size? " + "What is the national anthem?")
.build()))
.options(OllamaOptions.builder().temperature(0.9).build().toMap())
.build();
Flux<ChatResponse> streamingResponse = this.ollamaApi.streamingChat(this.request2);
最后编辑:Jeebiz 更新时间:2025-08-31 23:07