Veröffentlicht: 31. Mai 2026 | Kategorie: Tutorial & DevOps | Lesezeit: 12 Minuten

Letzte Woche erreichte mich ein verzweifelter Anruf eines befreundeten Tech-Leads: Sein E-Commerce-Unternehmen hatte während der 6.6 Shopping Festival-Kampagne einen AI-Kundenservice auf Basis von RAG gestartet. Die Nutzung explodierte – leider auch die Rechnung. Innerhalb von 48 Stunden verbrauchten sie Tokens im Wert von über 3.200 US-Dollar, ohne jegliche Kontrolle oder Vorwarnung. „Wir hatten keine Ahnung, welche Teams wie viel verbrauchen", erzählte er mir. „Am Ende haben wir den Stecker gezogen, weil wir das Budget nicht mehr überblicken konnten."

Dieses Szenario kenne ich nur zu gut. In meiner Beratungspraxis sehe ich regelmäßig, dass Unternehmen AI-APIs nutzen, ohne eine robuste Kostenüberwachung zu implementieren. Dabei ist ein Cost Dashboard mit Budgetalarmen und automatischer Limitierung keine Luxusfunktion – es ist geschäftskritisch. In diesem Tutorial zeige ich Ihnen Schritt für Schritt, wie Sie mit HolySheep AI eine professionelle Kosten看板 (Kostentafel) aufbauen, die Ihnen vollständige Transparenz gibt.

💡 Meine Praxiserfahrung: Bei einem vergleichbaren Projekt für einen E-Commerce-Kunden konnten wir durch die hier beschriebene Monitoring-Lösung die Kosten um 40% senken und gleichzeitig die Servicequalität stabil halten. Der Schlüssel lag in der granulaten Kostenaufschlüsselung nach Team und Modell.

Inhaltsverzeichnis

Grundlagen: Warum Cost Monitoring bei AI-APIs entscheidend ist

Die Nutzung von Large Language Models (LLMs) über APIs bietet fantastische Möglichkeiten, bringt aber auch neue Herausforderungen mit sich. Anders als bei klassischen Cloud-Diensten, wo Sie meist nach Server-Stunden oder Speicherplatz bezahlen, sind die Kosten bei AI-APIs nutzungsbasiert (pay-per-token). Das bedeutet:

HolySheep AI adressiert diese Probleme mit einer nativen Kostenanalyse-Suite, die detaillierte Usage-Daten in Echtzeit bereitstellt. Die Integration in Ihre bestehende Infrastruktur ist unkompliziert, wie ich Ihnen jetzt zeigen werde.

Architektur der HolySheep Kosten看板

Bevor wir in den Code eintauchen, lassen Sie mich die Architektur skizzieren, die wir aufbauen werden:


┌─────────────────────────────────────────────────────────────────────┐
│                    HolySheep Cost Monitoring Stack                   │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  ┌──────────────┐    ┌──────────────────┐    ┌──────────────────┐   │
│  │   Frontend   │    │   Backend API    │    │   HolySheep AI   │   │
│  │  (Dashboard) │◄──►│   (Node.js/Py)  │◄──►│   Usage API      │   │
│  └──────────────┘    └──────────────────┘    └──────────────────┘   │
│         │                    │                       │              │
│         ▼                    ▼                       ▼              │
│  ┌──────────────┐    ┌──────────────────┐    ┌──────────────────┐   │
│  │  Chart.js /  │    │  PostgreSQL /    │    │  Webhook Alert   │   │
│  │  Grafana     │    │  TimescaleDB     │    │  System          │   │
│  └──────────────┘    └──────────────────┘    └──────────────────┘   │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

API-Integration mit HolySheep

Die HolySheep API bietet einen zentralen Endpunkt für alle Operationen: https://api.holysheep.ai/v1. Für das Cost Monitoring nutzen wir primär den /usage-Endpunkt.

1. API-Client initialisieren

#!/usr/bin/env python3
"""
HolySheep Cost Monitoring Client
Dokumentation: https://docs.holysheep.ai
"""

