OpenClaw: Wie du in ~400 Zeilen Code deinen eigenen AI-Assistenten baust
Nader Dabit zeigt Schritt für Schritt, wie man einen persistenten AI-Assistenten mit Gedächtnis, Tools und Multi-Channel-Support von Grund auf baut — und erklärt damit die Architektur hinter OpenClaw.
OpenClaw: Wie du in ~400 Zeilen Code deinen eigenen AI-Assistenten baust
Was wäre, wenn dein AI-Assistent nicht in einem Browser-Tab leben würde, sondern in allen deinen Messaging-Apps gleichzeitig — mit einem Gedächtnis, das Sessions überlebt, Tools die deinen Computer steuern können, und einem Zeitplan der ihn selbständig aufweckt?
Genau das macht OpenClaw. Und Nader Dabit — Developer-Advocate und Autor — hat in einem brillanten Substack-Artikel gezeigt, dass die Kernarchitektur dahinter überraschend einfach ist. So einfach, dass du sie selbst hättest erfinden können.
Das Problem mit ChatGPT & Co.
Jeder kennt die Limitationen der grossen Chat-Interfaces:
- Zustandslos: Jedes Gespräch startet bei Null. Dein Name, deine Projekte, deine Vorlieben — alles weg
- Passiv: Du gehst zur AI. Die AI kommt nie zu dir. Kein Morning-Briefing, kein automatischer Check
- Isoliert: Keine Shell-Commands, kein Dateizugriff, keine Browser-Kontrolle — die AI lebt in einer Textbox ohne Hände
- Single-Channel: Dein Leben spielt sich auf WhatsApp, Telegram, Discord, Slack ab — aber die AI existiert in einem separaten Tab
Die Vision: Ein AI-Assistent der auf deiner eigenen Hardware läuft (Laptop, VPS, Mac Mini), in allen Messaging-Apps lebt, sich an dich erinnert, Befehle ausführen kann, und selbständig periodische Aufgaben erledigt.
Von Null zum Assistenten — in 10 Schritten
Dabits Ansatz ist genial: Er baut den Assistenten iterativ auf, und jeder Schritt löst ein konkretes Problem.
Schritt 1: Der dümmste Bot der Welt
# bot-v0.py
async def handle_message(update, context):
response = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[{"role": "user", "content": update.message.text}]
)
await update.message.reply_text(response.content[0].text)
Ein Telegram-Bot der Claude aufruft. Funktioniert, aber: Jede Nachricht ist unabhängig. Kein Gedächtnis. Keine Persönlichkeit. Kein Nutzen gegenüber dem Claude Web-Interface.
Schritt 2: Sessions — "Wie heisse ich?"
Das Problem: Der Bot vergisst alles sofort. Die Lösung: JSONL-Dateien als Session-Storage.
# Eine Zeile pro Nachricht, append-only
{"role": "user", "content": "Ich heisse René"}
{"role": "assistant", "content": "Freut mich, René!"}
Jeder User bekommt seine eigene Datei. Append-only heisst: Wenn der Prozess abstürzt, verlierst du maximal eine Zeile. Restart und alles ist noch da. Das ist exakt dasselbe Format, das OpenClaw für Session-Transcripts nutzt.
Schritt 3: Persönlichkeit — SOUL.md
Ein generischer Assistent ist langweilig. Die Lösung: Ein System-Prompt der bei jedem API-Call injiziert wird:
SOUL = """
# Who You Are
**Name:** Jarvis
## Personality
- Be genuinely helpful, not performatively helpful
- Skip the "Great question!" - just help
- Have opinions. You're allowed to disagree
## Boundaries
- Private things stay private
- When in doubt, ask before acting externally
"""
Je spezifischer der SOUL, desto konsistenter das Verhalten. "Be helpful" ist vage. "Be the assistant you'd actually want to talk to. Not a corporate drone. Not a sycophant. Just... good." gibt dem Modell etwas zum Arbeiten.
Schritt 4: Tools — Hände für die AI
Der Kerngedanke: Gib der AI strukturierte Tool-Definitionen und lass sie selbst entscheiden, wann sie welches Tool nutzt.
TOOLS = [
{"name": "run_command", "description": "Run a shell command"},
{"name": "read_file", "description": "Read a file"},
{"name": "write_file", "description": "Write to a file"},
{"name": "web_search", "description": "Search the web"},
]
Plus den Agent Loop: LLM aufrufen → prüfen ob Tool-Call → Tool ausführen → Ergebnis zurück ins LLM → wiederholen bis fertig.
Du: Erstelle hello.py und führe es aus
Bot: [write_file → hello.py]
[run_command → python hello.py]
Done! Output: "hello world"
Die AI entscheidet selbst über Reihenfolge und Auswahl der Tools. OpenClaws Produktions-Katalog umfasst Browser-Automation, Inter-Agent-Messaging, Sub-Agent-Spawning und mehr — aber jedes Tool folgt exakt diesem Muster: Schema + Beschreibung + Ausführungsfunktion.
Schritt 5: Sicherheit — "rm -rf /" verhindern
Shell-Commands über Telegram ausführen? Albtraum-Szenario. Die Lösung: Eine Allowlist mit persistenten Approvals.
SAFE_COMMANDS = {"ls", "cat", "head", "date", "whoami", "git"}
def check_command_safety(command):
if base_cmd in SAFE_COMMANDS: return "safe"
if command in approved_list: return "approved"
return "needs_approval" # → User wird gefragt
Einmal genehmigt, wird der Command gespeichert. OpenClaw erweitert das mit Glob-Patterns (git * einmal genehmigen) und einem drei-stufigen Modell: ask (User fragen), record (loggen aber erlauben), ignore (auto-allow).
Schritt 6: Multi-Channel — Das Gateway-Pattern
Bisher: Ein Telegram-Bot. Aber was ist mit Discord? WhatsApp? Slack?
Der Trick: Die run_agent_turn()-Funktion weiss nichts über Telegram. Sie nimmt Messages rein und gibt Text zurück. Die Agent-Logik ist bereits vom Channel entkoppelt.
Beweis: Einen HTTP-Endpoint daneben stellen, der die gleichen Sessions nutzt:
# Via Telegram:
"Ich heisse Nader" → "Freut mich, Nader!"
# Via HTTP (gleiche User-ID):
curl -X POST /chat -d '{"user_id": "SAME_ID", "message": "Wie heisse ich?"}'
→ {"response": "Du heisst Nader!"}
Gleicher Agent, gleiche Sessions, gleiches Gedächtnis. Zwei verschiedene Interfaces. Das ist das Gateway-Pattern — und exakt so funktioniert OpenClaw: Ein zentraler Prozess, der Telegram, Discord, WhatsApp, Slack, Signal und iMessage über eine Config-Datei verwaltet.
Schritt 7: Context Compaction — Wenn das Fenster überläuft
Nach Wochen des Chattens: Tausende Messages, Token-Limit überschritten. Die Lösung: Alte Nachrichten zusammenfassen, neue behalten.
def compact_session(messages):
if token_count < 100_000: return messages # Noch Platz
old, recent = messages[:half], messages[half:]
summary = ai.summarize(old) # "Preserve key facts, decisions, TODOs"
return [{"role": "user", "content": f"[Summary]\n{summary}"}] + recent
Der Bot behält sein Wissen, ohne am Token-Limit zu scheitern. OpenClaws Compaction ist ausgefeilter — chunked Summaries mit Safety-Margin — aber die Kernidee ist identisch.
Schritt 8: Langzeitgedächtnis — Über Sessions hinaus
Session-History = Gesprächsgedächtnis. Aber was passiert bei Session-Reset? Alles weg.
Lösung: Datei-basiertes Gedächtnis als separate Tools:
Du: Mein Lieblingsrestaurant ist Elvies, 19 Uhr Reservierung
Bot: [save_memory → user-preferences.md] Gespeichert!
[Session-Reset, Tage später...]
Du: Wo sollen wir essen gehen?
Bot: [memory_search → "restaurant"] Wie wärs mit Elvies? 19 Uhr wie immer?
Das Gedächtnis überlebt Session-Resets, weil es in Dateien lebt — nicht in der Session. OpenClaws Produktion nutzt Vektor-Suche mit Embeddings für semantisches Matching ("Auth Bug" findet auch "Authentifizierungs-Problem").
Schritt 9: Heartbeats — Der Agent wacht von selbst auf
Bisher: Der Agent reagiert nur auf Nachrichten. Aber was ist mit dem morgendlichen Kalender-Check?
schedule.every().day.at("07:30").do(morning_briefing)
Jeder Heartbeat bekommt seine eigene Session (cron:morning-briefing), damit geplante Tasks den Hauptchat nicht verschmutzen. Es ist derselbe run_agent_turn() — nur ausgelöst durch einen Timer statt durch einen Menschen.
Schritt 10: Multi-Agent — Spezialisierung
Ein Agent für alles wird irgendwann zum Flaschenhals. Lösung: Mehrere Agents mit eigenem SOUL und eigenem Session-Key:
Du: Wie wird das Wetter?
[Jarvis] Sonnig und warm!
Du: /research Best Practices für Python Async
[Scout] Hier meine Recherche-Ergebnisse...
[web_search → save_memory]
Die wichtigsten Practices sind: 1) asyncio.gather...
Du: Was hat Scout über Python Async herausgefunden?
[Jarvis] [memory_search] Scout fand heraus, dass...
Jeder Agent hat seine eigene Conversation History, aber sie teilen sich das gleiche Memory-Verzeichnis. Scout speichert Recherche-Ergebnisse; Jarvis kann sie später abrufen. Kollaboration über geteilte Dateien, ohne direktes Messaging.
Das Gesamtbild: ~400 Zeilen
Dabits finaler Prototyp kombiniert alles in einem lauffähigen Script:
uv run --with anthropic --with schedule python mini-openclaw.py
| Feature | Löst welches Problem? |
|---|---|
| JSONL Sessions | "Die AI kann sich an nichts erinnern" |
| SOUL.md | "Sie antwortet wie ein generischer Chatbot" |
| Tools + Agent Loop | "Sie kann nur reden, nicht handeln" |
| Permission Controls | "Sie führt gefährliche Commands aus" |
| Gateway Pattern | "Ich will sie auf allen Messaging-Apps" |
| Context Compaction | "Die Konversation wurde zu lang" |
| Langzeitgedächtnis | "Sie vergisst alles zwischen Sessions" |
| Session Locks | "Zwei Nachrichten gleichzeitig = Chaos" |
| Heartbeats | "Ich will dass sie selbständig Dinge tut" |
| Multi-Agent Routing | "Ein Agent kann nicht alles gut" |
Jedes Feature entstand aus einem konkreten Problem. Keine Overengineering-Fantasie, sondern: "Das nervt → so fixe ich es."
Was OpenClaw darüber hinaus bietet
Der Prototyp deckt die Kernarchitektur ab. OpenClaws Produktion erweitert jedes Konzept:
- Browser-Automation: Playwright-basiert, aber statt 5MB-Screenshots werden semantische Snapshots (Text-Repräsentation des Accessibility Trees) verwendet — ~100x kleiner, jedes Element bekommt eine Ref-ID zum Anklicken
- Session-Scoping:
main(ein Chat für alles),per-peer(pro Person),per-channel-peer(pro Person pro Kanal) — plus Identity-Links um Sessions über Kanäle zu mergen - Channel-Plugins: Jeder Kanal (Telegram, Discord, WhatsApp, Slack, Signal, iMessage) ist ein separater Adapter — neuen Kanal hinzufügen = ein Plugin schreiben, keine Agent-Logik anfassen
- Hybride Memory-Suche: Vektor-Suche via SQLite + FTS5 für exakte Keywords, konfigurierbare Embedding-Provider (OpenAI, lokale Modelle, Gemini, Voyage)
- Sub-Agent Spawning: Ein Parent-Agent spawnt programmgesteuert Child-Agents für fokussierte Tasks — "recherchiere das im Detail" als Delegation
Fazit: Einfacher als gedacht, mächtiger als erwartet
Dabits Artikel ist einer der besten "from first principles"-Texte im AI-Agent-Space. Er zeigt, dass hinter dem Buzzword "persönlicher AI-Assistent" keine Magie steckt — sondern solide Software-Engineering-Patterns:
- JSONL als crash-safe Session-Storage
- System-Prompts als Persönlichkeits-Definition
- Strukturierte Tools mit Agent Loop
- Per-Session Locking für Concurrency
- Das Gateway-Pattern für Multi-Channel
Wer die Grundlagen versteht, kann entweder sein eigenes System bauen — oder OpenClaw nutzen und wissen, was unter der Haube passiert.
"Or just use OpenClaw. It's open source and handles all the edge cases we glossed over. But now you know how it works under the hood." — Nader Dabit
Links
- Originalartikel: You Could've Invented OpenClaw (Nader Dabit, Substack)
- OpenClaw GitHub: github.com/openclaw/openclaw
- OpenClaw Docs: docs.openclaw.ai