Проект аудита отелей: основные скрипты и документация
- Краулеры: smart_crawler.py, regional_crawler.py - Аудит: audit_orel_to_excel.py, audit_chukotka_to_excel.py - РКН проверка: check_rkn_registry.py, recheck_unclear_rkn.py - Отчёты: create_orel_horizontal_report.py - Обработка: process_all_hotels_embeddings.py - Документация: README.md, DB_SCHEMA_REFERENCE.md
This commit is contained in:
277
model_providers.py
Normal file
277
model_providers.py
Normal file
@@ -0,0 +1,277 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
API для получения списка моделей от разных провайдеров
|
||||
"""
|
||||
|
||||
import requests
|
||||
import json
|
||||
from typing import Dict, List, Optional
|
||||
from llm_config import OPENAI_CONFIG, OPENROUTER_CONFIG, OLLAMA_CONFIG
|
||||
|
||||
class ModelProvider:
|
||||
"""Базовый класс для провайдеров моделей"""
|
||||
|
||||
def __init__(self, config: Dict):
|
||||
self.config = config
|
||||
self.provider = config['provider']
|
||||
self.api_base = config['api_base']
|
||||
self.api_key = config.get('api_key')
|
||||
self.proxy = config.get('proxy')
|
||||
|
||||
def get_models(self) -> List[Dict]:
|
||||
"""Получить список доступных моделей"""
|
||||
raise NotImplementedError
|
||||
|
||||
def _make_request(self, endpoint: str, method: str = 'GET', data: Optional[Dict] = None) -> Optional[Dict]:
|
||||
"""Универсальный запрос к API"""
|
||||
url = f"{self.api_base}/{endpoint}"
|
||||
|
||||
headers = {}
|
||||
if self.api_key:
|
||||
headers["Authorization"] = f"Bearer {self.api_key}"
|
||||
|
||||
if self.provider == 'openrouter':
|
||||
headers["HTTP-Referer"] = "https://hotel-audit.ru"
|
||||
headers["X-Title"] = "Hotel Audit System"
|
||||
|
||||
headers["Content-Type"] = "application/json"
|
||||
|
||||
proxies = None
|
||||
if self.proxy:
|
||||
proxies = {'http': self.proxy, 'https': self.proxy}
|
||||
|
||||
try:
|
||||
if method == 'GET':
|
||||
response = requests.get(url, headers=headers, proxies=proxies, timeout=30)
|
||||
elif method == 'POST':
|
||||
response = requests.post(url, headers=headers, json=data, proxies=proxies, timeout=30)
|
||||
|
||||
if response.status_code == 200:
|
||||
return response.json()
|
||||
else:
|
||||
print(f"Ошибка {self.provider}: {response.status_code} - {response.text}")
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
print(f"Ошибка соединения {self.provider}: {e}")
|
||||
return None
|
||||
|
||||
|
||||
class OpenAIProvider(ModelProvider):
|
||||
"""Провайдер OpenAI"""
|
||||
|
||||
def get_models(self) -> List[Dict]:
|
||||
"""Получить модели OpenAI"""
|
||||
data = self._make_request("models")
|
||||
if not data:
|
||||
return []
|
||||
|
||||
models = []
|
||||
for model in data.get('data', []):
|
||||
model_id = model['id']
|
||||
|
||||
# Фильтруем только чат-модели
|
||||
if any(x in model_id.lower() for x in ['gpt-3.5', 'gpt-4', 'o1']):
|
||||
models.append({
|
||||
'id': model_id,
|
||||
'name': model_id,
|
||||
'provider': 'openai',
|
||||
'description': self._get_model_description(model_id),
|
||||
'context_length': model.get('context_length', 0),
|
||||
'pricing': self._get_pricing(model_id)
|
||||
})
|
||||
|
||||
return sorted(models, key=lambda x: x['name'])
|
||||
|
||||
def _get_model_description(self, model_id: str) -> str:
|
||||
"""Описание модели"""
|
||||
descriptions = {
|
||||
'gpt-4o-mini': 'Быстрая и дешёвая модель',
|
||||
'gpt-4o': 'Самая умная модель OpenAI',
|
||||
'gpt-4-turbo': 'Баланс скорости и качества',
|
||||
'gpt-4': 'Классическая GPT-4',
|
||||
'gpt-3.5-turbo': 'Проверенная временем модель',
|
||||
'o1-preview': 'Новая рассуждающая модель',
|
||||
'o1-mini': 'Компактная рассуждающая модель'
|
||||
}
|
||||
|
||||
for key, desc in descriptions.items():
|
||||
if key in model_id.lower():
|
||||
return desc
|
||||
|
||||
return 'Модель OpenAI'
|
||||
|
||||
def _get_pricing(self, model_id: str) -> Dict:
|
||||
"""Примерная стоимость"""
|
||||
pricing = {
|
||||
'gpt-4o-mini': {'input': 0.15, 'output': 0.60},
|
||||
'gpt-4o': {'input': 5.00, 'output': 15.00},
|
||||
'gpt-4-turbo': {'input': 10.00, 'output': 30.00},
|
||||
'gpt-3.5-turbo': {'input': 0.50, 'output': 1.50},
|
||||
'o1-preview': {'input': 15.00, 'output': 60.00},
|
||||
'o1-mini': {'input': 3.00, 'output': 12.00},
|
||||
'gpt-4': {'input': 30.00, 'output': 60.00},
|
||||
'gpt-3.5': {'input': 0.50, 'output': 1.50}
|
||||
}
|
||||
|
||||
# Ищем точное совпадение или частичное
|
||||
for key, price in pricing.items():
|
||||
if key in model_id.lower():
|
||||
return price
|
||||
|
||||
# Если не найдено, возвращаем базовую цену
|
||||
return {'input': 0.50, 'output': 1.50}
|
||||
|
||||
|
||||
class OpenRouterProvider(ModelProvider):
|
||||
"""Провайдер OpenRouter"""
|
||||
|
||||
def get_models(self) -> List[Dict]:
|
||||
"""Получить модели OpenRouter"""
|
||||
data = self._make_request("models")
|
||||
if not data:
|
||||
return []
|
||||
|
||||
models = []
|
||||
for model in data.get('data', []):
|
||||
model_id = model['id']
|
||||
|
||||
# Фильтруем популярные модели
|
||||
if any(x in model_id.lower() for x in ['claude', 'gemini', 'llama', 'mistral', 'qwen']):
|
||||
models.append({
|
||||
'id': model_id,
|
||||
'name': model_id,
|
||||
'provider': 'openrouter',
|
||||
'description': self._get_model_description(model_id),
|
||||
'context_length': model.get('context_length', 0),
|
||||
'pricing': self._get_pricing(model_id)
|
||||
})
|
||||
|
||||
return sorted(models, key=lambda x: x['name'])
|
||||
|
||||
def _get_model_description(self, model_id: str) -> str:
|
||||
"""Описание модели"""
|
||||
if 'claude' in model_id.lower():
|
||||
if 'haiku' in model_id.lower():
|
||||
return 'Claude 3 Haiku - быстрая модель Anthropic'
|
||||
elif 'sonnet' in model_id.lower():
|
||||
return 'Claude 3.5 Sonnet - умная модель Anthropic'
|
||||
elif 'opus' in model_id.lower():
|
||||
return 'Claude 3 Opus - самая мощная модель Anthropic'
|
||||
else:
|
||||
return 'Claude модель от Anthropic'
|
||||
|
||||
elif 'gemini' in model_id.lower():
|
||||
return 'Gemini модель от Google'
|
||||
|
||||
elif 'llama' in model_id.lower():
|
||||
return 'Llama модель от Meta'
|
||||
|
||||
elif 'mistral' in model_id.lower():
|
||||
return 'Mistral модель'
|
||||
|
||||
elif 'qwen' in model_id.lower():
|
||||
return 'Qwen модель от Alibaba'
|
||||
|
||||
return 'Модель через OpenRouter'
|
||||
|
||||
def _get_pricing(self, model_id: str) -> Dict:
|
||||
"""Примерная стоимость"""
|
||||
pricing = {
|
||||
'claude-3-haiku': {'input': 0.25, 'output': 1.25},
|
||||
'claude-3.5-sonnet': {'input': 3.00, 'output': 15.00},
|
||||
'claude-3-opus': {'input': 15.00, 'output': 75.00},
|
||||
'gemini-flash': {'input': 0.075, 'output': 0.30},
|
||||
'gemini-pro': {'input': 0.50, 'output': 1.50},
|
||||
'llama3.1': {'input': 0.20, 'output': 0.20},
|
||||
'mistral': {'input': 0.25, 'output': 0.25}
|
||||
}
|
||||
|
||||
for key, price in pricing.items():
|
||||
if key in model_id.lower():
|
||||
return price
|
||||
|
||||
return {'input': 0, 'output': 0}
|
||||
|
||||
|
||||
class OllamaProvider(ModelProvider):
|
||||
"""Провайдер Ollama (локальный)"""
|
||||
|
||||
def get_models(self) -> List[Dict]:
|
||||
"""Получить модели Ollama"""
|
||||
data = self._make_request("api/tags")
|
||||
if not data:
|
||||
return []
|
||||
|
||||
models = []
|
||||
for model in data.get('models', []):
|
||||
model_id = model['name']
|
||||
|
||||
models.append({
|
||||
'id': model_id,
|
||||
'name': model_id,
|
||||
'provider': 'ollama',
|
||||
'description': self._get_model_description(model_id),
|
||||
'context_length': model.get('size', 0),
|
||||
'pricing': {'input': 0, 'output': 0} # Бесплатно
|
||||
})
|
||||
|
||||
return sorted(models, key=lambda x: x['name'])
|
||||
|
||||
def _get_model_description(self, model_id: str) -> str:
|
||||
"""Описание модели"""
|
||||
if 'llama' in model_id.lower():
|
||||
return 'Llama модель (локальная)'
|
||||
elif 'mistral' in model_id.lower():
|
||||
return 'Mistral модель (локальная)'
|
||||
elif 'qwen' in model_id.lower():
|
||||
return 'Qwen модель (локальная)'
|
||||
elif 'codellama' in model_id.lower():
|
||||
return 'Code Llama для программирования'
|
||||
else:
|
||||
return 'Локальная модель Ollama'
|
||||
|
||||
|
||||
def get_all_models() -> Dict[str, List[Dict]]:
|
||||
"""Получить все модели от всех провайдеров"""
|
||||
|
||||
providers = {
|
||||
'openai': OpenAIProvider(OPENAI_CONFIG),
|
||||
'openrouter': OpenRouterProvider(OPENROUTER_CONFIG),
|
||||
'ollama': OllamaProvider(OLLAMA_CONFIG)
|
||||
}
|
||||
|
||||
all_models = {}
|
||||
|
||||
for provider_name, provider in providers.items():
|
||||
print(f"Загружаю модели {provider_name}...")
|
||||
try:
|
||||
models = provider.get_models()
|
||||
all_models[provider_name] = models
|
||||
print(f"✅ {provider_name}: {len(models)} моделей")
|
||||
except Exception as e:
|
||||
print(f"❌ {provider_name}: ошибка - {e}")
|
||||
all_models[provider_name] = []
|
||||
|
||||
return all_models
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("=" * 70)
|
||||
print("🤖 ЗАГРУЗКА МОДЕЛЕЙ ОТ ПРОВАЙДЕРОВ")
|
||||
print("=" * 70)
|
||||
|
||||
all_models = get_all_models()
|
||||
|
||||
print(f"\n📊 ИТОГО:")
|
||||
for provider, models in all_models.items():
|
||||
print(f" {provider.upper()}: {len(models)} моделей")
|
||||
|
||||
print(f"\n🎯 ПРИМЕРЫ МОДЕЛЕЙ:")
|
||||
for provider, models in all_models.items():
|
||||
if models:
|
||||
print(f"\n{provider.upper()}:")
|
||||
for model in models[:3]: # Показываем первые 3
|
||||
print(f" - {model['name']}: {model['description']}")
|
||||
|
||||
print("=" * 70)
|
||||
Reference in New Issue
Block a user