Ollama 聊天

通过 Ollama,您可以在本地运行多种大型语言模型(LLMs),并从这些模型生成文本。 Spring AI 使用 OllamaChatModel API 支持 Ollama 的聊天补全功能。spring-doc.cadn.net.cn

Ollama同样提供了一个与OpenAI API兼容的端点。 OpenAI API兼容性部分说明了如何使用Spring AI OpenAI连接到Ollama服务器。

前提条件

首先,您需要访问一个Ollama实例。有几种选择,包括以下:spring-doc.cadn.net.cn

您可以在应用程序中从Ollama模型库拉取所需模型:spring-doc.cadn.net.cn

ollama pull <model-name>

您也可以拉取数千个免费的Hugging Face GGUF模型:spring-doc.cadn.net.cn

ollama pull hf.co/<username>/<model-repository>

另外,您可以启用自动下载所需模型的选项: 模型自动拉取.spring-doc.cadn.net.cn

自动配置

There has been a significant change in the Spring AI auto-configuration, starter modules' artifact names. Please refer to the 升级说明以获取更多信息。spring-doc.cadn.net.cn

Spring AI 为 Ollama 聊天集成提供了 Spring Boot 自动配置功能。要启用它,请将以下依赖项添加到项目的 Maven pom.xml 或 Gradle build.gradle 构建文件中:spring-doc.cadn.net.cn

<dependency>
   <groupId>org.springframework.ai</groupId>
   <artifactId>spring-ai-starter-model-ollama</artifactId>
</dependency>
dependencies {
    implementation 'org.springframework.ai:spring-ai-starter-model-ollama'
}
参考以下依赖管理部分,添加Spring AI BOM到你的构建文件中。

基本属性

前缀 spring.ai.ollama 是配置与 Ollama 连接的属性前缀。spring-doc.cadn.net.cn

属性spring-doc.cadn.net.cn

描述spring-doc.cadn.net.cn

默认spring-doc.cadn.net.cn

spring.ai.ollama.base-urlspring-doc.cadn.net.cn

Ollama API 服务器运行的基础URL。spring-doc.cadn.net.cn

http://localhost:11434spring-doc.cadn.net.cn

这里是初始化Ollama集成和自动拉取模型的属性设置。spring-doc.cadn.net.cn

属性spring-doc.cadn.net.cn

描述spring-doc.cadn.net.cn

默认spring-doc.cadn.net.cn

spring.ai.ollama.init.pull-model-strategyspring-doc.cadn.net.cn

是否在启动时拉取模型以及如何拉取。spring-doc.cadn.net.cn

neverspring-doc.cadn.net.cn

spring.ai.ollama.init.timeoutspring-doc.cadn.net.cn

等待模型被拉取的时长。spring-doc.cadn.net.cn

5mspring-doc.cadn.net.cn

spring.ai.ollama.init.max-retriesspring-doc.cadn.net.cn

模型拉取操作的最大重试次数。spring-doc.cadn.net.cn

0spring-doc.cadn.net.cn

spring.ai.ollama.init.chat.includespring-doc.cadn.net.cn

在初始化任务中包含此类模型。spring-doc.cadn.net.cn

truespring-doc.cadn.net.cn

spring.ai.ollama.init.chat.additional-modelsspring-doc.cadn.net.cn

除通过默认属性配置的模型之外,需要额外初始化的模型。spring-doc.cadn.net.cn

[]spring-doc.cadn.net.cn

聊天属性

启用和禁用聊天自动配置现在通过顶级属性使用前缀 spring.ai.model.chat 配置完成。spring-doc.cadn.net.cn

要启用,请设置 spring.ai.model.chat=ollama (默认已启用)spring-doc.cadn.net.cn

要禁用,请设置 spring.ai.model.chat=none(或任何不匹配 ollama 的值)spring-doc.cadn.net.cn

这种修改是为了允许配置多个模型。spring-doc.cadn.net.cn

前缀 spring.ai.ollama.chat.options 是配置Ollama聊天模型的属性前缀。 它包含了Ollama请求(高级)参数,如 modelkeep-aliveformat,以及Ollama模型的 options 属性设置。spring-doc.cadn.net.cn

以下是Ollama聊天模型的高级请求参数:spring-doc.cadn.net.cn

属性spring-doc.cadn.net.cn

