AI_MMI_Analyser/app/ai/base.py

159 lines
3.9 KiB
Python

"""
AI Provider 기본 클래스 정의
모든 AI 프로바이더는 이 기본 클래스를 상속받아 구현합니다.
"""
from abc import ABC, abstractmethod
from typing import Optional, Dict, Any, List
from dataclasses import dataclass
from enum import Enum
class AIProviderType(Enum):
"""지원하는 AI 프로바이더 타입"""
OPENAI = "openai"
OPENROUTER = "openrouter"
GEMINI = "gemini"
XAI = "xai"
@dataclass
class AIMessage:
"""AI 메시지 데이터 클래스"""
role: str # 'system', 'user', 'assistant'
content: str
@dataclass
class AIResponse:
"""AI 응답 데이터 클래스"""
content: str
model: str
provider: str
usage: Optional[Dict[str, int]] = None
raw_response: Optional[Any] = None
class BaseAIProvider(ABC):
"""
AI Provider 추상 기본 클래스
모든 AI 프로바이더는 이 클래스를 상속받아 구현해야 합니다.
"""
def __init__(self, api_key: str, model: Optional[str] = None):
"""
Args:
api_key: API 키
model: 사용할 모델명 (None이면 기본 모델 사용)
"""
self._api_key = api_key
self._model = model or self.default_model
self._is_initialized = False
@property
@abstractmethod
def provider_type(self) -> AIProviderType:
"""프로바이더 타입 반환"""
pass
@property
@abstractmethod
def provider_name(self) -> str:
"""프로바이더 이름 반환"""
pass
@property
@abstractmethod
def default_model(self) -> str:
"""기본 모델명 반환"""
pass
@property
@abstractmethod
def available_models(self) -> List[str]:
"""사용 가능한 모델 목록 반환"""
pass
@property
def model(self) -> str:
"""현재 사용 중인 모델명"""
return self._model
@model.setter
def model(self, value: str):
"""모델 변경"""
self._model = value
@property
def api_key(self) -> str:
"""API 키 (마스킹된 값)"""
if self._api_key:
return self._api_key[:8] + "..." + self._api_key[-4:]
return ""
def update_api_key(self, api_key: str):
"""API 키 업데이트"""
self._api_key = api_key
self._is_initialized = False
@abstractmethod
def initialize(self) -> bool:
"""
프로바이더 초기화 (클라이언트 생성 등)
Returns:
초기화 성공 여부
"""
pass
@abstractmethod
async def chat(
self,
messages: List[AIMessage],
temperature: float = 0.7,
max_tokens: Optional[int] = None,
**kwargs
) -> AIResponse:
"""
채팅 요청 (비동기)
Args:
messages: 대화 메시지 리스트
temperature: 응답 다양성 (0.0 ~ 1.0)
max_tokens: 최대 토큰 수
**kwargs: 추가 파라미터
Returns:
AI 응답
"""
pass
@abstractmethod
def chat_sync(
self,
messages: List[AIMessage],
temperature: float = 0.7,
max_tokens: Optional[int] = None,
**kwargs
) -> AIResponse:
"""
채팅 요청 (동기)
Args:
messages: 대화 메시지 리스트
temperature: 응답 다양성 (0.0 ~ 1.0)
max_tokens: 최대 토큰 수
**kwargs: 추가 파라미터
Returns:
AI 응답
"""
pass
def validate_api_key(self) -> bool:
"""API 키 유효성 검사 (간단한 형식 체크)"""
return bool(self._api_key and len(self._api_key) > 10)
def __repr__(self):
return f"{self.__class__.__name__}(model={self._model}, initialized={self._is_initialized})"