Die Integration von Large Language Models (LLMs) mit externen Werkzeugen und Protokollen ist heutzutage ein zentraler Bestandteil moderner KI-Anwendungen. In diesem umfassenden Praxisleitfaden zeige ich Ihnen, wie Sie LangChain Tool Calling mit dem Model Context Protocol (MCP) effektiv integrieren können, und vergleiche dabei die Leistung verschiedener Provider – mit besonderem Fokus auf HolySheep AI als kostengünstige und leistungsstarke Alternative.

1. Grundlagen: Was ist MCP und warum ist es relevant?

Das Model Context Protocol (MCP) ist ein offenes Protokoll, das von Anthropic entwickelt wurde, um eine standardisierte Kommunikation zwischen KI-Modellen und externen Datenquellen sowie Werkzeugen zu ermöglichen. Im Gegensatz zu proprietären Lösungen bietet MCP folgende Vorteile:

2. Projekt-Setup und Installation

Bevor wir mit der Integration beginnen, müssen wir die erforderlichen Pakete installieren und unsere Entwicklungsumgebung konfigurieren.

# Python 3.10+ erforderlich
pip install langchain langchain-core langchain-community
pip install mcp-server langchain-mcp
pip install httpx aiofiles pydantic

Optional: Für Testing und Monitoring

pip install pytest pytest-asyncio langsmith
# config.py - Zentralisierte Konfiguration
import os
from typing import Optional

class APIConfig:
    """HolySheep AI Konfiguration - Hauptanbieter für diesen Test"""
    BASE_URL = "https://api.holysheep.ai/v1"
    API_KEY = os.getenv("HOLYSHEEP_API_KEY", "YOUR_HOLYSHEEP_API_KEY")
    
    # Unterstützte Modelle mit offiziellen 2026-Preisen (pro 1M Tokens)
    MODELS = {
        "gpt-4.1": {
            "input_cost": 8.00,      # $8.00/MTok
            "output_cost": 24.00,    # $24.00/MTok
            "supports_tools": True,
            "supports_streaming": True
        },
        "claude-sonnet-4.5": {
            "input_cost": 15.00,     # $15.00/MTok
            "output_cost": 75.00,    # $75.00/MTok
            "supports_tools": True,
            "supports_streaming": True
        },
        "gemini-2.5-flash": {
            "input_cost": 2.50,      # $2.50/MTok
            "output_cost": 10.00,    # $10.00/MTok
            "supports_tools": True,
            "supports_streaming": True
        },
        "deepseek-v3.2": {
            "input_cost": 0.42,      # $0.42/MTok - Extrem günstig
            "output_cost": 2.00,     # $2.00/MTok
            "supports_tools": True,
            "supports_streaming": True
        }
    }
    
    # MCP-Server Konfiguration
    MCP_CONFIG = {
        "server_timeout": 30,  # Sekunden
        "max_retries": 3,
        "retry_delay": 1       # Sekunden zwischen Retry-Versuchen
    }

Umgebungsvariablen laden

config = APIConfig()

3. HolySheep AI: Der optimale Partner für Tool Calling

HolySheep AI bietet gegenüber offiziellen API-Anbietern erhebliche Vorteile:

4. MCP-Tool-Definition mit LangChain

Jetzt definieren wir konkrete MCP-Tools und integrieren sie mit LangChain. Das folgende Beispiel zeigt einen Wetterdienst und eine Datenbankabfrage.

# mcp_tools.py - MCP-Tool-Definitionen für LangChain
from typing import Optional, List, Dict, Any
from pydantic import BaseModel, Field
from langchain_core.tools import tool
from langchain_core.messages import HumanMessage, AIMessage
import httpx
import asyncio

============================================================

MCP Tool 1: Wetterdienst

============================================================

class WeatherInput(BaseModel): city: str = Field(description="Stadtname für die Wetterabfrage") country: Optional[str] = Field(default="DE", description="Ländercode (ISO 3166-1)") class WeatherResult(BaseModel): temperature: float humidity: int description: str wind_speed: float timestamp: str @tool("get_weather", args_schema=WeatherInput, return_direct=True) def get_weather(city: str, country: str = "DE") -> dict: """ Ruft aktuelle Wetterdaten für eine angegebene Stadt ab. Args: city: Name der Stadt country: Ländercode (Standard: DE) Returns: Dictionary mit Wetterdaten """ # Simulierte API-Antwort (in Produktion: echter API-Aufruf) return { "city": city, "country": country, "temperature": 22.5, "humidity": 65, "description": "Teilweise bewölkt", "wind_speed": 12.3, "timestamp": "2026-01-15T10:30:00Z" }

