Was uns der Bau von Shippy über den Bau von Agenten gelehrt hat
Erkenntnisse aus der Entwicklung von Shippy, einem KI-Agenten für die Logistik, zeigen, dass modulares Design, menschliche Validierung im Kreislauf und der Umgang mit realen Unschärfen entscheidend für den Aufbau zuverlässiger, skalierbarer Agenten sind.
Tags
Kurze Zusammenfassung
Erkenntnisse aus der Entwicklung von Shippy, einem KI-Agenten für die Logistik, zeigen, dass modulares Design, menschliche Validierung im Kreislauf und der Umgang mit realen Unschärfen entscheidend für den Aufbau zuverlässiger, skalierbarer Agenten sind.
Was uns der Bau von Shippy über die Entwicklung von Agents gelehrt hat
Zuverlässige KI-Agents zu bauen ist eines der schwierigsten Probleme der angewandten maschinellen Intelligenz. Im letzten Jahr hat unser Team Shippy entwickelt, einen Open-Source-Agenten, der Software-Auslieferungs-Workflows automatisiert – von der Code-Review bis zum Deployment. Was als einfacher Proof-of-Concept begann, wurde zu einer tiefgreifenden Lektion in Agentenarchitektur, Fehlerbehandlung und Systemdesign. Dieser Artikel teilt die praktischen Erkenntnisse, die wir gewonnen haben, komplett mit konkreten Codebeispielen und Konfigurationsschritten, die du auf deine eigenen Agentenprojekte anwenden kannst.
Das Problem, das wir lösen wollten
Software auszuliefern umfasst Dutzende sich wiederholender Aufgaben: Linting, Tests ausführen, Changelogs aktualisieren, Versionen erhöhen und Deployments auslösen. Die meisten Teams nutzen CI/CD-Pipelines, aber diese Pipelines sind anfällig – sie brechen, wenn ein Test flaky wird, eine Abhängigkeit sich ändert oder eine Konfigurationsdatei verschoben wird. Wir wollten einen Agenten, der diese Schritte nicht nur ausführen, sondern auch von Fehlern erholen, den Status kommunizieren und sich ohne manuelles Eingreifen an neue Projektstrukturen anpassen kann.
Das Ziel war ambitioniert: Einen Agenten bauen, der ein Repository klonen, sein Build-System verstehen, Tests ausführen, häufige Probleme beheben und einen Pull-Request mit der Lösung eröffnen kann – alles ohne menschliche Aufforderung über das anfängliche Ziel hinaus.
Voraussetzungen
Bevor wir in die Implementierung eintauchen, hier die Kernanforderungen für den Bau eines Agenten wie Shippy:
- **Python 3.10+** – Die Agentenlogik ist in Python geschrieben und nutzt asynchrone Muster für die parallele Aufgabenausführung.
- **Git** – Der Agent muss Repositories klonen, committen und pushen können.
- **OpenAI-API-Schlüssel** – Wir haben GPT-4 für Reasoning und Codegenerierung verwendet, aber jede LLM-API funktioniert.
- **Docker** (optional) – Zum Ausführen von Tests in isolierten Umgebungen.
- **Eine Aufgabenwarteschlange** – Wir haben Redis + Celery für die asynchrone Verarbeitung langlebiger Aufgaben verwendet.
- **Node.js 18+** – Nur erforderlich, wenn dein Agent mit JavaScript/TypeScript-Projekten interagieren muss.
Schritt-für-Schritt-Installation
Lass uns die Einrichtung einer minimalen Version von Shippy auf deinem lokalen Rechner durchgehen. Das gibt dir einen funktionierenden Agenten, der ein Repository klonen, seine Struktur analysieren und eine Lösung für einen fehlschlagenden Test vorschlagen kann.
1. Virtuelle Umgebung erstellen und Abhängigkeiten installieren
Richte zunächst eine isolierte Python-Umgebung ein:
python3 -m venv shippy-env
source shippy-env/bin/activateInstalliere die Kernabhängigkeiten:
pip install openai gitpython pydantic httpx redis celeryDiese Pakete bieten die LLM-Schnittstelle (`openai`), Git-Operationen (`gitpython`), Datenvalidierung (`pydantic`), HTTP-Anfragen (`httpx`) und asynchrones Aufgabenmanagement (`redis`, `celery`).
2. Umgebungsvariablen konfigurieren
Erstelle eine `.env`-Datei in deinem Projektstammverzeichnis:
OPENAI_API_KEY=sk-dein-schlüssel-hier
GITHUB_TOKEN=ghp_dein-token-hier
REDIS_URL=redis://localhost:6379/0Lade diese in deinem Python-Code:
import os
from dotenv import load_dotenv
load_dotenv()
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN")
REDIS_URL = os.getenv("REDIS_URL")3. Den Agentenkern einrichten
Erstelle `agent.py` mit der grundlegenden Agentenklasse:
from openai import OpenAI
from git import Repo
import json
class ShippyAgent:
def __init__(self, api_key: str, github_token: str):
self.client = OpenAI(api_key=api_key)
self.github_token = github_token
def clone_repo(self, repo_url: str, local_path: str) -> Repo:
"""Klont ein GitHub-Repository in einen lokalen Pfad."""
repo = Repo.clone_from(
repo_url,
local_path,
env={"GIT_ASKPASS": "echo", "GITHUB_TOKEN": self.github_token}
)
return repo
def analyze_project(self, repo_path: str) -> dict:
"""Analysiert die Projektstruktur, um das Build-System zu verstehen."""
import os
files = os.listdir(repo_path)
structure = {}
if "package.json" in files:
structure["type"] = "node"
elif "pyproject.toml" in files:
structure["type"] = "python"
elif "Cargo.toml" in files:
structure["type"] = "rust"
else:
structure["type"] = "unknown"
return structure
def generate_fix(self, error_log: str, project_type: str) -> str:
"""Verwendet LLM, um eine Lösung für einen gegebenen Fehler zu generieren."""
prompt = f"""
Du bist ein erfahrener Softwareentwickler. Angesichts dieses Fehlerprotokolls aus einem {project_type}-Projekt schlage eine Code-Lösung vor.
Fehlerprotokoll:
{error_log}
Gib die Lösung als Diff oder Code-Änderung an.
"""
response = self.client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}],
temperature=0.2
)
return response.choices[0].message.content4. Aufgabenwarteschlange für langlebige Operationen hinzufügen
Erstelle `tasks.py` für die Hintergrundverarbeitung:
from celery import Celery
from agent import ShippyAgent
app = Celery('shippy', broker='redis://localhost:6379/0')
@app.task
def fix_repo(repo_url: str, error_log: str):
agent = ShippyAgent(
api_key="dein-openai-schlüssel",
github_token="dein-github-token"
)
local_path = "/tmp/repos/" + repo_url.split("/")[-1].replace(".git", "")
repo = agent.clone_repo(repo_url, local_path)
structure = agent.analyze_project(local_path)
fix = agent.generate_fix(error_log, structure["type"])
# Lösung anwenden und PR erstellen (vereinfacht)
with open(f"{local_path}/fix.patch", "w") as f:
f.write(fix)
return {"status": "fix_generated", "patch_file": "fix.patch"}Starte den Celery-Worker:
celery -A tasks worker --loglevel=infoAnwendungsbeispiele
Jetzt sehen wir Shippy in Aktion mit realen Szenarien.
Beispiel 1: Beheben eines fehlschlagenden Python-Tests
Angenommen, du hast ein Python-Projekt, bei dem Tests aufgrund eines fehlenden Imports fehlschlagen. Führe den Agenten aus:
from agent import ShippyAgent
agent = ShippyAgent(
api_key="sk-dein-schlüssel",
github_token="ghp_dein-token"
)
error = """
ModuleNotFoundError: No module named 'requests'
Datei: tests/test_api.py, Zeile 3
"""
result = agent.generate_fix(error, "python")
print(result)
# Ausgabe: Füge `import requests` am Anfang von test_api.py hinzu, oder füge `requests` zu requirements.txt hinzuBeispiel 2: Automatisieren einer Code-Review
Der Agent kann auch Pull-Requests überprüfen. Hier ein minimaler PR-Reviewer:
def review_pr(repo_url: str, pr_number: int):
# Klone den PR-Branch
repo = agent.clone_repo(repo_url, "/tmp/pr-review")
# Diff abrufen
diff = repo.git.diff("main", "feature-branch")
# LLM um Review bitten
prompt = f"Überprüfe dieses Diff und liste alle Probleme auf:\n{diff}"
response = agent.client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}]
)
return response.choices[0].message.contentBeispiel 3: Ausführen in Docker zur Isolation
Um Tests sicher auszuführen, ohne dein Hostsystem zu beeinträchtigen, verwende Docker:
docker run --rm -v $(pwd):/workspace python:3.11 bash -c "cd /workspace && pip install -r requirements.txt && pytest"Integriere dies in den Agenten:
import subprocess
def run_tests_in_docker(repo_path: str) -> str:
result = subprocess.run(
["docker", "run", "--rm", "-v", f"{repo_path}:/workspace", "python:3.11",
"bash", "-c", "cd /workspace && pip install -r requirements.txt && pytest"],
capture_output=True, text=True
)
return result.stdout + result.stderrWichtige Erkenntnisse
1. Agents brauchen robuste Fehlerbehandlung
Die erste Version von Shippy ging davon aus, dass jeder Schritt gelingen würde. Das tat er nicht. Wir haben gelernt, Wiederholungslogik mit exponentiellem Backoff zu implementieren. Zum Beispiel: Wenn ein Git-Clone aufgrund von Netzwerkproblemen fehlschlägt, wiederhole bis zu dreimal:
import time
from tenacity import retry, stop_after_attempt, wait_exponential
@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=4, max=10))
def clone_with_retry(repo_url, local_path):
return Repo.clone_from(repo_url, local_path)2. Kontext ist alles
LLMs sind leistungsstark, aber es fehlt ihnen an projektspezifischem Wissen. Wir haben festgestellt, dass die Bereitstellung der README, der letzten Commit-Historie und der CI-Konfiguration für den Agenten die Qualität der Lösungen drastisch verbessert hat. Wir haben einen "Kontextsammel"-Schritt hinzugefügt, der diese Dateien liest, bevor eine Antwort generiert wird.
3. In produktionsähnlichen Umgebungen testen
Agenten auf deinem Laptop auszuführen ist für Prototypen in Ordnung, aber die Produktion erfordert Isolation. Docker-Container für jede Aufgabe verhinderten Zustandsverschmutzung zwischen den Läufen. Wir haben auch Timeouts hinzugefügt, um ausufernde Agenten zu verhindern:
from concurrent.futures import TimeoutError
with timeout(seconds=120):
result = agent.run_task()4. Menschliche Kontrolle ist weiterhin unerlässlich
Trotz beeindruckender Ergebnisse produzierte der Agent gelegentlich sinnlose Lösungen. Wir haben einen Überprüfungsschritt hinzugefügt, bei dem der Agent einen PR erstellt, aber ein Mensch ihn genehmigen muss, bevor er gemerged wird. Das balanciert Automatisierung mit Sicherheit aus.
5. Überwachung und Protokollierung sind unverhandelbar
Wir haben jede Aktion des Agenten mit strukturierter Protokollierung versehen. Das ermöglichte es uns, Fehler zu debuggen und Prompts im Laufe der Zeit zu verbessern. Verwende das `logging`-Modul von Python mit einem JSON-Formatter:
import logging
import json
class JsonFormatter(logging.Formatter):
def format(self, record):
return json.dumps(record.__dict__)
logger = logging.getLogger("shippy")
handler = logging.StreamHandler()
handler.setFormatter(JsonFormatter())
logger.addHandler(handler)Fazit
Der Bau von Shippy hat uns gelehrt, dass KI-Agents keine Magie sind – sie sind sorgfältig entworfene Systeme, die LLM-Reasoning mit robusten Ingenieurspraktiken kombinieren. Die wichtigste Erkenntnis ist, dass die Zuverlässigkeit von Agenten aus der Infrastruktur kommt, nicht nur aus dem Modell. Wiederholungslogik, Kontextsammlung, Isolation und menschliche Aufsicht haben aus einem fragilen Prototypen ein nützliches Werkzeug gemacht.
Wenn du deinen eigenen Agenten baust, fang klein an. Klone ein Repository, führe einen Test aus, behebe ein einzelnes Problem. Füge dann Fehlerbehandlung hinzu. Dann Überwachung. Dann die nächste Funktion. Der Weg von der Demo zur Produktion ist mit Randfällen gepflastert, aber die Reise lohnt sich. Agents, die Software autonom ausliefern können, sind keine Science-Fiction – sie sind nur gute Ingenieursarbeit.
*Weiterführende Literatur zu Agenten-Entwurfsmustern findest du im Hugging Face Blog, OpenAI News, Microsoft AI Blog und Anthropic News.*
Quellen
FAQ
Worum geht es in diesem Artikel?
Dieser Artikel behandelt „Was uns der Bau von Shippy über den Bau von Agenten gelehrt hat“ in der Kategorie KI-Agenten. Erkenntnisse aus der Entwicklung von Shippy, einem KI-Agenten für die Logistik, zeigen, dass modulares Design, menschliche Validierung im Kreislauf und der Umgang mit realen Unschärfen entscheidend für den Aufbau zuverlässiger, skalierbarer Agenten sind.
Für wen ist dieser Artikel nützlich?
Er ist nützlich für Leserinnen und Leser, die KI-Tools und KI-Anwendungen praktisch verstehen möchten.
Was ist der nächste Schritt?
Lesen Sie den Artikel, prüfen Sie die angegebenen Quellen und testen Sie passende Ideen in Ihrem Kontext.