描述spring-doc.cadn.net.cn

默认spring-doc.cadn.net.cn

spring.ai.ollama.chat.enabled(已移除,不再有效)spring-doc.cadn.net.cn

启用Ollama聊天模型。spring-doc.cadn.net.cn

truespring-doc.cadn.net.cn

spring.ai.model.chatspring-doc.cadn.net.cn

启用Ollama聊天模型。spring-doc.cadn.net.cn

Ollamaspring-doc.cadn.net.cn

spring.ai.ollama.chat.options.modelspring-doc.cadn.net.cn

所使用的支持模型的名称。spring-doc.cadn.net.cn

密史脱拉风spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.formatspring-doc.cadn.net.cn

返回响应的格式。接受 "json"(任何JSON结构)或JSON Schema对象(强制结构)。详细信息请参见结构化输出spring-doc.cadn.net.cn

-spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.keep_alivespring-doc.cadn.net.cn

控制模型在请求后保持加载在内存中的时长spring-doc.cadn.net.cn

5mspring-doc.cadn.net.cn

剩余的options个属性基于Ollama有效参数及值Ollama类型。默认值依据Ollama类型默认值设定。spring-doc.cadn.net.cn

属性spring-doc.cadn.net.cn

描述spring-doc.cadn.net.cn

默认spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.numaspring-doc.cadn.net.cn

是否使用NUMA。spring-doc.cadn.net.cn

falsespring-doc.cadn.net.cn

spring.ai.ollama.chat.options.num-ctxspring-doc.cadn.net.cn

设置用于生成下一个Tokens的上下文窗口的大小。spring-doc.cadn.net.cn

2048spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.num-batchspring-doc.cadn.net.cn

提示处理最大批次大小。spring-doc.cadn.net.cn

512spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.num-gpuspring-doc.cadn.net.cn

发送到GPU(s)的层数。在macOS上,默认为1以启用Metal支持,设置为0则禁用。此处的1表示NumGPU应动态设置。spring-doc.cadn.net.cn

-1spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.main-gpuspring-doc.cadn.net.cn

在使用多块GPU时,此选项用于控制哪些小型张量使用的GPU。对于这些小型张量,跨所有GPU分配计算的开销并不划算。被选中的GPU将稍微占用更多的VRAM来存储临时结果的缓冲区。spring-doc.cadn.net.cn

0spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.low-vramspring-doc.cadn.net.cn

-spring-doc.cadn.net.cn

falsespring-doc.cadn.net.cn

spring.ai.ollama.chat.options.f16-kvspring-doc.cadn.net.cn

-spring-doc.cadn.net.cn

truespring-doc.cadn.net.cn

spring.ai.ollama.chat.options.logits-allspring-doc.cadn.net.cn

为所有Tokens返回logits,而不仅仅是最后一个。为了使 completions 能够返回 logprobs,此选项必须为真。spring-doc.cadn.net.cn

-spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.vocab-onlyspring-doc.cadn.net.cn

仅加载词汇表,不加载权重。spring-doc.cadn.net.cn

-spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.use-mmapspring-doc.cadn.net.cn

默认情况下,模型会被映射到内存中,这使得系统能够按需只加载模型的必要部分。然而,如果模型大小超过您总RAM量,或者系统可用内存较低,使用mmap可能会增加页面交换的风险,从而负面影响性能。禁用mmap会导致加载时间变慢,但如果未使用mlock,可能会减少页面调度。请注意,如果模型大小超过总RAM量,关闭mmap将根本阻止模型加载。spring-doc.cadn.net.cn

空值spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.use-mlockspring-doc.cadn.net.cn

将模型锁定在内存中,防止在使用内存映射时将其换出。这可以提高性能,但会牺牲内存映射的一些优势,因为它需要更多的RAM来运行,并且在模型加载到RAM时可能减慢加载时间。spring-doc.cadn.net.cn

falsespring-doc.cadn.net.cn

spring.ai.ollama.chat.options.num-threadspring-doc.cadn.net.cn

设置计算过程中使用的线程数。默认情况下,Ollama 会自动检测以达到最佳性能。建议将此值设置为系统物理CPU核心数(而非逻辑核心数)。0 = 让运行时自动决定。spring-doc.cadn.net.cn

0spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.num-keepspring-doc.cadn.net.cn

