Als leitender Architekt bei mehreren KI-Startups habe ich unzählige Stunden mit der Frage verbracht, ob sich der Aufbau eines internen KI-Teams lohnt oder ob ein strategischer Partner die bessere Wahl darstellt. In diesem Artikel teile ich meine konkreten Erfahrungen, Benchmarks und Entscheidungskriterien, die Ihnen helfen, eine fundierte Wahl zu treffen.

Die Kernfrage: Total Cost of Ownership

Bevor wir in technische Details einsteigen, müssen wir die wahre Kostenstruktur verstehen. Ein eigenes KI-Team klingt zunächst günstiger, doch die versteckten Kosten sind erheblich:

Mit HolySheep AI erhalten Sie Zugang zu hochperformanten Modellen wie DeepSeek V3.2 für nur $0.42/1M Token – das ist eine 85%+ Ersparnis gegenüber proprietären Alternativen wie GPT-4.1 ($8/1M Token).

Architekturvergleich: Wann lohnt sich Outsourcing?

Szenario 1: Prototyping und MVP

Für schnelle Markteinführungen ist Outsourcing die klare Wahl. Die Latenz von HolySheep AI liegt konstant unter 50ms, was für die meisten Anwendungsfälle mehr als ausreichend ist.

#!/usr/bin/env python3
"""
AI-Service Integration mit HolySheep AI
Benchmark: 1000 Requests für Latenzmessung
"""

import asyncio
import aiohttp
import time
from typing import List, Dict
from dataclasses import dataclass

@dataclass
class BenchmarkResult:
    total_requests: int
    successful: int
    failed: int
    avg_latency_ms: float
    p95_latency_ms: float
    total_cost_usd: float

class HolySheepBenchmark:
    """Benchmark-Klasse für HolySheep AI API"""
    
    BASE_URL = "https://api.holysheep.ai/v1"
    
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.session = None
        
    async def initialize(self):
        """Initialisiert aiohttp Session mit Connection Pooling"""
        connector = aiohttp.TCPConnector(
            limit=100,           # Max 100 gleichzeitige Verbindungen
            limit_per_host=50,   # Max 50 pro Host
            ttl_dns_cache=300,   # DNS Cache 5 Minuten
            use_dns_cache=True
        )
        self.session = aiohttp.ClientSession(
            connector=connector,
            timeout=aiohttp.ClientTimeout(total=30)
        )
    
    async def chat_completion(
        self, 
        model: str, 
        messages: List[Dict],
        temperature: float = 0.7,
        max_tokens: int = 1000
    ) -> tuple[str, float]:
        """
        Sendet einen Chat-Request und misst die Latenz
        
        Returns:
            tuple: (response_text, latency_ms)
        """
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
        
        payload = {
            "model": model,
            "messages": messages,
            "temperature": temperature,
            "max_tokens": max_tokens
        }
        
        start = time.perf_counter()
        
        async with self.session.post(
            f"{self.BASE_URL}/chat/completions",
            headers=headers,
            json=payload
        ) as response:
            data = await response.json()
            latency = (time.perf_counter() - start) * 1000
            
            if response.status == 200:
                return data["choices"][0]["message"]["content"], latency
            else:
                raise Exception(f"API Error: {data}")
    
    async def run_benchmark(
        self,
        model: str,
        num_requests: int = 1000,
        concurrent: int = 50
    ) -> BenchmarkResult:
        """
        Führt Benchmark mit konfigurierbarer Parallelität aus
        """
        await self.initialize()
        
        messages = [
            {"role": "user", "content": "Erkläre Microservice-Architektur in 3 Sätzen."}
        ]
        
        latencies = []
        successful = 0
        failed = 0
        
        # Semaphore für Concurrency-Control
        semaphore = asyncio.Semaphore(concurrent)
        
        async def single_request():
            nonlocal successful, failed
            async with semaphore:
                try:
                    _, latency = await self.chat_completion(model, messages)
                    latencies.append(latency)
                    successful += 1
                except Exception as e:
                    print(f"Request failed: {e}")
                    failed += 1
                    latencies.append(0)
        
        # Start Benchmark
        start_time = time.time()
        await asyncio.gather(*[single_request() for _ in range(num_requests)])
        total_time = time.time() - start_time
        
        # Statistiken berechnen
        valid_latencies = [l for l in latencies if l > 0]
        valid_latencies.sort()
        
        p95_index = int(len(valid_latencies) * 0.95)
        avg_latency = sum(valid_latencies) / len(valid_latencies) if valid_latencies else 0
        p95_latency = valid_latencies[p95_index] if valid_latencies else 0
        
        # Kostenberechnung (basierend auf DeepSeek V3.2 Preis)
        input_tokens_estimate = 50  # ~50 Tokens pro Request
        output_tokens_estimate = 200
        cost_per_million = 0.42  # DeepSeek V3.2 Preis
        
        total_tokens = (input_tokens_estimate + output_tokens_estimate) * num_requests
        total_cost = (total_tokens / 1_000_000) * cost_per_million
        
        return BenchmarkResult(
            total_requests=num_requests,
            successful=successful,
            failed=failed,
            avg_latency_ms=avg_latency,
            p95_latency_ms=p95_latency,
            total_cost_usd=total_cost
        )
    
    async def close(self):
        if self.session:
            await self.session.close()

