콘텐츠로 이동

OpenAI 클라이언트 구현

  • OpenAI API(gpt-4o)를 활용한 검색어 확장 기능 구현
  • 기존 Ollama 클라이언트와 동일한 인터페이스 제공
  • 토큰 사용량 및 비용 추적 기능
파일설명
app/services/openai_client.pyOpenAI API 클라이언트
app/services/llm_factory.pyProvider 선택 팩토리

class OpenAIClient:
"""OpenAI LLM 클라이언트"""
def __init__(
self,
api_key: Optional[str] = None,
model: Optional[str] = None,
timeout: Optional[float] = None
)
# 주요 메서드
async def expand_keywords(query, max_keywords, context) -> Dict
async def suggest_synonyms(keyword) -> Dict
async def analyze_intent(query) -> Dict
async def test_connection() -> Dict
# 속성
@property
def usage_stats -> Dict # 누적 사용량 통계
class LLMFactory:
"""LLM 클라이언트 팩토리"""
@classmethod
def get_client(provider: str) -> LLMClientProtocol
@classmethod
def get_all_clients() -> Dict[str, LLMClientProtocol]

입력:

await client.expand_keywords(
query="인구", # 검색어
max_keywords=5, # 최대 키워드 수
context=None # RAG 컨텍스트 (선택)
)

출력:

{
"original_query": "인구",
"expanded_keywords": ["출산율", "고령화", "인구밀도", "세대수", "인구이동"],
"source": "openai",
"model": "gpt-4o",
"usage": {
"prompt_tokens": 125,
"completion_tokens": 45,
"total_tokens": 170,
"estimated_cost_usd": 0.00076,
"response_time_ms": 892.5
}
}

입력:

await client.suggest_synonyms(keyword="주택")

출력:

{
"keyword": "주택",
"synonyms": ["주거", "거주지", "가옥", "주거시설", "아파트"],
"source": "openai",
"model": "gpt-4o",
"usage": {...}
}

입력:

await client.analyze_intent(query="강남구 아파트 가격 추이")

출력:

{
"query": "강남구 아파트 가격 추이",
"analysis": {
"intent": "트렌드 분석",
"category": "주거",
"time_scope": "추세",
"region_scope": "특정 구",
"confidence": 0.9
},
"source": "openai",
"model": "gpt-4o",
"usage": {...}
}

from app.services import get_llm_client
# 기본 provider (설정 파일 기준)
client = get_llm_client()
# 특정 provider 지정
ollama_client = get_llm_client("ollama")
openai_client = get_llm_client("openai")

4.2 벤치마크용 모든 클라이언트

섹션 제목: “4.2 벤치마크용 모든 클라이언트”
from app.services import LLMFactory
clients = LLMFactory.get_all_clients()
# {"ollama": OllamaClientWrapper, "openai": OpenAIClient}

모델Input (1M tokens)Output (1M tokens)
gpt-4o$2.50$10.00
gpt-4o-mini$0.15$0.60
모델평균 토큰예상 비용
gpt-4o~200~$0.0008
gpt-4o-mini~200~$0.00006

5.3 월간 예상 비용 (1만 건 기준)

섹션 제목: “5.3 월간 예상 비용 (1만 건 기준)”
모델월 비용
gpt-4o~$8
gpt-4o-mini~$0.6

@retry(
stop=stop_after_attempt(3), # 최대 3회 시도
wait=wait_exponential( # 지수 백오프
multiplier=1,
min=1,
max=10
)
)
예외원인처리
AuthenticationError잘못된 API 키키 확인 필요
RateLimitError요청 한도 초과자동 재시도
APITimeoutError응답 시간 초과타임아웃 증가

당신은 서울연구데이터서비스의 검색 키워드 확장 전문가입니다.
사용자가 입력한 검색어와 관련된 연관 검색어를 추천해주세요.
규칙:
1. 한국어로 응답하세요
2. 서울 관련 통계/데이터 검색에 적합한 키워드를 추천하세요
3. JSON 배열 형태로만 응답하세요: ["키워드1", "키워드2", ...]
4. 다른 설명 없이 JSON 배열만 출력하세요
당신은 검색 의도 분석 전문가입니다.
사용자의 검색어를 분석하여 다음 정보를 JSON 형태로 반환하세요:
{
"intent": "데이터 조회 | 트렌드 분석 | 비교 분석 | 지역 정보 | 기타",
"category": "인구 | 경제 | 환경 | 교통 | 주거 | 문화 | 복지 | 역사 | 기타",
"time_scope": "현재 | 과거 | 추세 | 미지정",
"region_scope": "서울 전체 | 특정 구 | 미지정",
"confidence": 0.0~1.0
}

Terminal window
# API 실행 후
curl -X GET "http://localhost:8000/api/keywords/test?provider=openai"
Terminal window
curl -X POST "http://localhost:8000/api/keywords/expand" \
-H "Content-Type: application/json" \
-d '{"query": "인구", "max_keywords": 5, "provider": "openai"}'