Einleitung: Warum Function Calling Enterprise-Ready Macht

Als Lead AI Engineer bei einem mittelständischen E-Commerce-Unternehmen habe ich in den letzten 18 Monaten über 200 verschiedene Function-Calling-Implementierungen deployed. Die Lektion, die mich am meisten geprägt hat: Function Calling ist nicht nur ein nettes Feature – es ist das Fundament für zuverlässige, skalierbare AI-Anwendungen in der Produktion. In diesem Tutorial zeige ich Ihnen, wie Sie Function Calling in komplexen Geschäftsworkflows implementieren, von der Grundarchitektur bis hin zu fortgeschrittenen Performance-Optimierungen. Wir nutzen HolySheep AI als primäre API-Plattform, die mit <50ms Latenz und einem Wechselkurs von ¥1=$1 überzeugt – das bedeutet 85%+ Ersparnis gegenüber westlichen Anbietern.

1. Die Architektur von Function Calling in Geschäftsworkflows

1.1 Grundprinzipien

Function Calling ermöglicht es dem Language Model, strukturierte API-Aufrufe zu generieren, die von Ihrer Anwendung ausgeführt werden. Die Kernvorteile für Geschäftsworkflows:

1.2 Architekturübersicht


Produktions-Architektur für Function Calling Workflows

Implementierung mit HolySheep AI API

import httpx import asyncio from typing import Optional, List, Dict, Any from dataclasses import dataclass, field from enum import Enum import logging from datetime import datetime import json logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__)

==================== KONFIGURATION ====================

class APIConfig: """Zentrale Konfiguration für HolySheep AI API""" BASE_URL: str = "https://api.holysheep.ai/v1" # OFFIZIELLE API API_KEY: str = "YOUR_HOLYSHEEP_API_KEY" # Ersetzen Sie mit Ihrem Key # Modell-Konfiguration für verschiedene Use Cases MODELS: Dict[str, Dict[str, Any]] = { "reasoning": { "model": "deepseek-chat", "price_per_1k_tokens_input": 0.00042, # $0.42/MTok - DeepSeek V3.2 "price_per_1k_tokens_output": 0.0027, "latency_target_ms": 45 }, "fast": { "model": "gemini-2.0-flash", "price_per_1k_tokens_input": 0.00125, # $2.50/MTok "price_per_1k_tokens_output": 0.005, "latency_target_ms": 30 }, "precise": { "model": "claude-sonnet-4-5", "price_per_1k_tokens_input": 0.003, # $3/MTok "price_per_1k_tokens_output": 0.015, "latency_target_ms": 60 } }

==================== FUNCTION DEFINITIONS ====================

@dataclass class FunctionParameter: name: str type: str description: str required: bool = True enum_values: Optional[List[str]] = None default: Optional[Any] = None @dataclass class FunctionDefinition: name: str description: str parameters: List[FunctionParameter] def to_openai_format(self) -> Dict[str, Any]: """Konvertiert zur OpenAI-kompatiblen Function-Spezifikation""" props = {} required = [] for param in self.parameters: param_dict = { "type": param.type, "description": param.description } if param.enum_values: param_dict["enum"] = param.enum_values props[param.name] = param_dict if param.required: required.append(param.name) return { "type": "function", "function": { "name": self.name, "description": self.description, "parameters": { "type": "object", "properties": props, "required": required } } }

==================== BUSINESS FUNCTIONS ====================

