跳到主要内容
版本:2.0.1

Docker 模型运行器聊天

QWen 3.8 中英对照 Docker Model Runner Docker Model Runner Chat

Docker Model Runner 是一个 AI 推理引擎,提供来自多家提供商的多种模型。

Spring AI 通过复用基于 OpenAI 的 ChatClient 与 Docker Model Runner 集成。为此,将基础 URL 设置为 [localhost:12434/engines/v1](http://localhost:12434/engines/v1),并从提供的 LLM 模型 中选择一个。

查看 DockerModelRunnerWithOpenAiChatModelIT.java 测试文件,了解如何在 Spring AI 中使用 Docker Model Runner 的示例。

前置条件​

  • 下载 Docker Desktop for Mac 4.40.0。

选择以下任一选项以启用 Model Runner:

选项 1:

  • 启用 Model Runner docker desktop enable model-runner --tcp 12434。
  • 将 base-url 设置为 [localhost:12434/engines/v1](http://localhost:12434/engines/v1)

选项 2:

  • 启用 Model Runner docker desktop enable model-runner。

  • 使用 Testcontainers,并按以下方式设置 base-url:

@Container
private static final DockerModelRunnerContainer DMR = new DockerModelRunnerContainer("alpine/socat:1.7.4.3-r0");

@Bean
public OpenAiChatModel chatModel() {
var baseUrl = DMR.getOpenAIEndpoint();
return OpenAiChatModel.builder()
.options(OpenAiChatOptions.builder().baseUrl(baseUrl).apiKey("test").build())
.build();
}

你可以通过阅读 Run LLMs Locally with Docker 博客文章,进一步了解 Docker Model Runner。

自动配置​

备注

自 1.0.0.M7 版本起,Spring AI starter 模块的 artifact ID 已重新命名。依赖名称现在应遵循针对 models、vector stores 以及 MCP starters 的更新命名模式。更多信息请参阅 升级说明。

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 聊天模型的重试机制。

PropertyDescriptionDefault
spring.ai.retry.max-attempts最大重试次数。10
spring.ai.retry.backoff.initial-interval指数退避策略的初始休眠时长。2 sec.
spring.ai.retry.backoff.multiplier退避间隔乘数。5
spring.ai.retry.backoff.max-interval最大退避时长。3 min.
spring.ai.retry.on-client-errors如果设置为 false,抛出 NonTransientAiException,并且不针对 4xx 客户端错误码尝试重试。false
spring.ai.retry.exclude-on-http-codes不应触发重试的 HTTP 状态码列表(例如,抛出 NonTransientAiException)。empty
spring.ai.retry.on-http-codes应触发重试的 HTTP 状态码列表(例如,抛出 TransientAiException)。empty

连接属性​

前缀 spring.ai.openai 用作属性前缀,用于连接到 OpenAI。

属性描述默认值
spring.ai.openai.base-url要连接的 URL。必须设置为 [localhost:12434/engines/v1](http://localhost:12434/engines/v1)-
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/v1](http://localhost:12434/engines/v1)-
spring.ai.openai.chat.api-keyOptional 用于覆盖 spring.ai.openai.api-key,以提供专门用于聊天的 api-key-
spring.ai.openai.chat.model要使用的 LLM 模型-
spring.ai.openai.chat.temperature控制生成补全内容表面创造性的采样温度。较高的值会使输出更加随机,而较低的值会使结果更加集中和确定。不建议在同一次补全请求中同时修改 temperature 和 top_p,因为这两个设置之间的相互作用难以预测。0.8
spring.ai.openai.chat.frequency-penalty取值范围在 -2.0 和 2.0 之间的数值。正值会根据新词元在迄今为止文本中已有的频率对其进行惩罚,从而降低模型逐字重复相同内容的概率。0.0f
spring.ai.openai.chat.max-tokens在聊天补全中生成令牌的 maximum 数量。输入令牌与生成令牌的总长度受模型的上下文长度限制。-
spring.ai.openai.chat.n为每个输入消息生成多少个聊天补全选项。请注意,费用将根据所有选项中生成的 token 总数计算。为了最小化成本,建议将 n 设置为 1。1
spring.ai.openai.chat.presence-penalty取值范围为 -2.0 到 2.0 之间的数值。正值会根据新标记在此前文本中是否出现对其进行惩罚,从而提高模型讨论新话题的可能性。-
spring.ai.openai.chat.response-format一个指定模型必须输出的格式的对象。设置为 { "type": "json_object" } 可启用 JSON 模式,该模式可保证模型生成的消息是有效的 JSON。-
spring.ai.openai.chat.seed此功能处于 Beta 阶段。如果指定了该参数,我们的系统将尽力进行确定性采样,使得在相同 seed 和参数下,重复的请求应返回相同的结果。-
spring.ai.openai.chat.stopAPI 停止生成更多 token 的最多 4 个序列。-
spring.ai.openai.chat.top-p一种替代温度采样的方法是核采样(nucleus sampling),其中模型仅考虑概率质量位于 top_p 范围内的 token 结果。例如,0.1 表示仅考虑占据前 10% 概率质量的 token。我们通常建议调整 top_p 或 temperature,但不建议同时调整两者。-
spring.ai.openai.chat.tools模型可以调用的工具列表。目前,仅支持将函数作为工具使用。使用此参数可提供模型可能生成 JSON 输入的一组函数。-
spring.ai.openai.chat.tool-choice控制模型调用哪个(如果有)函数。none 表示模型不会调用函数,而是生成一条消息。auto 表示模型可以在生成消息和调用函数之间自行选择。通过指定特定函数,例如 {"type: "function", "function": {"name": "my_function"}},可以强制模型调用该函数。在未提供函数时,none 是默认值。在提供函数时,auto 是默认值。-
spring.ai.openai.chat.user用于表示您的终端用户的唯一标识符,可帮助 OpenAI 监控并检测滥用行为。-
spring.ai.openai.chat.stream-usage(仅适用于流式传输)设置为 true 时,将在整个请求的最后添加一个包含 token 使用统计信息的额外块。此块的 choices 字段为空数组,并且所有其他块也将包含 usage 字段,但其值为 null。false
spring.ai.openai.chat.tool-callbacks要与 ChatModel 注册的 Tool Callbacks。-
提示

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

运行时选项​

OpenAiChatOptions.java 提供模型配置,例如要使用的模型、温度、频率惩罚等。

在启动时,默认选项可以通过 OpenAiChatModel(api, options) 构造函数或 spring.ai.openai.chat.* 属性进行配置。

在运行时,您可以通过向 Prompt 调用中添加新的、针对特定请求的选项来覆盖默认选项。例如,若要覆盖特定请求的默认模型和温度:

ChatResponse response = chatModel.call(
new Prompt(
"Generate the names of 5 famous pirates.",
OpenAiChatOptions.builder()
.model("ai/gemma3:4B-F16")
.build()
));
提示

除了模型特定的 OpenAiChatOptions 之外,你还可以使用一个可移植的 ChatOptions 实例,该实例通过 ChatOptions#builder() 创建。

工具调用​

Docker Model Runner 支持工具调用,前提是所选模型支持该功能。Spring AI 负责处理工具执行循环。

对于大多数应用,请搭配自动注册的 ToolCallingAdvisor 使用 ChatClient —— 请参阅 工具调用。若需要低级控制并由您自行驱动循环,请参阅 ChatModel 工具调用。

示例控制器​

创建 一个新的 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=http://localhost:12434/engines/v1
spring.ai.openai.chat.model=ai/gemma3:4B-F16

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

以下是一个使用聊天模型进行文本生成的简单 @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);
}
}