-spring-doc.cadn.net.cn

4spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.seedspring-doc.cadn.net.cn

设置用于生成的随机数种子。将此设置为特定数值将使模型在接收到相同的提示时生成相同的文本。spring-doc.cadn.net.cn

-1spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.num-predictspring-doc.cadn.net.cn

生成文本时预测的最大Tokens数量。(-1 = 无限生成, -2 = 填充上下文)spring-doc.cadn.net.cn

-1spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.top-kspring-doc.cadn.net.cn

降低生成无意义内容的概率。较高的值(例如,100)将提供更加多样化的答案,而较低的值(例如,10)则更为保守。spring-doc.cadn.net.cn

40spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.top-pspring-doc.cadn.net.cn

与 top-k 配合使用。较高的值(例如,0.95)将产生更多样化的文本,而较低的值(例如,0.5)将生成更集中和保守的文本。spring-doc.cadn.net.cn

0.9spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.min-pspring-doc.cadn.net.cn

作为`top_p`的替代方案,旨在确保质量和多样性的平衡。参数p表示一个标记被考虑的最低概率,相对于最可能标记的概率。例如,如果p=0.05且最可能的标记概率为0.9,则值小于0.045的logits会被过滤掉。spring-doc.cadn.net.cn

0.0spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.tfs-zspring-doc.cadn.net.cn

无尾采样用于减少输出中较不可能的Tokens的影响。较高的值(例如,2.0)会更大程度地减少这种影响,而1.0的值则会禁用此设置。spring-doc.cadn.net.cn

1.0spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.typical-pspring-doc.cadn.net.cn

-spring-doc.cadn.net.cn

1.0spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.repeat-last-nspring-doc.cadn.net.cn

设置模型回溯以防重复的时间跨度。默认值为64,0表示禁用,-1表示回溯长度等于上下文数量(num_ctx)。spring-doc.cadn.net.cn

64spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.temperaturespring-doc.cadn.net.cn

模型的温度。提高温度将使模型的回答更具创造性。spring-doc.cadn.net.cn

0.8spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.repeat-penaltyspring-doc.cadn.net.cn

设置重复内容的惩罚强度。值越高(例如,1.5),对重复内容的惩罚越重;值越低(例如,0.9),则对重复内容更加宽容。spring-doc.cadn.net.cn

1.1spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.presence-penaltyspring-doc.cadn.net.cn

-spring-doc.cadn.net.cn

0.0spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.frequency-penaltyspring-doc.cadn.net.cn

-spring-doc.cadn.net.cn

0.0spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.mirostatspring-doc.cadn.net.cn

启用Mirostat采样以控制困惑度。(默认值:0,0=禁用,1=Mirostat,2=Mirostat 2.0)spring-doc.cadn.net.cn

0spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.mirostat-tauspring-doc.cadn.net.cn

控制输出的一致性与多样性之间的平衡。较低的值将产生更集中且连贯的文本。spring-doc.cadn.net.cn

5.0spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.mirostat-etaspring-doc.cadn.net.cn

影响算法根据生成文本的反馈进行响应的速度。较低的学习率将导致调整速度较慢,而较高的学习率将使算法更加灵敏。spring-doc.cadn.net.cn

0.1spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.penalize-newlinespring-doc.cadn.net.cn

-spring-doc.cadn.net.cn

truespring-doc.cadn.net.cn

spring.ai.ollama.chat.options.stopspring-doc.cadn.net.cn

设置要使用的停止序列。当遇到此模式时,LLM 将停止生成文本并返回。可以在模型文件中通过指定多个独立的停止参数来设置多个停止模式。spring-doc.cadn.net.cn

-spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.tool-namesspring-doc.cadn.net.cn

用于在单个提示请求中启用函数调用的工具列表,这些工具通过它们的名称来识别。具有这些名称的工具必须存在于ToolCallback注册表中。spring-doc.cadn.net.cn

-spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.tool-callbacksspring-doc.cadn.net.cn

向ChatModel注册的工具回调。spring-doc.cadn.net.cn

-spring-doc.cadn.net.cn

spring.ai.ollama.chat.options.internal-tool-execution-enabledspring-doc.cadn.net.cn

