1- # Spring AI 완벽 가이드 (2025년 9월 기준)
1+ # Spring AI 1.0.1 완벽 가이드 (2025년 9월 기준)
22
33## 목차
441 . [ Spring AI란?] ( #spring-ai란 )
@@ -41,16 +41,16 @@ repositories {
4141 maven { url = uri(" https://repo.spring.io/snapshot" ) }
4242}
4343
44- extra[" springAiVersion" ] = " 1.0.0-M5 "
44+ extra[" springAiVersion" ] = " 1.0.1 "
4545
4646dependencies {
4747 // Spring Boot 기본
4848 implementation(" org.springframework.boot:spring-boot-starter-web" )
4949 implementation(" org.springframework.boot:spring-boot-starter-webflux" )
50-
51- // Spring AI - OpenAI
52- implementation(" org.springframework.ai:spring-ai-openai-spring-boot-starter " )
53-
50+
51+ // Spring AI - OpenAI (1.0.1 정식 버전)
52+ implementation(" org.springframework.ai:spring-ai-starter-model-openai " )
53+
5454 // 환경 변수 관리
5555 implementation(" io.github.cdimascio:dotenv-kotlin:6.4.1" )
5656}
@@ -68,14 +68,24 @@ dependencyManagement {
6868spring :
6969 ai :
7070 openai :
71- api-key : ${OPENAI_API_KEY }
72- # Groq 사용시
73- # base-url: https://api.groq.com/openai/v1
71+ api-key : ${GROQ_API_KEY }
72+ # Groq API 사용 (OpenAI 호환)
73+ base-url : https://api.groq.com/openai
7474 chat :
7575 options :
76- model : gpt-4o # 또는 gpt-3.5-turbo
76+ model : openai/ gpt-oss-120b # Groq의 오픈소스 모델
7777 temperature : 0.7
7878 max-tokens : 4096
79+
80+ # 또는 OpenAI 직접 사용시:
81+ # spring:
82+ # ai:
83+ # openai:
84+ # api-key: ${OPENAI_API_KEY}
85+ # chat:
86+ # options:
87+ # model: gpt-4o
88+ # temperature: 0.7
7989
8090logging :
8191 level :
@@ -264,22 +274,35 @@ fun openAiChatModel(): ChatModel {
264274}
265275```
266276
267- ### Groq (OpenAI 호환)
277+ ### Groq (OpenAI 호환) - 우리 프로젝트 설정
268278
269279``` kotlin
280+ // application.yml 설정만으로 간단하게 사용 가능
281+ spring:
282+ ai:
283+ openai:
284+ api- key: ${GROQ_API_KEY }
285+ base- url: https: // api.groq.com/openai # /v1 제거 (자동 추가됨)
286+ chat:
287+ options:
288+ model: openai/ gpt- oss- 120b # Groq 의 오픈소스 모델
289+ temperature: 0.7
290+ max- tokens: 4096
291+
292+ # 또는 프로그래밍 방식
270293@Bean
271294fun groqChatModel (): ChatModel {
272295 val api = OpenAiApi (
273- " https://api.groq.com/openai/v1 " ,
296+ " https://api.groq.com/openai" , # / v1 제거
274297 System .getenv(" GROQ_API_KEY" )
275298 )
276-
299+
277300 val options = OpenAiChatOptions .builder()
278- .model(" llama-3.3-70b-versatile " ) // Groq 모델
301+ .model(" openai/gpt-oss-120b " ) # 오픈소스 모델
279302 .temperature(0.7 )
280303 .maxTokens(4096 )
281304 .build()
282-
305+
283306 return OpenAiChatModel (api, options)
284307}
285308```
@@ -306,7 +329,75 @@ spring:
306329
307330## 실전 예제
308331
309- ### 날씨 조회 봇
332+ ### 실제 프로젝트 예제 (WeatherTool - 우리 프로젝트)
333+
334+ 우리 프로젝트에서 구현한 실제 WeatherTool 예제입니다:
335+
336+ ``` kotlin
337+ @Service
338+ class WeatherTool (
339+ private val webClient : WebClient ,
340+ @Value(" \$ {weather.api.key}" ) private val serviceKey : String ,
341+ @Value(" \$ {weather.api.base-url}" ) private val apiUrl : String
342+ ) {
343+
344+ @Tool(description = " 중기 날씨 예보를 조회합니다. 3-10일 후의 날씨, 기온, 강수 확률 정보를 제공합니다." )
345+ fun getWeatherForecast (
346+ @ToolParam(description = " 지역 이름 (예: 서울, 부산, 대구 등)" , required = false ) location : String? ,
347+ @ToolParam(description = " 지역 코드 (예: 11B10101)" , required = false ) regionCode : String? ,
348+ @ToolParam(description = " 발표 시각 (YYYYMMDDHHMM)" , required = false ) baseTime : String?
349+ ): WeatherResponse {
350+
351+ val actualLocation = location ? : " 서울"
352+ val actualRegionCode = regionCode ? : getRegionCodeFromLocation(actualLocation)
353+ val actualBaseTime = baseTime ? : getCurrentBaseTime()
354+
355+ return try {
356+ // 3개 기상청 API 통합 호출
357+ val midForecastResponse = fetchMidForecast(actualRegionCode, actualBaseTime).block()
358+ val temperatureResponse = fetchTemperature(actualRegionCode, actualBaseTime).block()
359+ val landForecastResponse = fetchLandForecast(actualRegionCode, actualBaseTime).block()
360+
361+ // 데이터 병합 및 처리
362+ val combinedForecast = combineWeatherData(
363+ midForecastText = midForecastResponse,
364+ temperatureData = temperatureResponse,
365+ landForecastData = landForecastResponse
366+ )
367+
368+ WeatherResponse (
369+ region = actualLocation,
370+ regionCode = actualRegionCode,
371+ baseTime = actualBaseTime,
372+ forecast = combinedForecast.summary,
373+ details = combinedForecast.details
374+ )
375+
376+ } catch (e: Exception ) {
377+ WeatherResponse (
378+ region = actualLocation,
379+ regionCode = actualRegionCode,
380+ baseTime = actualBaseTime,
381+ forecast = " 날씨 정보를 가져올 수 없습니다: \$ {e.message}" ,
382+ details = WeatherDetails ()
383+ )
384+ }
385+ }
386+
387+ // 3개 API 호출 메서드들
388+ private fun fetchMidForecast (regionId : String , baseTime : String ): Mono <String ?> { /* ... */ }
389+ private fun fetchTemperature (regionId : String , baseTime : String ): Mono <TemperatureData ?> { /* ... */ }
390+ private fun fetchLandForecast (regionId : String , baseTime : String ): Mono <PrecipitationData ?> { /* ... */ }
391+ }
392+ ```
393+
394+ ### 핵심 특징:
395+ - ** 3개 API 통합** : 기상청 getMidFcst, getMidTa, getMidLandFcst 활용
396+ - ** 지역 자동 변환** : "서울" → "11B10101" 지역코드 변환
397+ - ** 시간 자동 계산** : 현재 시간 기준 최신 발표시각 사용
398+ - ** 에러 처리** : API 실패시에도 안정적 응답 제공
399+
400+ ### 간단한 날씨 조회 봇
310401
311402``` kotlin
312403@Service
@@ -418,11 +509,19 @@ fun chatClient(chatModel: ChatModel, toolService: ToolService): ChatClient {
418509}
419510```
420511
421- ### 2. Groq API 사용시 주의사항
512+ ### 2. Groq API 사용시 주의사항 (우리 프로젝트 경험)
422513
423- - Function Calling 지원 여부 확인 필요
424- - 일부 모델은 Tool Calling 미지원
425- - OpenAI 호환 엔드포인트 사용: ` https://api.groq.com/openai/v1 `
514+ - ** URL 중복 문제** : ` base-url ` 에 ` /v1 ` 포함하면 ` /v1/v1/chat/completions ` 오류 발생
515+ ``` yaml
516+ # ❌ 잘못된 설정
517+ base-url : https://api.groq.com/openai/v1
518+
519+ # ✅ 올바른 설정
520+ base-url : https://api.groq.com/openai
521+ ` ` `
522+ - **모델명**: ` openai/gpt-oss-120b` 사용 (오픈소스 모델)
523+ - **Tool Calling**: Groq에서 @Tool 기능 정상 작동 확인
524+ - **응답 속도**: OpenAI보다 빠른 응답 속도
426525
427526# ## 3. 메모리 관리
428527
@@ -451,15 +550,28 @@ class ConversationMemory {
451550
452551- [Spring AI 공식 문서](https://docs.spring.io/spring-ai/reference/)
453552- [Spring AI GitHub](https://github.com/spring-projects/spring-ai)
454- - [ Spring AI 1.0.0-M5 릴리즈 노트] ( https://spring.io/blog/2024/12/23/spring-ai-1-0-0-m5-released/ )
553+ - [Spring AI 1.0.1 릴리즈 노트](https://spring.io/blog/2025/05/20/spring-ai-1-0-GA-released/)
554+ - [우리 프로젝트 GitHub](https://github.com/Mrbaeksang/spring-ai-weather-tool)
455555
456556---
457557
458558# # 버전 정보
459559
460- - ** Spring AI** : 1.0.0-M5 (2024년 12월 릴리즈)
560+ - **Spring AI**: 1.0.1 (2025년 5월 GA 릴리즈)
461561- **Spring Boot**: 3.5.5
462562- **Kotlin**: 1.9.25
563+ - **Groq API**: openai/gpt-oss-120b 모델
564+ - **기상청 API**: 중기예보조회서비스
463565- **작성일**: 2025년 9월
464566
465- > ⚠️ ** 주의** : Spring AI는 아직 마일스톤 버전입니다. GA(General Availability) 버전은 2025년 초 예정입니다.
567+ > ✅ **안정화**: Spring AI 1.0.1은 정식 GA(General Availability) 버전으로 프로덕션 환경에서 안전하게 사용 가능합니다.
568+
569+ # # 실제 프로젝트 적용 사례
570+
571+ 이 가이드의 모든 예제는 실제 동작하는 [spring-ai-weather-tool](https://github.com/Mrbaeksang/spring-ai-weather-tool) 프로젝트에서 검증되었습니다 :
572+
573+ - ✅ **Spring AI 1.0.1 + Groq API** 연동 완료
574+ - ✅ **@Tool 어노테이션** 기반 날씨 예보 서비스
575+ - ✅ **3개 기상청 API 통합** (중기전망, 기온, 강수)
576+ - ✅ **24개 지역 지원** 및 자동 지역코드 변환
577+ - ✅ **에러 처리** 및 안정적인 응답 제공
0 commit comments