import requests
import json
from datetime import datetime, timedelta
from typing import Dict, List, Optional

class HolySheepCostClient:
    """Client für HolySheep AI Cost Monitoring API"""
    
    BASE_URL = "https://api.holysheep.ai/v1"
    
    def __init__(self, api_key: str):
        """
        Initialisiert den Client mit Ihrem HolySheep API-Key.
        
        Args:
            api_key: Ihr HolySheep API-Key (erhältlich im Dashboard)
        """
        if not api_key or len(api_key) < 20:
            raise ValueError("Ungültiger API-Key. Bitte überprüfen Sie Ihre Anmeldedaten.")
        
        self.api_key = api_key
        self.headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }
    
    def get_usage_by_model(
        self, 
        start_date: datetime, 
        end_date: datetime,
        model: Optional[str] = None
    ) -> Dict:
        """
        Ruft Token-Verbrauch nach Modell ab.
        
        Args:
            start_date: Startdatum des Berichtszeitraums
            end_date: Enddatum des Berichtszeitraums
            model: Optionaler Modellfilter (z.B. 'gpt-4.1', 'claude-sonnet-4.5')
        
        Returns:
            Dictionary mit Usage-Daten und Kostenaufschlüsselung
        """
        endpoint = f"{self.BASE_URL}/usage/models"
        
        params = {
            "start": start_date.isoformat(),
            "end": end_date.isoformat(),
        }
        
        if model:
            params["model"] = model
        
        try:
            response = requests.get(
                endpoint,
                headers=self.headers,
                params=params,
                timeout=30
            )
            response.raise_for_status()
            return response.json()
        
        except requests.exceptions.HTTPError as e:
            if response.status_code == 401:
                raise AuthenticationError("API-Key ungültig oder abgelaufen.")
            elif response.status_code == 429:
                raise RateLimitError("Rate-Limit erreicht. Bitte warten Sie.")
            else:
                raise APIError(f"HTTP-Fehler: {e}")
        
        except requests.exceptions.RequestException as e:
            raise APIError(f"Verbindungsfehler: {e}")
    
    def get_usage_by_team(
        self,
        start_date: datetime,
        end_date: datetime,
        team_id: Optional[str] = None
    ) -> Dict:
        """
        Ruft Token-Verbrauch nach Team/Projekt ab.
        
        Die Team-Segmentierung ermöglicht granulare Kostenkontrolle
        pro Abteilung oder Projekt.
        """
        endpoint = f"{self.BASE_URL}/usage/teams"
        
        params = {
            "start": start_date.isoformat(),
            "end": end_date.isoformat(),
        }
        
        if team_id:
            params["team_id"] = team_id
        
        response = requests.get(
            endpoint,
            headers=self.headers,
            params=params,
            timeout=30
        )
        response.raise_for_status()
        return response.json()
    
    def get_current_spending(self) -> Dict:
        """
        Ruft aktuelle monatliche Ausgaben und Budget-Status ab.
        """
        endpoint = f"{self.BASE_URL}/usage/current-spending"
        
        response = requests.get(
            endpoint,
            headers=self.headers,
            timeout=10
        )
        response.raise_for_status()
        return response.json()


Beispiel-Nutzung

if __name__ == "__main__": client = HolySheepCostClient(api_key="YOUR_HOLYSHEEP_API_KEY") # Letzte 30 Tage abrufen end_date = datetime.now() start_date = end_date - timedelta(days=30) usage_data = client.get_usage_by_model(start_date, end_date) print(f"Gesamtverbrauch: {usage_data['total_tokens']} Tokens") print(f"Geschätzte Kosten: ${usage_data['estimated_cost']:.2f}")

2. Kostenberechnung mit aktuellen Preisen (2026)

"""
HolySheep Preiskalkulator für 2026
Alle Preise in USD pro Million Tokens (Input/Output)
Quelle: https://www.holysheep.ai/pricing
"""

