Docker Model Runner 채팅
Docker Model Runner 채팅 (Docker Model Runner Chat)
Docker Model Runner는 다양한 제공자의 광범위한 모델을 제공하는 AI 추론 엔진이에요. Spring AI는 기존의 OpenAI 기반 ChatClient를 재사용해 Docker Model Runner와 통합해요. base URL을 localhost:12434/engines/v1로 설정하고 제공되는 LLM 모델 중 하나를 선택하면 되죠. 이 글에서는 Docker Model Runner를 활성화하고 Spring AI와 함께 사용하는 방법을 알아볼게요.
출처: 문서
본문
Docker Model Runner는 다양한 제공자의 광범위한 모델을 제공하는 AI 추론 엔진(AI Inference Engine)이에요.
Spring AI는 기존 OpenAI 기반 ChatClient를 재사용해 Docker Model Runner와 통합해요. 이를 위해 base URL을 [localhost:12434/engines/v1](<http://localhost:12434/engines/v1>)로 설정하고 제공되는 LLM 모델 중 하나를 선택하세요.
Spring AI와 함께 Docker Model Runner를 사용하는 예제는 DockerModelRunnerWithOpenAiChatModelIT.java 테스트를 확인해보세요.
Prerequisite
- Mac용 Docker Desktop 4.40.0을 다운로드하세요.
다음 옵션 중 하나를 선택해 Model Runner를 활성화하세요:
Option 1:
-
Model Runner 활성화
docker desktop enable model-runner --tcp 12434. -
base-url을
[localhost:12434/engines/v1](<http://localhost:12434/engines/v1>)로 설정하세요
Option 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(); }
Docker Model Runner에 대해 더 자세히 알고 싶다면 Run LLMs Locally with Docker 블로그 글을 읽어보세요.
Auto-configuration
| __ | Spring AI 스타터 모듈의 artifact ID는 1.0.0.M7부터 이름이 바뀌었어요. 의존성 이름은 이제 모델, 벡터 저장소, MCP 스타터에 대한 업데이트된 명명 패턴을 따라야 해요. 자세한 내용은 upgrade notes를 참고하세요. |
|---|
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을 추가하려면 Dependency Management 섹션을 참고해주세요. |
|---|
Chat Properties
Retry Properties
프리픽스 spring.ai.retry는 OpenAI 채팅 모델의 재시도 메커니즘을 구성할 수 있게 해주는 프로퍼티 프리픽스예요.
| Property | Description | Default |
|---|---|---|
| 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면 4xx 클라이언트 오류 코드에 대해 NonTransientAiException을 던지고 재시도하지 않음 |
false |
| spring.ai.retry.exclude-on-http-codes | 재시도를 유발하지 않아야 하는 HTTP 상태 코드 목록 (예: NonTransientAiException을 던지기 위해). | empty |
| spring.ai.retry.on-http-codes | 재시도를 유발해야 하는 HTTP 상태 코드 목록 (예: TransientAiException을 던지기 위해). | empty |
Connection Properties
프리픽스 spring.ai.openai는 OpenAI에 연결할 수 있게 해주는 프로퍼티 프리픽스예요.
| Property | Description | Default |
|---|---|---|
| spring.ai.openai.base-url | 연결할 URL. [localhost:12434/engines/v1](<http://localhost:12434/engines/v1>)로 설정해야 해요 |
- |
| spring.ai.openai.api-key | 아무 문자열이나 | - |
Configuration Properties
| __ | 채팅 자동 설정의 활성화/비활성화는 이제 프리픽스 spring.ai.model.chat이 붙은 최상위 프로퍼티로 수행해요. 활성화하려면 spring.ai.model.chat=openai (기본값으로 활성화됨). 비활성화하려면 spring.ai.model.chat=none (또는 openai와 일치하지 않는 어떤 값). 이 변경은 애플리케이션에서 여러 모델을 설정할 수 있게 해줘요. |
|---|
프리픽스 spring.ai.openai.chat은 OpenAI의 채팅 모델 구현을 구성할 수 있게 해주는 프로퍼티 프리픽스예요.
| Property | Description | Default |
|---|---|---|
| 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-key | 선택적으로 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 | 채팅 완성에서 생성할 최대 토큰 수. 입력 토큰과 생성 토큰의 총 길이는 모델의 컨텍스트 길이로 제한돼요. | - |
| spring.ai.openai.chat.n | 각 입력 메시지에 대해 생성할 채팅 완성 선택지 수. 모든 선택지에 걸쳐 생성된 토큰 수에 따라 요금이 부과된다는 점에 유의하세요. 비용을 최소화하려면 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 | 이 기능은 베타입니다. 지정하면 시스템이 결정적으로 샘플링하도록 최선을 다해, 동일한 seed와 매개변수로 반복 요청 시 같은 결과를 반환해야 해요. | - |
| spring.ai.openai.chat.stop | API가 더 이상 토큰을 생성하지 않을 최대 4개의 시퀀스. | - |
| spring.ai.openai.chat.top-p | temperature를 사용한 샘플링의 대안인 nucleus sampling으로, 모델이 top_p 확률 질량을 가진 토큰들의 결과를 고려해요. 즉 0.1은 상위 10% 확률 질량을 구성하는 토큰만 고려한다는 뜻이에요. 일반적으로 이 값이나 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 | (스트리밍 전용) 전체 요청에 대한 토큰 사용량 통계가 포함된 추가 청크를 추가하도록 설정. 이 청크의 choices 필드는 빈 배열이고, 다른 모든 청크도 usage 필드를 포함하지만 null 값이에요. |
false |
| spring.ai.openai.chat.tool-callbacks | ChatModel에 등록할 Tool Callbacks. | - |
| __ | spring.ai.openai.chat 프리픽스가 붙은 모든 프로퍼티는 런타임에 Prompt 호출에 요청별 Runtime Options를 추가해 재정의할 수 있어요. |
|---|
Runtime Options
OpenAiChatOptions.java는 사용할 모델, temperature, frequency penalty 등 모델 구성을 제공해요.
시작 시 기본 옵션은 OpenAiChatModel(api, options) 생성자나 spring.ai.openai.chat.* 프로퍼티로 구성할 수 있어요.
런타임에는 Prompt 호출에 새 요청별 옵션을 추가해 기본 옵션을 재정의할 수 있어요. 예를 들어 특정 요청의 기본 모델과 temperature를 재정의하려면:
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 인스턴스를 사용할 수도 있어요. |
|---|
Tool Calling
Docker Model Runner는 선택한 모델이 지원할 때 툴 호출을 지원해요. Spring AI가 툴 실행 루프를 처리해요.
대부분의 애플리케이션에서는 자동 등록된 ToolCallingAdvisor와 함께 ChatClient를 사용하세요 — Tool Calling 참고. 루프를 직접 제어하는 저수준 제어가 필요하다면 ChatModel Tool Calling을 참고하세요.
Sample Controller
새 Spring Boot 프로젝트를 만들고, pom(또는 gradle) 의존성에 spring-ai-starter-model-openai를 추가하세요.
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);
}
}