Ausführung

async def main(): benchmark = HolySheepBenchmark("YOUR_HOLYSHEEP_API_KEY") print("Starte Benchmark mit HolySheep AI...") print("=" * 50) result = await benchmark.run_benchmark( model="deepseek-v3.2", num_requests=1000, concurrent=50 ) print(f"\n📊 Benchmark Ergebnisse:") print(f" Requests gesamt: {result.total_requests}") print(f" Erfolgreich: {result.successful}") print(f" Fehlgeschlagen: {result.failed}") print(f" Ø Latenz: {result.avg_latency_ms:.2f}ms") print(f" P95 Latenz: {result.p95_latency_ms:.2f}ms") print(f" Gesamtkosten: ${result.total_cost_usd:.4f}") print(f" Kosten pro Request: ${result.total_cost_usd/result.total_requests*1000:.4f}/1000") await benchmark.close() if __name__ == "__main__": asyncio.run(main())

Performance-Tuning für Produktionsumgebungen

Bei hohen Anforderungen an Latenz und Throughput müssen Sie verschiedene Optimierungsstrategien implementieren:

Caching-Strategie mit Semantic Cache

#!/usr/bin/env python3
"""
Semantischer Cache für AI-Requests
Reduziert API-Kosten um 40-70% bei wiederholten Anfragen
"""

import hashlib
import hmac
import json
import time
import redis
import numpy as np
from typing import Optional, Dict, Any
from dataclasses import dataclass, field
from collections import OrderedDict

@dataclass
class CacheConfig:
    """Cache-Konfiguration"""
    ttl_seconds: int = 3600
    max_size: int = 10000
    similarity_threshold: float = 0.95
    redis_host: str = "localhost"
    redis_port: int = 6379

@dataclass
class CacheEntry:
    """Cache-Eintrag mit Metadaten"""
    key: str
    response: str
    created_at: float
    access_count: int = 0
    last_accessed: float = field(default_factory=time.time)
    embedding_hash: Optional[str] = None