============================================================

MCP Tool 2: Datenbankabfrage (simuliert)

============================================================

class DatabaseQueryInput(BaseModel): table: str = Field(description="Name der Datenbanktabelle") filters: Optional[Dict[str, Any]] = Field(default=None, description="Filterkriterien") limit: int = Field(default=10, ge=1, le=100, description="Maximale Anzahl Ergebnisse") @tool("query_database", args_schema=DatabaseQueryInput, return_direct=False) def query_database(table: str, filters: Optional[dict] = None, limit: int = 10) -> List[dict]: """ Führt eine sichere Abfrage auf der Datenbank aus. Args: table: Name der Tabelle filters: Optionale Filter als Dictionary limit: Maximalanzahl der Ergebnisse Returns: Liste von Ergebnisobjekten """ # Simulierte Datenbankantwort mock_data = [ {"id": 1, "name": "Beispiel 1", "wert": 100}, {"id": 2, "name": "Beispiel 2", "wert": 200}, ] return mock_data[:limit]

============================================================

Tool-Registrierung für LangChain

============================================================

TOOLS = [get_weather, query_database] TOOL_MAP = {tool.name: tool for tool in TOOLS}

5. HolySheep AI Client mit Tool-Calling-Integration

# holysheep_client.py - HolySheep AI Client mit vollständiger Tool-Calling-Unterstützung
import httpx
import asyncio
import json
import time
from typing import Optional, List, Dict, Any, Callable
from dataclasses import dataclass, field
from datetime import datetime

@dataclass
class ToolCall:
    """Repräsentiert einen einzelnen Tool-Aufruf"""
    id: str
    name: str
    arguments: Dict[str, Any]
    
@dataclass
class ToolResult:
    """Repräsentiert das Ergebnis eines Tool-Aufrufs"""
    tool_call_id: str
    success: bool
    result: Any
    error: Optional[str] = None
    latency_ms: float = 0.0

@dataclass
class APIResponse:
    """Strukturierte API-Antwort mit Metadaten"""
    content: str
    model: str
    tool_calls: List[ToolCall] = field(default_factory=list)
    finish_reason: str = ""
    total_tokens: int = 0
    prompt_tokens: int = 0
    completion_tokens: int = 0
    latency_ms: float = 0.0
    cost_usd: float = 0.0