如果为 false,Spring AI 将不内部处理工具调用,而是将它们代理给客户端。此后,处理工具调用、将其分派给适当函数并返回结果的责任在于客户端。如果为 true(默认值),Spring AI 将内部处理函数调用。此设置仅适用于支持函数调用的聊天模型。spring-doc.cadn.net.cn

truespring-doc.cadn.net.cn

所有以spring.ai.ollama.chat.options为前缀的属性都可以通过向Prompt调用中添加请求特定的运行时选项在运行时覆盖。

运行时选项

OllamaChatOptions.java 类提供了模型配置,如使用的模型、温度、思考模式等。spring-doc.cadn.net.cn

OllamaOptions 类已被弃用。对于聊天模型,请使用 OllamaChatOptions,而对于嵌入模型,请使用 OllamaEmbeddingOptions。新类提供了类型安全、针对模型的配置选项。

On start-up, the default options can be configured with the OllamaChatModel(api, options) constructor or the spring.ai.ollama.chat.options.* properties.spring-doc.cadn.net.cn

在运行时,您可以通过向 Prompt 调用添加新的、特定于请求的选项来覆盖默认选项。 例如,要为特定请求覆盖默认模型和温度:spring-doc.cadn.net.cn

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实例,通过ChatOptions#builder()创建。

模型自动拉取

Spring AI Ollama 可在您的 Ollama 实例中未提供模型时自动拉取它们。 此功能对于开发和测试特别有用,同时也适用于将您的应用程序部署到新环境。spring-doc.cadn.net.cn

您也可以按名称拉取任何数千个免费的Hugging Face GGUF模型

模型拉取有三种策略:spring-doc.cadn.net.cn

  • always (定义于 PullModelStrategy.ALWAYS):始终拉取模型,即使它已可用。确保使用模型的最新版本很有帮助。spring-doc.cadn.net.cn

  • when_missing (定义于 PullModelStrategy.WHEN_MISSING):仅在模型尚未获取时才拉取。这可能导致使用模型的较旧版本。spring-doc.cadn.net.cn

  • never (定义于 PullModelStrategy.NEVER 中):从不自动拉取模型。spring-doc.cadn.net.cn

由于在下载模型时可能存在延迟,不建议在生产环境中使用自动拉取功能。建议事先评估并预先下载所需的模型。

所有通过配置属性和默认选项定义的模型都可在启动时自动拉取。 您可以使用配置属性来设置拉取策略、超时时间和最大重试次数:spring-doc.cadn.net.cn

spring:
  ai:
    ollama:
      init:
        pull-model-strategy: always
        timeout: 60s
        max-retries: 1
应用程序在Ollama中所有指定的模型都可用之前,不会完成其初始化。根据模型大小和互联网连接速度,这可能会显著延长应用程序的启动时间。

您可以在启动时初始化额外的模型,这对于在运行时动态使用的模型非常有用:spring-doc.cadn.net.cn

spring:
  ai:
    ollama:
      init:
        pull-model-strategy: always
        chat:
          additional-models:
            - llama3.2
            - qwen2.5

如果您只想对特定类型的模型应用拉取策略,可以从初始化任务中排除聊天模型:spring-doc.cadn.net.cn

spring:
  ai:
    ollama:
      init:
        pull-model-strategy: always
        chat:
          include: false

此配置将拉取策略应用于所有模型,除了聊天模型。spring-doc.cadn.net.cn

函数调用

您可以使用OllamaChatModel注册自定义Java函数,并让Ollama模型智能地选择输出一个包含参数的JSON对象,以调用一个或多个已注册的函数。 这是一种将LLM功能与外部工具和API连接起来的强大技术。 了解更多关于工具调用的信息。spring-doc.cadn.net.cn

您需要使用 Ollama 0.2.8 或更高版本以利用函数调用功能,并且需要 Ollama 0.4.6 或更高版本以在流模式下使用这些功能。

思考模式(推理)

Ollama 支持为推理模型提供思考模式,这些模型在给出最终答案之前能展示其内部推理过程。此功能适用于诸如Qwen3、DeepSeek-v3.1、DeepSeek R1和GPT-OSS等模型。spring-doc.cadn.net.cn