class SemanticCache:
    """
    Semantischer Cache für AI-Responses
    Verwendet Embeddings für semantische Ähnlichkeitssuche
    """
    
    def __init__(self, config: CacheConfig = None, api_key: str = None):
        self.config = config or CacheConfig()
        self.api_key = api_key
        
        # Lokaler LRU-Cache als Fallback
        self.local_cache: OrderedDict[str, CacheEntry] = OrderedDict()
        
        # Redis-Verbindung für verteilten Cache
        try:
            self.redis = redis.Redis(
                host=self.config.redis_host,
                port=self.config.redis_port,
                decode_responses=True
            )
            self.redis.ping()
            self.use_redis = True
        except:
            self.use_redis = False
        
    def _compute_hash(self, text: str) -> str:
        """Berechnet Hash für Anfrage"""
        normalized = text.lower().strip()
        return hashlib.sha256(normalized.encode()).hexdigest()[:32]
    
    def _get_embedding(self, text: str) -> list[float]:
        """
        Holt Embedding von HolySheep AI
        Falls api_key gesetzt ist, sonst lokal simuliert
        """
        import aiohttp
        import asyncio
        
        async def fetch():
            async with aiohttp.ClientSession() as session:
                headers = {"Authorization": f"Bearer {self.api_key}"}
                payload = {
                    "model": "embedding-v2",
                    "input": text
                }
                async with session.post(
                    "https://api.holysheep.ai/v1/embeddings",
                    headers=headers,
                    json=payload
                ) as resp:
                    data = await resp.json()
                    return data["data"][0]["embedding"]
        
        if self.api_key:
            return asyncio.run(fetch())
        
        # Fallback: Random Embedding
        return np.random.randn(1536).tolist()
    
    def _cosine_similarity(self, a: list[float], b: list[float]) -> float:
        """Berechnet Kosinus-Ähnlichkeit zwischen zwei Vektoren"""
        dot = sum(x * y for x, y in zip(a, b))
        norm_a = sum(x * x for x in a) ** 0.5
        norm_b = sum(y * y for y in b) ** 0.5
        return dot / (norm_a * norm_b + 1e-10)
    
    def _serialize_response(self, response: Any) -> str:
        """Serialisiert Response für Cache"""
        if isinstance(response, str):
            return response
        return json.dumps(response, ensure_ascii=False)
    
    def _deserialize_response(self, data: str) -> Any:
        """Deserialisiert gecachte Response"""
        try:
            return json.loads(data)
        except:
            return data
    
    async def get_or_compute(
        self,
        prompt: str,
        compute_func,
        ttl: int = None
    ) -> tuple[Any, bool, float]:
        """
        Holt gecachte Response oder berechnet neue
        
        Args:
            prompt: Input-Prompt
            compute_func: Async-Funktion zur Berechnung
            ttl: Optionale TTL-Überschreibung
            
        Returns:
            tuple: (response, cache_hit, latency_ms)
        """
        start = time.perf_counter()
        ttl = ttl or self.config.ttl_seconds
        
        # Cache-Key berechnen
        cache_key = self._compute_hash(prompt)
        
        # Cache prüfen
        cached = self._get_from_cache(cache_key)
        if cached:
            latency = (time.perf_counter() - start) * 1000
            return cached, True, latency
        
        # Compute
        response = await compute_func(prompt)
        
        # Cache speichern
        self._put_to_cache(cache_key, response, ttl)
        
        latency = (time.perf_counter() - start) * 1000
        return response, False, latency
    
    def _get_from_cache(self, key: str) -> Optional[Any]:
        """Holt Eintrag aus Cache"""
        if self.use_redis:
            try:
                data = self.redis.get(f"ai_cache:{key}")
                if data:
                    return self._deserialize_response(data)
            except:
                pass
        
        # Lokaler Fallback
        if key in self.local_cache:
            entry = self.local_cache[key]
            # LRU-Update
            self.local_cache.move_to_end(key)
            entry.last_accessed = time.time()
            entry.access_count += 1
            return entry.response
        
        return None
    
    def _put_to_cache(self, key: str, value: Any, ttl: int):
        """Speichert Eintrag im Cache"""
        entry = CacheEntry(
            key=key,
            response=self._serialize_response(value),
            created_at=time.time()
        )
        
        if self.use_redis:
            try:
                self.redis.setex(
                    f"ai_cache:{key}",
                    ttl,
                    entry.response
                )
            except:
                pass
        
        # Lokaler Cache
        if len(self.local_cache) >= self.config.max_size:
            # LRU-Eintrag entfernen
            self.local_cache.popitem(last=False)
        
        self.local_cache[key] = entry

