Ollama Chat

通过 Ollama,我们可以在本地运行各种大型语言模型 (LLM) 并从中生成文本。 Spring AI 通过 OllamaChatModel 支持 文本生成。

前提条件(Prerequisites)

首先,您需要访问 Ollama 实例。有以下几个选择:

你可以从 Ollama 模型库中提取想要在应用程序中使用的模型:

ollama pull <model-name>

你还可以下载数千个免费的 GGUF Hugging Face 模型中的任何一个:

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

或者,您可以启用自动下载任何所需模型的选项:自动拉取模型。

添加存储库和 BOM

Spring AI 工件发布在 Spring MilestoneSnapshot 存储库中。请参阅存储库部分将这些存储库添加到您的构建系统中。

为了帮助进行依赖管理,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 请求 (高级) 参数,如 modelkeep-aliveformat ,以及 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 中提供的一些支持多模态的模型包括 LLaVABakLLaVA (参见完整列表)。有关更多详细信息,请参阅 LLaVA: 大语言和视觉助手

Ollama 消息 API 提供了一个 “images ” 参数,用于将 base64 编码的图像列表与消息结合起来。

Spring AI 的消息接口通过引入媒体类型来促进多模态 AI 模型。这种类型利用 Spring 的 org.springframework.util.MimeTypeorg.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-03 11:43
最后编辑:Jeebiz  更新时间:2025-08-31 23:07