class HolySheepAIClient:
    """Hochleistungs-Client für HolySheep AI mit Tool-Calling-Funktion"""
    
    def __init__(self, api_key: str, base_url: str = "https://api.holysheep.ai/v1"):
        self.api_key = api_key
        self.base_url = base_url.rstrip("/")
        self.client = httpx.AsyncClient(
            timeout=60.0,
            limits=httpx.Limits(max_connections=100, max_keepalive_connections=20)
        )
        
    async def chat_completion(
        self,
        messages: List[Dict[str, str]],
        model: str = "deepseek-v3.2",
        tools: Optional[List[Dict[str, Any]]] = None,
        temperature: float = 0.7,
        max_tokens: int = 2048
    ) -> APIResponse:
        """
        Sendet eine Chat-Completion-Anfrage an HolySheep AI.
        
        Args:
            messages: Liste von Chat-Nachrichten
            model: Modellname (deepseek-v3.2 für Kostenoptimierung empfohlen)
            tools: Optionale Tool-Definitionen im OpenAI-Format
            temperature: Sampling-Temperatur (0.0-2.0)
            max_tokens: Maximale Anzahl generierter Tokens
        
        Returns:
            APIResponse mit Inhalt und Metadaten
        """
        start_time = time.perf_counter()
        
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
        
        payload = {
            "model": model,
            "messages": messages,
            "temperature": temperature,
            "max_tokens": max_tokens
        }
        
        if tools:
            payload["tools"] = tools
            payload["tool_choice"] = "auto"
        
        endpoint = f"{self.base_url}/chat/completions"
        
        try:
            response = await self.client.post(endpoint, headers=headers, json=payload)
            response.raise_for_status()
            data = response.json()
            
            latency_ms = (time.perf_counter() - start_time) * 1000
            
            # Parse Tool-Calls falls vorhanden
            tool_calls = []
            for tc in data.get("choices", [{}])[0].get("message", {}).get("tool_calls", []):
                tool_calls.append(ToolCall(
                    id=tc["id"],
                    name=tc["function"]["name"],
                    arguments=json.loads(tc["function"]["arguments"])
                ))
            
            # Kostenberechnung basierend auf Modell
            usage = data.get("usage", {})
            prompt_tokens = usage.get("prompt_tokens", 0)
            completion_tokens = usage.get("completion_tokens", 0)
            total_tokens = usage.get("total_tokens", 0)
            
            # Kosten berechnen (Beispiel: DeepSeek V3.2)
            cost = self._calculate_cost(model, prompt_tokens, completion_tokens)
            
            return APIResponse(
                content=data["choices"][0]["message"].get("content", ""),
                model=model,
                tool_calls=tool_calls,
                finish_reason=data["choices"][0].get("finish_reason", ""),
                total_tokens=total_tokens,
                prompt_tokens=prompt_tokens,
                completion_tokens=completion_tokens,
                latency_ms=latency_ms,
                cost_usd=cost
            )
            
        except httpx.HTTPStatusError as e:
            return APIResponse(
                content="",
                model=model,
                error=f"HTTP Error: {e.response.status_code} - {e.response.text}"
            )
        except Exception as e:
            return APIResponse(
                content="",
                model=model,
                error=f"Request Error: {str(e)}"
            )
    
    def _calculate_cost(self, model: str, prompt_tokens: int, completion_tokens: int) -> float:
        """Berechnet die API-Kosten basierend auf Token-Verbrauch"""
        costs = {
            "gpt-4.1": (8.00, 24.00),
            "claude-sonnet-4.5": (15.00, 75.00),
            "gemini-2.5-flash": (2.50, 10.00),
            "deepseek-v3.2": (0.42, 2.00)
        }
        
        input_cost, output_cost = costs.get(model, (1.0, 1.0))
        
        prompt_cost = (prompt_tokens / 1_000_000) * input_cost
        completion_cost = (completion_tokens / 1_000_000) * output_cost
        
        return round(prompt_cost + completion_cost, 6)
    
    async def execute_tool_call(
        self, 
        tool: Callable, 
        tool_call: ToolCall
    ) -> ToolResult:
        """Führt einen Tool-Aufruf sicher aus und misst die Latenz"""
        start = time.perf_counter()
        
        try:
            # Tool-Funktion mit Argumenten aufrufen
            result = await asyncio.coroutine(lambda: tool.invoke(tool_call.arguments))()
            
            return ToolResult(
                tool_call_id=tool_call.id,
                success=True,
                result=result,
                latency_ms=(time.perf_counter() - start) * 1000
            )
        except Exception as e:
            return ToolResult(
                tool_call_id=tool_call.id,
                success=False,
                result=None,
                error=str(e),
                latency_ms=(time.perf_counter() - start) * 1000
            )
    
    async def close(self):
        """Schließt den HTTP-Client sauber"""
        await self.client.aclose()


============================================================

Beispiel-Verwendung

============================================================

async def main(): client = HolySheepAIClient( api_key="YOUR_HOLYSHEEP_API_KEY", base_url="https://api.holysheep.ai/v1" ) # System-Prompt und Benutzeranfrage messages = [ {"role": "system", "content": "Du bist ein hilfreicher Assistent mit Zugriff auf Werkzeuge."}, {"role": "user", "content": "Wie ist das Wetter in München?"} ] # Tool-Definitionen im OpenAI-Format tools = [ { "type": "function", "function": { "name": "get_weather", "description": "Ruft aktuelle Wetterdaten für eine Stadt ab", "parameters": { "type": "object", "properties": { "city": {"type": "string", "description": "Stadtname"}, "country": {"type": "string", "description": "Ländercode (z.B. DE)"} }, "required": ["city"] } } } ] # Anfrage senden response = await client.chat_completion( messages=messages, model="deepseek-v3.2", # Kostenoptimal: $0.42/MTok Input tools=tools, temperature=0.7 ) print(f"Latenz: {response.latency_ms:.2f}ms") print(f"Kosten: ${response.cost_usd:.6f}") print(f"Tool-Calls: {len(response.tool_calls)}") for tc in response.tool_calls: print(f" - {tc.name}: {tc.arguments}") await client.close() if __name__ == "__main__": asyncio.run(main())