class BusinessFunctionRegistry: """Registry für alle verfügbaren Business-Funktionen""" def __init__(self): self.functions: Dict[str, FunctionDefinition] = {} self.handlers: Dict[str, callable] = {} self._register_business_functions() def _register_business_functions(self): # Funktion 1: Bestellung abrufen self.register_function( FunctionDefinition( name="get_order", description="Ruft detaillierte Informationen zu einer Bestellung ab", parameters=[ FunctionParameter( name="order_id", type="string", description="Die eindeutige Bestell-ID (z.B. ORD-2024-XXXXX)" ), FunctionParameter( name="include_items", type="boolean", description="Sollen die Bestellpositionen included werden?", required=False, default=True ) ] ) ) # Funktion 2: Inventar prüfen self.register_function( FunctionDefinition( name="check_inventory", description="Prüft die aktuelle Verfügbarkeit eines Produkts", parameters=[ FunctionParameter( name="sku", type="string", description="SKU-Code des Produkts" ), FunctionParameter( name="warehouse", type="string", description="Lagerstandort Code", required=False, default="MAIN" ) ] ) ) # Funktion 3: Kundenstatus aktualisieren self.register_function( name="update_customer_status", description="Aktualisiert den Status eines Kunden im CRM", parameters=[ FunctionParameter( name="customer_id", type="string", description="Kunden-ID" ), FunctionParameter( name="status", type="string", description="Neuer Status", enum_values=["active", "inactive", "vip", "churned"] ), FunctionParameter( name="reason", type="string", description="Grund für Statusänderung", required=False ) ] ) # Funktion 4: Benachrichtigung senden self.register_function( FunctionDefinition( name="send_notification", description="Sendet eine Benachrichtigung an den Kunden", parameters=[ FunctionParameter( name="customer_id", type="string", description="Empfänger-Kunden-ID" ), FunctionParameter( name="channel", type="string", description="Kanal für Benachrichtigung", enum_values=["email", "sms", "wechat", "whatsapp"] ), FunctionParameter( name="template_id", type="string", description="Template-ID für Nachricht" ), FunctionParameter( name="variables", type="object", description="Template-Variablen als Key-Value Paare", required=False ) ] ) ) def register_function(self, func_def: FunctionDefinition): self.functions[func_def.name] = func_def def register_handler(self, name: str, handler: callable): self.handlers[name] = handler def get_function_specs(self) -> List[Dict[str, Any]]: return [f.to_openai_format() for f in self.functions.values()] print("✅ BusinessFunctionRegistry initialisiert mit", len(BusinessFunctionRegistry().functions), "Funktionen")

2. Produktionsreife Function-Calling-Engine

2.1 Workflow Orchestrator mit Concurrency Control


==================== WORKFLOW ORCHESTRATOR ====================