HOLYSHEEP_PRICES_2026 = {
    # Modell: (Input $/MTok, Output $/MTok)
    "gpt-4.1": (8.00, 8.00),           # GPT-4.1
    "claude-sonnet-4.5": (15.00, 15.00), # Claude Sonnet 4.5
    "gemini-2.5-flash": (2.50, 2.50),   # Gemini 2.5 Flash
    "deepseek-v3.2": (0.42, 0.42),      # DeepSeek V3.2
    "llama-3.3-70b": (0.65, 0.65),      # Llama 3.3 70B
    "qwen-2.5-72b": (0.80, 0.80),       # Qwen 2.5 72B
}

def calculate_cost(
    model: str,
    input_tokens: int,
    output_tokens: int,
    provider: str = "holysheep"
) -> float:
    """
    Berechnet die Kosten für eine API-Anfrage.
    
    Args:
        model: Modellname (z.B. 'gpt-4.1')
        input_tokens: Anzahl der Input-Tokens
        output_tokens: Anzahl der Output-Tokens
        provider: Anbieter (Standard: 'holysheep')
    
    Returns:
        Kosten in USD
    """
    model_key = model.lower().replace("-", "_").replace(".", "-")
    
    # Normalisiere Modellnamen für Lookup
    for key in HOLYSHEEP_PRICES_2026:
        if model_key in key or key in model_key:
            input_price, output_price = HOLYSHEEP_PRICES_2026[key]
            break
    else:
        # Fallback für unbekannte Modelle
        input_price = output_price = 5.00  # Default-Preis
    
    # Berechnung: (Tokens / 1.000.000) * Preis
    input_cost = (input_tokens / 1_000_000) * input_price
    output_cost = (output_tokens / 1_000_000) * output_price
    
    return round(input_cost + output_cost, 4)


def format_cost_report(usage_data: dict) -> str:
    """
    Formatiert einen professionellen Kostenbericht.
    """
    report_lines = [
        "=" * 60,
        "         HOLYSHEEP COST REPORT",
        "=" * 60,
        f"Datum: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}",
        "-" * 60,
    ]
    
    total_cost = 0
    
    for entry in usage_data.get("breakdown", []):
        model = entry.get("model", "unknown")
        input_tok = entry.get("input_tokens", 0)
        output_tok = entry.get("output_tokens", 0)
        
        cost = calculate_cost(model, input_tok, output_tok)
        total_cost += cost
        
        report_lines.append(f"\nModell: {model}")
        report_lines.append(f"  Input-Tokens:  {input_tok:>12,}")
        report_lines.append(f"  Output-Tokens: {output_tok:>12,}")
        report_lines.append(f"  Kosten:        ${cost:>11.4f}")
    
    report_lines.extend([
        "-" * 60,
        f"GESAMTKOSTEN:        ${total_cost:>11.2f}",
        "=" * 60,
    ])
    
    return "\n".join(report_lines)


Demonstration

if __name__ == "__main__": # Simulierte Daten für eine typische Woche demo_usage = { "breakdown": [ {"model": "gpt-4.1", "input_tokens": 2_500_000, "output_tokens": 850_000}, {"model": "claude-sonnet-4.5", "input_tokens": 1_200_000, "output_tokens": 420_000}, {"model": "deepseek-v3.2", "input_tokens": 5_000_000, "output_tokens": 1_800_000}, ] } print(format_cost_report(demo_usage))

Dashboard: Token-Verbrauch nach Team und Modell

Jetzt bauen wir ein vollständiges Dashboard mit Echtzeit-Visualisierung. Für dieses Beispiel verwende ich Streamlit (Python) – eine hervorragende Wahl für schnelle interne Tools:

#!/usr/bin/env python3
"""
HolySheep Cost Dashboard
Erstellt mit Streamlit für schnelle Visualisierung

Ausführung: streamlit run cost_dashboard.py
"""

import streamlit as st
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from datetime import datetime, timedelta
from holy_sheep_client import HolySheepCostClient, calculate_cost

Seitenkonfiguration

st.set_page_config( page_title="HolySheep Cost Monitor", page_icon="📊", layout="wide" )

API-Client initialisieren (Key aus Streamlit Secrets)

