通过https://ollama.ai/[Ollama],您可以在本地运行各种大型语言模型(LLMs)并从中生成文本。Spring AI支持使用`OllamaChatClient`进行Ollama文本生成。

先决条件

首先,你需要在你的本地机器上运行Ollama。请参阅官方Ollama项目链接:https://github.com/jmorganca/ollama[README],以开始在你的本地机器上运行模型。

Note
安装`ollama run llama2`将会下载一个4GB的Docker镜像。

添加仓库和物料清单(BOM)

Spring AI 工件发布在 Spring Milestone 和 Snapshot 仓库中。请参考仓库部分,将这些仓库添加到你的构建系统中。

为了帮助依赖管理,Spring AI 提供了一个 BOM(物料清单),以确保在整个项目中使用一致的 Spring AI 版本。参考 依赖管理 部分将 Spring AI BOM 添加到您的构建系统中。

自动配置

Spring AI为Ollama聊天客户端提供了Spring Boot自动配置。要启用它,请在项目的Maven `pom.xml`文件中添加以下依赖:

<dependency>
   <groupId>org.springframework.ai</groupId>
   <artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
</dependency>

或添加到你的Gradle build.gradle 构建文件中。

dependencies {
    implementation 'org.springframework.ai:spring-ai-ollama-spring-boot-starter'
}
Tip
参考依赖管理部分,将Spring AI BOM添加到你的构建文件中。

聊天属性

前缀 spring.ai.ollama 是用来配置与Ollama连接的属性前缀。

Property Description Default

spring.ai.ollama.base-url

Base URL where Ollama API server is running.

http://localhost:11434

前缀 spring.ai.ollama.chat.options 是用于配置 Ollama 聊天客户端实现的属性前缀。