思考模式有助于您理解模型的推理过程,并能提高对复杂问题的响应质量。
默认行为(Ollama 0.12及以上版本):具有思考能力的模型(如 qwen3:*-thinking, deepseek-r1, deepseek-v3.1)在未明确设置思考选项时,默认自动启用思考功能。标准模型(如 qwen2.5:*, llama3.2)则默认不启用思考功能。要显式控制此行为,请使用 .enableThinking().disableThinking()

启用思维模式

大多数模型(Qwen3、DeepSeek-v3.1、DeepSeek R1)支持简单的布尔启用/禁用功能:spring-doc.cadn.net.cn

ChatResponse response = chatModel.call(
    new Prompt(
        "How many letter 'r' are in the word 'strawberry'?",
        OllamaChatOptions.builder()
            .model("qwen3")
            .enableThinking()
            .build()
    ));

// Access the thinking process
String thinking = response.getResult().getMetadata().get("thinking");
String answer = response.getResult().getOutput().getText();

您也可以显式地禁用思考功能:spring-doc.cadn.net.cn

ChatResponse response = chatModel.call(
    new Prompt(
        "What is 2+2?",
        OllamaChatOptions.builder()
            .model("deepseek-r1")
            .disableThinking()
            .build()
    ));

思维层级(仅限GPT-OSS)

GPT-OSS 模型需要明确的思维层次而非布尔值:spring-doc.cadn.net.cn

// Low thinking level
ChatResponse response = chatModel.call(
    new Prompt(
        "Generate a short headline",
        OllamaChatOptions.builder()
            .model("gpt-oss")
            .thinkLow()
            .build()
    ));

// Medium thinking level
ChatResponse response = chatModel.call(
    new Prompt(
        "Analyze this dataset",
        OllamaChatOptions.builder()
            .model("gpt-oss")
            .thinkMedium()
            .build()
    ));

// High thinking level
ChatResponse response = chatModel.call(
    new Prompt(
        "Solve this complex problem",
        OllamaChatOptions.builder()
            .model("gpt-oss")
            .thinkHigh()
            .build()
    ));

访问思考内容

思考内容可在响应元数据中获得:spring-doc.cadn.net.cn

ChatResponse response = chatModel.call(
    new Prompt(
        "Calculate 17 × 23",
        OllamaChatOptions.builder()
            .model("deepseek-r1")
            .enableThinking()
            .build()
    ));

// Get the reasoning process
String thinking = response.getResult().getMetadata().get("thinking");
System.out.println("Reasoning: " + thinking);
// Output: "17 × 20 = 340, 17 × 3 = 51, 340 + 51 = 391"

// Get the final answer
String answer = response.getResult().getOutput().getText();
System.out.println("Answer: " + answer);
// Output: "The answer is 391"

使用Spring进行流处理

思维模式同样适用于流式响应:spring-doc.cadn.net.cn

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 或为空。

多模态

多模态是指模型同时理解和处理来自多种来源信息的能力,这些来源包括文本、图像、音频及其他数据格式。spring-doc.cadn.net.cn

Ollama中支持多模态的模型有LLaVABakLLaVA(查看完整列表)。 更多详情,请参阅LLaVA:大型语言与视觉助手.spring-doc.cadn.net.cn

Ollama 消息API提供了"images"参数,以便将base64编码的图片列表与消息一起发送。spring-doc.cadn.net.cn

Spring AI的消息接口通过引入媒体类型,促进了多模态AI模型的开发。 此类型包含了关于消息中媒体附件的数据和详细信息,利用了Spring的org.springframework.util.MimeType和一个org.springframework.core.io.Resource来处理原始媒体数据。spring-doc.cadn.net.cn

以下是一个简单的代码示例,摘自OllamaChatModelMultimodalIT.java,展示了用户文本与图像的融合。spring-doc.cadn.net.cn

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号图像:spring-doc.cadn.net.cn

Multimodal Test Image

伴随着文本信息 "解释一下你在图片中看到了什么?",并生成如下的回复:spring-doc.cadn.net.cn

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-doc.cadn.net.cn

结构化输出的两种模式

Ollama支持通过format参数实现两种不同的结构化输出模式:spring-doc.cadn.net.cn

  1. 简单 "json" 格式: 指示 Ollama 返回任何有效的 JSON 结构(模式不可预测)spring-doc.cadn.net.cn

  2. JSON Schema 格式: 指示 Ollama 返回遵循特定模式(可预测结构)的 JSONspring-doc.cadn.net.cn

简单 "json" 格式