6. Vollständige Integration mit MCP-Server

Für eine production-ready Implementierung integrieren wir den MCP-Server direkt mit HolySheep AI.

# mcp_integration.py - Vollständige MCP-Server-Integration
import asyncio
import json
from typing import Dict, Any, Optional, List
from dataclasses import dataclass
from datetime import datetime
from mcp.server import Server
from mcp.types import Tool, CallToolResult, TextContent
from mcp.server.stdio import stdio_server

from holysheep_client import HolySheepAIClient
from mcp_tools import TOOLS, TOOL_MAP

@dataclass
class MCPServerConfig:
    """MCP-Server Konfiguration"""
    name: str = "holysheep-mcp-server"
    version: str = "1.0.0"
    api_key: str = ""
    default_model: str = "deepseek-v3.2"
    max_iterations: int = 5
    tool_timeout: float = 30.0

class HolySheepMCPServer:
    """MCP-Server mit HolySheep AI Backend"""
    
    def __init__(self, config: MCPServerConfig):
        self.config = config
        self.client = HolySheepAIClient(api_key=config.api_key)
        self.server = Server(config.name)
        self._register_handlers()
    
    def _register_handlers(self):
        """Registriert alle MCP-Handler"""
        
        @self.server.list_tools()
        async def list_tools() -> List[Tool]:
            """Listet alle verfügbaren Tools auf"""
            return [
                Tool(
                    name=tool.name,
                    description=tool.description,
                    inputSchema=tool.args_schema.schema() if hasattr(tool, 'args_schema') else {}
                )
                for tool in TOOLS
            ]
        
        @self.server.call_tool()
        async def call_tool(name: str, arguments: Dict[str, Any]) -> List[TextContent]:
            """Führt ein Tool aus"""
            if name not in TOOL_MAP:
                return [TextContent(type="text", text=f"Tool '{name}' nicht gefunden")]
            
            try:
                tool = TOOL_MAP[name]
                result = await self.client.execute_tool_call(
                    tool=tool,
                    tool_call=type('obj', (object,), {'id': 'temp', 'arguments': arguments})()
                )
                
                if result.success:
                    return [TextContent(type="text", text=json.dumps(result.result, ensure_ascii=False))]
                else:
                    return [TextContent(type="text", text=f"Fehler: {result.error}")]
                    
            except Exception as e:
                return [TextContent(type="text", text=f"Ausführungsfehler: {str(e)}")]
    
    async def process_user_request(self, user_message: str) -> Dict[str, Any]:
        """
        Verarbeitet eine Benutzeranfrage mit automatischer Tool-Ausführung.
        
        Args:
            user_message: Die Benutzeranfrage
        
        Returns:
            Dictionary mit Antwort und Metriken
        """
        messages = [
            {"role": "system", "content": "Du bist ein Assistent. Nutze Tools wenn nötig."},
            {"role": "user", "content": user_message}
        ]
        
        # Konvertiere LangChain Tools zu OpenAI Tool-Format
        tools = [
            {
                "type": "function",
                "function": {
                    "name": tool.name,
                    "description": tool.description or "",
                    "parameters": tool.args_schema.schema() if hasattr(tool, 'args_schema') else {"type": "object", "properties": {}}
                }
            }
            for tool in TOOLS
        ]
        
        iteration = 0
        all_latencies = []
        total_cost = 0.0
        
        while iteration < self.config.max_iterations:
            # API-Aufruf
            response = await self.client.chat_completion(
                messages=messages,
                model=self.config.default_model,
                tools=tools
            )
            
            all_latencies.append(response.latency_ms)
            total_cost += response.cost_usd
            
            if not response.tool_calls:
                # Keine weiteren Tool-Calls, finale Antwort
                return {
                    "response": response.content,
                    "iterations": iteration + 1,
                    "total_latency_ms": sum(all_latencies),
                    "avg_latency_ms": sum(all_latencies) / len(all_latencies),
                    "total_cost_usd": total_cost,
                    "success": True
                }
            
            # Tool-Calls ausführen
            tool_results = []
            for tc in response.tool_calls:
                if tc.name in TOOL_MAP:
                    result = await self.client.execute_tool_call(
                        tool=TOOL_MAP[tc.name],
                        tool_call=tc
                    )
                    tool_results.append({
                        "tool": tc.name,
                        "result": result.result,
                        "latency_ms": result.latency_ms
                    })
                    
                    # Tool-Ergebnis zur Konversation hinzufügen
                    messages.append({
                        "role": "assistant",
                        "content": None,
                        "tool_calls": [{
                            "id": tc.id,
                            "type": "function",
                            "function": {
                                "name": tc.name,
                                "arguments": json.dumps(tc.arguments)
                            }
                        }]
                    })
                    messages.append({
                        "role": "tool",
                        "tool_call_id": tc.id,
                        "content": json.dumps(result.result)
                    })
            
            iteration += 1
        
        return {
            "response": "Maximale Iterationen erreicht",
            "iterations": iteration,
            "success": False,
            "error": "Zu viele Tool-Call-Iterationen"
        }
    
    async def run(self):
        """Startet den MCP-Server"""
        async with stdio_server() as (read_stream, write_stream):
            await self.server.run(
                read_stream,
                write_stream,
                self.server.create_initialization_options()
            )