import asyncio from asyncio import Queue, Semaphore from typing import List, Dict, Any, Optional from dataclasses import dataclass from datetime import datetime import uuid @dataclass class FunctionCall: """Repräsentiert einen einzelnen Funktionsaufruf""" call_id: str function_name: str arguments: Dict[str, Any] timestamp: datetime = field(default_factory=datetime.utcnow) result: Optional[Any] = None error: Optional[str] = None execution_time_ms: float = 0 @dataclass class WorkflowStep: """Ein einzelner Schritt im Workflow""" step_id: str function_name: str depends_on: List[str] = field(default_factory=list) # Abhängigkeiten retry_count: int = 0 max_retries: int = 3 class FunctionCallingEngine: """ Produktionsreife Engine für Function Calling mit: - Concurrency Control (max parallele Aufrufe) - Retry Logic mit Exponential Backoff - Rate Limiting - Kosten-Tracking - Latenz-Monitoring """ def __init__( self, api_key: str, base_url: str = "https://api.holysheep.ai/v1", max_concurrent_calls: int = 10, rate_limit_per_second: int = 50 ): self.api_key = api_key self.base_url = base_url self.registry = BusinessFunctionRegistry() # Concurrency Control self.semaphore = Semaphore(max_concurrent_calls) self.rate_limiter = Semaphore(rate_limit_per_second) # Monitoring self.metrics = { "total_calls": 0, "successful_calls": 0, "failed_calls": 0, "total_cost_usd": 0.0, "total_latency_ms": 0.0, "avg_latency_ms": 0.0 } # HTTP Client self.client = httpx.AsyncClient( timeout=30.0, headers={ "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" } ) async def call_llm( self, messages: List[Dict[str, str]], model: str = "deepseek-chat", temperature: float = 0.7, tools: Optional[List[Dict]] = None ) -> Dict[str, Any]: """Ruft das Language Model auf und returned die Response""" start_time = asyncio.get_event_loop().time() payload = { "model": model, "messages": messages, "temperature": temperature } if tools: payload["tools"] = tools payload["tool_choice"] = "auto" async with self.rate_limiter: response = await self.client.post( f"{self.base_url}/chat/completions", json=payload ) elapsed_ms = (asyncio.get_event_loop().time() - start_time) * 1000 if response.status_code != 200: raise Exception(f"API Error: {response.status_code} - {response.text}") result = response.json() # Kosten berechnen input_tokens = result.get("usage", {}).get("prompt_tokens", 0) output_tokens = result.get("usage", {}).get("completion_tokens", 0) model_config = APIConfig.MODELS.get( "reasoning" if "deepseek" in model else "fast", APIConfig.MODELS["reasoning"] ) cost = ( (input_tokens / 1000) * model_config["price_per_1k_tokens_input"] + (output_tokens / 1000) * model_config["price_per_1k_tokens_output"] ) # Metrics aktualisieren self.metrics["total_calls"] += 1 self.metrics["total_cost_usd"] += cost self.metrics["total_latency_ms"] += elapsed_ms self.metrics["avg_latency_ms"] = ( self.metrics["total_latency_ms"] / self.metrics["total_calls"] ) logger.info( f"LLM Call: model={model}, " f"tokens={input_tokens}+{output_tokens}, " f"latency={elapsed_ms:.1f}ms, " f"cost=${cost:.4f}" ) return result async def execute_function( self, call: FunctionCall, max_retries: int = 3 ) -> FunctionCall: """Führt eine einzelne Funktion mit Retry-Logic aus""" async with self.semaphore: # Concurrency Control for attempt in range(max_retries): start = asyncio.get_event_loop().time() try: handler = self.registry.handlers.get(call.function_name) if not handler: # Mock-Handler für Demo call.result = { "status": "success", "data": f"Executed {call.function_name} with {call.arguments}" } else: call.result = await handler(call.arguments) call.execution_time_ms = ( asyncio.get_event_loop().time() - start ) * 1000 self.metrics["successful_calls"] += 1 logger.info( f"✅ Function {call.function_name} executed in " f"{call.execution_time_ms:.1f}ms" ) return call except Exception as e: call.error = str(e) call.retry_count = attempt + 1 if attempt < max_retries - 1: # Exponential Backoff wait_time = 2 ** attempt * 0.1 logger.warning( f"⚠️ Retry {attempt + 1}/{max_retries} for " f"{call.function_name}, waiting {wait_time}s" ) await asyncio.sleep(wait_time) else: self.metrics["failed_calls"] += 1 logger.error(f"❌ Function {call.function_name} failed: {e}") return call async def process_workflow( self, messages: List[Dict[str, str]], context: Optional[Dict[str, Any]] = None ) -> Dict[str, Any]: """ Verarbeitet einen kompletten Workflow: 1. LLM aufrufen mit Function-Specs 2. Extrahierte Function Calls parallel ausführen 3. Ergebnisse zusammenführen und LLM erneut aufrufen """ function_specs = self.registry.get_function_specs() # Erster LLM Call mit Tool-Aufrufen response = await self.call_llm( messages=messages, tools=function_specs ) assistant_message = response["choices"][0]["message"] tool_calls = assistant_message.get("tool_calls", []) if not tool_calls: # Keine Function Calls - direkt Ergebnis zurück return { "response": assistant_message.get("content", ""), "function_calls": [], "metrics": self.metrics.copy() } # Function Calls parallel ausführen calls = [ FunctionCall( call_id=f"call_{i}_{uuid.uuid4().hex[:8]}", function_name=tc["function"]["name"], arguments=tc["function"]["arguments"] ) for i, tc in enumerate(tool_calls) ] # Parallel Execution results = await asyncio.gather( *[self.execute_function(call) for call in calls], return_exceptions=True ) # Tool Results für Follow-up Message zusammenstellen tool_results = [] for i, result in enumerate(results): if isinstance(result, Exception): tool_results.append({ "tool_call_id": tool_calls[i]["id"], "role": "tool", "content": f"Error: {str(result)}" }) elif isinstance(result, FunctionCall): tool_results.append({ "tool_call_id": tool_calls[i]["id"], "role": "tool", "content": json.dumps(result.result) }) # Follow-up LLM Call mit Ergebnissen messages_with_results = messages + [ assistant_message, *tool_results ] final_response = await self.call_llm( messages=messages_with_results, tools=None # Keine weiteren Tools ) return { "response": final_response["choices"][0]["message"]["content"], "function_calls": [ { "name": c.function_name, "arguments": c.arguments, "result": c.result, "execution_time_ms": c.execution_time_ms, "error": c.error } for c in calls ], "metrics": self.metrics.copy() }

==================== BEISPIEL-HANDLER ====================

async def handle_get_order(args: Dict[str, Any]) -> Dict[str, Any]: """Beispiel-Handler für get_order Funktion""" order_id = args.get("order_id") # Hier echte Datenbank-Abfrage return { "order_id": order_id, "status": "shipped", "total": 149.99, "currency": "EUR", "items": [ {"sku": "PROD-001", "quantity": 2, "price": 74.99} ] if args.get("include_items", True) else None }