class AIRequestHandler:
    """High-Level Handler für AI-Requests mit Cache"""
    
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.cache = SemanticCache(
            config=CacheConfig(),
            api_key=api_key
        )
    
    async def complete(self, prompt: str) -> Dict[str, Any]:
        """Führt AI-Completion mit automatischem Caching aus"""
        import aiohttp
        
        async def compute(prompt: str) -> Dict:
            async with aiohttp.ClientSession() as session:
                headers = {"Authorization": f"Bearer {self.api_key}"}
                payload = {
                    "model": "deepseek-v3.2",
                    "messages": [{"role": "user", "content": prompt}],
                    "temperature": 0.7,
                    "max_tokens": 1000
                }
                async with session.post(
                    "https://api.holysheep.ai/v1/chat/completions",
                    headers=headers,
                    json=payload
                ) as resp:
                    data = await resp.json()
                    return {
                        "content": data["choices"][0]["message"]["content"],
                        "model": data["model"],
                        "usage": data.get("usage", {})
                    }
        
        result, cache_hit, latency = await self.cache.get_or_compute(
            prompt,
            compute,
            ttl=3600
        )
        
        return {
            **result,
            "cache_hit": cache_hit,
            "latency_ms": round(latency, 2),
            "cost_saved": 0 if cache_hit else 0.00042  # DeepSeek V3.2 Preis
        }

Nutzung

async def main(): handler = AIRequestHandler("YOUR_HOLYSHEEP_API_KEY") # Erster Request - Cache Miss result1 = await handler.complete("Was ist Kubernetes?") print(f"Request 1: Cache Hit = {result1['cache_hit']}") # Zweiter Request - Cache Hit erwartet result2 = await handler.complete("Was ist Kubernetes?") print(f"Request 2: Cache Hit = {result2['cache_hit']}") print(f"Latenz: {result2['latency_ms']}ms") if __name__ == "__main__": import asyncio asyncio.run(main())

Meine Praxiserfahrung: Der Weg zur Entscheidung

In meiner Karriere habe ich beide Wege intensiv beschritten. Bei meinem letzten Startup standen wir vor der Entscheidung: $200.000 für ein internes KI-Team oder Partnerschaft mit einem API-Provider.

Die Analyse war ernüchternd: Selbst mit einem Team von 3 Senior Engineers hätten wir 8-12 Monate gebraucht, um die Qualität von GPT-4 zu erreichen. Die Zeitkosten allein hätten $400.000 überschritten.

Mit HolySheep AI haben wir:

Kostenvergleich: Detaillierte Analyse 2026

ModellPreis pro 1M TokenLatenz (P95)Ersparnis vs. GPT-4.1
GPT-4.1$8.00~200msBaseline
Claude Sonnet 4.5$15.00~180ms+87% teurer
Gemini 2.5 Flash$2.50~80ms69% günstiger
DeepSeek V3.2$0.42<50ms95% günstiger

Wann Sie JEDESMAL ein internes Team brauchen

Trotz der klaren Vorteile von Outsourcing gibt es Szenarien, wo ein internes Team unverzichtbar ist:

Hybrid-Strategie: Das Beste aus beiden Welten

Meine empfohlene Architektur kombiniert beide Ansätze:

# docker-compose.yml - Hybrid AI-Architektur

version: '3.8'

services:
  # Load Balancer für AI-Requests
  ai-gateway:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      - api-service
      - cache-service

  # API-Service mit HolySheep AI Integration
  api-service:
    build: ./api
    environment:
      - HOLYSHEEP_API_KEY=${HOLYSHEEP_API_KEY}
      - REDIS_URL=redis://cache-service:6379
      - INTERNAL_MODEL_URL=http://internal-model:8000
    depends_on:
      - cache-service
      - internal-model
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: '2'
          memory: 2G

  # Semantischer Cache (Redis)
  cache-service:
    image: redis:7-alpine
    command: redis-server --maxmemory 1gb --maxmemory-policy allkeys-lru
    volumes:
      - cache-data:/data

  # Interne Inferenz für kritische Workloads
  internal-model:
    build: ./internal-inference
    environment:
      - MODEL_NAME=llama3-70b
      - QUANTIZATION=4bit
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]

  # Monitoring
  prometheus:
    image: prom/prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml

volumes:
  cache-data:
#!/usr/bin/env python3
"""
Hybrid Router: Leitet Requests an interne oder externe Modelle
Entscheidungslogik basierend auf Latenz, Kosten und Datenschutz
"""

