Spring AI 集成 Ollama
提醒:该版本仍在开发中,尚未被认为是稳定版本。如需获取最新的快照版本,请使用 Spring AI 1.0.0-SNAPSHOT!
Ollama Chat
通过 Ollama,您可以在本地运行各种大型语言模型(LLMs),并从中生成文本。Spring AI 支持 Ollama 的聊天完成能力,使用 OllamaChatModel API。
Ollama 还提供一个与 OpenAI API 兼容的端点。OpenAI API 兼容性部分解释了如何使用 Spring AI OpenAI 连接到 Ollama 服务器。
先决条件
首先,您需要访问 Ollama 实例。有以下几种选择:
- 在本地机器上下载并安装 Ollama。
- 通过 Testcontainers 配置并运行 Ollama。
- 通过 Kubernetes 服务绑定连接到 Ollama 实例。
您可以从 Ollama 模型库中拉取您希望在应用中使用的模型:
ollama pull <model-name>
您还可以拉取数千个免费的 GGUF Hugging Face 模型:
ollama pull hf.co/<username>/<model-repository>
另外,您可以启用自动下载任何所需模型的选项:自动拉取模型。
自动配置
Spring AI 提供了 Ollama 聊天集成的 Spring Boot 自动配置。要启用它,请在项目的 Maven pom.xml 或 Gradle build.gradle 构建文件中添加以下依赖:
Maven
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
</dependency>
Gradle
implementation 'org.springframework.ai:spring-ai-ollama-spring-boot-starter'
请参考依赖管理部分,添加 Spring AI BOM 到您的构建文件。
基本属性
spring.ai.ollama 是配置连接到 Ollama 的属性前缀。
| 属性 | 描述 | 默认值 |
|---|---|---|
| spring.ai.ollama.base-url | Ollama API 服务器运行的基础 URL。 | 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 | 除通过默认属性配置的模型外,要初始化的其他模型。 | [] |
聊天属性
spring.ai.ollama.chat.options 是配置 Ollama 聊天模型的属性前缀。它包括 Ollama 请求(高级)参数,如模型、保持连接和格式,以及 Ollama 模型选项属性。
以下是 Ollama 聊天模型的高级请求参数:
| 属性 | 描述 | 默认值 |
|---|---|---|
| spring.ai.ollama.chat.enabled | 启用 Ollama 聊天模型。 | true |
| 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 类型的默认设置。
| 属性 | 描述 | 默认值 |
|---|---|---|
| spring.ai.ollama.chat.options.numa | 是否使用 NUMA。 | false |
| spring.ai.ollama.chat.options.num-ctx | 设置用于生成下一个标记的上下文窗口大小。 | 2048 |
| spring.ai.ollama.chat.options.num-batch | 提示处理的最大批量大小。 | 512 |
| spring.ai.ollama.chat.options.num-gpu | 发送到 GPU 的层数。在 macOS 上,默认值为 1(启用 metal 支持),0 表示禁用。1 表示 NumGPU 应动态设置。 | -1 |
| spring.ai.ollama.chat.options.main-gpu | 使用多个 GPU 时,此选项控制哪些 GPU 用于小张量。 | 0 |
| spring.ai.ollama.chat.options.low-vram | - | false |
| spring.ai.ollama.chat.options.f16-kv | - | true |
| spring.ai.ollama.chat.options.logits-all | 返回所有标记的 logits,而不仅仅是最后一个。要启用返回 logprobs 的完成,必须为 true。 | - |
| spring.ai.ollama.chat.options.vocab-only | 仅加载词汇,而不加载权重。 | - |
| spring.ai.ollama.chat.options.use-mmap | 默认情况下,模型被映射到内存中,这样系统可以按需加载模型的必要部分。但如果模型大于您的总内存或系统内存不足,使用 mmap 可能会增加页面换出的风险,从而影响性能。禁用 mmap 会导致加载时间变慢,但如果没有使用 mlock,可能会减少页面换出。请注意,如果模型大于总内存,关闭 mmap 会导致模型根本无法加载。 | null |
| spring.ai.ollama.chat.options.use-mlock | 锁定模型到内存中,防止其在进行内存映射时被交换出。这可以提高性能,但会要求更多的内存,并可能减慢加载时间。 | false |
| spring.ai.ollama.chat.options.num-thread | 设置在计算过程中使用的线程数。默认情况下,Ollama 会检测最佳性能。建议将此值设置为系统的物理 CPU 核心数(而不是逻辑核心数)。0 = 让运行时决定。 | 0 |
| spring.ai.ollama.chat.options.num-keep | - | 4 |
| spring.ai.ollama.chat.options.seed | 设置生成的随机数种子。设置为特定数字将使模型对相同的提示生成相同的文本。 | -1 |
| spring.ai.ollama.chat.options.num-predict | 生成文本时要预测的最大标记数。(-1 = 无限生成,-2 = 填充上下文) | -1 |
| spring.ai.ollama.chat.options.top-k | 降低生成无意义文本的概率。较高的值(例如 100)会给出更多样化的回答,而较低的值(例如 10)则会更加保守。 | 40 |
| spring.ai.ollama.chat.options.top-p | 与 top-k 一起工作。较高的值(例如 0.95)会生成更多样化的文本,而较低的值(例如 0.5)会生成更集中和保守的文本。 | 0.9 |
| spring.ai.ollama.chat.options.tfs-z | 使用尾部自由采样以减少输出中不太可能的标记的影响。较高的值(例如 2.0)会更大程度地减少影响,而 1.0 则禁用此设置。 | 1.0 |
| spring.ai.ollama.chat.options.typical-p | - | 1.0 |
| spring.ai.ollama.chat.options.repeat-last-n | 设置模型回溯的距离以防止重复。(默认值:64,0 = 禁用,-1 = num_ctx) | 64 |
| spring.ai.ollama.chat.options.temperature | 模型的温度。增加温度会使模型的回答更具创意。 | 0.8 |
| spring.ai.ollama.chat.options.repeat-penalty | 设置对重复的惩罚强度。较高的值(例如 1.5)会对重复的惩罚更强,而较低的值(例如 0.9)会更宽容。 | 1.1 |
| spring.ai.ollama.chat.options.presence-penalty | - | 0.0 |
| spring.ai.ollama.chat.options.frequency-penalty | - | 0.0 |
| spring.ai.ollama.chat.options.mirostat | 启用 Mirostat 采样来控制困惑度。(默认值:0,0 = 禁用,1 = Mirostat,2 = Mirostat 2.0) | 0 |
| spring.ai.ollama.chat.options.mirostat-tau | 控制输出的连贯性和多样性之间的平衡。较低的值会导致文本更集中和连贯。 | 5.0 |
| spring.ai.ollama.chat.options.mirostat-eta | 影响算法对生成文本反馈的响应速度。较低的学习率会导致调整速度较慢,而较高的学习率会使算法更灵敏。 | 0.1 |
| spring.ai.ollama.chat.options.penalize-newline | - | true |
| spring.ai.ollama.chat.options.stop | 设置停止序列。当遇到此模式时,LLM 将停止生成文本并返回。可以通过在模型文件中指定多个停止参数来设置多个停止模式。 | - |
| spring.ai.ollama.chat.options.functions | 启用的函数列表,按名称标识,用于在单个提示请求中调用函数。具有这些名称的函数必须存在于 functionCallbacks 注册表中。 | - |
| spring.ai.ollama.chat.options.proxy-tool-calls | 如果为 true,Spring AI 将不在内部处理函数调用,而是将其代理到客户端。然后由客户端负责处理函数调用,将其调度到适当的函数,并返回结果。如果为 false(默认值),Spring AI 将在内部处理函数调用。仅适用于支持函数调用的聊天模型。 | false |
提示:所有以 spring.ai.ollama.chat.options 开头的属性都可以通过在提示调用时添加特定的运行时选项来覆盖。
运行时选项
OllamaOptions.java 类提供了模型配置选项,如要使用的模型、温度等。
在启动时,可以使用 OllamaChatModel(api, options) 构造函数或 spring.ai.ollama.chat.options.* 属性来配置默认选项。
在运行时,您可以通过向 Prompt 调用中添加新的请求特定选项来覆盖默认选项。例如,要为特定请求覆盖默认模型和温度:
ChatResponse response = chatModel.call(
new Prompt(
"Generate the names of 5 famous pirates.", // 生成5个著名海盗的名字。
OllamaOptions.builder()
.model(OllamaModel.LLAMA3_1)
.temperature(0.4)
.build()
));
除了特定模型的 OllamaOptions,您还可以使用便携式的 ChatOptions 实例,它是通过 ChatOptionsBuilder#builder() 创建的。
自动拉取模型
当您的 Ollama 实例中没有模型时,Spring AI Ollama 可以自动拉取这些模型。此功能对于开发、测试以及将应用部署到新环境中非常有用。
您还可以通过名称拉取数千个免费的 GGUF Hugging Face 模型。
有三种拉取模型的策略:
- always(在 PullModelStrategy.ALWAYS 中定义):始终拉取模型,即使它已经可用。此策略有助于确保使用的是最新版本的模型。
- when_missing(在 PullModelStrategy.WHEN_MISSING 中定义):仅在模型尚未可用时拉取模型。这可能会导致使用旧版本的模型。
- never(在 PullModelStrategy.NEVER 中定义):永不自动拉取模型。
注意:由于下载模型可能会有延迟,因此不建议在生产环境中使用自动拉取功能。相反,建议事先评估并预先下载必要的模型。
所有通过配置属性和默认选项定义的模型可以在启动时自动拉取。您可以使用配置属性来配置拉取策略、超时和最大重试次数:
spring:
ai:
ollama:
init:
pull-model-strategy: always
timeout: 60s
max-retries: 1
注意:在所有指定的模型在 Ollama 中可用之前,应用程序将无法完成初始化。根据模型的大小和互联网连接速度,这可能会显著减慢应用程序的启动时间。
您还可以在启动时初始化额外的模型,这对于在运行时动态使用的模型非常有用:
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
此配置将对除聊天模型外的所有模型应用拉取策略。
函数调用
您可以在 OllamaChatModel 中注册自定义 Java 函数,并让 Ollama 模型智能地选择输出一个包含参数的 JSON 对象,以调用一个或多个已注册的函数。这是一种将 LLM 能力与外部工具和 API 连接的强大技术。详细了解 Ollama 函数调用。
提示:您需要使用 Ollama 0.2.8 或更新版本来使用功能调用能力,并且需要 Ollama 0.4.6 或更新版本才能在流模式下使用它们。
多模态
多模态性指的是模型能够同时理解和处理来自不同来源的信息,包括文本、图像、音频和其他数据格式。
在 Ollama 中,一些支持多模态的模型包括 LLaVa 和 bakllava(参见完整列表)。欲了解更多详细信息,请参考 LLaVA: 大型语言与视觉助手。
Ollama 消息 API 提供了一个 “images” 参数,用于将一组 base64 编码的图像嵌入到消息中。
Spring AI 的消息接口通过引入 Media 类型来促进多模态 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 图像作为输入,配合文本消息 “Explain what do you see on this picture?”,并生成如下响应:
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.
“这张图片显示了一个装满成熟香蕉和红苹果的小金属篮子。
篮子放在一个表面上,看起来像是桌子或台面,背景中有一点像是厨房橱柜或抽屉的影像。
篮子后面还有一个金色的环形物,可能表明这张照片拍摄的地方有金属装饰或固定装置。
整体环境给人的感觉是家庭环境,水果可能是为了便利或美观而展示的。”
结构化输出
Ollama 提供了自定义的结构化输出 API,确保您的模型生成的响应严格符合您提供的 JSON Schema。除了现有的 Spring AI 模型无关的结构化输出转换器,这些 API 还提供了更好的控制和精确度。
配置
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()
.withModel(OllamaModel.LLAMA3_2.getName())
.withFormat(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()
.withModel(OllamaModel.LLAMA3_2.getName())
.withFormat(outputConverter.getJsonSchemaMap())
.build());
ChatResponse response = this.ollamaChatModel.call(this.prompt);
String content = this.response.getResult().getOutput().getText();
MathReasoning mathReasoning = this.outputConverter.convert(this.content);
提示:确保您使用了 @JsonProperty(required = true, …) 注解来生成准确标记字段为必需的模式。尽管对于 JSON Schema 这是可选的,但为了确保结构化响应正确工作,建议这样做。
OpenAI API 兼容
Ollama 与 OpenAI API 兼容,您可以使用 Spring AI OpenAI 客户端与 Ollama 进行交互并使用工具。为此,您需要将 OpenAI 基础 URL 配置为您的 Ollama 实例: spring.ai.openai.chat.base-url=http://localhost:11434,并选择一个提供的 Ollama 模型:spring.ai.openai.chat.options.model=mistral。
可以查看 OllamaWithOpenAiChatModelIT.java 中的测试,以了解如何通过 Spring AI OpenAI 使用 Ollama 的示例。
HuggingFace模型
Ollama 可以直接访问所有 GGUF Hugging Face 聊天模型。您可以通过名称拉取任何这些模型:ollama pull hf.co//,或者配置自动拉取策略:
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。
示例控制器
创建一个新的 Spring Boot 项目,并将 spring-ai-ollama-spring-boot-starter 添加到您的 pom(或gradle)依赖项中。
在 src/main/resources 目录下添加一个 application.yaml 文件,以启用和配置 Ollama 聊天模型:
spring:
ai:
openai:
base-url: http://localhost:11434
chat:
options:
model: mistral
temperature: 0.7
提示:用您的 Ollama 服务器URL替换 base-url。
这将创建一个 OllamaChatModel 实现,您可以将其注入到您的类中。以下是一个简单的 @RestController 类的示例,它使用聊天模型进行文本生成。
@RestController
public class ChatController {
private final OllamaChatModel chatModel;
@Autowired
public ChatController(OllamaChatModel chatModel) {
this.chatModel = chatModel;
}
@GetMapping("/ai/generate")
public Map<String,String> generate(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
return Map.of("generation", this.chatModel.call(message));
}
@GetMapping("/ai/generateStream")
public Flux<ChatResponse> generateStream(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
Prompt prompt = new Prompt(new UserMessage(message));
return this.chatModel.stream(prompt);
}
}
手动配置
如果您不想使用 Spring Boot 的自动配置,可以手动在您的应用程序中配置 OllamaChatModel。OllamaChatModel 实现了 ChatModel 和 StreamingChatModel,并使用低级别的 OllamaApi 客户端连接到 Ollama 服务。
要使用它,首先将 spring-ai-ollama 依赖添加到您的项目的 Maven pom.xml 或 Gradle build.gradle 构建文件中:
Maven
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-ollama</artifactId>
</dependency>
Gradle
dependencies {
implementation 'org.springframework.ai:spring-ai-ollama'
}
提示:
- 请参阅依赖管理部分,了解如何将 Spring AI BOM 添加到您的构建文件中。
- spring-ai-ollama 依赖项还提供对 OllamaEmbeddingModel 的访问。有关 OllamaEmbeddingModel 的更多信息,请参阅 Ollama 嵌入模型部分。
接下来,创建一个 OllamaChatModel 实例,并使用它发送文本生成请求:
var ollamaApi = new OllamaApi();
var chatModel = new OllamaChatModel(this.ollamaApi,
OllamaOptions.create()
.model(OllamaOptions.DEFAULT_MODEL)
.temperature(0.9));
ChatResponse response = this.chatModel.call(
new Prompt("Generate the names of 5 famous pirates."));
// 或使用流响应
Flux<ChatResponse> response = this.chatModel.stream(
new Prompt("Generate the names of 5 famous pirates."));
OllamaOptions 提供了所有聊天请求的配置信息。
低级别的 OllamaApi 客户端
OllamaApi 提供了一个轻量级的 Java 客户端,用于访问 Ollama 聊天回复 API。
以下类图展示了 OllamaApi 聊天接口和构建块:

提示:OllamaApi 是一个低级别的 API,不建议直接使用。请使用 OllamaChatModel 代替。
下面是一个简单的代码片段,展示如何通过编程方式使用 API:
OllamaApi ollamaApi = new OllamaApi("YOUR_HOST:YOUR_PORT");
// 同步请求
var request = ChatRequest.builder("orca-mini")
.stream(false) // 不使用流
.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.create().temperature(0.9))
.build();
ChatResponse response = this.ollamaApi.chat(this.request);
// 流式请求
var request2 = ChatRequest.builder("orca-mini")
.stream(true) // 使用流
.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.create().temperature(0.9).toMap())
.build();
Flux<ChatResponse> streamingResponse = this.ollamaApi.streamingChat(this.request2);
更多推荐



所有评论(0)