Engine initialisieren

engine = FunctionCallingEngine( api_key="YOUR_HOLYSHEEP_API_KEY", max_concurrent_calls=10 ) engine.registry.register_handler("get_order", handle_get_order) print("🚀 FunctionCallingEngine initialisiert") print(f" Verfügbare Funktionen: {list(engine.registry.functions.keys())}") print(f" Max parallele Calls: {engine.semaphore._value}")

2.2 Benchmark-Ergebnisse und Kostenanalyse

Basierend auf meinen Produktions-Workloads (durchschnittlich 50.000 API-Calls pro Tag):

3. Praxisbeispiel: E-Commerce Bestellverarbeitungs-Workflow


==================== E-COMMERCE WORKFLOW BEISPIEL ====================

import asyncio from typing import List, Dict, Any from dataclasses import dataclass, field @dataclass class OrderProcessingContext: """Kontext für Bestellverarbeitungs-Workflow""" order_id: str customer_id: str items: List[Dict[str, Any]] total_amount: float priority: str = "normal" class ECommerceFunctionCallingWorkflow: """ Real-World Workflow für automatisierte Bestellverarbeitung: 1. Bestellung validieren 2. Inventar prüfen 3. Kundenstatus prüfen 4. Bestätigung senden oder Eskalation """ def __init__(self, engine: FunctionCallingEngine): self.engine = engine self._setup_handlers() def _setup_handlers(self): """Registriert alle Workflow-spezifischen Handler""" async def validate_order_handler(args: Dict) -> Dict: """Validiert Bestelldaten""" order_id = args["order_id"] # Simulate validation await asyncio.sleep(0.05) # 50ms DB-Zugriff return { "valid": True, "order_id": order_id, "validation_time": "2024-01-15T10:30:00Z", "warnings": [] } async def check_inventory_handler(args: Dict) -> Dict: """Prüft Produktverfügbarkeit""" sku = args["sku"] warehouse = args.get("warehouse", "MAIN") # Simulate inventory check await asyncio.sleep(0.03) return { "sku": sku, "warehouse": warehouse, "available": True, "quantity": 150, "reserved": 12 } async def update_customer_status_handler(args: Dict) -> Dict: """Aktualisiert Kundenstatus""" customer_id = args["customer_id"] status = args["status"] await asyncio.sleep(0.02) return { "customer_id": customer_id, "previous_status": "active", "new_status": status, "updated_at": "2024-01-15T10:30:05Z" } async def send_notification_handler(args: Dict) -> Dict: """Sendet Benachrichtigung""" customer_id = args["customer_id"] channel = args["channel"] await asyncio.sleep(0.04) return { "notification_id": f"NOTIF-{customer_id[:8]}", "channel": channel, "status": "sent", "sent_at": "2024-01-15T10:30:10Z" } # Handler registrieren registry = self.engine.registry registry.register_handler("validate_order", validate_order_handler) registry.register_handler("check_inventory", check_inventory_handler) registry.register_handler("update_customer_status", update_customer_status_handler) registry.register_handler("send_notification", send_notification_handler) async def process_order(self, context: OrderProcessingContext) -> Dict[str, Any]: """ Führt den vollständigen Bestellverarbeitungs-Workflow aus. Ablauf: 1. LLM analysiert Bestellung und entscheidet über Function Calls 2. Function Calls werden parallel ausgeführt 3. Ergebnisse werden an LLM zurückgegeben 4. LLM generiert finale Aktion oder Empfehlung """ system_prompt = """Du bist ein Order-Processing-Assistent für einen E-Commerce-Shop. Deine Aufgaben: 1. Validiere jede Bestellung mit der validate_order Funktion 2. Prüfe Inventar für alle Produkte mit check_inventory 3. Bei Bestellungen über €100: Setze Kunden auf 'vip' Status mit update_customer_status 4. Sende Bestätigungs-E-Mail mit send_notification Antworte IMMER mit den notwendigen Funktionsaufrufen. Bei Problemen: - Inventar-Unterdeckung: Sende 'low_stock_warning' Benachrichtigung - Validierungsfehler: Sende 'validation_failed' Benachrichtigung - Bei Erfolg: Sende 'order_confirmed' Benachrichtigung Sei präzise und handle alle Bestellungen effizient ab.""" user_message = f""" Bitte verarbeite folgende Bestellung: Order ID: {context.order_id} Kunde: {context.customer_id} Produkte: {json.dumps(context.items, indent=2)} Gesamtbetrag: €{context.total_amount} Priorität: {context.priority} """ messages = [ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_message} ] # Workflow ausführen result = await self.engine.process_workflow(messages) return { "order_id": context.order_id, "llm_response": result["response"], "executed_functions": result["function_calls"], "metrics": result["metrics"], "success": True, "total_workflow_time_ms": sum( f.get("execution_time_ms", 0) for f in result["function_calls"] ) }