当您需要JSON输出但不需要特定结构时,请使用此方法:spring-doc.cadn.net.cn

ChatResponse response = chatModel.call(
    new Prompt(
        "List 3 countries in Europe",
        OllamaChatOptions.builder()
            .model("llama3.2")
            .format("json")  // Any valid JSON
            .build()
    ));

模型可以返回它选择的任何JSON结构:spring-doc.cadn.net.cn

["France", "Germany", "Italy"]
// or
{"countries": ["France", "Germany", "Italy"]}
// or
{"data": {"european_countries": ["France", "Germany", "Italy"]}}

当您需要一个有保证且可预测的结构时,请使用此方法:spring-doc.cadn.net.cn

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)  // Enforced schema
            .build()
    ));

模型必须返回这个确切的结构:spring-doc.cadn.net.cn

{"countries": ["France", "Germany", "Italy"]}

配置

Spring AI 允许您使用 OllamaChatOptions 构建器以编程方式配置响应格式。spring-doc.cadn.net.cn

使用JSON Schema的聊天选项构建器

可以通过编程方式使用OllamaChatOptions构建器设置响应格式:spring-doc.cadn.net.cn

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)  // Pass JSON Schema as string
            .build());

ChatResponse response = this.ollamaChatModel.call(this.prompt);

与BeanOutputConverter工具集成

您可以利用现有的BeanOutputConverter工具自动从领域对象生成JSON Schema,之后将结构化响应转换为领域特定的实例:spring-doc.cadn.net.cn

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())  // Get JSON Schema as string
            .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,…​) 注解来生成一个模式,该模式能准确地将字段标记为 required。 尽管这对于JSON Schema是可选的,但为了使结构化响应正确工作,建议这样做。

API 方法数量: .format().outputSchema()

Spring AI 为配置结构化输出提供了两种方法:spring-doc.cadn.net.cn

方法 使用案例 示例

.format("json")spring-doc.cadn.net.cn

简单JSON模式 - 任意结构spring-doc.cadn.net.cn

.format("json")spring-doc.cadn.net.cn

.outputSchema(jsonSchemaString)spring-doc.cadn.net.cn

JSON Schema模式 - 强制结构spring-doc.cadn.net.cn

.outputSchema("{\"type\":\"object\",…​}")spring-doc.cadn.net.cn

.format(mapObject)spring-doc.cadn.net.cn

JSON Schema 模式 - 替代 APIspring-doc.cadn.net.cn

.format(new ObjectMapper().readValue(schema, Map.class))spring-doc.cadn.net.cn

对于大多数使用场景,使用.outputSchema(jsonSchemaString)进行JSON Schema验证或使用.format("json")输出简单JSON格式。 也支持.format(Map)的方式,但需要手动进行JSON解析。

OpenAI API 兼容性

Ollama与OpenAI API兼容,您可以使用Spring AI OpenAI客户端与Ollama通信并使用工具。 为此,您需要将OpenAI基础URL配置为您的Ollama实例:`0`,并选择提供的Ollama模型之一:`1`。spring-doc.cadn.net.cn

在使用OpenAI客户端配合Ollama时,您可以借助extraBody选项传递Ollama特有的参数(如top_k, repeat_penalty, num_predict)。 这使得在使用OpenAI客户端的同时,能够充分利用Ollama的所有功能。
Ollama OpenAI API compatibility

通过OpenAI兼容性进行推理内容

Ollama的与OpenAI兼容的端点支持针对具有思考能力的模型(如qwen3:*-thinkingdeepseek-r1deepseek-v3.1)使用reasoning_content字段。 在使用Spring AI OpenAI客户端与Ollama交互时,模型的推理过程会被自动捕获,并通过响应元数据提供访问。spring-doc.cadn.net.cn

这是使用Ollama原生思考模式API(在上述思考模式(推理)文档中)的替代方法。 两种方法都与Ollama的思考模型兼容,但OpenAI兼容的端点使用reasoning_content字段名而非thinking

以下是一个通过OpenAI客户端从Ollama获取推理内容的例子:spring-doc.cadn.net.cn

// Configure Spring AI OpenAI client to point to Ollama
@Configuration
class OllamaConfig {
    @Bean
    OpenAiChatModel ollamaChatModel() {
        var openAiApi = new OpenAiApi("http://localhost:11434", "ollama");
        return new OpenAiChatModel(openAiApi,
            OpenAiChatOptions.builder()
                .model("deepseek-r1")  // or qwen3, deepseek-v3.1, etc.
                .build());
    }
}