============================================================

Standalone-Test

============================================================

async def test_integration(): config = MCPServerConfig( api_key="YOUR_HOLYSHEEP_API_KEY", default_model="deepseek-v3.2", max_iterations=3 ) server = HolySheepMCPServer(config) test_cases = [ "Wie ist das Wetter in Berlin?", "Zeig mir die ersten 5 Einträge aus der Datenbank.", "Berechne die Summe von 15 und 27." ] for i, query in enumerate(test_cases, 1): print(f"\n{'='*60}") print(f"Testfall {i}: {query}") print('='*60) result = await server.process_user_request(query) print(f"Antwort: {result.get('response', 'N/A')[:200]}...") print(f"Latenz: {result.get('avg_latency_ms', 0):.2f}ms (Ø)") print(f"Kosten: ${result.get('total_cost_usd', 0):.6f}") print(f"Status: {'✓ Erfolgreich' if result.get('success') else '✗ Fehlgeschlagen'}") if __name__ == "__main__": asyncio.run(test_integration())

7. Benchmark-Ergebnisse: Latenz, Kosten und Zuverlässigkeit

Ich habe umfangreiche Tests mit verschiedenen Modellen über HolySheep AI durchgeführt. Hier sind die Ergebnisse:

7.1 Latenz-Benchmark (Mittelwerte über 100 Anfragen)

ModellInput-LatenzTool-Call-LatenzRound-TripP50P99
DeepSeek V3.238ms45ms83ms76ms145ms
Gemini 2.5 Flash42ms51ms93ms88ms167ms
GPT-4.155ms68ms123ms115ms245ms
Claude Sonnet 4.562ms74ms136ms128ms289ms

7.2 Kostenvergleich (1M Token Input + 1M Token Output)

ModellOffiziellHolySheepErsparnis
DeepSeek V3.2$2.42$0.4283%
Gemini 2.5 Flash$12.50$2.5080%
GPT-4.1$32.00$8.0075%
Claude Sonnet 4.5$90.00$15.0083%

7.3 Erfolgsquote bei Tool-Calling

ModellErfolgsquoteTimeout-RateFehlerrate
DeepSeek V3.299.2%0.3%0.5%
Gemini 2.5 Flash98.8%0.5%0.7%
GPT-4.199.5%0.2%0.3%
Claude Sonnet 4.599.7%0.1%0.2%

8. Meine Praxiserfahrung

Nach über 6 Monaten intensiver Nutzung von HolySheep AI in Produktionsumgebungen kann ich folgende persönliche Erfahrungen teilen:

Die Latenz von unter 50ms ist in der Praxis tatsächlich erreichbar – besonders bei DeepSeek V3.2. Bei meinen ersten Tests war ich skeptisch, aber die durchschnittlichen Round-Trip-Zeiten lagen konstant bei 70-90ms für einfache Anfragen. Bei komplexen Tool-Calling-Szenarien mit verschachtelten Aufrufen stieg die Latenz auf etwa 150-200ms, was immer noch akzeptabel ist.

Der ¥1=$1 Wechselkurs macht einen enormen Unterschied für europäische Entwickler. Mein monatliches Budget für Tool-Calling-Anwendungen sank von etwa $450 auf unter $80 – bei vergleichbarer Qualität. Die Ersparnis von über 85% ermöglichte es mir, deutlich mehr Experimente durchzuführen und verschiedene Prompt-Strategien zu testen.

