5.2 KiB
5.2 KiB
Plan refaktoryzacji integracji OpenRouter
Cel
Refaktoryzacja kodu w resume_analysis.py w celu eliminacji wszystkich zależności od OpenAI API i wykorzystania wyłącznie OpenRouter API, z poprawą obecnej implementacji połączenia z OpenRouter.
Diagram przepływu zmian
graph TD
A[Obecna implementacja] --> B[Faza 1: Usunięcie zależności OpenAI]
B --> C[Faza 2: Refaktoryzacja klienta OpenRouter]
C --> D[Faza 3: Optymalizacja obsługi odpowiedzi]
D --> E[Faza 4: Testy i walidacja]
subgraph "Faza 1: Usunięcie zależności OpenAI"
B1[Usuń importy OpenAI]
B2[Usuń zmienne konfiguracyjne OpenAI]
B3[Usuń logikę wyboru klienta]
end
subgraph "Faza 2: Refaktoryzacja klienta OpenRouter"
C1[Stwórz dedykowaną klasę OpenRouterClient]
C2[Implementuj prawidłową konfigurację nagłówków]
C3[Dodaj obsługę różnych modeli]
end
subgraph "Faza 3: Optymalizacja obsługi odpowiedzi"
D1[Ujednolicenie formatu odpowiedzi]
D2[Implementacja lepszej obsługi błędów]
D3[Dodanie walidacji odpowiedzi]
end
subgraph "Faza 4: Testy i walidacja"
E1[Testy jednostkowe]
E2[Testy integracyjne]
E3[Dokumentacja zmian]
end
Szczegółowa implementacja
1. Dedykowana klasa OpenRouterClient
class OpenRouterClient:
def __init__(self, api_key: str, model_name: str):
self.api_key = api_key
self.model_name = model_name
self.base_url = "https://openrouter.ai/api/v1"
self.session = requests.Session()
self.session.headers.update({
"Authorization": f"Bearer {api_key}",
"HTTP-Referer": "https://github.com/OpenRouterTeam/openrouter-examples",
"X-Title": "CV Analysis Tool"
})
def create_chat_completion(self, messages: list, max_tokens: int = None):
endpoint = f"{self.base_url}/chat/completions"
payload = {
"model": self.model_name,
"messages": messages,
"max_tokens": max_tokens
}
response = self.session.post(endpoint, json=payload)
response.raise_for_status()
return response.json()
def get_available_models(self):
endpoint = f"{self.base_url}/models"
response = self.session.get(endpoint)
response.raise_for_status()
return response.json()
2. Konfiguracja i inicjalizacja
def initialize_openrouter_client():
if not OPENROUTER_API_KEY:
raise ValueError("OPENROUTER_API_KEY is required")
client = OpenRouterClient(
api_key=OPENROUTER_API_KEY,
model_name=OPENROUTER_MODEL_NAME
)
# Verify connection and model availability
try:
models = client.get_available_models()
if not any(model["id"] == OPENROUTER_MODEL_NAME for model in models):
raise ValueError(f"Model {OPENROUTER_MODEL_NAME} not available")
logger.debug(f"Successfully connected to OpenRouter. Available models: {models}")
return client
except Exception as e:
logger.error(f"Failed to initialize OpenRouter client: {e}")
raise
3. Obsługa odpowiedzi
class OpenRouterResponse:
def __init__(self, raw_response: dict):
self.raw_response = raw_response
self.choices = self._parse_choices()
self.usage = self._parse_usage()
self.model = raw_response.get("model")
def _parse_choices(self):
choices = self.raw_response.get("choices", [])
return [
{
"message": choice.get("message", {}),
"finish_reason": choice.get("finish_reason"),
"index": choice.get("index")
}
for choice in choices
]
def _parse_usage(self):
usage = self.raw_response.get("usage", {})
return {
"prompt_tokens": usage.get("prompt_tokens", 0),
"completion_tokens": usage.get("completion_tokens", 0),
"total_tokens": usage.get("total_tokens", 0)
}
4. Obsługa błędów
class OpenRouterError(Exception):
def __init__(self, message: str, status_code: int = None, response: dict = None):
super().__init__(message)
self.status_code = status_code
self.response = response
def handle_openrouter_error(error: Exception) -> OpenRouterError:
if isinstance(error, requests.exceptions.RequestException):
if error.response is not None:
try:
error_data = error.response.json()
message = error_data.get("error", {}).get("message", str(error))
return OpenRouterError(
message=message,
status_code=error.response.status_code,
response=error_data
)
except ValueError:
pass
return OpenRouterError(str(error))
Kolejne kroki
- Implementacja powyższych klas i funkcji
- Usunięcie wszystkich zależności OpenAI
- Aktualizacja istniejącego kodu do korzystania z nowego klienta
- Dodanie testów jednostkowych i integracyjnych
- Aktualizacja dokumentacji