// Use the model with thinking-capable models
ChatResponse response = chatModel.call(
    new Prompt("How many letter 'r' are in the word 'strawberry'?"));

// Access the reasoning process from metadata
String reasoning = response.getResult().getMetadata().get("reasoningContent");
if (reasoning != null && !reasoning.isEmpty()) {
    System.out.println("Model's reasoning process:");
    System.out.println(reasoning);
}

// Get the final answer
String answer = response.getResult().getOutput().getText();
System.out.println("Answer: " + answer);
Ollama 中的思考能力模型(0.12及以上版本)在通过与OpenAI兼容的端点访问时,会自动启用思考模式。 推理内容会自动被捕获,无需额外配置。

查看OllamaWithOpenAiChatModelIT.java测试中的示例,了解如何通过Spring AI OpenAI使用Ollama。spring-doc.cadn.net.cn

HuggingFace 模型

Ollama开箱即用地支持所有GGUF Hugging Face 聊天模型。 您可以通过名称拉取这些模型,如:ollama pull hf.co/<username>/<model-repository>,或配置自动拉取策略:模型自动拉取:spring-doc.cadn.net.cn

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-doc.cadn.net.cn

  • spring.ai.ollama.init.pull-model-strategy=always: (可选)启用启动时自动模型拉取。对于生产环境,您应预先下载模型以避免延迟:ollama pull hf.co/bartowski/gemma-2-2b-it-GGUFspring-doc.cadn.net.cn

示例控制器

创建一个新的Spring Boot项目,并将spring-boot-starter-web添加到您的pom(或gradle)依赖中。spring-doc.cadn.net.cn

src/main/resources目录下添加一个application.yaml文件,以启用并配置Ollama聊天模型:spring-doc.cadn.net.cn

spring:
  ai:
    ollama:
      base-url: http://localhost:11434
      chat:
        options:
          model: mistral
          temperature: 0.7
base-url替换为您的Ollama服务器URL。

这将创建一个您可以注入到类中的OllamaChatModel实现。 下面是一个使用聊天模型进行文本生成的简单@RestController类的例子。spring-doc.cadn.net.cn

@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的自动配置,您可以在应用程序中手动配置OllamaChatModelOllamaChatModel实现了ChatModelStreamingChatModel,并使用OllamaApi低级客户端连接到Ollama服务。spring-doc.cadn.net.cn

要在项目中使用,请将 spring-ai-ollama 依赖项添加到 Maven pom.xml 或 Gradle build.gradle 的构建文件中:spring-doc.cadn.net.cn

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-ollama</artifactId>
</dependency>
dependencies {
    implementation 'org.springframework.ai:spring-ai-ollama'
}
参考以下依赖管理部分,添加Spring AI BOM到你的构建文件中。
spring-ai-ollama 依赖项还提供了对 OllamaEmbeddingModel 的访问。有关 OllamaEmbeddingModel 的更多信息,请参阅 Ollama 嵌入模型 部分。

接下来,创建一个OllamaChatModel实例,并使用它来发送文本生成请求:spring-doc.cadn.net.cn

var ollamaApi = OllamaApi.builder().build();

var chatModel = OllamaChatModel.builder()
                    .ollamaApi(ollamaApi)
                    .defaultOptions(
                        OllamaChatOptions.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."));

数字OllamaChatOptions为所有聊天请求提供配置信息。spring-doc.cadn.net.cn

OllamaApi底层客户端

OllamaApiOllama 聊天补全 API 提供了一个轻量级的 Java 客户端。spring-doc.cadn.net.cn

以下类图展示了OllamaApi聊天接口和构建模块:spring-doc.cadn.net.cn

OllamaApi Chat Completion API Diagram
OllamaApi 是一个低级API,不建议直接使用。请改用 OllamaChatModel

以下是一个简单示例,展示了如何以编程方式使用API:spring-doc.cadn.net.cn

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(OllamaChatOptions.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(OllamaChatOptions.builder().temperature(0.9).build().toMap())
    .build();

Flux<ChatResponse> streamingResponse = this.ollamaApi.streamingChat(this.request2);