Search
🤖

AI 버티컬 서비스 — OpenAI 연동 배치 시스템

개요

항목
내용
기간
2025.03 ~ 2025.05
역할
API 및 배치 시스템 구현 담당
기술 스택
Kotlin, Spring Boot, OpenAI Batch API

배경

다나와 가격비교 플랫폼에서 상품 데이터를 기반으로 AI가 생성한 추천 문구를 제공하는 서비스를 구축해야 했습니다. 관리자가 다양한 컨셉의 프롬프트를 설정하고, 카테고리별로 추천 문구를 자동 생성하여 API로 제공하는 시스템이 필요했습니다.

문제

관리자가 프롬프트와 대상 카테고리를 설정할 수 있어야 함
주 단위로 추천 문구를 갱신하는 배치 시스템이 필요
카테고리 간 인기 상품이 겹치는 경우 중복 처리가 필요
AI 응답의 품질을 검증할 수 있는 프로세스가 필요
OpenAI API 호출 비용을 최적화해야 함

무엇을 했나

시스템 아키텍처

flowchart TD
    A[관리자 페이지] -->|프롬프트 & 카테고리 설정| B[관리자 API]
    B --> C[배치 스케줄러<br>주 1회]
    C --> D[상품 데이터 조회]
    D --> E[카테고리 간 중복 제거]
    E --> F[OpenAI Batch API 호출]
    F --> G[1분 주기 폴링]
    G --> H{결과 확인}
    H -->|성공| I[파싱 & 저장]
    H -->|파싱 실패| J[해당 건만 실패 처리]
    H -->|미완료| G
    I --> K[추천 문구 API 제공]
Mermaid
복사

구현 상세

1. OpenAI Batch API 활용
실시간 API 대신 Batch API(24시간 내 처리 보장)를 선택한 이유: OpenAI 공식 정책상 Batch API는 실시간 API 대비 토큰당 비용 50% 할인
Spring Cloud OpenFeign으로 OpenAI API 클라이언트를 선언적으로 정의하여 외부 API 연동 코드 간결화
Kotlin의 tailrec(꼬리 재귀)를 활용하여 배치 상태 폴링을 구현 — 컴파일러가 반복문으로 변환하여 스택 오버플로우 없이 장시간 폴링 가능
1분 주기 폴링으로 처리 결과를 확인하고, 배치 상태(COMPLETED, IN_PROGRESS, VALIDATING, FINALIZING)에 따라 분기 처리
2. 프롬프트 최적화
토큰 소비를 줄이면서도 품질을 유지하기 위해 프롬프트 튜닝 수행
3. 품질 검증 — 블라인드 테스트
같은 상품 목록에 대해 서로 다른 프롬프트로 각각 n회차 돌린 뒤 토큰 소모량 평균 측정
샘플링한 프롬프트 결과로 기획자와 개발자 동료들과의 블라인드 테스트 수행
프롬프트 결과에 대한 평가는 유의미한 퀄리티 차이가 없었지만, 토큰 사용량은 10% 정도 절감함.
4. AI 응답 포맷 불일치 처리
AI 응답은 \n\n으로 구분된 3개의 문장으로 구성되어야 하지만, 간혹 포맷이 다른 응답이 발생
3개가 아닌 경우 null을 반환하고 mapNotNull로 걸러내어, 전체 배치를 실패 처리하지 않고 해당 건만 개별 제외
// AI 응답 포맷 검증 private fun parseResponse(response: String): List<String>? { val lines = response.split("\n\n") return if (lines.size == 3) { lines.map { it.trim() } } else { null // 포맷 불일치 → 해당 건만 제외 } }
Kotlin
복사
5. 상품 중복 제거
카테고리 간 인기 상품이 겹치는 경우 distinctBy { it.productCode }로 상품 코드 기준 중복 제거 후 배치 파일 생성
6. 배치 로그 기록
각 배치 요청별로 요청/응답 토큰 수, 문자 수, finish reason 등을 DB에 기록
이 로그를 통해 프롬프트 별 토큰 소비량을 정량적으로 비교할 수 있었고, 이것이 블라인드 테스트의 근거 데이터가 됨

결과

성과

프롬프트 최적화를 통해 품질 저하 없이 토큰 사용량 약 10% 절감
파싱 실패 건을 개별 처리하여 배치 전체 실패율 0% 유지
OpenAI Batch API 활용으로 실시간 API 대비 토큰당 비용 50% 절감 (OpenAI Batch API 공식 정책 기준)
관리자가 프롬프트와 카테고리를 직접 설정할 수 있어 기획자의 자율도가 높아짐
블라인드 테스트를 통해 프롬프트 품질을 객관적으로 검증하는 프로세스를 확립

배운 점

AI 응답은 항상 동일한 포맷으로 돌아오지 않으므로, 파싱 실패를 정상 흐름의 일부로 간주하고 개별 재처리하는 방어적 설계가 중요함
토큰을 줄이면 비용은 내려가지만 품질도 내려갈 수 있어서, 블라인드 테스트 같은 객관적 검증 수단이 있어야 의사결정이 가능함
24시간 내 처리를 보장하는 외부 API와 연동할 때, 폴링 주기/타임아웃/부분 실패 처리 등 방어적 설계가 필수적이라는 걸 체감함