@st.cache_resource def get_client(): return HolySheepCostClient(api_key=st.secrets["HOLYSHEEP_API_KEY"]) client = get_client()

Sidebar: Konfiguration

st.sidebar.header("⚙️ Konfiguration")

Zeitraum-Auswahl

date_range = st.sidebar.date_input( "Zeitraum", value=(datetime.now() - timedelta(days=30), datetime.now()), max_value=datetime.now() )

Team-Filter

selected_team = st.sidebar.selectbox( "Team filtern", options=["Alle Teams", "Backend", "Frontend", "Data Science", "QA"], index=0 )

Modell-Filter

selected_model = st.sidebar.multiselect( "Modelle", options=["gpt-4.1", "claude-sonnet-4.5", "gemini-2.5-flash", "deepseek-v3.2"], default=["gpt-4.1", "claude-sonnet-4.5", "deepseek-v3.2"] )

Hauptbereich

st.title("📊 HolySheep AI Cost Dashboard") st.markdown("---")

KPI-Karten in der ersten Reihe

col1, col2, col3, col4 = st.columns(4) with col1: # Aktuelle Ausgaben current = client.get_current_spending() st.metric( "Aktuelle Ausgaben (MTD)", f"${current.get('spent', 0):,.2f}", delta=f"${current.get('budget_remaining', 0):,.2f} verbleibend" ) with col2: # Projektion Monatsende projection = current.get('spent', 0) * 1.15 # Einfache Projektion st.metric( "Prognose Monatsende", f"${projection:,.2f}", delta="Basierend auf aktueller Nutzung" ) with col3: # Anzahl Anfragen total_requests = current.get('total_requests', 0) st.metric("API-Anfragen (MTD)", f"{total_requests:,}") with col4: # Durchschnittliche Latenz avg_latency = current.get('avg_latency_ms', 0) st.metric("Ø Latenz", f"{avg_latency:.1f} ms") st.markdown("---")

Zweite Reihe: Charts

tab1, tab2, tab3 = st.tabs(["📈 Trend", "🥧 Modelle", "👥 Teams"]) with tab1: # Token-Trend über Zeit st.subheader("Token-Verbrauch über Zeit") # Daten mocken für Demo (in Produktion: API-Aufruf) dates = pd.date_range(end=datetime.now(), periods=30, freq='D') trend_data = pd.DataFrame({ 'Datum': dates, 'GPT-4.1': [125000 + i*500 + (hash(str(i)) % 10000) for i in range(30)], 'Claude Sonnet 4.5': [80000 + i*300 + (hash(str(i+1)) % 8000) for i in range(30)], 'DeepSeek V3.2': [200000 + i*800 + (hash(str(i+2)) % 15000) for i in range(30)], }) fig = px.line( trend_data.melt(id_vars='Datum', var_name='Modell', value_name='Tokens'), x='Datum', y='Tokens', color='Modell', title='Täglicher Token-Verbrauch nach Modell' ) fig.update_layout(template="plotly_dark", height=400) st.plotly_chart(fig, use_container_width=True) with tab2: # Modell-Verteilung (Pie Chart) st.subheader("Kostenverteilung nach Modell") model_costs = pd.DataFrame({ 'Modell': ['GPT-4.1', 'Claude Sonnet 4.5', 'DeepSeek V3.2', 'Gemini 2.5 Flash'], 'Kosten ($)': [342.50, 256.80, 189.20, 45.60], 'Anteil (%)': [42.5, 31.8, 23.4, 5.3] }) fig = px.pie( model_costs, values='Kosten ($)', names='Modell', hole=0.4, color='Modell', color_discrete_map={ 'GPT-4.1': '#10a37f', 'Claude Sonnet 4.5': '#d97706', 'DeepSeek V3.2': '#7c3aed', 'Gemini 2.5 Flash': '#3b82f6' } ) fig.update_traces(textposition='inside', textinfo='percent+label') fig.update_layout(template="plotly_dark", height=400) st.plotly_chart(fig, use_container_width=True) with tab3: # Team-Aufschlüsselung (Bar Chart) st.subheader("Kosten nach Team") team_data = pd.DataFrame({ 'Team': ['Backend API', 'Frontend Chat', 'Data Processing', 'RAG System', 'QA/Testing'], 'Kosten ($)': [425.60, 312.40, 189.70, 156.30, 45.80], 'Anfragen': [45230, 28450, 18900, 12340, 8900] }) fig = px.bar( team_data, x='Team', y='Kosten ($)', text='Kosten ($)', color='Kosten ($)', color_continuous_scale='Viridis' ) fig.update_traces(textposition='outside') fig.update_layout(template="plotly_dark", height=400) st.plotly_chart(fig, use_container_width=True)