Note
options` 属性基于链接:https://github.com/jmorganca/ollama/blob/main/docs/modelfile.md#valid-parameters-and-values[Ollama 有效参数和值]和链接:https://github.com/jmorganca/ollama/blob/main/api/types.go[Ollama 类型]。默认值基于:链接:https://github.com/ollama/ollama/blob/b538dc3858014f94b099730a592751a5454cab0a/api/types.go#L364[Ollama 类型默认值]。
属性 描述 默认值

spring.ai.ollama.chat.enabled

启用Ollama聊天客户端。

true

spring.ai.ollama.chat.options.model

使用的支持模型的名称 https://github.com/ollama/ollama?tab=readme-ov-file#model-library。

mistral

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-gqa

变压器层中GQA组的数量。对某些模型(例如llama2:70b)是必需的,它是8。

1

spring.ai.ollama.chat.options.num-gpu

发送到GPU(s)的层数。在macOS上,默认为1以启用metal支持,0以禁用。这里的1表示NumGPU应该动态设置

-1

spring.ai.ollama.chat.options.main-gpu

???

-

spring.ai.ollama.chat.options.low-vram

???

false

spring.ai.ollama.chat.options.f16-kv

???

true

spring.ai.ollama.chat.options.logits-all

???

-

spring.ai.ollama.chat.options.vocab-only

???

-

spring.ai.ollama.chat.options.use-mmap

???

true

spring.ai.ollama.chat.options.use-mlock

???

false

spring.ai.ollama.chat.options.embedding-only

???

false

spring.ai.ollama.chat.options.rope-frequency-base

???

10000.0

spring.ai.ollama.chat.options.rope-frequency-scale

???

1.0

spring.ai.ollama.chat.options.num-thread

设置计算时使用的线程数。默认情况下,Ollama会检测这个数值以获得最佳性能。建议将此值设置为系统拥有的物理CPU核心数量(与逻辑核心数相对)。0 = 让运行时决定

0

spring.ai.ollama.chat.options.num-keep

???

0

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

Note
聊天选项列表需要被审核。这个链接 https://github.com/spring-projects/spring-ai/issues/230 [问题] 将会追踪进展。
Tip
所有以 spring.ai.ollama.chat.options 为前缀的属性可以在运行时被覆盖,方法是在 Prompt 调用中添加特定于请求的 运行时选项

运行时选项

'''The OllamaOptions.java provides model configurations, such as the model to use, the temperature, etc.''' 翻译成中文是:OllamaOptions.java提供了模型配置,例如使用的模型、温度等。

在启动时,可以使用`OllamaChatClient(api, options)`构造函数或`spring.ai.ollama.chat.options.*`属性来配置默认选项。

在运行时,你可以通过向`Prompt`调用添加新的、特定于请求的选项来覆盖默认选项。例如,为了覆盖特定请求的默认模型和温度:

ChatResponse response = chatClient.call(
    new Prompt(
        "Generate the names of 5 famous pirates.",
        OllamaOptions.create()
            .withModel("llama2")
            .withTemperature(0.4)
    ));
Tip
除了特定模型的链接:https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaOptions.java[OllamaOptions],您还可以使用一个可移植的https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptions.java[ChatOptions]实例,该实例是通过https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptionsBuilder.java[ChatOptionsBuilder#builder()]创建的。

样本控制器

https://start.spring.io/ 上[创建]一个新的Spring Boot项目,并在你的pom(或gradle)依赖项中添加`springs-ai-openai-spring-boot-starter`。

在`src/main/resources`目录下添加一个`application.properties`文件,以启用和配置OpenAi聊天客户端:

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

这将创建一个可以注入到你的类中的`OllamaChatClient`实现。以下是一个简单的使用聊天客户端进行文本生成的`@Controller`类的示例。

@RestController
public class ChatController {

private final OllamaChatClient chatClient;

@Autowired
    public ChatController(OllamaChatClient chatClient) {
        this.chatClient = chatClient;
    }

@GetMapping("/ai/generate")
    public Map generate(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
        return Map.of("generation", chatClient.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 chatClient.stream(prompt);
    }

}

手动配置

如果你不想使用Spring Boot的自动配置功能,你可以在应用程序中手动配置`OllamaChatClient`。访问 https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaChatClient.java 的[OllamaChatClient]实现了`ChatClient`和`StreamingChatClient`接口,并使用[low-level-api]连接到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'
}
Tip
参考依赖管理部分,将Spring AI BOM添加到你的构建文件中。
Tip
依赖项`spring-ai-ollama`也提供了对`OllamaEmbeddingClient`的访问。有关`OllamaEmbeddingClient`的更多信息,请参考链接:../embeddings/ollama-embeddings.html[Ollama 嵌入式客户端]部分。

接下来,创建一个`OllamaChatClient`实例并使用它来进行文本生成请求:

var ollamaApi = new OllamaApi();

var chatClient = new OllamaChatClient(ollamaApi).withModel(MODEL)
        .withDefaultOptions(OllamaOptions.create()
                .withModel(OllamaOptions.DEFAULT_MODEL)
                .withTemperature(0.9f));

ChatResponse response = chatClient.call(
    new Prompt("Generate the names of 5 famous pirates."));

// Or with streaming responses
Flux<ChatResponse> response = chatClient.stream(
    new Prompt("Generate the names of 5 famous pirates."));

OllamaOptions` 提供了所有聊天请求的配置信息。

底层的OpenAiApi客户端

链接:https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaApi.java[OllamaApi] 提供了一个轻量级的Java客户端用于Ollama聊天API链接:https://github.com/ollama/ollama/blob/main/docs/api.md#generate-a-chat-completion[Ollama聊天完成API]。

以下类图说明了`OllamaApi`聊天接口和构建模块:

OllamaApi 聊天完成 API 图表

这是一个关于如何以编程方式使用API的简单代码片段:

OllamaApi ollamaApi =
    new OllamaApi("YOUR_HOST:YOUR_PORT");

// 同步请求
var request = ChatRequest.builder("orca-mini")
    .withStream(false) // 不进行流处理
    .withMessages(List.of(
            Message.builder(Role.SYSTEM)
                .withContent("你是地理老师。你正在和一个学生交谈。")
                .build(),
            Message.builder(Role.USER)
                .withContent("保加利亚的首都是什么,面积有多大?"
                        + "国歌是什么?")
                .build()))
    .withOptions(OllamaOptions.create().withTemperature(0.9f))
    .build();

ChatResponse response = ollamaApi.chat(request);

'''
// Streaming request
var request2 = ChatRequest.builder("orca-mini")
    .withStream(true) // streaming
    .withMessages(List.of(Message.builder(Role.USER)
        .withContent("What is the capital of Bulgaria and what is the size? " + "What it the national anthem?")
        .build()))
    .withOptions(OllamaOptions.create().withTemperature(0.9f).toMap())
    .build();
'''

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