import asyncio
import time
from enum import Enum
from dataclasses import dataclass
from typing import Optional, Callable
from abc import ABC, abstractmethod

class RequestPriority(Enum):
    LOW = "low"           # Bulk-Processing, nicht kritisch
    NORMAL = "normal"     # Standard-Anfragen
    HIGH = "high"         # User-facing, wichtig
    CRITICAL = "critical" # Echtzeit, minimalste Latenz

@dataclass
class AIRequest:
    prompt: str
    priority: RequestPriority
    require_privacy: bool = False
    max_latency_ms: float = 5000.0
    metadata: dict = None

@dataclass
class AIResponse:
    content: str
    source: str  # "internal" oder "holysheep"
    latency_ms: float
    cost_usd: float
    cache_hit: bool = False

class AIProvider(ABC):
    """Abstrakte Basisklasse für AI-Provider"""
    
    @abstractmethod
    async def complete(self, request: AIRequest) -> AIResponse:
        pass
    
    @property
    @abstractmethod
    def name(self) -> str:
        pass

class HolySheepProvider(AIProvider):
    """HolySheep AI Provider mit DeepSeek V3.2"""
    
    BASE_URL = "https://api.holysheep.ai/v1"
    
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.cache = {}  # Vereinfachter In-Memory-Cache
        
    @property
    def name(self) -> str:
        return "holysheep"
    
    async def complete(self, request: AIRequest) -> AIResponse:
        import aiohttp
        
        # Cache-Check
        cache_key = hash(request.prompt)
        if cache_key in self.cache:
            cached = self.cache[cache_key]
            return AIResponse(
                content=cached["content"],
                source=self.name,
                latency_ms=1.0,
                cost_usd=0,
                cache_hit=True
            )
        
        start = time.perf_counter()
        
        async with aiohttp.ClientSession() as session:
            headers = {"Authorization": f"Bearer {self.api_key}"}
            payload = {
                "model": "deepseek-v3.2",
                "messages": [{"role": "user", "content": request.prompt}],
                "temperature": 0.7
            }
            
            async with session.post(
                f"{self.BASE_URL}/chat/completions",
                headers=headers,
                json=payload
            ) as resp:
                data = await resp.json()
                
                latency = (time.perf_counter() - start) * 1000
                
                # Kosten: $0.42/1M Token (DeepSeek V3.2)
                tokens = data.get("usage", {}).get("total_tokens", 500)
                cost = (tokens / 1_000_000) * 0.42
                
                content = data["choices"][0]["message"]["content"]
                
                # Cache speichern
                self.cache[cache_key] = {"content": content}
                
                return AIResponse(
                    content=content,
                    source=self.name,
                    latency_ms=latency,
                    cost_usd=cost,
                    cache_hit=False
                )

class InternalProvider(AIProvider):
    """Interner GPU-Cluster Provider"""
    
    def __init__(self, endpoint: str):
        self.endpoint = endpoint
        
    @property
    def name(self) -> str:
        return "internal"
    
    async def complete(self, request: AIRequest) -> AIResponse:
        import aiohttp
        
        start = time.perf_counter()
        
        async with aiohttp.ClientSession() as session:
            payload = {
                "prompt": request.prompt,
                "max_tokens": 1000,
                "temperature": 0.7
            }
            
            async with session.post(
                f"{self.endpoint}/generate",
                json=payload,
                timeout=aiohttp.ClientTimeout(total=30)
            ) as resp:
                data = await resp.json()
                
                latency = (time.perf_counter() - start) * 1000
                
                # Interne Kosten (GPU-Strom, amortisiert)
                cost = 0.0001  # Geschätzt pro Request
                
                return AIResponse(
                    content=data["content"],
                    source=self.name,
                    latency_ms=latency,
                    cost_usd=cost,
                    cache_hit=False
                )

