Docker 模型執行器聊天

Docker 模型執行器 是一個 AI 推理引擎,提供了來自 各種提供商 的廣泛模型。

Spring AI 透過重用現有的基於 OpenAIChatClient 來與 Docker 模型執行器整合。為此,請將基本 URL 設定為 localhost:12434/engines 並選擇一個提供的 LLM 模型

檢視 DockerModelRunnerWithOpenAiChatModelIT.java 測試,瞭解如何在 Spring AI 中使用 Docker 模型執行器。

先決條件

  • 下載適用於 Mac 的 Docker Desktop 4.40.0。

選擇以下選項之一來啟用模型執行器

選項 1

  • 啟用模型執行器 docker desktop enable model-runner --tcp 12434

  • 將 base-url 設定為 localhost:12434/engines

選項 2

  • 啟用模型執行器 docker desktop enable model-runner

  • 使用 Testcontainers 並按如下方式設定 base-url

@Container
private static final SocatContainer socat = new SocatContainer().withTarget(80, "model-runner.docker.internal");

@Bean
public OpenAiApi chatCompletionApi() {
	var baseUrl = "http://%s:%d/engines".formatted(socat.getHost(), socat.getMappedPort(80));
	return OpenAiApi.builder().baseUrl(baseUrl).apiKey("test").build();
}

您可以閱讀《使用 Docker 在本地執行 LLM》部落格文章,瞭解有關 Docker 模型執行器的更多資訊。

自動配置

自版本 1.0.0.M7 起,Spring AI starter 模組的 artifact ID 已更名。依賴名稱現在應遵循模型、向量儲存和 MCP starter 的更新命名模式。請參閱升級注意事項瞭解更多資訊。

Spring AI 為 OpenAI Chat Client 提供了 Spring Boot 自動配置。要啟用它,請將以下依賴項新增到專案的 Maven pom.xml 檔案中

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>

或將以下內容新增到您的 Gradle build.gradle 構建檔案中。

dependencies {
    implementation 'org.springframework.ai:spring-ai-starter-model-openai'
}
請參閱依賴管理部分,將 Spring AI BOM 新增到您的構建檔案中。

聊天屬性

重試屬性

字首 spring.ai.retry 用作屬性字首,允許您配置 OpenAI 聊天模型的重試機制。

屬性 描述 預設值

spring.ai.retry.max-attempts

最大重試次數。

10

spring.ai.retry.backoff.initial-interval

指數退避策略的初始等待時長。

2 秒。

spring.ai.retry.backoff.multiplier

退避間隔乘數。

5

spring.ai.retry.backoff.max-interval

最大退避時長。

3 分鐘。

spring.ai.retry.on-client-errors

如果為 false,則丟擲 NonTransientAiException,並且不對 4xx 客戶端錯誤程式碼進行重試

false

spring.ai.retry.exclude-on-http-codes

不應觸發重試的 HTTP 狀態碼列表(例如,丟擲 NonTransientAiException)。

spring.ai.retry.on-http-codes

應觸發重試的 HTTP 狀態碼列表(例如,丟擲 TransientAiException)。

連線屬性

字首 spring.ai.openai 用作屬性字首,允許您連線到 OpenAI。

屬性 描述 預設值

spring.ai.openai.base-url

要連線的 URL。必須設定為 hub.docker.com/u/ai

-

spring.ai.openai.api-key

任意字串

-

配置屬性

啟用和停用聊天自動配置現在透過帶有字首 spring.ai.model.chat 的頂級屬性完成。

要啟用,設定為 spring.ai.model.chat=openai(預設啟用)

要停用,設定為 spring.ai.model.chat=none(或任何與 openai 不匹配的值)

此更改允許在應用程式中配置多個模型。

字首 spring.ai.openai.chat 是屬性字首,允許您配置 OpenAI 的聊天模型實現。

屬性 描述 預設值

spring.ai.openai.chat.enabled(已移除且不再有效)

啟用 OpenAI 聊天模型。

true

spring.ai.model.chat

啟用 OpenAI 聊天模型。

