OpenAI Chat
OpenAI Chat
Spring AI는 ChatGPT를 만든 회사인 OpenAI의 다양한 AI 언어 모델을 지원해요. OpenAI는 업계를 선도하는 텍스트 생성 모델과 임베딩을 만들어 AI 기반 텍스트 생성에 대한 관심을 촉발한 회사로 잘 알려져 있어요.
출처: 공식문서
2.0.0-M5부터 Spring AI는 모든 OpenAI 모델에 공식 openai-java SDK를 사용해요. 전환은 매끄러울 것으로 예상되며, 기존 OpenAI API 속성과 빌더 사용자에게는 깨지는 변경이 없어요. 문제를 발견하면 Spring AI GitHub Issues에 보고해주세요.
사전 준비
ChatGPT 모델에 접근하려면 OpenAI에서 API 키를 만들어야 해요.
Spring AI 프로젝트는 spring.ai.openai.api-key라는 구성 속성을 정의하는데, openai.com에서 얻은 API Key 값을 이 속성에 설정하면 돼요. application.properties 파일에 다음과 같이 설정해요.
spring.ai.openai.api-key=<your-openai-api-key>
API 키 같은 민감 정보를 다룰 때 보안을 강화하려면 Spring Expression Language(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>
애플리케이션 코드에서 프로그래밍 방식으로도 설정할 수 있어요.
// Retrieve API key from a secure source or environment variable
String apiKey = System.getenv("OPENAI_API_KEY");
저장소와 BOM 추가
Spring AI 아티팩트는 Maven Central과 Spring Snapshot 저장소에 게시돼요. Artifact Repositories 섹션을 참고해 빌드 시스템에 저장소를 추가해요. 의존성 관리를 위해 Spring AI는 일관된 버전을 보장하는 BOM을 제공해요. Dependency Management 섹션을 참고해 추가해요.
자동 설정 (Auto-configuration)
Spring AI의 자동 설정과 스타터 모듈의 아티팩트 이름이 크게 바뀌었어요. 자세한 내용은 업그레이드 노트를 확인해주세요.
Spring AI는 OpenAI 채팅 클라이언트를 위한 Spring Boot 자동 설정을 제공해요. Maven pom.xml이나 Gradle build.gradle에 다음 의존성을 추가하면 돼요.
- Maven
- Gradle
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
dependencies {
implementation 'org.springframework.ai:spring-ai-starter-model-openai'
}
채팅 속성 (Chat Properties)
재시도 속성
| 속성 | 설명 | 기본값 |
|---|---|---|
| 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 상태 코드 목록 | empty |
| spring.ai.retry.on-http-codes | 재시도를 트리거해야 하는 HTTP 상태 코드 목록 | empty |
연결 속성
| 속성 | 설명 | 기본값 |
|---|---|---|
| spring.ai.openai.base-url | 연결할 URL | |
| spring.ai.openai.api-key | API 키 | - |
| spring.ai.openai.organization-id | 선택적으로 API 요청에 사용할 조직 지정 | - |
| spring.ai.openai.project-id | 선택적으로 API 요청에 사용할 프로젝트 지정 | - |
| spring.ai.openai.timeout | OpenAI 클라이언트의 요청 타임아웃 | 60 sec. |
| spring.ai.openai.max-retries | OpenAI 클라이언트의 최대 재시도 횟수 | 3 |
| spring.ai.openai.proxy | OpenAI 클라이언트의 프록시 설정 | - |
| spring.ai.openai.custom-headers | OpenAI 클라이언트 요청에 추가할 사용자 정의 HTTP 헤더 | empty |
| spring.ai.openai.connection-pool-metrics-enabled | 기본 OkHttp 클라이언트의 연결 풀 메트릭 활성화 여부 | false |
여러 조직에 속한 사용자(또는 레거시 사용자 API 키로 프로젝트에 접근하는 사용자)는 API 요청에 어떤 조직·프로젝트를 사용할지 선택적으로 지정할 수 있어요. 이 요청들의 사용량은 지정된 조직·프로젝트로 집계돼요.
User-Agent 헤더
Spring AI는 모든 OpenAI 요청에 User-Agent: spring-ai 헤더를 자동으로 보내요. 이는 OpenAI가 분석·지원 목적으로 Spring AI에서 온 요청을 식별하는 데 도움을 줘요. 이 헤더는 자동으로 보내지며 Spring AI 사용자가 별도로 구성할 필요가 없어요.
OpenAI 호환 서비스를 만드는 API 제공자라면 서버에서 수신 요청의 User-Agent HTTP 헤더를 읽어 Spring AI 사용량을 추적할 수 있어요.
구성 속성
채팅 자동 설정의 활성·비활성은 프리픽스 spring.ai.model.chat로 관리해요. 활성화하려면 spring.ai.model.chat=openai(기본값), 비활성화하려면 spring.ai.model.chat=none을 쓰면 돼요.
| 속성 | 설명 | 기본값 |
|---|---|---|
| spring.ai.openai.chat.enabled (제거됨, 더는 유효하지 않음) | OpenAI 채팅 모델 활성화 | true |
| spring.ai.model.chat | OpenAI 채팅 모델 활성화 | openai |
| spring.ai.openai.chat.base-url | chat 전용 URL을 제공하기 위한 선택적 재정의 | - |
| spring.ai.openai.chat.api-key | chat 전용 API 키를 제공하기 위한 선택적 재정의 | - |
| spring.ai.openai.chat.organization-id | 선택적으로 API 요청에 사용할 조직 지정 | - |
| spring.ai.openai.chat.project-id | 선택적으로 API 요청에 사용할 프로젝트 지정 | - |
| spring.ai.openai.chat.model | 사용할 OpenAI 채팅 모델 이름. gpt-5-mini, gpt-4o, gpt-4o-mini, gpt-4-turbo, gpt-3.5-turbo 등에서 선택. models 페이지 참고 |
gpt-5-mini |
| 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.logit-bias | 특정 토큰이 생성에서 나타날 가능성 수정 | - |
| spring.ai.openai.chat.max-tokens | 채팅 완료에서 생성할 최대 토큰 수. 비-reasoning 모델(예: gpt-4o, gpt-3.5-turbo)용. reasoning 모델(예: o1, o3, o4-mini 시리즈)에는 사용 불가. maxCompletionTokens와 상호 배타적 — 둘 다 설정하면 API 오류 | - |
| spring.ai.openai.chat.max-completion-tokens | 완료에서 생성 가능한 토큰 수의 상한(가시적 출력 토큰과 reasoning 토큰 포함). reasoning 모델에 필수. 비-reasoning 모델에는 사용 불가. maxTokens와 상호 배타적 | - |
| spring.ai.openai.chat.n | 각 입력 메시지에 대해 생성할 채팅 완료 선택지 수. 모든 선택지의 생성 토큰 수 기준 과금. 비용 최소화를 위해 n을 1로 유지 |
1 |
| spring.ai.openai.chat.store | 이 채팅 완료 요청의 출력을 모델에 사용하기 위해 저장할지 여부 | false |
| spring.ai.openai.chat.metadata | 채팅 완료 대시보드에서 완료를 필터링하는 데 쓰는 개발자 정의 태그·값 | empty map |
| spring.ai.openai.chat.output-modalities | 이 요청에 모델이 생성하기를 원하는 출력 유형. 대부분 모델은 텍스트(기본)를 생성. gpt-audio 모델은 오디오도 생성 가능. 텍스트와 오디오 응답 모두 요청하려면 text, audio 사용. 스트리밍은 미지원 |
- |
| spring.ai.openai.chat.output-audio | 오디오 생성용 오디오 파라미터. output-modalities: audio와 함께 오디오 출력 요청 시 필요. gpt-audio 모델 필요, 스트리밍 완성 미지원 |
- |
| spring.ai.openai.chat.presence-penalty | -2.0 ~ 2.0 사이 숫자. 양수는 새 토큰이 지금까지의 텍스트에 나타나는지 여부를 기준으로 페널티해 새 주제에 대해 말할 가능성을 높임 | - |
| spring.ai.openai.chat.response-format.type | GPT-4o, GPT-4o mini, GPT-4 Turbo, gpt-3.5-turbo-1106보다 새로운 모든 GPT-3.5 Turbo 모델과 호환. JSON_OBJECT 유형은 JSON 모드를 켜서 모델이 생성하는 메시지가 유효한 JSON임을 보장. JSON_SCHEMA 유형은 Structured Outputs를 켜서 제공한 JSON 스키마와 일치함을 보장. JSON_SCHEMA 유형은 responseFormat.schema 속성도 설정해야 함 |
- |
| spring.ai.openai.chat.response-format.name | 응답 형식 스키마 이름. responseFormat.type=JSON_SCHEMA일 때만 적용 |
custom_schema |
| spring.ai.openai.chat.response-format.schema | 응답 형식 JSON 스키마. responseFormat.type=JSON_SCHEMA일 때만 적용 |
- |
| spring.ai.openai.chat.response-format.strict | 응답 형식 JSON 스키마 준수 엄격성. responseFormat.type=JSON_SCHEMA일 때만 적용 |
- |
Reasoning 콘텐츠 접근
reasoning 모델(예: o1, o3 계열, DeepSeek R1 같은 사고 과정을 노출하는 모델)은 최종 답변과 별도로 모델의 추론 과정을 포함하는 reasoning_content를 반환할 수 있어요. Spring AI는 reasoningContent라는 메타데이터 키로 이 내용을 노출해요.
reasoning_content의 가용성은 전적으로 사용 중인 추론 서버에 달려 있어요. reasoning 가능 모델을 쓰더라도 모든 OpenAI 호환 서버가 reasoning 콘텐츠를 노출하는 건 아니에요. 응답에 어떤 필드가 있는지 항상 서버의 API 문서를 참고하세요.