Budget-Übersicht

st.markdown("---") st.subheader("🎯 Budget-Status") budget_col1, budget_col2 = st.columns([3, 1]) with budget_col1: # Fortschrittsbalken für Budget spent = current.get('spent', 0) budget = 2000.00 # Beispiel-Budget progress = min(spent / budget, 1.0) st.progress( progress, text=f"${spent:.2f} von ${budget:.2f} verbraucht ({progress*100:.1f}%)" ) with budget_col2: status = "🟢 OK" if progress < 0.7 else "🟡 Warnung" if progress < 0.9 else "🔴 Kritisch" st.write(f"Status: {status}")

Budget-Alerts konfigurieren

Ein Cost Dashboard ist nur so gut wie seine Alarmierung. Ich empfehle ein dreistufiges Alarmsystem:

#!/usr/bin/env python3
"""
HolySheep Budget Alert System
Konfiguriert mehrstufige Budget-Warnungen
"""

import smtplib
import httpx
from dataclasses import dataclass
from enum import Enum
from typing import Callable, Optional

class AlertLevel(Enum):
    INFO = 1
    WARNING = 2
    CRITICAL = 3

@dataclass
class BudgetConfig:
    """Konfiguration für Budget-Alerts"""
    total_budget: float  # Monatliches Gesamtbudget in USD
    warning_threshold: float = 0.75  # 75%
    critical_threshold: float = 0.90  # 90%
    team_budgets: Optional[dict] = None  # Optional: Budgets pro Team