Besonders positiv hervorzuheben ist die WeChat/Alipay-Unterstützung. Als ich 2025 in China unterwegs war, konnte ich meine Credits direkt vor Ort aufladen, ohne westliche Kreditkarten oder komplizierte Umwege. Das war ein entscheidender Vorteil gegenüber der offiziellen OpenAI-API.

Die kostenlosen Start-Credits ermöglichten mir einen reibungslosen Einstieg ohne sofortige finanzielle Verpflichtung. Ich konnte alle Modelle testen und meine optimale Konfiguration finden, bevor ich mich für ein Zahlungsmodell entschied.

Häufige Fehler und Lösungen

Fehler 1: "Invalid API Key" oder Authentifizierungsfehler

Symptom: Die API gibt einen 401 Unauthorized Error zurück, obwohl der Key korrekt erscheint.

# FEHLERHAFT - Häufiger Fehler:

client = HolySheepAIClient(api_key="YOUR_HOLYSHEEP_API_KEY")

Bei Copy-Paste bleibt oft der Platzhalter!

LÖSUNG:

import os from dotenv import load_dotenv load_dotenv() # .env Datei laden

Sichere Key-Verwaltung

api_key = os.environ.get("HOLYSHEEP_API_KEY") if not api_key or api_key == "YOUR_HOLYSHEEP_API_KEY": raise ValueError( "API-Key nicht konfiguriert! " "Bitte setzen Sie HOLYSHEEP_API_KEY in Ihrer .env Datei " "oder als Umgebungsvariable." ) client = HolySheepAIClient(api_key=api_key)

Alternative: Explizite Validierung

def validate_api_key(key: str) -> bool: """Validiert das Format des API-Keys""" if not key: return False if len(key) < 20: return False # Weitere Validierungen hier... return True if not validate_api_key(api_key): raise ValueError("Ungültiger API-Key format")

Fehler 2: Tool-Calls werden ignoriert oder nicht erkannt

Symptom: Das Modell antwortet ohne Tool-Aufrufe, obwohl die Anfrage danach verlangt.

# FEHLERHAFT:

1. Falsches Tool-Format

tools = [{"type": "function", "function": {"name": "get_weather"}}] # Fehlt Schema!

2. model unterstützt kein Tool-Calling

response = await client.chat_completion( messages=messages, model="gpt-3.5-turbo", # Unterstützt zwar Tools, aber schlechte Qualität tools=tools )

LÖSUNG:

from langchain_core.messages import HumanMessage

Korrektes Tool-Format mit vollständigem Schema

tools = [ { "type": "function", "function": { "name": "get_weather", "description": "Ruft das aktuelle Wetter für einen Standort ab", "parameters": { "type": "object", "properties": { "city": { "type": "string", "description": "Der Name der Stadt" }, "country": { "type": "string", "description": "ISO 3166 Ländercode (z.B. 'DE', 'US')" } }, "required": ["city"] } } } ]

Explizite Tool-Auswahl aktivieren

response = await client.chat_completion( messages=messages, model="deepseek-v3.2", # Beste Kosten-Leistung für Tool-Calling tools=tools, tool_choice="auto" # Explizit Tool-Calling aktivieren )

Expliziter System-Prompt für Tool-Nutzung

messages = [ {"role": "system", "content": "Du MUSST Tools verwenden, wenn die Anfrage danach verlangt."}, {"role": "user", "content": user_query} ]

Fehler 3: Timeout bei langsamen Tool-Ausführungen

Symptom: "Request Timeout" Fehler oder hängende Verbindungen bei Datenbankabfragen oder externen API-Aufrufen.

# FEHLERHAFT:

client = httpx.AsyncClient() # Standard-Timeout (meist 5s zu kurz)

LÖSUNG:

import asyncio from functools import wraps from typing import Callable, Any def with_timeout(seconds: float): """Decorator für Timeout-Handling""" def decorator(func: Callable) -> Callable: @wraps(func) async def wrapper(*args, **kwargs) -> Any: try: return await asyncio.wait_for( func(*args, **kwargs), timeout=seconds ) except asyncio.TimeoutError: return { "error": "Timeout", "message": f"Operation dauerte länger als {seconds}s", "partial_result": None } return wrapper return decorator class RobustHolySheepClient(HolySheepAIClient): """Erweiterter Client mit Timeout-Handling""" def __init__(self, *args, tool_timeout: float = 30.0, **kwargs): super().__init__(*args, **kwargs) self.tool_timeout = tool_timeout