openai

spring.ai.openai.chat.base-url

可選,覆蓋 spring.ai.openai.base-url 以提供特定於聊天的 URL。必須設定為 localhost:12434/engines

-

spring.ai.openai.chat.api-key

可選,覆蓋 spring.ai.openai.api-key 以提供特定於聊天的 API 金鑰

-

spring.ai.openai.chat.options.model

要使用的 LLM 模型

-

spring.ai.openai.chat.options.temperature

控制生成補全文字表觀創造性的取樣溫度。值越高,輸出越隨機;值越低,結果越聚焦和確定。不建議在同一補全請求中同時修改 temperature 和 top_p,因為這兩個設定的相互作用難以預測。

0.8

spring.ai.openai.chat.options.frequencyPenalty

-2.0 到 2.0 之間的數值。正值根據新 token 在文字中出現的頻率對其進行懲罰,從而降低模型重複相同文字的可能性。

0.0f

spring.ai.openai.chat.options.maxTokens

在聊天補全中生成的最大 token 數。輸入 token 和生成 token 的總長度受模型的上下文長度限制。

-

spring.ai.openai.chat.options.n

為每個輸入訊息生成多少個聊天補全選項。請注意,您將根據所有選項中生成的 token 總數付費。將 n 保持為 1 以最小化成本。

1

spring.ai.openai.chat.options.presencePenalty

-2.0 到 2.0 之間的數值。正值根據新 token 是否已出現在文字中對其進行懲罰,從而增加模型討論新主題的可能性。

-

spring.ai.openai.chat.options.responseFormat

指定模型必須輸出的格式的物件。設定為 { "type": "json_object" } 可啟用 JSON 模式,確保模型生成的訊息是有效的 JSON。

-

spring.ai.openai.chat.options.seed

此功能處於 Beta 階段。如果指定,我們的系統將盡最大努力進行確定性取樣,以便使用相同的 seed 和引數的重複請求應返回相同的結果。

-

spring.ai.openai.chat.options.stop

API 將停止生成更多 token 的最多 4 個序列。

-

spring.ai.openai.chat.options.topP

一種替代溫度取樣的核取樣方法,模型在該方法中考慮 top_p 機率質量的 token 結果。因此,0.1 表示僅考慮構成前 10% 機率質量的 token。我們通常建議修改 top_p 或 temperature,但不要同時修改兩者。

-

spring.ai.openai.chat.options.tools

模型可能呼叫的工具列表。目前,只支援將函式作為工具。使用此項提供模型可能生成 JSON 輸入的函式列表。

-

spring.ai.openai.chat.options.toolChoice