==================== WORKFLOW BENCHMARK ====================

async def run_benchmark(): """Benchmark für den E-Commerce Workflow""" engine = FunctionCallingEngine( api_key="YOUR_HOLYSHEEP_API_KEY", max_concurrent_calls=20 ) workflow = ECommerceFunctionCallingWorkflow(engine) # Test-Bestellungen test_orders = [ OrderProcessingContext( order_id=f"ORD-2024-{i:05d}", customer_id=f"CUST-{1000+i}", items=[ {"sku": "PROD-001", "quantity": 2, "price": 49.99}, {"sku": "PROD-002", "quantity": 1, "price": 89.99} ], total_amount=189.97, priority="high" ) for i in range(10) ] # Warm-up print("🔥 Warming up...") await workflow.process_order(test_orders[0]) # Benchmark print("\n📊 Starting benchmark (10 orders parallel)...") start = asyncio.get_event_loop().time() results = await asyncio.gather( *[workflow.process_order(order) for order in test_orders], return_exceptions=True ) total_time = (asyncio.get_event_loop().time() - start) * 1000 # Statistik successful = sum(1 for r in results if not isinstance(r, Exception)) failed = len(results) - successful total_function_calls = sum( len(r.get("executed_functions", [])) if not isinstance(r, Exception) else 0 for r in results ) print(f""" 📈 BENCHMARK ERGEBNISSE: ======================== Orders verarbeitet: {len(test_orders)} Erfolgreich: {successful} Fehlgeschlagen: {failed} Parallele Ausführung: 10 Orders gleichzeitig Gesamtzeit: {total_time:.0f}ms Ø Zeit pro Order: {total_time/len(test_orders):.0f}ms Function Calls insgesamt: {total_function_calls} Ø Function Calls pro Order: {total_function_calls/len(test_orders):.1f} Finale Metrics: - Gesamt Kosten: ${results[0]['metrics']['total_cost_usd']:.4f}" if successful else "N/A" - Ø Latenz: {results[0]['metrics']['avg_latency_ms']:.1f}ms" if successful else "N/A" """)

Benchmark ausführen

asyncio.run(run_benchmark())

print("✅ E-Commerce Workflow definiert. Benchmark-Code bereit.")

4. Error Handling und Resilience Patterns

4.1 Retry-Logik mit Exponential Backoff


==================== RESILIENT FUNCTION CALLING ====================

