Spring AI / Models / Chat Models / Ollama
原文地址:https://docs.spring.io/spring-ai/reference/api/chat/ollama-chat.html
如下信息参考原文,如有不准确,请参考原文
Spring AI 参考文档
模型
聊天模型
Ollama
Ollama 聊天
借助 Ollama,您可以在本地运行各种大型语言模型(LLM)并从中生成文本。Spring AI 通过 OllamaChatModel API 支持 Ollama 的聊天补全功能。
Ollama 也提供了与 OpenAI API 兼容的端点。OpenAI API 兼容性部分说明了如何使用 Spring AI OpenAI 客户端连接到 Ollama 服务器。
前置条件
您首先需要能够访问一个 Ollama 实例。有以下几种选择,包括:
- 在本地机器上下载并安装 Ollama。
- 通过 Testcontainers 配置并运行 Ollama。
您可以从 Ollama 模型库中拉取您想在应用程序中使用的模型:
ollama pull <模型名称>
您也可以拉取 Hugging Face 上数千个免费的 GGUF 模型中的任何一个:
ollama pull hf.co/<用户名>/<模型仓库>
或者,您可以启用自动下载所需模型的选项:自动拉取模型。
注意
Spring AI 自动配置和启动器模块的工件名称有重大变化。请参阅升级说明以获取更多信息。
自动配置
Spring AI 为 Ollama 聊天集成提供了 Spring Boot 自动配置。要启用它,请将以下依赖项添加到项目的 Maven pom.xml 或 Gradle build.gradle 构建文件中:
Maven
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-ollama</artifactId>
</dependency>
Gradle
dependencies {
implementation 'org.springframework.ai:spring-ai-starter-model-ollama'
}
请参阅依赖管理部分,将 Spring AI BOM 添加到您的构建文件中。
基础属性
前缀 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 |
除通过默认属性配置的模型外,要额外初始化的模型列表。 | [] |
聊天属性
聊天自动配置的启用和禁用现在通过前缀为 spring.ai.model.chat 的顶层属性进行配置。
- 启用:
spring.ai.model.chat=ollama(默认启用) - 禁用:
spring.ai.model.chat=none(或任何不匹配ollama的值)
此更改是为了允许配置多个模型。
前缀 spring.ai.ollama.chat 是配置 Ollama 聊天模型的属性前缀。它包含 Ollama 请求(高级)参数,如模型、keep-alive 和 format,以及 Ollama 模型选项属性。
以下是 Ollama 聊天模型的高级请求参数:
| 属性 | 描述 | 默认值 |
|---|---|---|
spring.ai.ollama.chat.enabled (已移除,不再有效) |
启用 Ollama 聊天模型。 | true |
spring.ai.model.chat |
启用 Ollama 聊天模型。 | ollama |
spring.ai.ollama.chat.model |
要使用的支持的模型的名称。 | mistral |
spring.ai.ollama.chat.format |
返回响应的格式。接受 "json"(任意 JSON 结构)或 JSON Schema 对象(强制结构)。详见结构化输出。 |
- |
spring.ai.ollama.chat.keep_alive |
控制请求后模型在内存中保持加载的时间。 | 5m |
spring.ai.ollama.chat.think |
控制模型在给出最终答案前是否输出其推理过程。 | - |
其余选项属性基于 Ollama 有效参数和值 以及 Ollama 类型。默认值基于 Ollama 类型的默认值。
| 属性 | 描述 | 默认值 |
|---|---|---|
spring.ai.ollama.chat.numa |
是否使用 NUMA。 | false |
spring.ai.ollama.chat.num-ctx |
设置用于生成下一个令牌的上下文窗口大小。 | 2048 |
spring.ai.ollama.chat.num-batch |
提示处理的最大批量大小。 | 512 |
spring.ai.ollama.chat.num-gpu |
发送到 GPU 的层数。在 macOS 上默认为 1 以启用金属支持,0 为禁用。此处 1 表示 NumGPU 应动态设置。 | -1 |
spring.ai.ollama.chat.main-gpu |
使用多个 GPU 时,此选项控制哪个 GPU 用于处理那些跨 GPU 拆分计算开销不划算的小型张量。相关 GPU 将使用稍多的 VRAM 来存储临时结果的暂存缓冲区。 | 0 |
spring.ai.ollama.chat.low-vram |
- | false |
spring.ai.ollama.chat.f16-kv |
- | true |
spring.ai.ollama.chat.logits-all |
返回所有令牌的 logits,而不仅仅是最后一个。要使补全返回 logprobs,此值必须为 true。 | - |
spring.ai.ollama.chat.vocab-only |
仅加载词汇表,不加载权重。 | - |
spring.ai.ollama.chat.use-mmap |
默认情况下,模型被映射到内存中,这允许系统仅按需加载模型的必要部分。但如果模型大于您的总 RAM,或系统可用内存不足,使用 mmap 可能会增加页面交换的风险,从而影响性能。禁用 mmap 会导致加载时间变慢,但如果您不使用 mlock,可能会减少页面交换。注意,如果模型大于总 RAM,关闭 mmap 将阻止模型加载。 | null |
spring.ai.ollama.chat.use-mlock |
将模型锁定在内存中,防止其在内存映射时被交换出去。这可以提高性能,但会牺牲内存映射的一些优势,需要更多 RAM 来运行,并可能因将模型加载到 RAM 而减慢加载时间。 | false |
spring.ai.ollama.chat.num-thread |
设置计算时使用的线程数。默认情况下,Ollama 会自动检测以达到最佳性能。建议将此值设置为系统拥有的物理 CPU 核心数(而非逻辑核心数)。0 = 让运行时决定。 | 0 |
spring.ai.ollama.chat.num-keep |
- | 4 |
spring.ai.ollama.chat.seed |
设置生成时使用的随机数种子。设置为特定数字将使模型为相同提示生成相同文本。 | -1 |
spring.ai.ollama.chat.num-predict |
生成文本时要预测的最大令牌数。(-1 = 无限生成,-2 = 填充上下文) | -1 |
spring.ai.ollama.chat.top-k |
降低生成无意义内容的概率。较高的值(例如 100)会给出更多样化的答案,而较低的值(例如 10)会更保守。 | 40 |
spring.ai.ollama.chat.top-p |
与 top-k 协同工作。较高的值(例如 0.95)会导致更多样化的文本,而较低的值(例如 0.5)会生成更集中和保守的文本。 | 0.9 |
spring.ai.ollama.chat.min-p |
作为 top_p 的替代方案,旨在确保质量和多样性的平衡。参数 p 表示令牌被考虑的最小概率,相对于最可能令牌的概率。例如,p=0.05 且最可能令牌的概率为 0.9 时,值小于 0.045 的 logits 被过滤掉。 | 0.0 |
spring.ai.ollama.chat.tfs-z |
尾自由采样用于减少输出中概率较低的令牌的影响。较高的值(例如 2.0)会减少更多影响,而值为 1.0 则禁用此设置。 | 1.0 |
spring.ai.ollama.chat.typical-p |
- | 1.0 |
spring.ai.ollama.chat.repeat-last-n |
设置模型为防止重复而回溯的距离。(默认:64,0 = 禁用,-1 = num_ctx) | 64 |
spring.ai.ollama.chat.temperature |
模型的温度。提高温度会使模型的回答更具创造性。 | 0.8 |
spring.ai.ollama.chat.repeat-penalty |
设置惩罚重复的强度。较高的值(例如 1.5)会更强烈地惩罚重复,而较低的值(例如 0.9)会更宽容。 | 1.1 |
spring.ai.ollama.chat.presence-penalty |
- | 0.0 |
spring.ai.ollama.chat.frequency-penalty |
- | 0.0 |
spring.ai.ollama.chat.mirostat |
启用 Mirostat 采样以控制困惑度。(默认:0,0 = 禁用,1 = Mirostat,2 = Mirostat 2.0) | 0 |
spring.ai.ollama.chat.mirostat-tau |
控制输出连贯性和多样性之间的平衡。较低的值会导致更集中和连贯的文本。 | 5.0 |
spring.ai.ollama.chat.mirostat-eta |
影响算法对生成文本反馈的响应速度。较低的学习率会导致调整较慢,而较高的学习率会使算法响应更灵敏。 | 0.1 |
spring.ai.ollama.chat.penalize-newline |
- | true |
spring.ai.ollama.chat.stop |
设置要使用的停止序列。当遇到此模式时,LLM 将停止生成文本并返回。可以通过在模型文件中指定多个单独的 stop 参数来设置多个停止模式。 | - |
spring.ai.ollama.chat.tool-callbacks |
要向 ChatModel 注册的工具回调。 | - |
所有前缀为 spring.ai.ollama.chat 的属性都可以在运行时通过在 Prompt 调用中添加请求特定的运行时选项来覆盖。
运行时选项
OllamaChatOptions.java 类提供了模型配置,例如要使用的模型、温度、思考模式等。
注意
OllamaOptions类已被弃用。请对聊天模型使用OllamaChatOptions,对嵌入模型使用OllamaEmbeddingOptions。新类提供了类型安全、特定于模型的配置选项。
在启动时,默认选项可以通过 OllamaChatModel(api, options) 构造函数或 spring.ai.ollama.chat.* 属性进行配置。
在运行时,您可以通过向 Prompt 调用添加新的、特定于请求的选项来覆盖默认选项。例如,要为特定请求覆盖默认模型和温度:
ChatResponse response = chatModel.call(
new Prompt(
"Generate the names of 5 famous pirates.",
OllamaChatOptions.builder()
.model(OllamaModel.LLAMA3_1)
.temperature(0.4)
.build()
));
除了特定于模型的 OllamaChatOptions,您还可以使用通过 ChatOptions#builder() 创建的可移植 ChatOptions 实例。
自动拉取模型
Spring AI Ollama 可以在模型在您的 Ollama 实例中不可用时自动拉取它们。此功能对于开发和测试以及将应用程序部署到新环境特别有用。
您也可以按名称拉取 Hugging Face 上数千个免费的 GGUF 模型中的任何一个。
有三种拉取模型的策略:
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 0.2.8 或更新版本才能使用函数调用功能,需要 Ollama 0.4.6 或更新版本才能在流式模式中使用它们。
OllamaChatModel 不在内部执行工具调用。必须使用以下两种受支持的方法之一在外部处理工具执行:
- 带有
ToolCallingAdvisor的ChatClient— 推荐用于大多数用例。ToolCallingAdvisor透明地管理工具调用循环。 - 用户控制的工具执行 — 当您需要完全控制循环时,直接使用
ToolCallingManager。
通过 ChatClient 进行工具调用(推荐)
将 ChatClient 与 ToolCallingAdvisor 一起用于同步和流式工具执行。
ToolCallback weatherCallback = FunctionToolCallback.builder("getCurrentWeather", new WeatherService())
.description("Get the weather in location")
.inputType(WeatherService.Request.class)
.build();
// 同步
String response = ChatClient.create(chatModel)
.prompt()
.user("What's the weather in Paris, Tokyo, and New York?")
.tools(weatherCallback)
.call()
.content();
// 流式
Flux<String> stream = ChatClient.create(chatModel)
.prompt()
.user("What's the weather in Paris, Tokyo, and New York?")
.tools(weatherCallback)
.stream()
.content();
用户控制的工具执行
当您需要直接访问 ChatModel API 并希望完全控制工具调用循环时,使用此模式。直接调用 ChatModel(不使用 ToolCallingAdvisor);自行检查工具调用并使用 ToolCallingManager 驱动循环。
ToolCallingManager toolCallingManager = ToolCallingManager.builder().build();
OllamaChatOptions options = OllamaChatOptions.builder()
.toolCallbacks(ToolCallbacks.from(new WeatherService()))
.build();
Prompt prompt = new Prompt("What's the weather in Paris, Tokyo, and New York?", options);
ChatResponse response = chatModel.call(prompt);
while (response.hasToolCalls()) {
ToolExecutionResult result = toolCallingManager.executeToolCalls(prompt, response);
prompt = new Prompt(result.conversationHistory(), options);
response = chatModel.call(prompt);
}
对于流式,使用 flatMap 来检测工具调用并使用更新后的对话历史重新流式传输:
ToolCallingManager toolCallingManager = ToolCallingManager.builder().build();
Prompt prompt = new Prompt("What's the weather in Paris, Tokyo, and New York?", options);
String content = chatModel.stream(prompt).flatMap(response -> {
if (response.hasToolCalls()) {
ToolExecutionResult result = toolCallingManager.executeToolCalls(prompt, response);
return chatModel.stream(new Prompt(result.conversationHistory(), options));
}
return Flux.just(response);
})
.mapNotNull(r -> r.getResult() != null ? r.getResult().getOutput().getText() : null)
.collect(Collectors.joining())
.block();
思考模式(推理)
Ollama 支持推理模型的思考模式,这些模型可以在提供最终答案之前输出其内部推理过程。此功能适用于 Qwen3、DeepSeek-v3.1、DeepSeek R1 和 GPT-OSS 等模型。
思考模式可帮助您理解模型的推理过程,并可提高复杂问题的响应质量。
注意
默认行为(Ollama 0.12+):具备思考能力的模型(如
qwen3:*-thinking、deepseek-r1、deepseek-v3.1)在未明确设置think选项时,默认启用思考。标准模型(如qwen2.5:*、llama3.2)默认不启用思考。要显式控制此行为,请使用.enableThinking()或.disableThinking()。
启用思考模式
大多数模型(Qwen3、DeepSeek-v3.1、DeepSeek R1)支持简单的布尔值启用/禁用:
ChatResponse response = chatModel.call(
new Prompt(
"How many letter 'r' are in the word 'strawberry'?",
OllamaChatOptions.builder()
.model("qwen3")
.enableThinking()
.build()
));
// 访问思考过程
String thinking = response.getResult().getMetadata().get("thinking");
String answer = response.getResult().getOutput().getText();
您也可以显式禁用思考:
ChatResponse response = chatModel.call(
new Prompt(
"What is 2+2?",
OllamaChatOptions.builder()
.model("deepseek-r1")
.disableThinking()
.build()
));
思考级别(仅限 GPT-OSS)
GPT-OSS 模型需要显式的思考级别,而不是布尔值:
// 低思考级别
ChatResponse response = chatModel.call(
new Prompt(
"Generate a short headline",
OllamaChatOptions.builder()
.model("gpt-oss")
.thinkLow()
.build()
));
// 中思考级别
ChatResponse response = chatModel.call(
new Prompt(
"Analyze this dataset",
OllamaChatOptions.builder()
.model("gpt-oss")
.thinkMedium()
.build()
));
// 高思考级别
ChatResponse response = chatModel.call(
new Prompt(
"Solve this complex problem",
OllamaChatOptions.builder()
.model("gpt-oss")
.thinkHigh()
.build()
));
访问思考内容
思考内容可在响应元数据中获取:
ChatResponse response = chatModel.call(
new Prompt(
"Calculate 17 × 23",
OllamaChatOptions.builder()
.model("deepseek-r1")
.enableThinking()
.build()
));
// 获取推理过程
String thinking = response.getResult().getMetadata().get("thinking");
System.out.println("Reasoning: " + thinking);
// 输出: "17 × 20 = 340, 17 × 3 = 51, 340 + 51 = 391"
// 获取最终答案
String answer = response.getResult().getOutput().getText();
System.out.println("Answer: " + answer);
// 输出: "The answer is 391"
带思考的流式传输
思考模式同样适用于流式响应:
Flux<ChatResponse> stream = chatModel.stream(
new Prompt(
"Explain quantum entanglement",
OllamaChatOptions.builder()
.model("qwen3")
.enableThinking()
.build()
));
stream.subscribe(response -> {
String thinking = response.getResult().getMetadata().get("thinking");
String content = response.getResult().getOutput().getText();
if (thinking != null && !thinking.isEmpty()) {
System.out.println("[Thinking] " + thinking);
}
if (content != null && !content.isEmpty()) {
System.out.println("[Response] " + content);
}
});
当思考被禁用或未设置时,thinking 元数据字段将为 null 或空。
多模态
多模态是指模型同时理解和处理来自各种来源(包括文本、图像、音频和其他数据格式)的信息的能力。
Ollama 中一些支持多模态的模型有 LLaVA 和 BakLLaVA(请参阅完整列表)。有关更多详细信息,请参阅 LLaVA:大型语言和视觉助手。
Ollama Message API 提供了一个 images 参数,用于将 base64 编码的图像列表合并到消息中。
Spring AI 的 Message 接口通过引入 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,
OllamaChatOptions.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 提供了更强的控制力和精度。
结构化输出的两种模式
Ollama 通过 format 参数支持两种不同的结构化输出模式:
- 简单的 “json” 格式:指示 Ollama 返回任何有效的 JSON 结构(模式不可预测)。
- JSON Schema 格式:指示 Ollama 返回符合特定模式的 JSON(结构可预测)。
简单的 “json” 格式
当您需要 JSON 输出但不需要特定结构时使用:
ChatResponse response = chatModel.call(
new Prompt(
"List 3 countries in Europe",
OllamaChatOptions.builder()
.model("llama3.2")
.format("json") // 任何有效的 JSON
.build()
));
模型可以选择返回任何 JSON 结构:
["France", "Germany", "Italy"]
// 或
{"countries": ["France", "Germany", "Italy"]}
// 或
{"data": {"european_countries": ["France", "Germany", "Italy"]}}
JSON Schema 格式(推荐用于生产)
当您需要保证一个可预测的结构时使用:
String jsonSchema = """
{
"type": "object",
"properties": {
"countries": {
"type": "array",
"items": { "type": "string" }
}
},
"required": ["countries"]
}
""";
ChatResponse response = chatModel.call(
new Prompt(
"List 3 countries in Europe",
OllamaChatOptions.builder()
.model("llama3.2")
.outputSchema(jsonSchema) // 强制执行的模式
.build()
));
模型必须返回此确切结构:
{"countries": ["France", "Germany", "Italy"]}
配置
Spring AI 允许您使用 OllamaChatOptions 构建器以编程方式配置响应格式。
使用带有 JSON Schema 的聊天选项构建器
您可以使用 OllamaChatOptions 构建器以编程方式设置响应格式:
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",
OllamaChatOptions.builder()
.model(OllamaModel.LLAMA3_2.getName())
.outputSchema(jsonSchema) // 将 JSON Schema 作为字符串传递
.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",
OllamaChatOptions.builder()
.model(OllamaModel.LLAMA3_2.getName())
.outputSchema(outputConverter.getJsonSchema()) // 将 JSON Schema 作为字符串获取
.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,…)注解来生成能准确将字段标记为必需的 Schema。虽然这对于 JSON Schema 是可选的,但为了结构化响应能正常工作,建议使用。
API 方法:.format() 与 .outputSchema()
Spring AI 提供了两种配置结构化输出的方法:
| 方法 | 用例 | 示例 |
|---|---|---|
.format("json") |
简单 JSON 模式 - 任意结构 | .format("json") |
.outputSchema(jsonSchemaString) |
JSON Schema 模式 - 强制结构 | .outputSchema("{\"type\":\"object\",…}") |
.format(mapObject) |
JSON Schema 模式 - 替代 API | .format(new JsonMapper().readValue(schema, Map.class)) |
对于大多数用例,使用 .outputSchema(jsonSchemaString) 进行 JSON Schema 验证,或使用 .format("json") 进行简单的 JSON 输出。.format(Map) 方法也受支持,但需要手动解析 JSON。
OpenAI API 兼容性
Ollama 与 OpenAI API 兼容,您可以使用 Spring AI OpenAI 客户端与 Ollama 通信并使用工具。为此,您需要将 OpenAI 基础 URL 配置到您的 Ollama 实例:spring.ai.openai.chat.base-url=http://localhost:11434/v1,并选择提供的 Ollama 模型之一:spring.ai.openai.chat.model=mistral。
当将 OpenAI 客户端与 Ollama 一起使用时,您可以使用 extraBody 选项传递 Ollama 特定的参数(如 top_k、repeat_penalty、num_predict)。这允许您在使用 OpenAI 客户端的同时利用 Ollama 的全部功能。
通过 OpenAI 兼容性获取推理内容
Ollama 的 OpenAI 兼容端点支持具备思考能力的模型(如 qwen3:*-thinking、deepseek-r1、deepseek-v3.1)的 reasoning_content 字段。当将 Spring AI OpenAI 客户端与 Ollama 一起使用时,模型的推理过程会自动被捕获并通过响应元数据提供。
这是使用 Ollama 原生思考模式 API(在上述思考模式(推理)中记录)的替代方案。两种方法都适用于 Ollama 的思考模型,但 OpenAI 兼容端点使用 reasoning_content 字段名称而不是 thinking。
以下是通过 OpenAI 客户端从 Ollama 访问推理内容的示例:
// 将 Spring AI OpenAI 客户端配置为指向 Ollama
@Configuration
class OllamaConfig {
@Bean
OpenAiChatModel ollamaChatModel() {
return OpenAiChatModel.builder()
.options(OpenAiChatOptions.builder()
.baseUrl("http://localhost:11434/v1")
.apiKey("ollama")
.model("deepseek-r1") // 或 qwen3, deepseek-v3.1 等.
.build())
.build();
}
}
// 将模型与具备思考能力的模型一起使用
ChatResponse response = chatModel.call(
new Prompt("How many letter 'r' are in the word 'strawberry'?"));
// 从元数据中访问推理过程
String reasoning = response.getResult().getMetadata().get("reasoningContent");
if (reasoning != null && !reasoning.isEmpty()) {
System.out.println("Model's reasoning process:");
System.out.println(reasoning);
}
// 获取最终答案
String answer = response.getResult().getOutput().getText();
System.out.println("Answer: " + answer);
Ollama(0.12+)中具备思考能力的模型在通过 OpenAI 兼容端点访问时会自动启用思考模式。推理内容会被自动捕获,无需额外配置。
查看 OllamaWithOpenAiChatModelIT.java 测试以获取通过 Spring AI OpenAI 使用 Ollama 的示例。
HuggingFace 模型
Ollama 可以直接访问 Hugging Face 上所有的 GGUF 聊天模型。您可以通过名称拉取这些模型:ollama pull hf.co/<用户名>/<模型仓库>,或配置自动拉取策略:自动拉取模型:
spring.ai.ollama.chat.model=hf.co/bartowski/gemma-2-2b-it-GGUF
spring.ai.ollama.init.pull-model-strategy=always
spring.ai.ollama.chat.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-starter-model-ollama 添加到您的 pom(或 gradle)依赖项中。
在 src/main/resources 目录下添加一个 application.yaml 文件,以启用和配置 Ollama 聊天模型:
spring:
ai:
ollama:
base-url: http://localhost:11434
chat:
options:
model: mistral
temperature: 0.7
将 base-url 替换为您的 Ollama 服务器 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 = OllamaApi.builder().build();
var chatModel = OllamaChatModel.builder()
.ollamaApi(ollamaApi)
.options(
OllamaChatOptions.builder()
.model(OllamaModel.MISTRAL)
.temperature(0.9)
.build())
.build();
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."));
OllamaChatOptions 为所有聊天请求提供配置信息。
低级 OllamaApi 客户端
OllamaApi 为 Ollama 聊天补全 API(Ollama Chat Completion API)提供了一个轻量级 Java 客户端。
下图展示了 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(OllamaChatOptions.builder().temperature(0.9).build())
.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(OllamaChatOptions.builder().temperature(0.9).build().toMap())
.build();
Flux<ChatResponse> streamingResponse = this.ollamaApi.streamingChat(this.request2);
更多推荐


所有评论(0)