控制模型呼叫哪個(如果存在)函式。none 表示模型將不會呼叫函式,而是生成訊息。auto 表示模型可以在生成訊息或呼叫函式之間選擇。透過 {"type: "function", "function": {"name": "my_function"}} 指定特定函式會強制模型呼叫該函式。當不存在函式時,none 是預設值。如果存在函式,auto 是預設值。

-

spring.ai.openai.chat.options.user

表示您的終端使用者的唯一識別符號,可以幫助 OpenAI 監控和檢測濫用行為。

-

spring.ai.openai.chat.options.functions

函式列表,按名稱標識,用於在單個 prompt 請求中啟用函式呼叫。名稱與此列表匹配的函式必須存在於 functionCallbacks 登錄檔中。

-

spring.ai.openai.chat.options.stream-usage

(僅適用於流式傳輸)設定為新增一個包含整個請求 token 使用統計資訊的附加塊。此塊的 choices 欄位是一個空陣列,所有其他塊也將包含一個 usage 欄位,但值為 null。

false

spring.ai.openai.chat.options.proxy-tool-calls

如果為 true,Spring AI 將不會在內部處理函式呼叫,而是將其代理給客戶端。然後由客戶端負責處理函式呼叫,將其分派到適當的函式,並返回結果。如果為 false(預設值),Spring AI 將在內部處理函式呼叫。僅適用於支援函式呼叫的聊天模型。

false

所有以 spring.ai.openai.chat.options 為字首的屬性都可以在執行時透過向 Prompt 呼叫新增請求特定的執行時選項來覆蓋。

執行時選項

OpenAiChatOptions.java 提供了模型配置,例如要使用的模型、溫度、頻率懲罰等。

啟動時,可以使用 OpenAiChatModel(api, options) 建構函式或 spring.ai.openai.chat.options.* 屬性來配置預設選項。

在執行時,您可以透過向 Prompt 呼叫新增新的、特定於請求的選項來覆蓋預設選項。例如,為特定請求覆蓋預設模型和溫度

ChatResponse response = chatModel.call(
    new Prompt(
        "Generate the names of 5 famous pirates.",
        OpenAiChatOptions.builder()
            .model("ai/gemma3:4B-F16")
        .build()
    ));
除了特定於模型的 OpenAiChatOptions 外,您還可以使用透過 ChatOptions#builder() 建立的可移植 ChatOptions 例項。

函式呼叫

Docker 模型執行器在選擇支援工具/函式呼叫的模型時支援此功能。

您可以在 ChatModel 中註冊自定義 Java 函式,並讓提供的模型智慧選擇輸出包含引數的 JSON 物件,以呼叫一個或多個已註冊函式。這是將 LLM 能力與外部工具和 API 連線起來的強大技術。

工具示例

以下是一個使用 Docker 模型執行器函式呼叫與 Spring AI 的簡單示例

spring.ai.openai.api-key=test
spring.ai.openai.base-url=https://:12434/engines
spring.ai.openai.chat.options.model=ai/gemma3:4B-F16
@SpringBootApplication
public class DockerModelRunnerLlmApplication {

    public static void main(String[] args) {
        SpringApplication.run(DockerModelRunnerLlmApplication.class, args);
    }

    @Bean
    CommandLineRunner runner(ChatClient.Builder chatClientBuilder) {
        return args -> {
            var chatClient = chatClientBuilder.build();

            var response = chatClient.prompt()
                .user("What is the weather in Amsterdam and Paris?")
                .functions("weatherFunction") // reference by bean name.
                .call()
                .content();

            System.out.println(response);
        };
    }

    @Bean
    @Description("Get the weather in location")
    public Function<WeatherRequest, WeatherResponse> weatherFunction() {
        return new MockWeatherService();
    }

    public static class MockWeatherService implements Function<WeatherRequest, WeatherResponse> {

        public record WeatherRequest(String location, String unit) {}
        public record WeatherResponse(double temp, String unit) {}

        @Override
        public WeatherResponse apply(WeatherRequest request) {
            double temperature = request.location().contains("Amsterdam") ? 20 : 25;
            return new WeatherResponse(temperature, request.unit);
        }
    }
}

在此示例中,當模型需要天氣資訊時,它將自動呼叫 weatherFunction bean,該 bean 可以獲取即時天氣資料。預期響應為:“阿姆斯特丹目前的氣溫是 20 攝氏度,巴黎目前的氣溫是 25 攝氏度。”

瞭解更多關於 OpenAI 函式呼叫的資訊。

示例 Controller

建立 一個新的 Spring Boot 專案,並將 spring-ai-starter-model-openai 新增到您的 pom(或 gradle)依賴項中。

src/main/resources 目錄下新增一個 application.properties 檔案,以啟用和配置 OpenAI 聊天模型

spring.ai.openai.api-key=test
spring.ai.openai.base-url=https://:12434/engines
spring.ai.openai.chat.options.model=ai/gemma3:4B-F16

# Docker Model Runner doesn't support embeddings, so we need to disable them.
spring.ai.openai.embedding.enabled=false

這是一個簡單的 @Controller 類示例,它使用聊天模型進行文字生成。

@RestController
public class ChatController {

    private final OpenAiChatModel chatModel;

    @Autowired
    public ChatController(OpenAiChatModel chatModel) {
        this.chatModel = chatModel;
    }

    @GetMapping("/ai/generate")
    public Map 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);
    }
}