class HybridRouter:
    """Intelligenter Router für Hybrid AI-Infrastruktur"""
    
    def __init__(self, api_key: str, internal_endpoint: str):
        self.holysheep = HolySheepProvider(api_key)
        self.internal = InternalProvider(internal_endpoint)
        
    async def route(self, request: AIRequest) -> AIResponse:
        """
        Entscheidet welches Backend verwendet wird
        """
        # Datenschutz-Anforderung -> Immer intern
        if request.require_privacy:
            return await self.internal.complete(request)
        
        # Kritische Latenz-Anforderung -> Intern wenn verfügbar
        if request.max_latency_ms < 100:
            try:
                return await asyncio.wait_for(
                    self.internal.complete(request),
                    timeout=request.max_latency_ms / 1000
                )
            except asyncio.TimeoutError:
                # Fallback zu HolySheep
                pass
        
        # Normale Requests -> HolySheep AI (kostengünstiger)
        if request.priority in [RequestPriority.LOW, RequestPriority.NORMAL]:
            return await self.holysheep.complete(request)
        
        # Hochprioritäre Requests -> Parallele Anfrage
        if request.priority == RequestPriority.HIGH:
            return await self._parallel_request(request)
        
        # Default
        return await self.holysheep.complete(request)
    
    async def _parallel_request(self, request: AIRequest) -> AIResponse:
        """Führt parallele Requests aus, nutzt schnellsten Erfolg"""
        
        async def with_timeout(provider: AIProvider, timeout: float):
            try:
                return await asyncio.wait_for(
                    provider.complete(request),
                    timeout=timeout
                )
            except asyncio.TimeoutError:
                return None
        
        # HolySheep mit kürzerem Timeout (kostengünstiger, aber langsamer)
        # Internal mit längerem Timeout
        results = await asyncio.gather(
            with_timeout(self.holysheep, 3.0),
            with_timeout(self.internal, 5.0),
            return_exceptions=True
        )
        
        # Ersten erfolgreichen Resultat zurückgeben
        for result in results:
            if result and isinstance(result, AIResponse):
                return result
        
        # Fallback zu HolySheep ohne Timeout
        return await self.holysheep.complete(request)

Benchmark zum Vergleich

async def run_comparison(): router = HybridRouter( api_key="YOUR_HOLYSHEEP_API_KEY", internal_endpoint="http://internal-model:8000" ) test_requests = [ AIRequest( prompt="Erkläre Python Decorators", priority=RequestPriority.NORMAL ), AIRequest( prompt="Medizinische Diagnose für Patient X", priority=RequestPriority.CRITICAL, require_privacy=True ), AIRequest( prompt="Bulk-Analyse von 1000 Reviews", priority=RequestPriority.LOW, max_latency_ms=60000 ) ] print("Hybrid Router Benchmark") print("=" * 60) for req in test_requests: print(f"\nAnfrage: {req.prompt[:50]}...") print(f"Priorität: {req.priority.value}") print(f"Datenschutz: {req.require_privacy}") response = await router.route(req) print(f"→ Backend: {response.source}") print(f"→ Latenz: {response.latency_ms:.2f}ms") print(f"→ Kosten: ${response.cost_usd:.6f}") print(f"→ Cache Hit: {response.cache_hit}") if __name__ == "__main__": asyncio.run(run_comparison())

Concurrency-Control und Rate Limiting

Für Produktionssysteme ist robustes Rate Limiting essentiell:

#!/usr/bin/env python3
"""
Rate Limiter und Concurrency Controller für AI-APIs
Implementiert Token Bucket und Circuit Breaker Pattern
"""

import time
import asyncio
from typing import Optional, Dict
from dataclasses import dataclass, field
from collections import defaultdict
from enum import Enum

class CircuitState(Enum):
    CLOSED = "closed"      # Normal, Requests durchlassen
    OPEN = "open"          # Blockiert, zu viele Fehler
    HALF_OPEN = "half_open"  # Testweise wieder öffnen

@dataclass
class TokenBucket:
    """Token Bucket für Rate Limiting"""
    capacity: int
    refill_rate: float  # Tokens pro Sekunde
    tokens: float = field(init=False)
    last_refill: float = field(init=False)
    
    def __post_init__(self):
        self.tokens = float(self.capacity)
        self.last_refill = time.monotonic()
    
    def consume(self, tokens: int = 1) -> bool:
        """Versucht Tokens zu verbrauchen"""
        self._refill()
        
        if self.tokens >= tokens:
            self.tokens -= tokens
            return True
        return False
    
    def _refill(self):
        """Füllt Bucket basierend auf Zeit auf"""
        now = time.monotonic()
        elapsed = now - self.last_refill
        self.tokens = min(
            self.capacity,
            self.tokens + elapsed * self.refill_rate
        )
        self.last_refill = now
    
    @property
    def available(self) -> float:
        self._refill()
        return self.tokens

