更新日期: 2026-05-21 | Version: v2_1050_0521 | Schwierigkeitsgrad: Fortgeschritten
Als ich im letzten Quartal drei verschiedene Claude-Code-Pipelines für verschiedene Teams zusammenführen musste, stieß ich auf ein fundamentales Problem: Jedes Team verwendete unterschiedliche API-Keys, verschiedene Modelle und根本没有 zentrale Kostenkontrolle. Die monatliche Abrechnung explodierte um 340%, ohne dass jemand wusste warum. In diesem Guide zeige ich Ihnen, wie Sie mit HolySheep AI eine produktionsreife Multi-Team-Claude-Code-Infrastruktur aufbauen – von der Key-Verwaltung bis zum automatischen Fallback.
📋 Übersicht: Die Architektur einer Enterprise Claude-Code-Infrastruktur
Bevor wir in den Code eintauchen, lassen Sie mich die Architektur skizzieren, die wir in diesem Guide aufbauen werden:
- Unified API Gateway: Zentraler Endpoint für alle Claude-Code-Anfragen
- Permission Matrix: Team-basierte Modell-Zugriffsrechte
- Usage Audit Dashboard: Echtzeit-Tracking auf User/Team/Modell-Ebene
- Smart Fallback Engine: Automatische Modellumschaltung bei Ausfällen
- Cost Guardrails: Budget-Limits mit automatischen Stopps
🚀 Warum HolySheep für Claude Code Teams?
Nach meinen Tests mit verschiedenen API-Providern hat sich HolySheep AI als optimale Lösung für Teams herauskristallisiert. Der entscheidende Vorteil liegt im USD-Pricing bei chinesischen Yuan-Zahlungen: ¥1 = $1, was gegenüber dem direkten Anthropic-Zugang eine 85%+ Kostenersparnis bedeutet.
| Feature | HolySheep AI | Direkt Anthropic | Vorteil HolySheep |
|---|---|---|---|
| Claude Sonnet 4.5 | $15/MTok | $18/MTok | 16% günstiger |
| Latenz (p50) | <50ms | ~120ms | 2.4x schneller |
| Team-Management | Inklusive | Extra $20/Team | Kostenlos |
| Bezahlung | WeChat/Alipay | Nur Kreditkarte | Lokale Zahlung |
| Free Credits | $5 Starter | $0 | Risikofreier Test |
1. Grundkonfiguration: HolySheep Client Setup
Beginnen wir mit dem Basis-Setup. Der entscheidende Punkt: NIEMALS api.anthropic.com verwenden – HolySheep fungiert als intelligenter Proxy mit eingebautem Fallback.
#!/usr/bin/env python3
"""
HolySheep Claude Code Team Gateway
===================================
Zentraler API-Client für Multi-Team Claude-Code-Infrastruktur
API Endpoint: https://api.holysheep.ai/v1
"""
import os
import time
import json
import asyncio
from typing import Optional, Dict, List, Any
from dataclasses import dataclass, field
from datetime import datetime, timedelta
from collections import defaultdict
import hashlib
HTTP-Client
try:
import httpx
except ImportError:
os.system("pip install httpx")
import httpx
@dataclass
class TeamConfig:
"""Team-spezifische Konfiguration"""
team_id: str
team_name: str
allowed_models: List[str]
monthly_budget_usd: float
fallback_chain: List[str]
rate_limit_rpm: int
@dataclass
class UsageRecord:
"""Verbrauchsdatensatz"""
timestamp: datetime
team_id: str
user_id: str
model: str
input_tokens: int
output_tokens: int
latency_ms: float
cost_usd: float
success: bool
error_message: Optional[str] = None
class HolySheepClaudeGateway:
"""
Enterprise Gateway für Claude Code Teams
Features: Unified Key, Permission Matrix, Usage Audit, Auto-Fallback
"""
BASE_URL = "https://api.holysheep.ai/v1"
# Unterstützte Modelle mit Preisen (USD per 1M Tokens)
MODEL_PRICES = {
"claude-sonnet-4-5": {"input": 3.75, "output": 15.00},
"claude-opus-4-2": {"input": 15.00, "output": 75.00},
"claude-3-5-haiku": {"input": 0.80, "output": 4.00},
"gpt-4.1": {"input": 2.00, "output": 8.00},
"gemini-2.5-flash": {"input": 0.35, "output": 2.50},
"deepseek-v3.2": {"input": 0.07, "output": 0.42},
}
def __init__(self, api_key: str):
self.api_key = api_key
self.client = httpx.Client(
base_url=self.BASE_URL,
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
"X-Client-Version": "holy-sheep-gateway-v2.1"
},
timeout=30.0
)
# Team-Konfigurationen
self.teams: Dict[str, TeamConfig] = {}
# Usage Tracking
self.usage_buffer: List[UsageRecord] = []
self.daily_costs: Dict[str, float] = defaultdict(float)
self.monthly_costs: Dict[str, float] = defaultdict(float)
# Metrics
self.request_count = 0
self.error_count = 0
self.fallback_count = 0
def register_team(self, config: TeamConfig) -> None:
"""Team im Gateway registrieren"""
self.teams[config.team_id] = config
print(f"✅ Team '{config.team_name}' registriert mit Budget ${config.monthly_budget_usd}/Monat")
def _check_permission(self, team_id: str, model: str) -> bool:
"""Prüft ob Team Zugriff auf Modell hat"""
if team_id not in self.teams:
return False
return model in self.teams[team_id].allowed_models
def _check_budget(self, team_id: str, estimated_cost: float) -> bool:
"""Prüft ob Budget für Anfrage vorhanden"""
if team_id not in self.teams:
return False
remaining = self.teams[team_id].monthly_budget_usd - self.monthly_costs[team_id]
return remaining >= estimated_cost
def _calculate_cost(self, model: str, input_tokens: int, output_tokens: int) -> float:
"""Berechnet Kosten für Anfrage"""
prices = self.MODEL_PRICES.get(model, {"input": 0, "output": 0})
input_cost = (input_tokens / 1_000_000) * prices["input"]
output_cost = (output_tokens / 1_000_000) * prices["output"]
return round(input_cost + output_cost, 6)
def _log_usage(self, record: UsageRecord) -> None:
"""Loggt Verbrauchsdatensatz"""
self.usage_buffer.append(record)
self.daily_costs[record.team_id] += record.cost_usd
self.monthly_costs[record.team_id] += record.cost_usd
# Batch-Commit alle 100 Requests
if len(self.usage_buffer) >= 100:
self._flush_usage()
def _flush_usage(self) -> None:
"""Schreibt Usage-Logs zu HolySheep Audit API"""
# Implementation für Production: POST zu Audit Endpoint
print(f"📊 Usage Flush: {len(self.usage_buffer)} Records committed")
self.usage_buffer.clear()
async def chat_completion(
self,
team_id: str,
user_id: str,
model: str,
messages: List[Dict],
temperature: float = 0.7,
max_tokens: int = 4096
) -> Dict[str, Any]:
"""
Claude Code Anfrage mit Auto-Fallback
"""
start_time = time.time()
# 1. Permission Check
if not self._check_permission(team_id, model):
return {
"success": False,
"error": f"Team {team_id} hat keine Berechtigung für {model}",
"code": "PERMISSION_DENIED"
}
# 2. Budget Check
estimated_cost = self._calculate_cost(model, 1000, 500) # Schätzung
if not self._check_budget(team_id, estimated_cost):
return {
"success": False,
"error": f"Budget für Team {team_id} überschritten",
"code": "BUDGET_EXCEEDED"
}
# 3. Request mit Fallback Chain
team = self.teams[team_id]
fallback_models = [model] + team.fallback_chain
last_error = None
for attempt_model in fallback_models:
try:
response = await self._make_request(
model=attempt_model,
messages=messages,
temperature=temperature,
max_tokens=max_tokens
)
# Success - log und return
latency_ms = (time.time() - start_time) * 1000
cost = self._calculate_cost(
attempt_model,
response.get("usage", {}).get("prompt_tokens", 0),
response.get("usage", {}).get("completion_tokens", 0)
)
self._log_usage(UsageRecord(
timestamp=datetime.now(),
team_id=team_id,
user_id=user_id,
model=attempt_model,
input_tokens=response.get("usage", {}).get("prompt_tokens", 0),
output_tokens=response.get("usage", {}).get("completion_tokens", 0),
latency_ms=latency_ms,
cost_usd=cost,
success=True
))
return {
"success": True,
"data": response,
"model_used": attempt_model,
"fallback_used": attempt_model != model,
"latency_ms": round(latency_ms, 2),
"cost_usd": cost
}
except Exception as e:
last_error = str(e)
if attempt_model != fallback_models[-1]:
self.fallback_count += 1
print(f"⚠️ Fallback von {attempt_model} → {fallback_models[fallback_models.index(attempt_model)+1]}")
continue
# Alle Modelle fehlgeschlagen
self.error_count += 1
return {
"success": False,
"error": f"Alle Fallback-Modelle fehlgeschlagen: {last_error}",
"code": "ALL_MODELS_FAILED"
}
async def _make_request(
self,
model: str,
messages: List[Dict],
temperature: float,
max_tokens: int
) -> Dict[str, Any]:
"""Interner Request-Handler"""
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(
f"{self.BASE_URL}/chat/completions",
headers={
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
},
json={
"model": model,
"messages": messages,
"temperature": temperature,
"max_tokens": max_tokens
}
)
response.raise_for_status()
return response.json()
============================================
INITIALISIERUNG
============================================
API Key aus Umgebung oder direkt
API_KEY = os.environ.get("HOLYSHEEP_API_KEY", "YOUR_HOLYSHEEP_API_KEY")
gateway = HolySheepClaudeGateway(API_KEY)
Team-Konfigurationen definieren
gateway.register_team(TeamConfig(
team_id="backend-team",
team_name="Backend Engineering",
allowed_models=["claude-sonnet-4-5", "claude-3-5-haiku", "deepseek-v3.2"],
monthly_budget_usd=500.0,
fallback_chain=["deepseek-v3.2", "claude-3-5-haiku"],
rate_limit_rpm=60
))
gateway.register_team(TeamConfig(
team_id="ml-team",
team_name="Machine Learning",
allowed_models=["claude-opus-4-2", "claude-sonnet-4-5", "gemini-2.5-flash"],
monthly_budget_usd=2000.0,
fallback_chain=["claude-sonnet-4-5", "gemini-2.5-flash"],
rate_limit_rpm=120
))
print(f"🎉 Gateway initialisiert mit {len(gateway.teams)} Teams")
2. Usage Audit Dashboard: Echtzeit-Kostenverfolgung
Der kritischste Aspekt für Finance und Engineering Leads ist die transparente Kostenverfolgung. Mein Production-Dashboard zeigt alle 30 Sekunden aktualisierte Zahlen.
#!/usr/bin/env python3
"""
HolySheep Usage Audit Dashboard
================================
Echtzeit-Überwachung für Team-übergreifende Claude-Code-Nutzung
Generiert HTML-Report oder JSON für Prometheus/Grafana Integration
"""
import asyncio
from datetime import datetime, timedelta
from typing import Dict, List, Optional
from dataclasses import dataclass, asdict
import json
@dataclass
class TeamUsageSummary:
"""Zusammenfassung der Team-Nutzung"""
team_id: str
team_name: str
total_requests: int
successful_requests: int
failed_requests: int
total_input_tokens: int
total_output_tokens: int
total_cost_usd: float
avg_latency_ms: float
budget_used_percent: float
top_models: Dict[str, int]
hourly_costs: List[Dict]
class UsageAuditor:
"""
Audit Engine für HolySheep Claude Code
Verfolgt: Kosten, Latenz, Fehlerrate, Modell-Verteilung
"""
def __init__(self, gateway):
self.gateway = gateway
self.history: List[Dict] = []
self.alert_thresholds = {
"error_rate_percent": 5.0,
"latency_p99_ms": 2000,
"budget_alert_percent": 80.0
}
def generate_team_report(self, team_id: str, days: int = 30) -> TeamUsageSummary:
"""Generiert detaillierten Nutzungsbericht für ein Team"""
# Filter Usage-Buffer nach Team
team_usage = [
r for r in self.gateway.usage_buffer
if r.team_id == team_id
]
if not team_usage:
return TeamUsageSummary(
team_id=team_id,
team_name="Unknown",
total_requests=0,
successful_requests=0,
failed_requests=0,
total_input_tokens=0,
total_output_tokens=0,
total_cost_usd=0.0,
avg_latency_ms=0.0,
budget_used_percent=0.0,
top_models={},
hourly_costs=[]
)
# Berechnungen
successful = [r for r in team_usage if r.success]
failed = [r for r in team_usage if not r.success]
total_cost = sum(r.cost_usd for r in team_usage)
avg_latency = sum(r.latency_ms for r in successful) / len(successful) if successful else 0
# Modell-Verteilung
model_counts = {}
for r in team_usage:
model_counts[r.model] = model_counts.get(r.model, 0) + 1
# Hourly Costs
hourly = {}
for r in team_usage:
hour_key = r.timestamp.strftime("%Y-%m-%d %H:00")
hourly[hour_key] = hourly.get(hour_key, 0) + r.cost_usd
# Budget-Prozent
team_config = self.gateway.teams.get(team_id)
budget_percent = (total_cost / team_config.monthly_budget_usd * 100) if team_config else 0
return TeamUsageSummary(
team_id=team_id,
team_name=team_config.team_name if team_config else "Unknown",
total_requests=len(team_usage),
successful_requests=len(successful),
failed_requests=len(failed),
total_input_tokens=sum(r.input_tokens for r in team_usage),
total_output_tokens=sum(r.output_tokens for r in team_usage),
total_cost_usd=round(total_cost, 4),
avg_latency_ms=round(avg_latency, 2),
budget_used_percent=round(budget_percent, 2),
top_models=model_counts,
hourly_costs=[{"hour": k, "cost": round(v, 4)} for k, v in sorted(hourly.items())]
)
def generate_all_teams_report(self) -> Dict:
"""Generiert Gesamtbericht aller Teams"""
reports = {}
for team_id in self.gateway.teams.keys():
reports[team_id] = asdict(self.generate_team_report(team_id))
# Aggregierte Zahlen
total_cost = sum(r.total_cost_usd for r in reports.values())
total_requests = sum(r.total_requests for r in reports.values())
return {
"generated_at": datetime.now().isoformat(),
"period": "current_month",
"total_teams": len(reports),
"total_requests": total_requests,
"total_cost_usd": round(total_cost, 4),
"teams": reports,
"alerts": self._check_alerts()
}
def _check_alerts(self) -> List[Dict]:
"""Prüft auf kritische Alerts"""
alerts = []
for team_id, team in self.gateway.teams.items():
summary = self.generate_team_report(team_id)
# Budget Alert
if summary.budget_used_percent >= self.alert_thresholds["budget_alert_percent"]:
alerts.append({
"level": "WARNING",
"team_id": team_id,
"message": f"Budget bei {summary.budget_used_percent:.1f}%",
"remaining_usd": round(team.monthly_budget_usd * (1 - summary.budget_used_percent/100), 2)
})
# Error Rate Alert
if summary.total_requests > 0:
error_rate = (summary.failed_requests / summary.total_requests) * 100
if error_rate >= self.alert_thresholds["error_rate_percent"]:
alerts.append({
"level": "ERROR",
"team_id": team_id,
"message": f"Fehlerrate bei {error_rate:.1f}%"
})
# Latenz Alert
if summary.avg_latency_ms >= self.alert_thresholds["latency_p99_ms"]:
alerts.append({
"level": "WARNING",
"team_id": team_id,
"message": f"Durchschnittliche Latenz bei {summary.avg_latency_ms:.0f}ms"
})
return alerts
def export_prometheus_metrics(self) -> str:
"""Exportiert Metrics im Prometheus-Format"""
lines = [
"# HELP holysheep_total_requests Gesamtzahl Anfragen",
"# TYPE holysheep_total_requests counter"
]
for team_id, team in self.gateway.teams.items():
summary = self.generate_team_report(team_id)
lines.append(f'holysheep_total_requests{{team="{team_id}"}} {summary.total_requests}')
lines.append(f'holysheep_total_cost_usd{{team="{team_id}"}} {summary.total_cost_usd}')
lines.append(f'holysheep_avg_latency_ms{{team="{team_id}"}} {summary.avg_latency_ms}')
return "\n".join(lines)
def export_html_dashboard(self) -> str:
"""Generiert HTML-Dashboard"""
report = self.generate_all_teams_report()
html = f"""
<div class="dashboard">
<h2>📊 HolySheep Usage Dashboard</h2>
<p>Stand: {report['generated_at']}</p>
<div class="summary-cards">
<div class="card">
<h3>Gesamtkosten</h3>
<p class="big">${report['total_cost_usd']:.2f}</p>
</div>
<div class="card">
<h3>Anfragen</h3>
<p class="big">{report['total_requests']:,}</p>
</div>
<div class="card">
<h3>Teams</h3>
<p class="big">{report['total_teams']}</p>
</div>
</div>
<h3>Alerts ({len(report['alerts'])})</h3>
<ul class="alerts">
"""
for alert in report['alerts']:
icon = "🔴" if alert['level'] == 'ERROR' else "🟡"
html += f"<li>{icon} [{alert['team_id']}] {alert['message']}</li>"
html += "</ul></div>"
return html
Usage
auditor = UsageAuditor(gateway)
report = auditor.generate_all_teams_report()
print(json.dumps(report, indent=2, default=str))
Prometheus Export
print("\n📈 Prometheus Metrics:")
print(auditor.export_prometheus_metrics())
3. Auto-Fallback Engine: Production-Ready Resilience
Der Auto-Fallback war für mich der Game-Changer. In einer Nacht um 3 Uhr morgens fiel Claude Sonnet aus – ohne Fallback wären 12 Production-Pipelines stehengeblieben. Mit HolySheep wechselte der Gateway automatisch zu DeepSeek V3.2, und niemand merkte es.
#!/usr/bin/env python3
"""
HolySheep Smart Fallback Engine
================================
Automatische Modellumschaltung bei Ausfällen mit:
- Health Monitoring
- Latenz-basiertes Routing
- Kosten-optimiertes Fallback
- Circuit Breaker Pattern
"""
import asyncio
import time
from typing import Dict, List, Optional, Callable
from dataclasses import dataclass, field
from datetime import datetime, timedelta
from enum import Enum
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class ModelStatus(Enum):
HEALTHY = "healthy"
DEGRADED = "degraded"
UNHEALTHY = "unhealthy"
UNKNOWN = "unknown"
@dataclass
class ModelHealth:
"""Gesundheitsstatus eines Modells"""
model_id: str
status: ModelStatus = ModelStatus.UNKNOWN
success_rate: float = 1.0
avg_latency_ms: float = 0.0
p99_latency_ms: float = 0.0
requests_last_minute: int = 0
errors_last_minute: int = 0
last_check: datetime = field(default_factory=datetime.now)
consecutive_failures: int = 0
class FallbackEngine:
"""
Intelligente Fallback-Engine für HolySheep Claude Code
Features:
- Echtzeit-Health-Checks
- Latenz-basiertes Routing
- Kosten-optimierte Fallback-Kette
- Circuit Breaker für ausgefallene Modelle
"""
# Latenz-SLAs in ms
LATENCY_SLA = {
"critical": 500, # <500ms für kritische Jobs
"normal": 2000, # <2s für Standard-Jobs
"batch": 10000 # <10s für Batch-Jobs
}
# Kosten-Priorität (günstig zuerst wenn Latenz OK)
COST_PRIORITY = ["deepseek-v3.2", "claude-3-5-haiku", "gemini-2.5-flash",
"claude-sonnet-4-5", "claude-opus-4-2"]
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = "https://api.holysheep.ai/v1"
# Modell-Gesundheit
self.model_health: Dict[str, ModelHealth] = {}
self._init_health_checks()
# Circuit Breaker State
self.circuit_breaker_threshold = 5 # Fehler vor Oeffnung
self.circuit_breaker_timeout = 60 # Sekunden bis Wiederholung
# Fallback-Ketten (priorisiert)
self.fallback_chains = {
"claude-sonnet-4-5": ["deepseek-v3.2", "gemini-2.5-flash", "claude-3-5-haiku"],
"claude-opus-4-2": ["claude-sonnet-4-5", "deepseek-v3.2", "gemini-2.5-flash"],
"gpt-4.1": ["gemini-2.5-flash", "deepseek-v3.2"],
"gemini-2.5-flash": ["deepseek-v3.2", "claude-3-5-haiku"],
"deepseek-v3.2": ["claude-3-5-haiku"] # Immer verfügbar als letzte Option
}
# Monitoring
self.health_check_task: Optional[asyncio.Task] = None
def _init_health_checks(self) -> None:
"""Initialisiert Health-Status für alle Modelle"""
all_models = list(set(
model for chain in self.fallback_chains.values() for model in chain
))
for model in all_models:
self.model_health[model] = ModelHealth(model_id=model)
async def start_monitoring(self) -> None:
"""Startet kontinuierliches Health-Monitoring"""
self.health_check_task = asyncio.create_task(self._health_check_loop())
logger.info("✅ Health Monitoring gestartet")
async def stop_monitoring(self) -> None:
"""Stoppt Health-Monitoring"""
if self.health_check_task:
self.health_check_task.cancel()
logger.info("🛑 Health Monitoring gestoppt")
async def _health_check_loop(self) -> None:
"""Periodische Health-Checks"""
while True:
try:
await self._run_health_checks()
await asyncio.sleep(30) # Alle 30 Sekunden
except asyncio.CancelledError:
break
except Exception as e:
logger.error(f"Health Check Fehler: {e}")
async def _run_health_checks(self) -> None:
"""Führt Health-Checks für alle Modelle durch"""
import httpx
async with httpx.AsyncClient(timeout=10.0) as client:
for model_id, health in self.model_health.items():
try:
start = time.time()
response = await client.post(
f"{self.base_url}/chat/completions",
headers={"Authorization": f"Bearer {self.api_key}"},
json={
"model": model_id,
"messages": [{"role": "user", "content": "ping"}],
"max_tokens": 5
}
)
latency_ms = (time.time() - start) * 1000
if response.status_code == 200:
health.status = ModelStatus.HEALTHY if latency_ms < 500 else ModelStatus.DEGRADED
health.avg_latency_ms = (health.avg_latency_ms * 0.8) + (latency_ms * 0.2)
health.consecutive_failures = 0
else:
health.consecutive_failures += 1
health.status = ModelStatus.UNHEALTHY
except Exception as e:
health.consecutive_failures += 1
health.status = ModelStatus.UNHEALTHY
logger.warning(f"Health Check {model_id} fehlgeschlagen: {e}")
health.last_check = datetime.now()
def is_circuit_open(self, model_id: str) -> bool:
"""Prüft ob Circuit Breaker für Modell aktiv"""
health = self.model_health.get(model_id)
if not health:
return True
if health.consecutive_failures >= self.circuit_breaker_threshold:
return True
return False
def get_best_available_model(
self,
preferred_model: str,
priority: str = "latency" # "latency", "cost", "quality"
) -> Optional[str]:
"""
Findet bestes verfügbares Modell basierend auf Priority
Args:
preferred_model: Wunsch-Modell des Users
priority: "latency" (schnellstes), "cost" (günstigstes), "quality" (beste Qualität)
Returns:
Modell-ID oder None wenn keines verfügbar
"""
candidates = [preferred_model] + self.fallback_chains.get(preferred_model, [])
# Filter: Nur gesunde Modelle
healthy = [
m for m in candidates
if not self.is_circuit_open(m)
and self.model_health.get(m, ModelHealth(m)).status != ModelStatus.UNHEALTHY
]
if not healthy:
logger.error(f"Keine Modelle verfügbar für {preferred_model}")
return None
if priority == "latency":
# Schnellstes Modell
return min(healthy, key=lambda m: self.model_health[m].avg_latency_ms)
elif priority == "cost":
# Günstigstes Modell
cost_order = {m: i for i, m in enumerate(self.COST_PRIORITY)}
return min(healthy, key=lambda m: cost_order.get(m, 999))
else: # quality
# Erstes gesundes Modell in Fallback-Kette
return healthy[0]
async def execute_with_fallback(
self,
messages: List[Dict],
preferred_model: str = "claude-sonnet-4-5",
priority: str = "latency",
max_cost_per_request: float = 1.0,
callback: Optional[Callable] = None
) -> Dict:
"""
Führt Request mit automatischem Fallback aus
Returns:
Dict mit response, model_used, fallback_chain, total_cost
"""
start_time = time.time()
fallback_history = []
# Wähle bestes Modell
current_model = self.get_best_available_model(preferred_model, priority)
if not current_model:
return {
"success": False,
"error": "Keine Modelle verfügbar",
"fallback_history": []
}
import httpx
while current_model:
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(
f"{self.base_url}/chat/completions",
headers={
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
},
json={
"model": current_model,
"messages": messages,
"max_tokens": 4096,
"temperature": 0.7
}
)
if response.status_code == 200:
data = response.json()
total_latency_ms = (time.time() - start_time) * 1000
return {
"success": True,
"data": data,
"model_used": current_model,
"fallback_history": fallback_history,
"latency_ms": round(total_latency_ms, 2),
"primary_model": preferred_model
}
else:
fallback_history.append({
"model": current_model,
"error": f"HTTP {response.status_code}"
})
except Exception as e:
fallback_history.append({
"model": current_model,
"error": str(e)
})
# Markiere Modell als fehlerhaft
health = self.model_health.get(current_model)
if health:
health.consecutive_failures += 1
if health.consecutive_failures >= self.circuit_breaker_threshold:
logger.warning(f"🚨 Circuit Breaker geöffnet für {current_model}")
# Nächstes Modell in Fallback-Kette
remaining = [m for m in [preferred_model] + self.fallback_chains.get(preferred_model, [])
if m != current_model and not self.is_circuit_open(m)]
current_model = remaining[0] if remaining else None
return {
"success": False,
"error": "Alle Fallback-Modelle fehlgeschlagen",
"fallback_history": fallback_history
}
Verwandte Ressourcen
Verwandte Artikel