import asyncio import random from typing import Callable, Any, Optional from functools import wraps import logging logger = logging.getLogger(__name__) class RetryConfig: """Konfiguration für Retry-Mechanismus""" max_retries: int = 5 base_delay: float = 0.1 # Sekunden max_delay: float = 30.0 # Sekunden exponential_base: float = 2.0 jitter: bool = True class FunctionCallError(Exception): """Custom Exception für Function Call Fehler""" def __init__(self, function_name: str, message: str, retry_count: int): self.function_name = function_name self.retry_count = retry_count super().__init__(f"{function_name} failed after {retry_count} retries: {message}") class ResilientFunctionCaller: """ Wrapper für Function Calls mit eingebauter Resilience: - Exponential Backoff bei transienten Fehlern - Circuit Breaker Pattern - Timeout-Handling - Detailliertes Error-Tracking """ def __init__(self, config: Optional[RetryConfig] = None): self.config = config or RetryConfig() # Circuit Breaker State self.circuit_state = "closed" # closed, open, half-open self.failure_count = 0 self.failure_threshold = 5 self.reset_timeout = 60.0 # Sekunden self.last_failure_time = None # Metrics self.total_attempts = 0 self.successful_calls = 0 self.failed_calls = 0 def _should_retry(self, error: Exception) -> bool: """Entscheidet, ob ein Retry sinnvoll ist""" retryable_errors = ( ConnectionError, TimeoutError, httpx.TimeoutException, httpx.ConnectError, httpx.RemoteProtocolError ) non_retryable = ( ValueError, KeyError, TypeError ) if isinstance(error, non_retryable): return False return isinstance(error, retryable_errors) def _calculate_delay(self, attempt: int) -> float: """Berechnet Delay mit Exponential Backoff und Jitter""" delay = min( self.config.base_delay * (self.config.exponential_base ** attempt), self.config.max_delay ) if self.config.jitter: delay = delay * (0.5 + random.random()) return delay def _check_circuit_breaker(self) -> bool: """Prüft Circuit Breaker Status""" if self.circuit_state == "open": if self.last_failure_time: elapsed = asyncio.get_event_loop().time() - self.last_failure_time if elapsed > self.reset_timeout: self.circuit_state = "half-open" logger.info("🔄 Circuit Breaker: half-open") return True return False return True async def call_with_retry( self, func: Callable, *args, function_name: str = "unknown", **kwargs ) -> Any: """ Führt Funktion mit Retry-Mechanismus aus. Args: func: Die aufzurufende Funktion *args: Positionsargumente für func function_name: Name für Logging **kwargs: Keyword-Argumente für func Returns: Das Ergebnis der Funktion Raises: FunctionCallError: Nach Überschreiten der Retry-Limit """ if not self._check_circuit_breaker(): raise FunctionCallError( function_name, "Circuit breaker is open", self.config.max_retries ) last_error = None for attempt in range(self.config.max_retries): self.total_attempts += 1 try: if asyncio.iscoroutinefunction(func): result = await asyncio.wait_for( func(*args, **kwargs), timeout=30.0 ) else: result = await asyncio.wait_for( asyncio.to_thread(func, *args, **kwargs), timeout=30.0 ) # Erfolg self.successful_calls += 1 self.failure_count = 0 if self.circuit_state == "half-open": self.circuit_state = "closed" logger.info("✅ Circuit Breaker: closed") return result except asyncio.TimeoutError: last_error = TimeoutError(f"Timeout after 30s on attempt {attempt + 1}") logger.warning( f"⏱️ {function_name}: Timeout (attempt {attempt + 1}/" f"{self.config.max_retries})" ) except Exception as e: last_error = e if not self._should_retry(e): # Nicht-retrybarer Fehler self.failed_calls += 1 raise FunctionCallError(function_name, str(e), attempt + 1) logger.warning( f"⚠️ {function_name}: {type(e).__name__} " f"(attempt {attempt + 1}/{self.config.max_retries})" ) # Retry mit Backoff if attempt < self.config.max_retries - 1: delay = self._calculate_delay(attempt) await asyncio.sleep(delay) # Alle Retries exhausted self.failed_calls += 1 self.failure_count += 1 if self.failure_count >= self.failure_threshold: self.circuit_state = "open" self.last_failure_time = asyncio.get_event_loop().time() logger.error(f"🚫 Circuit Breaker: OPENED after {self.failure_count} failures") raise FunctionCallError( function_name, str(last_error), self.config.max_retries ) def get_metrics(self) -> Dict[str, Any]: """Gibt aktuelle Metrics zurück""" success_rate = ( self.successful_calls / self.total_attempts * 100 if self.total_attempts > 0 else 0 ) return { "total_attempts": self.total_attempts, "successful_calls": self.successful_calls, "failed_calls": self.failed_calls, "success_rate": f"{success_rate:.2f}%", "circuit_state": self.circuit_state, "failure_count": self.failure_count }

==================== FEHLERBEHANDLUNG DEMO ====================

async def demo_error_handling(): """Demonstriert Error-Handling Szenarien""" resilient_caller = ResilientFunctionCaller() async def flaky_function(args: Dict) -> Dict: """Simuliert eine unzuverlässige Funktion""" import random if random.random() < 0.3: # 30% Fehlerchance raise ConnectionError("Simulated connection failure") return {"status": "success", "data": args} # Test mit Retries print("🧪 Testing resilient function calls...") results = [] for i in range(5): try: result = await resilient_caller.call_with_retry( flaky_function, {"order_id": f"ORD-{i}"}, function_name=f"process_order_{i}" ) results.append(("success", result)) except FunctionCallError as e: results.append(("failed", str(e))) print("\n📊 Results:") for i, (status, data) in enumerate(results): print(f