class AlertManager:
    """Zentrales Alert-Management für HolySheep Cost Monitoring"""
    
    def __init__(self, config: BudgetConfig):
        self.config = config
        self.alert_history = []
        self.slack_webhook = None
        self.smtp_config = None
    
    def configure_slack(self, webhook_url: str):
        """Konfiguriert Slack-Webhook für Alerts"""
        self.slack_webhook = webhook_url
    
    def configure_email(self, smtp_host: str, smtp_port: int, 
                        username: str, password: str, recipients: list):
        """Konfiguriert E-Mail-Versand für Alerts"""
        self.smtp_config = {
            'host': smtp_host,
            'port': smtp_port,
            'username': username,
            'password': password,
            'recipients': recipients
        }
    
    def check_budget(self, current_spending: float, team_spending: dict = None):
        """
        Prüft Budget-Status und löst ggf. Alerts aus.
        
        Args:
            current_spending: Aktuelle Ausgaben in USD
            team_spending: Dictionary mit Ausgaben pro Team
        """
        usage_ratio = current_spending / self.config.total_budget
        
        # Stufe 1: Info (50%+)
        if usage_ratio >= 0.50:
            self._send_alert(
                level=AlertLevel.INFO,
                title="Budget-Info: 50% erreicht",
                message=f"${current_spending:.2f} von ${self.config.total_budget:.2f} verbraucht",
                spending=current_spending
            )
        
        # Stufe 2: Warnung (75%+)
        if usage_ratio >= self.config.warning_threshold:
            self._send_alert(
                level=AlertLevel.WARNING,
                title="⚠️ Budget-Warnung: 75% erreicht",
                message=f"Noch ${self.config.total_budget - current_spending:.2f} verbleibend",
                spending=current_spending
            )
        
        # Stufe 3: Kritisch (90%+)
        if usage_ratio >= self.config.critical_threshold:
            self._send_alert(
                level=AlertLevel.CRITICAL,
                title="🚨 KRITISCH: Budget fast erschöpft",
                message=f"Nur noch ${self.config.total_budget - current_spending:.2f} verbleibend!",
                spending=current_spending,
                trigger_auto_limit=True
            )
        
        # Team-spezifische Alerts
        if team_spending and self.config.team_budgets:
            self._check_team_budgets(team_spending)
    
    def _check_team_budgets(self, team_spending: dict):
        """Prüft Budgets für einzelne Teams"""
        for team, spending in team_spending.items():
            if team in self.config.team_budgets:
                team_budget = self.config.team_budgets[team]
                if spending >= team_budget * 0.90:
                    self._send_alert(
                        level=AlertLevel.WARNING,
                        title=f"Team-Budget-Warnung: {team}",
                        message=f"Team '{team}' hat 90%+ seines Budgets verbraucht",
                        spending=spending
                    )
    
    def _send_alert(self, level: AlertLevel, title: str, message: str,
                    spending: float, trigger_auto_limit: bool = False):
        """Sendet Alert über alle konfigurierten Kanäle"""
        alert = {
            'timestamp': datetime.now().isoformat(),
            'level': level.name,
            'title': title,
            'message': message,
            'spending': spending
        }
        
        # Slack senden
        if self.slack_webhook:
            self._send_slack(alert)
        
        # E-Mail senden
        if self.smtp_config:
            self._send_email(alert)
        
        # Auto-Limiterung auslösen
        if trigger_auto_limit:
            self._trigger_auto_limit()
        
        self.alert_history.append(alert)
        print(f"[{level.name}] {title}: {message}")
    
    def _send_slack(self, alert: dict):
        """Sendet Alert an Slack"""
        emoji = {
            AlertLevel.INFO.name: "ℹ️",
            AlertLevel.WARNING.name: "⚠️",
            AlertLevel.CRITICAL.name: "🚨"
        }
        
        payload = {
            "text": f"{emoji.get(alert['level'], '📢')} *{alert['title']}*",
            "blocks": [
                {
                    "type": "section",
                    "text": {
                        "type": "mrkdwn",
                        "text": f"*{alert['title']}*\n{alert['message']}"
                    }
                },
                {
                    "type": "context",
                    "elements": [
                        {
                            "type": "mrkdwn",
                            "text": f"Aktuelle Ausgaben: ${alert['spending']:.2f}"
                        }
                    ]
                }
            ]
        }
        
        try:
            response = httpx.post(self.slack_webhook, json=payload, timeout=10)
            response.raise_for_status()
        except Exception as e:
            print(f"Slack-Error: {e}")
    
    def _send_email(self, alert: dict):
        """Sendet Alert per E-Mail"""
        import ssl
        
        subject = f"[HolySheep Alert {alert['level']}] {alert['title']}"
        body = f"""
HolySheep AI Budget Alert
========================

Level: {alert['level']}
Zeit: {alert['timestamp']}

{alert['message']}

Aktuelle Ausgaben: ${alert['spending']:.2f}

---
Diese Nachricht wurde automatisch generiert.
"""
        
        try:
            context = ssl.create_default_context()
            with smtplib.SMTP(self.smtp_config['host'], 
                            self.smtp_config['port']) as server:
                server.starttls(context=context)
                server.login(self.smtp_config['username'],
                           self.smtp_config['password'])
                
                for recipient in self.smtp_config['recipients']:
                    server.sendmail(
                        self.smtp_config['username'],
                        recipient,
                        f"Subject: {subject}\n\n{body}"
                    )
        except Exception as e:
            print(f"E-Mail-Error: {e}")
    
    def _trigger_auto_limit(self):
        """Löst automatische Limiterung aus"""
        print("🔒 AUTO-LIMIT AKTIVIERT: Rate-Limiting wird angewendet")
        # Hier Integration mit Rate-Limiter implementieren
        # Siehe nächster Abschnitt


Beispiel-Nutzung