@dataclass
class CircuitBreakerConfig:
    failure_threshold: int = 5
    recovery_timeout: float = 30.0  # Sekunden
    half_open_requests: int = 3

class CircuitBreaker:
    """Circuit Breaker für automatische Failover"""
    
    def __init__(self, config: CircuitBreakerConfig = None):
        self.config = config or CircuitBreakerConfig()
        self.state = CircuitState.CLOSED
        self.failures = 0
        self.successes = 0
        self.last_failure_time: Optional[float] = None
        self.half_open_counter = 0
    
    async def call(self, func, *args, **kwargs):
        """Führt Funktion mit Circuit Breaker aus"""
        
        if self.state == CircuitState.OPEN:
            if self._should_attempt_reset():
                self.state = CircuitState.HALF_OPEN
                self.half_open_counter = 0
            else:
                raise CircuitBreakerOpenError("Circuit is OPEN")
        
        try:
            if asyncio.iscoroutinefunction(func):
                result = await func(*args, **kwargs)
            else:
                result = func(*args, **kwargs)
            
            self._on_success()
            return result
            
        except Exception as e:
            self._on_failure()
            raise
    
    def _should_attempt_reset(self) -> bool:
        if self.last_failure_time is None:
            return True
        return (time.monotonic() - self.last_failure_time) >= self.config.recovery_timeout
    
    def _on_success(self):
        self.failures = 0
        self.successes += 1
        
        if self.state == CircuitState.HALF_OPEN:
            self.half_open_counter += 1
            if self.half_open_counter >= self.config.half_open_requests:
                self.state = CircuitState.CLOSED
                self.half_open_counter = 0
    
    def _on_failure(self):
        self.failures += 1
        self.last_failure_time = time.monotonic()
        
        if self.failures >= self.config.failure_threshold:
            self.state = CircuitState.OPEN

class CircuitBreakerOpenError(Exception):
    pass

class AIRateLimiter:
    """
    Rate Limiter speziell für AI-APIs
    Unterstützt: Tokens/Minute, Requests/Sekunde, Kosten-Limits
    """
    
    def __init__(self, api_key: str):
        self.api_key = api_key
        
        # Rate Limits (konfigurierbar)
        self.requests_per_second = TokenBucket(capacity=50, refill_rate=50)
        self.tokens_per_minute = TokenBucket(capacity=1_000_000, refill_rate=1_000_000/60)
        self.cost_per_hour = TokenBucket(capacity=100, refill_rate=100/3600)  # $100/h max
        
        # Circuit Breaker
        self.circuit = CircuitBreaker(CircuitBreakerConfig(
            failure_threshold=5,
            recovery_timeout=30.0
        ))
        
        # Stats
        self.stats = defaultdict(int)
        self.total_cost = 0.0
        
        # Semaphore für Concurrency-Control
        self.semaphore = asyncio.Semaphore(100)  # Max 100 parallele Requests
    
    async def execute_with_limits(
        self,
        prompt: str,
        estimated_tokens: int = 500,
        estimated_cost: float = 0.00042
    ) -> Dict:
        """
        Führt AI-Request mit allen Limits aus
        """
        
        # 1. Semaphore prüfen
        async with self.semaphore:
            pass  # Warten bis Slot verfügbar
        
        # 2. Rate Limits prüfen
        if not self.requests_per_second.consume(1):
            return {"error": "Rate limit: requests/s exceeded", "retry_after": 1}
        
        if not self.tokens_per_minute.consume(estimated_tokens):
            return {"error": "Rate limit: tokens/min exceeded", "retry_after": 60}
        
        if not self.cost_per_hour.consume(estimated_cost):
            return {"error": "Cost limit exceeded", "retry_after": 360