OpenAI 임베딩 설정
OpenAI 임베딩 설정
Spring AI는 OpenAI의 텍스트 임베딩 모델을 지원해요. 임베딩은 텍스트 문자열의 연관성을 측정하는 벡터(부동소수점 숫자 목록)예요. 두 벡터 사이의 거리가 작을수록 연관성이 크고, 클수록 연관성이 작다고 볼 수 있어요.
출처: 공식문서
사전 준비 (Prerequisites)
OpenAI 임베딩 모델에 접근하려면 OpenAI에서 API 키를 만들어야 해요. Spring AI는 spring.ai.openai.api-key 라는 설정 프로퍼티를 정의하고 있어요.
application.properties 파일에서 이렇게 설정할 수 있어요.
spring.ai.openai.api-key=<your-openai-api-key>
민감 정보를 다룰 때 보안을 높이려면 SpEL로 환경 변수를 참조할 수도 있어요.
# In application.yml spring: ai: openai: api-key: ${OPENAI_API_KEY}
# In your environment or .env file export OPENAI_API_KEY=<your-openai-api-key>
저장소와 BOM 추가
Spring AI 아티팩트는 Maven Central과 Spring Snapshot 저장소에 게시돼요. 저장소 추가 방법은 아티팩트 저장소, BOM 추가 방법은 의존성 관리 섹션을 참고하세요.
자동 설정 (Auto-Configuration)
Spring AI는 OpenAI 임베딩 모델에 대한 Spring Boot 자동 설정을 제공해요. 활성화하려면 Maven pom.xml에 spring-ai-starter-model-openai 의존성을 추가하면 돼요.
<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' }
재시도 프로퍼티 (Retry Properties)
spring.ai.retry 프리픽스로 OpenAI 임베딩 모델의 재시도 메커니즘을 설정해요.
| Property | Description | Default |
|---|---|---|
| spring.ai.retry.max-attempts | Maximum number of retry attempts. | 10 |
| spring.ai.retry.backoff.initial-interval | Initial sleep duration for the exponential backoff policy. | 2 sec. |
| spring.ai.retry.backoff.multiplier | Backoff interval multiplier. | 5 |
| spring.ai.retry.backoff.max-interval | Maximum backoff duration. | 3 min. |
| spring.ai.retry.on-client-errors | If false, throw a NonTransientAiException, and do not attempt retry for 4xx client error codes |
false |
| spring.ai.retry.exclude-on-http-codes | List of HTTP status codes that should not trigger a retry. | empty |
| spring.ai.retry.on-http-codes | List of HTTP status codes that should trigger a retry. | empty |
연결 프로퍼티 (Connection Properties)
OpenAI에 연결하는 설정은 spring.ai.openai 프리픽스를 사용해요.
| Property | Description | Default |
|---|---|---|
| spring.ai.openai.base-url | The URL to connect to | https://api.openai.com |
| spring.ai.openai.api-key | The API Key | - |
| spring.ai.openai.organization-id | Optionally you can specify which organization used for an API request. | - |
| spring.ai.openai.project-id | Optionally, you can specify which project is used for an API request. | - |
여러 조직에 속해 있거나 레거시 사용자 API 키로 여러 프로젝트에 접근하는 경우, 특정 organization/project를 지정할 수 있고 그 요청의 사용량은 지정한 organization/project로 집계돼요.
설정 프로퍼티 (Configuration Properties)
임베딩 자동 설정의 켜고 끔은 spring.ai.model.embedding 프리픽스로 제어해요. 켜려면 spring.ai.model.embedding=openai(기본값), 끄려면 spring.ai.model.embedding=none으로 설정하면 돼요.
OpenAI EmbeddingModel 구현을 설정하는 프리픽스는 spring.ai.openai.embedding 이에요.
| Property | Description | Default |
|---|---|---|
| spring.ai.model.embedding | Enable OpenAI embedding model. | openai |
| spring.ai.openai.embedding.base-url | Optional overrides the spring.ai.openai.base-url to provide embedding specific url | - |
| spring.ai.openai.embedding.api-key | Optional overrides the spring.ai.openai.api-key to provide embedding specific api-key | - |
| spring.ai.openai.embedding.organization-id | Optionally you can specify which organization used for an API request. | - |
| spring.ai.openai.embedding.project-id | Optionally, you can specify which project is used for an API request. | - |
| spring.ai.openai.embedding.metadata-mode | Document content extraction mode. | EMBED |
| spring.ai.openai.embedding.model | The model to use | text-embedding-ada-002 (other options: text-embedding-3-large, text-embedding-3-small) |
| spring.ai.openai.embedding.encoding-format | The format to return the embeddings in. Can be either float or base64. | - |
| spring.ai.openai.embedding.user | A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. | - |
| spring.ai.openai.embedding.dimensions | The number of dimensions the resulting output embeddings should have. Only supported in text-embedding-3 and later models. |
- |
공통 spring.ai.openai.base-url과 spring.ai.openai.api-key를 ChatModel과 EmbeddingModel 구현에서 각각 덮어쓸 수 있어요. spring.ai.openai.embedding.base-url/.embedding.api-key를 설정하면 공통 프로퍼티보다 우선하고, spring.ai.openai.chat.base-url/.chat.api-key도 마찬가지예요. 서로 다른 OpenAI 계정·엔드포인트를 모델별로 쓰고 싶을 때 유용해요.
spring.ai.openai.embedding으로 시작하는 모든 프로퍼티는 런타임 옵션을 EmbeddingRequest 호출에 추가해 실행 시점에 덮어쓸 수 있어요. 기본 옵션은 spring.ai.openai.embedding.options 프로퍼티로도 설정할 수 있어요.
시작 시점에는 OpenAiEmbeddingModel 생성자로 모든 임베딩 요청의 기본 옵션을 설정하고, 런타임에는 OpenAiEmbeddingOptions 인스턴스를 EmbeddingRequest의 일부로 사용해 특정 요청의 기본 옵션을 덮어쓸 수 있어요.
특정 요청의 기본 모델 이름을 덮어쓰는 예시예요.
EmbeddingResponse embeddingResponse = embeddingModel.call( new EmbeddingRequest(List.of("Hello World", "World is big and salvation is near"), OpenAiEmbeddingOptions.builder() .model("Different-Embedding-Model-Deployment-Name") .build()));
샘플 컨트롤러
이렇게 하면 클래스에 주입할 수 있는 EmbeddingModel 구현이 만들어져요. EmbeddingModel 구현을 쓰는 간단한 @Controller 클래스 예시예요.
spring.ai.openai.api-key=YOUR_API_KEY spring.ai.openai.embedding.model=text-embedding-ada-002
@RestController public class EmbeddingController { private final EmbeddingModel embeddingModel; @Autowired public EmbeddingController(EmbeddingModel embeddingModel) { this.embeddingModel = embeddingModel; } @GetMapping("/ai/embedding") public Map embed(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) { EmbeddingResponse embeddingResponse = this.embeddingModel.embedForResponse(List.of(message)); return Map.of("embedding", embeddingResponse); } }
수동 설정 (Manual Configuration)
Spring Boot를 쓰지 않는다면 OpenAI 임베딩 모델을 직접 구성할 수 있어요. spring-ai-openai 의존성을 Maven pom.xml에 추가하면 돼요.
<dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-openai</artifactId> </dependency>
또는 Gradle build.gradle:
dependencies { implementation 'org.springframework.ai:spring-ai-openai' }
그 다음 OpenAiEmbeddingModel 인스턴스를 만들고 두 입력 텍스트 사이의 유사도를 계산해요.
var embeddingModel = new OpenAiEmbeddingModel( MetadataMode.EMBED, OpenAiEmbeddingOptions.builder() .apiKey(System.getenv("OPENAI_API_KEY")) .model("text-embedding-ada-002") .user("user-6") .build()); EmbeddingResponse embeddingResponse = this.embeddingModel .embedForResponse(List.of("Hello World", "World is big and salvation is near"));
OpenAiEmbeddingOptions는 임베딩 요청에 대한 설정 정보를 제공해요. api와 options 클래스는 손쉬운 옵션 생성용 builder()를 제공해요.
HTTP 클라이언트 커스터마이징
Spring AI는 내부적으로 공식 openai-java SDK를 쓰고, SpringAiOpenAiHttpClient.Builder가 만든 커스텀 OkHttp 클라이언트로 HTTP 전송을 구성해요. 하나 이상의 OpenAiHttpClientBuilderCustomizer 빈을 노출해서 기반 OkHttpClient가 만들어지기 전에 그 빌더를 가로챌 수 있어요. 각 커스터마이저는 모든 OpenAI 모델(채팅, 임베딩, 이미지, 오디오, moderation)이 쓰는 같은 빌더를 받으므로 커스터마이징이 일관되게 적용돼요.
@FunctionalInterface public interface OpenAiHttpClientBuilderCustomizer { void customize(SpringAiOpenAiHttpClient.Builder builder); }
대표적인 사용 사례는 다음과 같아요.
- OkHttp
Interceptor등록(인증, 헤더 전파, 커스텀 로깅) - dispatcher
ExecutorService교체(예: async I/O를 가상 스레드로 라우팅) - 프록시, SSL, 호스트명 검증, 빌더가 노출하는 커넥션 풀 크기 구성
커스터마이저가 여러 개면 @Order/Ordered 순서로 Spring AI 기본값 다음에 적용되므로 사용자 코드가 이겨요. 같은 훅은 OpenAi*Model.Builder로 모델을 수동으로 연결할 때도 쓸 수 있어요.
var chatModel = OpenAiChatModel.builder() .options(OpenAiChatOptions.builder().model("gpt-4o").build()) .httpClientBuilderCustomizer(myCustomizer) .build();