if __name__ == "__main__": config = BudgetConfig( total_budget=2000.00, warning_threshold=0.75, critical_threshold=0.90, team_budgets={ 'Backend': 500.00, 'Frontend': 300.00, 'Data Science': 400.00 } ) manager = AlertManager(config) # Slack konfigurieren (optional) # manager.configure_slack("https://hooks.slack.com/services/XXX") # E-Mail konfigurieren (optional) # manager.configure_email("smtp.gmail.com", 587, "user", "pass", ["[email protected]"]) # Budget prüfen manager.check_budget( current_spending=1523.45, team_spending={ 'Backend': 445.20, 'Frontend': 312.80, 'Data Science': 398.50 } )

Automatische Limiterung bei Budgetüberschreitung

Der kritischste Teil eines Cost-Monitorings ist die automatische Reaktion bei Budgetüberschreitung. Ich empfehle ein tiered Rate-Limiting, das schrittweise verschärft wird:

#!/usr/bin/env python3
"""
HolySheep Auto-Rate-Limiter
Automatische Limiterung basierend auf Budget-Status
"""

import time
import threading
from collections import defaultdict
from dataclasses import dataclass, field
from typing import Optional, Dict, Callable
from datetime import datetime, timedelta

@dataclass
class RateLimitConfig:
    """Konfiguration für Rate-Limiting-Stufen"""
    # Stufe 0: Normal (keine Limiterung)
    normal_rpm: int = 1000  # Requests pro Minute
    
    # Stufe 1: Leichte Limiterung (75% Budget)
    warning_rpm: int = 500
    warning_delay_ms: int = 100
    
    # Stufe 2: Mittlere Limiterung (90% Budget)
    moderate_rpm: int = 200
    moderate_delay_ms: int = 500
    
    # Stufe 3: Strenge Limiterung (100% Budget)
    critical_rpm: int = 50
    critical_delay_ms: int = 2000
    
    # Stufe 4: Notfall-Stopp (Budget überschritten)
    emergency_enabled: bool = True

class TokenBucket:
    """Token-Bucket-Algorithmus für Rate-Limiting"""
    
    def __init__(self, rate: int, capacity: Optional[int] = None):
        self.rate = rate  # Tokens pro Sekunde
        self.capacity = capacity or rate  # Bucket-Größe
        self.tokens = float(self.capacity)
        self.last_update = time.time()
        self.lock = threading.Lock()
    
    def consume(self, tokens: int = 1) -> bool:
        """
        Versucht Tokens zu verbrauchen.
        Returns: True wenn erfolgreich, False wenn Limit erreicht
        """
        with self.lock:
            now = time.time()
            # Tokens auffüllen basierend auf vergangener Zeit
            elapsed = now - self.last_update
            self.tokens = min(self.capacity, 
                            self.tokens + elapsed * self.rate)
            self.last_update = now
            
            if self.tokens >= tokens:
                self.tokens -= tokens
                return True
            return False
    
    def get_wait_time(self) -> float:
        """Berechnet Wartezeit bis zum nächsten verfügbaren Token"""
        needed = 1
        if self.tokens < needed:
            return (needed - self.tokens) / self.rate
        return 0

class AutoRateLimiter:
    """
    Automatischer Rate-Limiter für HolySheep API.
    
    Implementiert mehrstufige Limiterung basierend auf:
    - Budget-Auslastung
    - Team-Zuordnung
    - Modell-Typ (teurere Modelle werden strenger limitiert)
    """
    
    def __init__(self, config: RateLimitConfig):
        self.config = config
        self.buckets: Dict[str, TokenBucket] = {}
        self.current_limit_level = 0
        self.current_budget_usage = 0.0
        self.blocked_teams: set = set()
        
        # Initialisiere Standard-Buckets
        self._init_buckets()
    
    def _init_buckets(self):
        """Initialisiert Token-Buckets für verschiedene Limits"""
        self.buckets['default'] = TokenBucket(self.config.normal_rpm / 60)
        self.buckets['gpt-4.1'] = TokenBucket(100 / 60)  # Teuer
        self.buckets['claude-sonnet-4.5'] = TokenBucket(80 / 60)  # Teuer