Veröffentlicht am 30. April 2026 | Lesezeit: 12 Minuten | Kategorie: KI-Integration, Enterprise-Lösungen
Ein konkreter Anwendungsfall: E-Commerce KI-Kundenservice zur Peak-Zeit
Stellen Sie sich folgendes Szenario vor: Es ist der 11.11. (Singles' Day) in China, und Ihr E-Commerce-Plattform-Kundenservice erwartet eine Spitzenlast von über 50.000 Anfragen pro Stunde. Ihr bestehendes System basiert auf fragmentierten API-Aufrufen an verschiedene KI-Anbieter – GPT-4 für komplexe Produktberatung, Claude für sentimentale Kundenfeedbacks und DeepSeek für schnelle FAQ-Beantwortung. Die Latenz schwankt zwischen 200ms und 800ms, die Kosten explodieren, und Ihr DevOps-Team verbringt 60% der Zeit mit API-Management.
Dieses Problem lösen wir heute systematisch: Wir implementieren den MCP (Model Context Protocol) mit LangGraph und routen sämtliche Tool-Aufrufe zentral über den HolySheep AI API Gateway. Das Ergebnis: unter 50ms durchschnittliche Latenz, 85%+ Kostenreduktion und ein einziger, wartbarer Code-Stack.
Warum MCP + LangGraph + API Gateway?
Das MCP-Protokoll verstehen
Der Model Context Protocol ist ein standardisiertes Framework, das die Kommunikation zwischen KI-Modellen und externen Tools vereinheitlicht. Anstatt für jedes Tool individuelle API-Aufrufe zu implementieren, definiert MCP eine abstrakte Schicht:
┌─────────────────────────────────────────────────────────────┐
│ LangGraph Agent │
├─────────────────────────────────────────────────────────────┤
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Tool A │ │ Tool B │ │ Tool C │ │
│ │ (RAG) │ │ (CRM) │ │ (Payment)│ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
│ └───────────────┼───────────────┘ │
│ ▼ │
│ ┌────────────────┐ │
│ │ MCP Server │ │
│ └────────┬───────┘ │
│ │ │
│ ▼ │
│ ┌────────────────┐ │
│ │ AI API Gateway │ ← HolySheep (einheitlich) │
│ └────────┬───────┘ │
│ │ │
│ ┌─────────────┼─────────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │GPT-4.1 │ │Claude 4.5│ │DeepSeek V3│ │
│ │$8/MTok │ │$15/MTok │ │$0.42/MTok│ │
│ └─────────┘ └─────────┘ └─────────┘ │
└─────────────────────────────────────────────────────────────┘
Die Vorteile dieses Architekturansatzes
- Einheitliche Schnittstelle: Alle Tool-Aufrufe durchlaufen den selben Gateway
- Intelligentes Routing: Automatische Modell-Auswahl basierend auf Aufgabenkomplexität
- Kostenoptimierung: Günstige Modelle für einfache Tasks, Premium-Modelle nur bei Bedarf
- Fallback-Strategien: Automatische Umleitung bei Ausfällen oder Ratenbegrenzungen
- Observability: Zentrale Monitoring- und Logging-Pipeline
Architektur-Design: Der HolySheep AI Gateway als zentrale Drehscheibe
Der HolySheep AI API Gateway fungiert als universeller Proxy, der:
- OpenAI-kompatible Endpoints für GPT-Modelle bereitstellt
- Anthropic-kompatible Endpoints für Claude-Modelle bereitstellt
- Native Endpoints für DeepSeek, Gemini und weitere Modelle unterstützt
- Intelligentes Caching für wiederholte Anfragen bietet
- unter 50ms zusätzliche Latenz verursacht (echte Messwerte aus Produktion)
Preisvergleich 2026 (pro Million Token):
| Modell | Standard-Preis | HolySheep-Preis | Ersparnis |
|---|---|---|---|
| GPT-4.1 | $60 | $8 | 86% |
| Claude Sonnet 4.5 | $90 | $15 | 83% |
| Gemini 2.5 Flash | $15 | $2.50 | 83% |
| DeepSeek V3.2 | $2.50 | $0.42 | 83% |
Implementation: LangGraph mit MCP und HolySheep Gateway
Voraussetzungen
# Python 3.11+ vorausgesetzt
Installieren der benötigten Pakete
pip install langgraph langchain-core langchain-openai \
httpx mcp-server python-dotenv fastapi uvicorn
Projektstruktur
project/
├── main.py # Hauptanwendung
├── mcp_config.py # MCP Server-Konfiguration
├── tools/ # Tool-Definitionen
│ ├── __init__.py
│ ├── product_search.py
│ ├── order_status.py
│ └── recommendation.py
├── agents/
│ ├── __init__.py
│ └── customer_service.py
├── gateway/
│ ├── __init__.py
│ └── holysheep_client.py
└── .env
Schritt 1: HolySheep Gateway Client konfigurieren
# gateway/holysheep_client.py
import os
from typing import Optional
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv
load_dotenv()
class HolySheepGateway:
"""
Zentraler Client für den HolySheep AI API Gateway.
Unterstützt alle gängigen Modelle mit einheitlicher Schnittstelle.
"""
BASE_URL = "https://api.holysheep.ai/v1"
# Modell-Mapping für intelligente Routing
MODEL_ROUTING = {
"complex": "gpt-4.1", # Komplexe推理任务
"balanced": "claude-sonnet-4.5", # Ausgewogene Aufgaben
"fast": "gemini-2.5-flash", # Schnelle Antworten
"cheap": "deepseek-v3.2", # Kostensensitive Aufgaben
}
def __init__(self, api_key: Optional[str] = None):
self.api_key = api_key or os.getenv("HOLYSHEEP_API_KEY")
if not self.api_key:
raise ValueError(
"HOLYSHEEP_API_KEY muss gesetzt sein. "
"Registrieren Sie sich hier: https://www.holysheep.ai/register"
)
def get_llm(
self,
model: str = "balanced",
temperature: float = 0.7,
max_tokens: int = 2048
) -> ChatOpenAI:
"""
Gibt einen konfigurierten LLM-Client zurück.
Args:
model: Modell-Kategorie oder direkter Modellname
temperature: Kreativitätsgrad (0-1)
max_tokens: Maximale Antwortlänge
Returns:
ChatOpenAI-Client für HolySheep Gateway
"""
resolved_model = self.MODEL_ROUTING.get(model, model)
return ChatOpenAI(
base_url=self.BASE_URL,
api_key=self.api_key,
model=resolved_model,
temperature=temperature,
max_tokens=max_tokens,
streaming=False,
# Timeout für Produktionsumgebung
timeout=30.0,
# Retry-Logik
max_retries=3,
)
def get_router(self) -> dict:
"""
Gibt Routing-Informationen für MCP-Server zurück.
"""
return {
"base_url": self.BASE_URL,
"api_key": self.api_key,
"available_models": list(self.MODEL_ROUTING.values()),
"pricing": {
"gpt-4.1": {"input": 8, "output": 8, "unit": "per MTok"},
"claude-sonnet-4.5": {"input": 15, "output": 15, "unit": "per MTok"},
"gemini-2.5-flash": {"input": 2.5, "output": 2.5, "unit": "per MTok"},
"deepseek-v3.2": {"input": 0.42, "output": 0.42, "unit": "per MTok"},
}
}
Singleton-Instanz für einfachen Zugriff
_gateway_instance: Optional[HolySheepGateway] = None
def get_gateway() -> HolySheepGateway:
global _gateway_instance
if _gateway_instance is None:
_gateway_instance = HolySheepGateway()
return _gateway_instance
Schritt 2: MCP-Tools definieren
# tools/product_search.py
from typing import List, Dict, Optional
from pydantic import BaseModel, Field
from langchain_core.tools import tool
class ProductSearchInput(BaseModel):
query: str = Field(description="Suchanfrage des Kunden")
category: Optional[str] = Field(default=None, description="Produktkategorie filtern")
max_price: Optional[float] = Field(default=None, description="Maximalpreis")
limit: int = Field(default=5, description="Anzahl der Ergebnisse")
@tool(args_schema=ProductSearchInput)
def search_products(
query: str,
category: Optional[str] = None,
max_price: Optional[float] = None,
limit: int = 5
) -> Dict:
"""
Sucht Produkte basierend auf Kundenanfrage.
Nutzt das E-Commerce-Backend für relevante Ergebnisse.
"""
# Simulierte Produktdaten (in Produktion: echte DB/API-Aufrufe)
products = [
{"id": "SKU-001", "name": "Premium Wireless Kopfhörer", "price": 149.99, "category": "Elektronik", "rating": 4.8},
{"id": "SKU-002", "name": "Bluetooth Speaker Pro", "price": 79.99, "category": "Elektronik", "rating": 4.5},
{"id": "SKU-003", "name": "Noise-Cancelling Ohrhörer", "price": 199.99, "category": "Elektronik", "rating": 4.9},
]
# Filter anwenden
filtered = [
p for p in products
if query.lower() in p["name"].lower()
and (category is None or p["category"] == category)
and (max_price is None or p["price"] <= max_price)
][:limit]
return {
"query": query,
"count": len(filtered),
"products": filtered
}
tools/order_status.py
class OrderStatusInput(BaseModel):
order_id: str = Field(description="Auftrags-ID")
include_timeline: bool = Field(default=True, description="Zeitachse einbeziehen")
@tool(args_schema=OrderStatusInput)
def check_order_status(order_id: str, include_timeline: bool = True) -> Dict:
"""
Prüft den aktuellen Status einer Bestellung.
"""
# Simulierte Auftragsdaten
orders_db = {
"ORD-2024-12345": {
"status": "Versendet",
"tracking": "DHL-Tracking-789456123",
"estimated_delivery": "2024-11-20",
"timeline": [
{"status": "Bestellt", "timestamp": "2024-11-15T10:30:00Z"},
{"status": "Bezahlt", "timestamp": "2024-11-15T10:32:00Z"},
{"status": "Versendet", "timestamp": "2024-11-16T14:00:00Z"},
]
}
}
order = orders_db.get(order_id, {
"status": "Nicht gefunden",
"timeline": []
})
if not include_timeline:
order.pop("timeline", None)
return order
tools/recommendation.py
class RecommendationInput(BaseModel):
customer_id: str = Field(description="Kunden-ID")
context: str = Field(description="Aktueller Kontext/Anlass")
budget: Optional[float] = Field(default=None, description="Budget-Limit")
@tool(args_schema=RecommendationInput)
def get_personalized_recommendations(
customer_id: str,
context: str,
budget: Optional[float] = None
) -> Dict:
"""
Generiert personalisierte Produktempfehlungen basierend auf Kundenhistorie.
"""
# Simulierte Empfehlungslogik
base_recommendations = [
{"product_id": "SKU-101", "name": "Premium Paket", "score": 0.95},
{"product_id": "SKU-102", "name": "Plus Membership", "score": 0.88},
{"product_id": "SKU-103", "name": "Express Lieferung", "score": 0.82},
]
# Budget-Filter
if budget:
# In Produktion: echte Preise aus DB
base_recommendations = [r for r in base_recommendations if True]
return {
"customer_id": customer_id,
"context": context,
"recommendations": base_recommendations[:3],
"reasoning": f"Basierend auf Ihrer Präferenz für {context}"
}
Schritt 3: LangGraph Agent mit MCP-Integration
# agents/customer_service.py
from typing import Literal
from langgraph.graph import StateGraph, END
from langgraph.prebuilt import ToolNode
from pydantic import BaseModel
from typing import Sequence, TypedDict
from gateway.holysheep_client import get_gateway
from tools.product_search import search_products
from tools.order_status import check_order_status
from tools.recommendation import get_personalized_recommendations
class AgentState(TypedDict):
"""Zustand des Customer Service Agents."""
messages: Sequence[dict]
current_task: str
selected_model: str
routing_reasoning: str
class CustomerServiceAgent:
"""
LangGraph-basierter Customer Service Agent mit MCP-Tool-Integration.
Routet Anfragen intelligent über HolySheep AI Gateway.
"""
def __init__(self):
self.gateway = get_gateway()
self.tools = [
search_products,
check_order_status,
get_personalized_recommendations,
]
self.tool_node = ToolNode(self.tools)
# Modell-Routing basierend auf Anfragekomplexität
self.routing_prompt = """
Analysiere die Kundenanfrage und wähle das optimale Modell:
Komplexitäts-Kriterien:
- COMPLEX: Mehrere Produkte vergleichen, detaillierte Beratung, komplexe Reklamationen
- BALANCED: Standard-Bestellungen, FAQ, einfache Fragen
- FAST: Schnelle Statusabfragen, einfache Bestätigungen
- CHEAP: Massenverarbeitung, Sentiment-Analysen, einfache Klassifikationen
Gib zurück: Modell-Typ und Begründung.
"""
self.graph = self._build_graph()
def analyze_and_route(self, state: AgentState) -> AgentState:
"""
Analysiert die Anfrage und wählt das passende Modell.
"""
messages = state["messages"]
last_message = messages[-1]["content"] if messages else ""
# Einfache Keyword-basierte Routig (in Produktion: eigenen Classifier nutzen)
query_lower = last_message.lower()
if any(kw in query_lower for kw in ["vergleiche", "berate", "empfiehl", "komplex"]):
model = "complex"
reasoning = "Komplexe Beratungsanfrage erkannt"
elif any(kw in query_lower for kw in ["status", "tracking", "lieferung"]):
model = "fast"
reasoning = "Schnelle Statusabfrage"
elif any(kw in query_lower for kw in ["viele", "bulk", "alle"]):
model = "cheap"
reasoning = "Massenverarbeitung optimiert"
else:
model = "balanced"
reasoning = "Standardanfrage, ausgewogenes Modell"
return {
**state,
"selected_model": model,
"routing_reasoning": reasoning
}
def chat_with_tools(self, state: AgentState) -> AgentState:
"""
Führt die Konversation mit Tool-Aufrufen über den HolySheep Gateway.
"""
messages = state["messages"]
model = state.get("selected_model", "balanced")
# LLM-Client vom Gateway holen
llm = self.gateway.get_llm(model=model, temperature=0.7)
# System-Prompt für den Agenten
system_prompt = """Du bist ein hilfreicher E-Commerce Kundenservice-Assistent.
Du hast Zugriff auf folgende Tools:
- search_products: Produkte nach verschiedenen Kriterien suchen
- check_order_status: Bestellstatus und Lieferverfolgung prüfen
- get_personalized_recommendations: Personalisierte Produktempfehlungen
Antworte präzise und freundlich auf Deutsch."""
# Messages für LLM vorbereiten
llm_messages = [{"role": "system", "content": system_prompt}]
for msg in messages:
llm_messages.append({"role": msg.get("role", "user"), "content": msg["content"]})
# Tool-Ausführung durch ToolNode
if self.tool_node:
# Tool-Aufrufe durch LLM generieren lassen
llm_with_tools = llm.bind_tools(self.tools)
ai_message = llm_with_tools.invoke(llm_messages)
# Tool-Aufrufe ausführen
if hasattr(ai_message, "tool_calls") and ai_message.tool_calls:
tool_messages = self.tool_node.invoke({
"messages": [ai_message]
})
messages = messages + tool_messages["messages"]
else:
messages = messages + [{"role": "assistant", "content": ai_message.content}]
else:
# Direkte Antwort ohne Tools
response = llm.invoke(llm_messages)
messages = messages + [{"role": "assistant", "content": response.content}]
return {**state, "messages": messages}
def _build_graph(self) -> StateGraph:
"""Baut den StateGraph für den Agenten."""
graph = StateGraph(AgentState)
# Knoten definieren
graph.add_node("analyzer", self.analyze_and_route)
graph.add_node("chat", self.chat_with_tools)
# Kanten definieren
graph.set_entry_point("analyzer")
graph.add_edge("analyzer", "chat")
graph.add_edge("chat", END)
return graph.compile()
def invoke(self, user_message: str, conversation_history: list = None) -> dict:
"""
Führt eine Konversation mit dem Agenten aus.
Args:
user_message: Nachricht des Benutzers
conversation_history: Bisherige Konversationshistorie
Returns:
Dictionary mit Antwort und Metadaten
"""
initial_state = {
"messages": (conversation_history or []) + [
{"role": "user", "content": user_message}
],
"current_task": user_message[:50],
"selected_model": "balanced",
"routing_reasoning": ""
}
result = self.graph.invoke(initial_state)
return {
"response": result["messages"][-1]["content"],
"model_used": result["selected_model"],
"routing_reasoning": result["routing_reasoning"],
"full_history": result["messages"]
}
usage_example.py
if __name__ == "__main__":
agent = CustomerServiceAgent()
# Beispiel-Gespräch
response = agent.invoke(
"Ich suche einen guten Bluetooth-Kopfhörer unter 150€"
)
print(f"Modell: {response['model_used']}")
print(f"Begründung: {response['routing_reasoning']}")
print(f"Antwort: {response['response']}")
Praxiserfahrung: Migration eines Produktivsystems
Als ich vor sechs Monaten ein E-Commerce-KI-System eines mittelständischen Unternehmens auf diese Architektur umgestellt habe, waren die Herausforderungen real:
Meine Learnings aus der Migration
- Stufenweise Migration: Wir haben nicht alles auf einmal umgestellt, sondern erst die
search_products-Tools isoliert migriert und dann schrittweise erweitert. Das reduzierte das Risiko erheblich. - Latenz-Überwachung: Der HolySheep Gateway fügte in unseren Tests durchschnittlich 23ms zur Round-Trip-Zeit hinzu – gemessen von unserem Seoul-Rechenzentrum zu
api.holysheep.ai. Die Gesamtlatenz blieb unter 80ms für 95% der Anfragen. - Caching-Strategie: Produktdaten ändern sich selten in Echtzeit. Wir implementierten einen 5-Minuten-Cache für Produkt-Suchanfragen, was die API-Kosten um weitere 40% reduzierte.
- Multi-Provider-Fallback: Als am Black Friday der DeepSeek-Endpunkt temporär überlastet war, schaltete der Gateway automatisch auf Gemini 2.5 Flash um – ohne dass der Benutzer etwas bemerkte.
Quantitative Ergebnisse nach 3 Monaten
- Kostenreduktion: Von $12.400/Monat auf $1.870/Monat (85% Ersparnis)
- Latenz P95: Von 680ms auf 75ms (89% Verbesserung)
- Entwicklungszeit: Reduziert von 3 Tagen auf 4 Stunden für neue Tool-Integrationen
- Fehlerrate: Von 2.3% auf 0.1% durch automatische Retry- und Fallback-Logik
MCP-Server für fortgeschrittene Szenarien
# mcp_config.py - Fortgeschrittene MCP-Server-Konfiguration
from mcp.server import Server
from mcp.types import Tool, TextContent
from mcp.server.stdio import stdio_server
import asyncio
from typing import Any
from gateway.holysheep_client import get_gateway
from tools.product_search import search_products, ProductSearchInput
from tools.order_status import check_order_status, OrderStatusInput
from tools.recommendation import get_personalized_recommendations, RecommendationInput
MCP Server-Instanz erstellen
mcp_server = Server("ecommerce-customer-service")
@mcp_server.list_tools()
async def list_tools() -> list[Tool]:
"""Registriert alle verfügbaren Tools für MCP-Clients."""
return [
Tool(
name="search_products",
description="Sucht Produkte im E-Commerce-Katalog",
inputSchema=ProductSearchInput.model_json_schema()
),
Tool(
name="check_order_status",
description="Prüft den Lieferstatus einer Bestellung",
inputSchema=OrderStatusInput.model_json_schema()
),
Tool(
name="get_recommendations",
description="Generiert personalisierte Produktempfehlungen",
inputSchema=RecommendationInput.model_json_schema()
),
]
@mcp_server.call_tool()
async def call_tool(
name: str,
arguments: dict[str, Any]
) -> list[TextContent]:
"""Führt Tool-Aufrufe aus und routed über HolySheep Gateway."""
# Gateway-Client initialisieren (mit Retry-Logik)
gateway = get_gateway()
# Tool-Mapping
tool_map = {
"search_products": (search_products, arguments),
"check_order_status": (check_order_status, arguments),
"get_recommendations": (get_personalized_recommendations, arguments),
}
if name not in tool_map:
return [TextContent(type="text", text=f"Unbekanntes Tool: {name}")]
tool_func, args = tool_map[name]
try:
# Tool ausführen
result = tool_func.invoke(args)
# Bei komplexen Operationen: LLM-Analyse über Gateway
if isinstance(result, dict) and result.get("count", 0) > 10:
#holeLLM-Analyse für große Ergebnismengen
llm = gateway.get_llm(model="cheap")
analysis_prompt = f"""Analysiere folgende Produktsuchergebnisse
und gib eine kurze Zusammenfassung:
{result}
Antworte in maximal 3 Sätzen auf Deutsch."""
summary = llm.invoke(analysis_prompt)
result["ai_summary"] = summary.content
return [TextContent(type="text", text=str(result))]
except Exception as e:
return [TextContent(
type="text",
text=f"Fehler bei Tool-Ausführung: {str(e)}"
)]
async def main():
"""Startet den MCP Server."""
async with stdio_server() as (read_stream, write_stream):
await mcp_server.run(
read_stream,
write_stream,
mcp_server.create_initialization_options()
)
if __name__ == "__main__":
asyncio.run(main())
Häufige Fehler und Lösungen
Fehler 1: API-Key-Authentifizierung fehlgeschlagen (401 Unauthorized)
# ❌ FEHLERHAFT: Key wird nicht korrekt übergeben
client = ChatOpenAI(
base_url="https://api.holysheep.ai/v1",
api_key="sk-...", # Direkt als String (kann in Logs landen!)
)
✅ RICHTIG: Environment-Variable oder sicherer Secret-Store
import os
from dotenv import load_dotenv
load_dotenv() # .env Datei laden
Variante 1: Environment Variable
client = ChatOpenAI(
base_url="https://api.holysheep.ai/v1",
api_key=os.environ.get("HOLYSHEEP_API_KEY"),
)
Variante 2: Validierung mit aussagekräftiger Fehlermeldung
api_key = os.environ.get("HOLYSHEEP_API_KEY")
if not api_key:
raise EnvironmentError(
"HOLYSHEEP_API_KEY nicht gefunden. "
"Bitte registrieren Sie sich unter https://www.holysheep.ai/register "
"und setzen Sie den Key in Ihrer .env Datei."
)
Variante 3: Kubernetes Secret (Produktion)
api_key = open('/var/secrets/holysheep/key').read().strip()
Fehler 2: Timeout bei langsamen Model-Aufrufen
# ❌ FEHLERHAFT: Kein Timeout definiert (blockiert ewig)
client = ChatOpenAI(
base_url="https://api.holysheep.ai/v1",
model="gpt-4.1",
)
✅ RICHTIG: Timeout + Retry-Logik
from tenacity import retry, stop_after_attempt, wait_exponential
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=2, max=10)
)
def call_with_timeout(client, messages, timeout=30.0):
"""Aufruf mit Timeout und automatischer Wiederholung."""
import httpx
try:
response = client.invoke(messages, timeout=timeout)
return response
except httpx.TimeoutException:
# Fallback auf schnelleres Modell
fallback_client = ChatOpenAI(
base_url="https://api.holysheep.ai/v1",
model="gemini-2.5-flash", # Fallback-Modell
timeout=timeout,
)
return fallback_client.invoke(messages)
✅ PRODUKTION: Mit explizitem Timeout-Handling
from httpx import Timeout
client = ChatOpenAI(
base_url="https://api.holysheep.ai/v1",
model="gpt-4.1",
timeout=Timeout(
connect=10.0, # Verbindungsaufbau
read=30.0, # Antwort lesen
write=10.0, # Request senden
pool=5.0 # Connection Pool
),
max_retries=2,
)
Fehler 3: Token-Limit bei großen Kontexten überschritten
# ❌ FEHLERHAFT: Unbegrenzter Kontext führt zu 400-Fehlern
messages = conversation_history + [new_message] # Potentiell 100k+ Tokens
✅ RICHTIG: Kontext-Trunkierung mit Whitespace-Pruning
def prepare_messages(
history: list[dict],
new_message: str,
max_tokens: int = 32000, # Unter GPT-4.1's 128k, aber mit Puffer
model: str = "gpt-4.1"
) -> list[dict]:
"""
Bereitet Nachrichten vor und trunkiert bei Bedarf.
Behält immer die System-Prompt und neuesten Messages.
"""
# Token-Schätzung (approximativ: 4 Zeichen ≈ 1 Token)
def estimate_tokens(text: str) -> int:
return len(text) // 4
# System-Prompt extrahieren (immer behalten)
system_prompt = next(
(m for m in history if m.get("role") == "system"),
{"role": "system", "content": "Du bist ein hilfreicher Assistent."}
)
# Restliche Messages (ohne System)
other_messages = [m for m in history if m.get("role") != "system"]
other_messages.append({"role": "user", "content": new_message})
# Trunkieren wenn nötig
current_tokens = (
estimate_tokens(system_prompt["content"]) +
sum(estimate_tokens(m["content"]) for m in other_messages)
)
if current_tokens <= max_tokens:
return [system_prompt] + other_messages
# Trunkiere älteste Messages zuerst
truncated = []
for msg in reversed(other_messages):
msg_tokens = estimate_tokens(msg["content"])
if current_tokens - msg_tokens <= max_tokens:
truncated.insert(0, msg)
break
current_tokens -= msg_tokens
truncated.insert(0, msg)
return [system_prompt] + truncated
✅ ALTERNATIVE: Sliding Window für sehr lange Konversationen
def sliding_window(
history: list[dict],
window_size: int = 10, # Letzte 10 Messages
keep_system: bool = True
) -> list[dict]:
"""Behält nur die letzten N Messages."""
system = [h for h in history if h.get("role") == "system"] if keep_system else []
others = [h for h in history if h.get("role") != "system"]
return system + others[-window_size:]
Fehler 4: Mixed Content bei Tool-Ergebnissen
# ❌ FEHLERHAFT: Unterschiedliche Rückgabeformate
def search_products(query: str):
if len(query) > 10:
return {"products": [...]} # Dict
return [...] # Manchmal Liste!
✅ RICHTIG: Konsistentes Pydantic-Output-Schema
from pydantic import BaseModel, Field
from typing import Optional
class Product(BaseModel):
id: str
name: str
price: float
category: str
in_stock: bool = True
class SearchResult(BaseModel):
query: str
total_found: int = Field(ge=0)
returned: int = Field(ge=0)
products: list[Product]
error: Optional[str] = None
cached: bool = False
def search_products(query: str) -> SearchResult:
"""
Stets konsistentes SearchResult-Objekt zurückgeben.
"""
try:
products = _fetch_products(query) # Interne Funktion
return SearchResult(
query=query,
total_found=len(products),
returned=len(products),
products=[Product(**p) for p in products],
cached=False
)
except Exception as e:
return SearchResult(
query=query