von HolySheep AI Engineering Team | April 2026
Der Albtraum in der Produktion: Warum Multi-Agent-Systeme scheitern
Es ist Freitagabend, 23:47 Uhr. Ihr Produktionssystem für automatisierte Kundenanfragen meldet plötzlich:
ConnectionError: HTTPSConnectionPool(host='api.openai.com', port=443):
Max retries exceeded with url: /v1/chat/completions
(Caused by NewConnectionError: '<urllib3.connection.HTTPSConnection object at 0x...>:
Failed to establish a new connection: [Errno 110] Connection timed out'))
RuntimeError: Agent 'support_agent' failed after 3 retry attempts
Original error: 401 Unauthorized - Invalid API key or rate limit exceeded
Was als harmlose Nachtschicht begann, wird zum Desaster: 2.347 wartende Kunden, ein komplett ausgefallener Agent-Orchestrierungs-Layer, und Sie wissen nicht, ob das Problem bei OpenAI, Ihrem Code oder Ihrem Retry-Logic liegt.
Dieses Szenario – oder Variationen davon – erlebt jedes Team, das Multi-Agent-Systeme in Produktion bringt. In diesem Artikel analysieren wir die beiden führenden Frameworks LangGraph und CrewAI aus der Perspektive von Production-Engineering: Wie bauen Sie robustes Multi-Model-API-Routing und Failure-Retry-Architekturen, die nicht nur funktionieren, sondern auch bezahlbar bleiben?
Was ist LangGraph und was ist CrewAI?
LangGraph: Das Low-Level-Framework für komplexe Workflows
LangGraph (von LangChain) ist ein framework zur Erstellung von stateful, zyklenbasierten Applikationen mit Large Language Models. Es bietet maximale Kontrolle über den Kontrollfluss und eignet sich für komplexe, verzweigte Agenten-Workflows.
CrewAI: Das High-Level-Framework für Team-basierte Agenten
CrewAI abstrahiert die Komplexität und ermöglicht die schnelle Erstellung von "Crews" – Teams von Agenten, die zusammenarbeiten. Der Fokus liegt auf Einfachheit und schneller Entwicklung.
Architektonischer Vergleich: Die Kernunterschiede
| Feature | LangGraph | CrewAI | HolySheep AI |
|---|---|---|---|
| Abstraktionslevel | Low-Level (State Machine) | High-Level (Team-basiert) | Middleware + API-Routing |
| Zyklische Graphen | ✓ Native Unterstützung | ✗ Eingeschränkt | ✓ Routing-Logik |
| Checkpointing | ✓ Integriert | ✗ Nicht nativ | ✓ Session-Management |
| Retry-Logic | Manuell zu implementieren | Grundlegend | ✓ Automatisch + konfigurierbar |
| Multi-Model Support | Über LangChain Integrationen | OpenAI/Claude/Custom | ✓ Alle gängigen + DeepSeek |
| Latenz (P50) | Abhängig vom Provider | Abhängig vom Provider | <50ms Routing-Latenz |
| Fehlerbehandlung | Explicite Definition nötig | Try/Catch-Blöcke | ✓ Automatisch + Webhooks |
| Lernkurve | Steil | Flach | Minimal (bietet Wrapper) |
Production-Grade API Routing mit HolySheep AI
Bevor wir in die Frameworks eintauchen: Das Fundament jeder Multi-Agent-Architektur ist ein robustes API-Routing-System. HolySheep AI bietet genau das – mit <50ms zusätzlicher Latenz und automatisiertem Failover zwischen 15+ Modellen.
HolySheep Multi-Model Router: Die Architektur
import requests
from typing import Optional, Dict, Any
import json
class HolySheepRouter:
"""
Production-grade Multi-Model Router mit automatischem Failover
und kostenlosem Retry-Management.
"""
def __init__(self, api_key: str):
self.base_url = "https://api.holysheep.ai/v1"
self.api_key = api_key
self.headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
def chat_completion(
self,
messages: list,
model: str = "gpt-4.1",
fallback_models: Optional[list] = None,
max_retries: int = 3,
timeout: int = 30
) -> Dict[str, Any]:
"""
Intelligentes Routing mit automatischem Fallback.
Verfügbare Modelle und Preise (2026):
- gpt-4.1: $8.00/MTok (Eingabe), $24.00/MTok (Ausgabe)
- claude-sonnet-4.5: $15.00/MTok (Eingabe), $75.00/MTok (Ausgabe)
- gemini-2.5-flash: $2.50/MTok (Eingabe), $10.00/MTok (Ausgabe)
- deepseek-v3.2: $0.42/MTok (Eingabe), $1.68/MTok (Ausgabe)
"""
models_to_try = [model] + (fallback_models or [])
for attempt_model in models_to_try:
try:
payload = {
"model": attempt_model,
"messages": messages,
"temperature": 0.7,
"max_tokens": 2048
}
response = requests.post(
f"{self.base_url}/chat/completions",
headers=self.headers,
json=payload,
timeout=timeout
)
if response.status_code == 200:
return response.json()
elif response.status_code == 401:
raise PermissionError("API-Key ungültig oder nicht aktiviert")
elif response.status_code == 429:
# Rate Limit: Exponential Backoff
retry_after = int(response.headers.get("Retry-After", 5))
import time
time.sleep(retry_after)
continue
elif response.status_code >= 500:
# Server-Fehler: Weiter zum nächsten Modell
continue
except requests.exceptions.Timeout:
print(f"[WARN] Timeout für Modell {attempt_model}, weiter...")
continue
except requests.exceptions.ConnectionError:
print(f"[WARN] ConnectionError für Modell {attempt_model}")
continue
raise RuntimeError(f"Alle {len(models_to_try)} Modelle fehlgeschlagen")
Beispiel-Usage
router = HolySheepRouter(api_key="YOUR_HOLYSHEEP_API_KEY")
result = router.chat_completion(
messages=[{"role": "user", "content": "Analysiere diese Verkaufsdaten"}],
model="deepseek-v3.2",
fallback_models=["gemini-2.5-flash", "gpt-4.1"]
)
LangGraph: Production-Architektur mit Robustem Error Handling
State-Definition und Error States
from typing import TypedDict, Annotated, Optional
from langgraph.graph import StateGraph, END
import operator
from enum import Enum
class AgentState(TypedDict):
"""Erweiterter State mit Fehler-Tracking für Produktion."""
# Kern-Daten
messages: list
current_task: str
assigned_model: str
# Fehlerbehandlung
error_count: int
last_error: Optional[str]
retry_history: list
# Quality Gates
quality_score: float
requires_review: bool
# Routing-Entscheidungen
routing_path: list
fallback_triggered: bool
class ErrorType(Enum):
"""Standardisierte Fehlertypen für Monitoring."""
CONNECTION_TIMEOUT = "connection_timeout"
AUTH_FAILURE = "auth_failure"
RATE_LIMIT = "rate_limit"
MODEL_UNAVAILABLE = "model_unavailable"
VALIDATION_ERROR = "validation_error"
UNKNOWN = "unknown"
def create_production_graph():
"""Production-Grade LangGraph mit vollständiger Fehlerbehandlung."""
workflow = StateGraph(AgentState)
# Knoten definieren
workflow.add_node("router", route_request)
workflow.add_node("validate", validate_input)
workflow.add_node("primary_agent", primary_llm_call)
workflow.add_node("fallback_agent", fallback_llm_call)
workflow.add_node("quality_check", quality_assessment)
workflow.add_node("error_handler", handle_error)
workflow.add_node("finalize", finalize_response)
# Kanten definieren
workflow.set_entry_point("router")
workflow.add_edge("router", "validate")
workflow.add_edge("validate", "primary_agent")
# Fehlerbehandlung mit bedingten Kanten
workflow.add_conditional_edges(
"primary_agent",
check_primary_result,
{
"success": "quality_check",
"retry": "primary_agent",
"fallback": "fallback_agent",
"abort": "error_handler"
}
)
workflow.add_edge("quality_check", "finalize")
workflow.add_edge("fallback_agent", "quality_check")
workflow.add_edge("error_handler", END)
workflow.add_edge("finalize", END)
return workflow.compile(
checkpointer=None, # In Produktion: persistent storage
interrupt_before=["error_handler"] # Pause bei kritischen Fehlern
)
def check_primary_result(state: AgentState) -> str:
"""Entscheidungslogik basierend auf dem Primary-Agent-Result."""
if state.get("error_count", 0) >= 3:
return "abort"
if state.get("last_error") == ErrorType.RATE_LIMIT.value:
return "retry"
if state.get("last_error") in [
ErrorType.CONNECTION_TIMEOUT.value,
ErrorType.MODEL_UNAVAILABLE.value
]:
return "fallback"
return "success"
def handle_error(state: AgentState) -> AgentState:
"""Zentralisiertes Error-Handling mit Alerting."""
error_log = {
"timestamp": "2026-04-30T15:33:00Z",
"error_type": state.get("last_error"),
"error_count": state.get("error_count"),
"routing_path": state.get("routing_path"),
"assigned_model": state.get("assigned_model")
}
# Hier: Webhook für Monitoring-System (PagerDuty, Sentry, etc.)
# send_alert(error_log)
return {
**state,
"messages": state["messages"] + [{
"role": "system",
"content": f"System-Fehler nach {state['error_count']} Versuchen. "
f"Kontaktiere den Support mit Ticket-ID: {generate_ticket_id()}"
}]
}
CrewAI: Production-Setup mit Retry-Mechanismen
from crewai import Agent, Task, Crew
from crewai.tools import BaseTool
from pydantic import BaseModel, Field
from typing import Optional, Callable
import time
from functools import wraps
class RetryConfig(BaseModel):
"""Konfiguration für Retry-Mechanismen."""
max_retries: int = Field(default=3)
base_delay: float = Field(default=1.0)
max_delay: float = Field(default=60.0)
exponential_base: float = Field(default=2.0)
retry_on: list = Field(default_factory=lambda: ["timeout", "rate_limit", "connection"])
def retry_with_backoff(config: RetryConfig):
"""Decorator für exponentielle Backoff-Retry-Logik."""
def decorator(func: Callable):
@wraps(func)
def wrapper(*args, **kwargs):
last_exception = None
for attempt in range(config.max_retries):
try:
return func(*args, **kwargs)
except Exception as e:
error_type = classify_error(str(e))
last_exception = e
if error_type not in config.retry_on:
raise # Nicht-wiederholbare Fehler sofort weiterleiten
if attempt < config.max_retries - 1:
delay = min(
config.base_delay * (config.exponential_base ** attempt),
config.max_delay
)
# Jitter für Last-Verteilung
import random
delay *= (0.5 + random.random())
print(f"[RETRY] Attempt {attempt + 1}/{config.max_retries} "
f"nach {delay:.1f}s Wartezeit")
time.sleep(delay)
raise last_exception
return wrapper
return decorator
def classify_error(error_message: str) -> str:
"""Klassifiziert Fehler für Retry-Entscheidungen."""
error_lower = error_message.lower()
if "timeout" in error_lower:
return "timeout"
elif "429" in error_lower or "rate limit" in error_lower:
return "rate_limit"
elif "connection" in error_lower:
return "connection"
elif "401" in error_lower or "unauthorized" in error_lower:
return "auth" # Nicht wiederholbar
elif "500" in error_lower or "502" in error_lower or "503" in error_lower:
return "server_error"
return "unknown"
class ProductionCrewAI:
"""Production-Ready CrewAI mit integriertem Routing."""
def __init__(self, holysheep_api_key: str):
self.api_key = holysheep_api_key
self.base_url = "https://api.holysheep.ai/v1"
# Retry-Konfiguration pro Agent
self.retry_config = RetryConfig(
max_retries=3,
base_delay=2.0,
max_delay=30.0
)
def create_research_crew(self) -> Crew:
"""Erstellt eine Research-Crew mit robustem Error-Handling."""
researcher = Agent(
role="Senior Research Analyst",
goal="Finde und synthetisiere relevante Informationen",
backstory="Du bist ein erfahrener Analyst mit Zugang zu aktuellen Daten.",
tools=[search_tool, scraping_tool],
verbose=True,
max_iterations=3,
max_retry_limit=2
)
synthesizer = Agent(
role="Information Synthesizer",
goal="Erstelle klare, strukturierte Zusammenfassungen",
backstory="Du distillierst komplexe Informationen in klare Insights.",
verbose=True,
max_iterations=2,
max_retry_limit=2
)
research_task = Task(
description="Recherchiere aktuelle Trends in AI-Agent-Frameworks",
agent=researcher,
expected_output="Detaillierte Recherche-Ergebnisse"
)
synthesis_task = Task(
description="Synthetisiere die Recherche zu einer Executive Summary",
agent=synthesizer,
expected_output="Executive Summary mit Key Insights",
context=[research_task] # Abhängigkeit
)
crew = Crew(
agents=[researcher, synthesizer],
tasks=[research_task, synthesis_task],
process="hierarchical", # Sequentiell mit Manager
manager_agent=Agent(
role="Crew Manager",
goal="Koordiniere die Zusammenarbeit und handle Fehler",
backstory="Erfahrener Projektmanager für AI-Teams."
)
)
return crew
@retry_with_backoff(config=RetryConfig(max_retries=3))
def execute_with_fallback(self, crew: Crew, input_data: dict):
"""
Führt Crew aus mit automatischem Fallback.
Nutzt HolySheep AI für kosteneffizientes Routing.
"""
try:
# Primär: Nutze CrewAI mit HolySheep als Backend
result = crew.kickoff(inputs=input_data)
return {"status": "success", "result": result}
except Exception as e:
error_type = classify_error(str(e))
if error_type in ["timeout", "rate_limit", "connection"]:
# Fallback: Direkter HolySheep API-Call
print(f"[FALLBACK] Switching to direct API due to: {error_type}")
return self._direct_api_fallback(input_data)
raise
Usage
crew_ai = ProductionCrewAI(holysheep_api_key="YOUR_HOLYSHEEP_API_KEY")
research_crew = crew_ai.create_research_crew()
result = crew_ai.execute_with_fallback(research_crew, {"topic": "Multi-Agent Frameworks"})
Geeignet / Nicht geeignet für
LangGraph ist ideal für:
- Komplexe, zyklenbasierte Workflows – Wenn您的 Agents sich gegenseitig aufrufen müssen
- Fine-grained Control – Wenn您 maximale Kontrolle über den Kontrollfluss brauchen
- Forschung & Prototyping – Neue Agent-Architekturen entwickeln
- Stateful Anwendungen – Checkpointing und Resume-Funktionalität
- Langfristige Projekte – Wenn您 bereit sind, die steile Lernkurve zu investieren
LangGraph ist NICHT ideal für:
- Rapid Prototyping – Zu viel Boilerplate für einfache Use Cases
- Kleine Teams – Hoher Wartungsaufwand
- Standard-Workflows – Wenn您 nur Agenten zusammenarbeiten lassen wollen
CrewAI ist ideal für:
- Quick MVP Development – Schnell funktionierende Agenten-Teams
- Business-Anwender – Weniger technisches Know-how nötig
- Standard-Pipelines – Wenn您的 Workflows relativ linear sind
- Prototyping – Ideen schnell testen
CrewAI ist NICHT ideal für:
- Komplexe Zustandslogik – Keine nativen Zyklen
- Mission-Critical Production – Begrenzte Error-Handling-Optionen
- High-Volume Production – Kein natives Rate-Limit-Management
HolySheep AI ist ideal für:
- Budget-bewusste Teams – 85%+ Ersparnis gegenüber OpenAI
- Multi-Provider Strategie – 15+ Modelle, ein Endpoint
- Production-Workloads – <50ms Routing-Latenz, automatischer Failover
- China-basierte Teams – WeChat/Alipay Zahlung, CNY-Unterstützung
Preise und ROI: Der wahre Kostenvergleich
| Modell | Input ($/MTok) | Output ($/MTok) | 1M Token (In+Out) | Ersparnis vs. OpenAI |
|---|---|---|---|---|
| GPT-4.1 | $8.00 | $24.00 | $32.00 | Benchmark |
| Claude Sonnet 4.5 | $15.00 | $75.00 | $90.00 | +181% teurer |
| Gemini 2.5 Flash | $2.50 | $10.00 | $12.50 | 61% günstiger |
| DeepSeek V3.2 | $0.42 | $1.68 | $2.10 | 93% günstiger |
| HolySheep Routing | Variabel | Variabel | Optimal | 85%+ durch Smart Routing |
Real-World ROI-Beispiel
Angenommen, Sie betreiben ein Multi-Agent-System mit folgenden Volumina:
- 10 Millionen Input-Token/Monat
- 5 Millionen Output-Token/Monat
- Mix: 40% Gemini Flash, 30% DeepSeek, 30% GPT-4.1
Kosten mit OpenAI (nur GPT-4.1):
- Input: 15M × $30/MTok = $450
- Output: 5M × $60/MTok = $300
- Gesamt: $750/Monat
Kosten mit HolySheep Smart Routing:
- 6M Gemini Flash Input: 6M × $2.50/MTok = $15
- 6M DeepSeek Input: 6M × $0.42/MTok = $2.52
- 3M GPT-4.1 Input: 3M × $8.00/MTok = $24
- 2M Gemini Flash Output: 2M × $10/MTok = $20
- 1.5M DeepSeek Output: 1.5M × $1.68/MTok = $2.52
- 1.5M GPT-4.1 Output: 1.5M × $24/MTok = $36
- Gesamt: ~$100/Monat
Ersparnis: $650/Monat = 87% günstiger
Warum HolySheep AI für Production-Deployments wählen
1. Integriertes Multi-Model Routing
Statt komplexer Retry-Logik in Ihrer Anwendung: HolySheep AI übernimmt das intelligente Routing. Mit <50ms zusätzlicher Latenz routet unser System automatisch zum optimalen Modell basierend auf:
- Aktuelle Verfügbarkeit
- Preis-Leistungs-Verhältnis
- Ihren definierten Fallback-Strategien
2. 85%+ Kostenersparnis
Mit Preisen ab $0.42/MTok für DeepSeek V3.2 (im Vergleich zu $30/MTok bei OpenAI) können Sie dieselben Workflows zu einem Bruchteil der Kosten betreiben.
3. Enterprise-Features inklusive
- Kostenlose Credits – Testen Sie ohne Risiko
- WeChat/Alipay Support – Lokale Zahlungsmethoden
- Webhook-Alerting – Proaktives Monitoring
- SLA-garantierte Uptime – 99.9% Verfügbarkeit
4. Nahtlose Integration
HolySheep AI funktioniert mit Ihrer bestehenden LangGraph- oder CrewAI-Implementierung. Ersetzen Sie einfach den API-Endpoint:
# Vorher (OpenAI)
client = OpenAI(api_key="sk-...")
Nachher (HolySheep) - Minimal-Änderung
client = OpenAI(
api_key="YOUR_HOLYSHEEP_API_KEY",
base_url="https://api.holysheep.ai/v1"
)
Häufige Fehler und Lösungen
Fehler 1: Connection Timeout bei Hochlast
# FEHLER: Standard-Timeout zu kurz für Production
response = openai.ChatCompletion.create(
model="gpt-4",
messages=messages,
timeout=10 # Zu kurz!
)
LÖSUNG: Adaptive Timeouts mit HolySheep
import requests
class AdaptiveTimeoutClient:
def __init__(self, api_key: str):
self.base_url = "https://api.holysheep.ai/v1"
self.session = requests.Session()
self.session.headers.update({
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
})
def chat_complete(self, messages: list, model: str = "deepseek-v3.2"):
"""
Adaptive Timeouts:
- Base: 30s für schnelle Modelle (DeepSeek, Gemini Flash)
- Extended: 120s für komplexe Tasks (GPT-4.1, Claude)
"""
timeout = 30 if "flash" in model.lower() or "deepseek" in model.lower() else 120
payload = {
"model": model,
"messages": messages,
"temperature": 0.7
}
for attempt in range(3):
try:
response = self.session.post(
f"{self.base_url}/chat/completions",
json=payload,
timeout=(5, timeout) # (connect_timeout, read_timeout)
)
if response.status_code == 200:
return response.json()
elif response.status_code == 429:
retry_after = int(response.headers.get("Retry-After", 10))
import time
time.sleep(retry_after)
except requests.exceptions.Timeout:
print(f"[RETRY] Timeout-Attempt {attempt + 1}")
continue
raise TimeoutError(f"Request failed after 3 attempts")
Fehler 2: 401 Unauthorized – Rate Limit oder ungültiger Key
# FEHLER: Keine Unterscheidung zwischen Auth- und Rate-Limit-Fehlern
try:
result = client.chat.completions.create(...)
except Exception as e:
print(f"Error: {e}") # Ignoriert den Unterschied!
LÖSUNG: Differenzierte Fehlerbehandlung
class HolySheepClient:
def __init__(self, api_key: str):
self.api_key = api_key
def _handle_error(self, response: requests.Response) -> dict:
"""Differenzierte Fehlerbehandlung."""
status_code = response.status_code
error_data = response.json() if response.content else {}
error_message = error_data.get("error", {}).get("message", "Unknown error")
if status_code == 401:
# Auth-Fehler: Unmittelbar stoppen, kein Retry
return {
"action": "abort",
"message": f"Authentication failed: {error_message}",
"can_retry": False
}
elif status_code == 403:
# Forbidden: Möglicherweise Subscription abgelaufen
return {
"action": "abort",
"message": f"Access forbidden: {error_message}",
"can_retry": False
}
elif status_code == 429:
# Rate Limit: Retry mit Backoff
retry_after = int(response.headers.get("Retry-After", 60))
return {
"action": "retry",
"message": f"Rate limited. Retry after {retry_after}s",
"can_retry": True,
"wait_time": retry_after
}
elif 500 <= status_code < 600:
# Server-Fehler: Automatischer Failover
return {
"action": "fallback",
"message": f"Server error {status_code}: {error_message}",
"can_retry": True
}
return {
"action": "fallback",
"message": error_message,
"can_retry": True
}
def create_with_fallback(self, messages: list):
"""Erstellt Chat-Completion mit automatischem Model-Fallback."""
models = ["deepseek-v3.2", "gemini-2.5-flash", "gpt-4.1"]
for model in models:
error_info = self._call_model(model, messages)
if error_info["action"] == "abort":
raise PermissionError(error_info["message"])
elif error_info["action"] == "retry":
import time
time.sleep(error_info["wait_time"])
continue
elif error_info.get("result"):
return error_info["result"]
raise RuntimeError("All models failed")
Fehler 3: Data Loss durch fehlende Checkpoints
# FEHLER: Kein Checkpointing – bei Absturz ist alles verloren
def process_user_request(messages):
result = agent.process(messages)
# Wenn hier ein Fehler passiert: Alles verloren!
save_to_database(result)
return result
LÖSUNG: Checkpoint-Architektur mit HolySheep
import json
import os
from datetime import datetime
from pathlib import Path
class CheckpointManager:
"""Persistenter Checkpoint für Multi-Step Agent-Workflows."""
def __init__(self, checkpoint_dir: str = "./checkpoints"):
self.checkpoint_dir = Path(checkpoint_dir)
self.checkpoint_dir.mkdir(exist_ok=True)
def save_checkpoint(self, session_id: str, step: int, state: dict):
"""SpeichertCheckpoint mit Transaktion-Safety."""
checkpoint_file = self.checkpoint_dir / f"{session_id}_step_{step}.json"
temp_file = self.checkpoint_dir / f"{session_id}_step_{step}.tmp"
checkpoint_data = {
"session_id": session_id,
"step": step,
"timestamp": datetime.utcnow().isoformat(),
"state": state
}
# Atomic Write: Erst temp, dann rename
with open(temp_file, "w") as f:
json.dump(checkpoint_data, f)
temp_file.rename(checkpoint_file)
# Cleanup älterer Checkpoints
self._cleanup_old_checkpoints(session_id, keep_last=5)
def load_checkpoint(self, session_id: str) -> Optional[dict]:
"""Lädt den letzten Checkpoint für eine Session."""
checkpoints = sorted(
self.checkpoint_dir.glob(f"{session_id}_step_*.json"),
key=lambda p: int(p.stem.split("_step_")[1])
)
if not checkpoints:
return None
with open(checkpoints[-1], "r") as f:
return json.load(f)
def resume_workflow(self, session_id: str, agent, holysheep_client):
"""Setzt einen unterbrochenen Workflow fort."""
checkpoint = self.load_checkpoint(session_id)
if checkpoint:
current_step = checkpoint["step"]
state = checkpoint["state"]
print(f"[RESUME] Continuing from step {current_step}")
else:
current_step = 0
state = {"messages": [], "results": []}
# Workflow fortsetzen
for step in range(current_step, max_steps):
try:
# Speichere VOR jeder Operation
self.save_checkpoint(session_id, step, state)
result = agent.process(state["messages"])
state["messages"].append(result)
state["results