TuBrief
구독 채널
비디오
커뮤니티

Fehlerbehebung beim Einrichten von Open-Source-KI-Agenten auf dem eigenen Computer

TuBrief 편집팀
2026년 9월 11일
0
Computing/Software

원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.

Deutsch한국어EnglishEspañolहिन्दी中文العربيةFrançaisPortuguêsРусскийBahasa Indonesia日本語

관련 영상

10 NEUE GitHub-Repositories, die jeder Claude-Nutzer kennen muss13:58

10 NEUE GitHub-Repositories, die jeder Claude-Nutzer kennen muss

Chase AI

커뮤니티의 다른 글

사내 시스템에 llm api 붙일 때 마주하는 현실적인 한계와 대응법

2026년 9월 13일

레거시 백엔드에 GPT-6 Astra 붙일 때 예산 승인과 보안 통과를 먼저 끝내는 법이 있습니다

2026년 9월 13일

에이전트끼리 대화하다 6천만 원 청구서가 나오는 이유

2026년 9월 13일

사내 RAG 벡터 검색에 Okta 권한 필터를 직접 거는 방법

2026년 9월 13일

브라우저 에이전트에게 내 구글 계정을 통째로 넘기면 안 되는 이유

2026년 9월 12일

Apple Won the AI Race

2026년 9월 12일

댓글 (0)

Log in to leave a comment

아직 작성된 글이 없습니다

© 2026 . All rights reserved.

TuBrief
구독 채널
비디오
커뮤니티
로그인

Fehlerbehebung beim Einrichten von Open-Source-KI-Agenten auf dem eigenen Computer

YouTube-Tutorials vermitteln oft den Eindruck, man müsse nur ein Open-Source-KI-Tool mit tausenden GitHub-Stars klonen und ein paar Befehle eingeben, damit es läuft. Öffnet man jedoch tatsächlich das Terminal und klont das Repository, prasseln reihenweise Fehlermeldungen auf einen ein – angefangen bei C++-Binärkonflikten bis hin zu verdrehten Paketversionen. Wenn Junior-Developer mit weniger als einem Jahr Berufserfahrung an dieser Stelle scheitern, liegt das meist daran, dass sie Tools unüberlegt im gesamten System installiert haben, ohne eine strikte Isolierung von Python- und Laufzeitumgebungen vorzunehmen. Bevor Sie anfangen, Prompt-Texte zu feilen, sollten Sie daher die Isolation von lokalen Prozessen und das Proxy-Routing in den Griff bekommen, um nächtelanges Debuggen zu vermeiden.

Build-Fehler direkt nach dem Klonen eines GitHub-Repositories verhindern

Open-Source-KI-Projekte kombinieren Python-Bibliotheken, die mit C++-Build-Tools verknüpft sind, oft mit Node.js-Paketen, die native Bindings erfordern. Wer diese unbedarft in der globalen Umgebung installiert, riskiert Symbol-Link-Fehler in der Python-Laufzeit wie etwa ImportError: dynamic module does not define module export function. Im Fall des Node.js-basierten Proxies OmniRoute sind im engines-Feld der package.json Node 22 sowie Node 24 bis 26 vorgeschrieben, weshalb der Dienst in der ungeraden Version Node 23 sofort beim Start abstürzt.

Um anfängliche Build-Fehler zu vermeiden, sollten Sie eine virtuelle Umgebung einrichten und die Pakete konsequent anhand der Lock-Dateien installieren:

`bash

1. Python-virtuelle Umgebung erstellen und Build-Tools aktualisieren

python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip setuptools wheel

2. Abhängigkeiten basierend auf der Lock-Datei installieren

if [ -f "poetry.lock" ]; then
poetry install --no-root
elif [ -f "requirements.txt" ]; then
pip install --no-cache-dir -r requirements.txt
fi

3. Node.js-Laufzeitversion überprüfen und installieren

node -v # Überprüfen, ob v22.x LTS
pnpm install --frozen-lockfile

`

Auch beim manuellen Ausfüllen der .env nach dem Kopieren der .env.example-Datei führen selbst kleinste Tippfehler zu Parsing-Fehlern. Die Open-Source-Agenten-Laufzeit DeepSeek Harness (dsh) trennt die allgemeine Konfigurationsdatei (settings.yaml) strikt von der eigentlichen API-Anmeldeschlüssel-Datei (~/.dsh/.credentials.yaml). Wenn Schlüssel an einem falschen Ort hinterlegt oder Pfadsyntaxen fehlerhaft sind, startet der Agent nicht.

Umgebungsvariable Korrektes Eingabebeispiel Ursache des Fehlers & Lösungsweg
OPENAI_API_BASE http://localhost:20128/v1 Schrägstrich (/) am Ende führt zu 404-Routing-Fehler; Schrägstrich entfernen
ANTHROPIC_API_KEY sk-ant-api03-... Unnötige Anführungszeichen ("") in der Docker .env verursachen Authentifizierungsfehler; Anführungszeichen entfernen
DSH_HOME /home/developer/.dsh Verwendung der Tilde (~) führt zu Pfadberechtigungsfehlern; absoluten Pfad angeben
SECRET_KEY 32-Byte-Hexadezimalwert Wird der Wert leer gelassen, schlägt die Session-Initialisierung fehl; mit openssl rand -hex 32 generieren

Fehlerbehebung für im Terminal versandete, lange Log-Ausgaben beim Aufbau lokaler Open-Source-KI-Agenten

Sobald man ein Open-Source-KI-Projekt mit Zehntausenden von GitHub-Stars klont und den ersten Startbefehl eingibt, füllt sich der Bildschirm komplett mit roten Log-Meldungen. Der Vortragende im Tutorial-Video startet die Demo mit nur einem Tastendruck sauber, doch im eigenen Terminal bleiben nur C++-Kompilierungsfehler und Laufzeitkonflikte zurück. Das liegt nicht an der Intelligenz des Modells, sondern an Python-C-Binärkonflikten, der Kontamination der globalen Umgebung sowie einer Architektur, die fest an einen einzigen, teuren API-Endpunkt gekoppelt ist.

Hier sind die konkreten Einrichtungsschritte zusammengefasst, um Setup-Engpässe für Junior-Developer im ersten Berufsjahr bei der Ausführung von KI-Agenten lokal zu beseitigen und gleichzeitig die API-Kosten durch Multi-Model-Routing zu senken.

Laufzeitkonflikte unmittelbar nach dem Klonen des Repositories stoppen

Open-Source-KI-Projekte verknüpfen Python-Pakete mit integrierten nativen C++-Bibliotheken auf komplexe Weise mit Node.js-Tools, die native Bindings erfordern. Eine unbedarfte Installation im globalen System führt dazu, dass Bibliotheks-Symbol-Links beschädigt werden und lästige Fehler wie ImportError: dynamic module does not define module export function ausgegeben werden.

Beim Node.js-basierten Gateway OmniRoute sind die Laufzeitbeschränkungen noch strenger. Da im engines-Feld der package.json nur Node 22 sowie Version 24 und höher aufgeführt sind, bricht das System den Bootvorgang in einer ungeraden Node 23-Umgebung sofort ab. Um unnötige Wege zu vermeiden, müssen zuerst die Laufzeit-Isolierung und die Synchronisierung der Paket-Lock-Dateien abgeschlossen werden.

`bash

Python-virtuelle Umgebung erstellen und zuerst die Build-Wheel-Tools aktualisieren

python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip setuptools wheel

Abhängigkeiten anhand der Lock-Datei des Paketmanagers installieren

if [ -f "poetry.lock" ]; then
poetry install --no-root
elif [ -f "requirements.txt" ]; then
pip install --no-cache-dir -r requirements.txt
fi

Node.js-Laufzeitversion überprüfen und anhand der Lock-Datei installieren

node -v # Prüfen, ob Node.js in der v22 LTS-Reihe läuft
pnpm install --frozen-lockfile

`

Auch die Konfiguration der Umgebungsvariablendatei (.env) sorgt oft für Stolpersteine. DeepSeek Harness (dsh) trennt die Konfigurationsdatei (settings.yaml) und den eigentlichen API-Schlüssel (~/.dsh/.credentials.yaml) physisch voneinander. Dies geschieht in der Absicht, zu verhindern, dass Schlüssel versehentlich in das Repository eingecheckt werden.

Name der Umgebungsvariable Standardformat und Beispielwert Hauptursache für Defekte & Schutzmaßnahmen
OPENAI_API_BASE http://localhost:20128/v1 Endpunkt-404-Fehler durch doppelte oder fehlende Schrägstriche (/) am URL-Ende
ANTHROPIC_API_KEY sk-ant-api03-... Beschädigung von Zeichenketten durch unnötige Anführungszeichen in der Docker .env
DSH_HOME /home/developer/.dsh Abnormale Verzeichniserstellung und Berechtigungsfehler durch Eingabe relativer Tilde-Pfade (~)
SECRET_KEY 32-Byte-Hexadezimalzeichenkette Fehlschlagen der Sitzungsverschlüsselung bei leerem Wert (generierbar mit openssl rand -hex 32)

Schlägt der Start fehl, sollte man statt der langen Logs weiter oben im Terminal direkt die untersten Symbole des Fehlers prüfen. Mit dem Befehl grep -Ein "(error|exception|errno|fatal)" runtime.log | tail -n 15 lassen sich die Fehlercodes herausfiltern, um anschließend über die GitHub CLI mit Abfragen wie gh issue list -R deepseek-ai/deepseek-harness --search "EADDRINUSE is:closed" geschlossene Issues einzusehen und so den Zeitaufwand für die Fehlersuche drastisch zu reduzieren.

Einrichtung von DeepSeek Harness und Omarchy OS

DeepSeek Harness ist eine Laufzeitumgebung, die auf dem Cordis-Framework aufbaut und Modelladapter sowie Tools als unabhängige Plugins zusammenfügt. Omarchy OS, angeführt von David Heinemeier Hansson (DHH) aus dem Basecamp-Umland, nutzt QuickShell und Btrfs-Snapshots, um eine Entwicklungsumgebung in etwa 1 Minute und 30 Sekunden wiederherzustellen. Diese Kombination erspart Ihnen den halben Tag, den Sie sonst mit mühsamem Setup verbringen würden.

Schreiben von System-Prompts unter Wahrung der KV-Cache-Integrität

Im dsh-Engine werden die System-Prompts für das LLM in jeder Runde von dem Kernpaket dsh-system-prompt neu zusammengesetzt. Wird der Text am Anfang des Prompts nicht fixiert, sondern dynamisch ständig verändert, bricht der Key-Value (KV)-Cache des Modells vom ersten Absatz an zusammen. Da für jede Runde der gesamte Eingabetoken-Strom neu berechnet werden muss, verlangsamt sich die Antwortgeschwindigkeit und die Kosten steigen.

`yaml

~/.dsh/settings.yaml - Kernkonfiguration und Prompt-Steuerung

llm-pi-ai:
providers:
local-omniroute:
type: openai-compatible
api:
baseURL: "http://127.0.0.1:20128/v1"
apiKeyEnv: "OMNIROUTE_API_KEY"
models:
- id: "auto/coding"
contextWindow: 128000
maxTokens: 8192

systemPrompt:
includeHarnessIdentity: false
persona: |
Sie sind ein Ingenieur, der strikt die TDD-Prinzipien einhält.
1. Schreiben Sie vor jeder Code-Änderung zwingend einen fehlschlagenden Unit-Test.
2. Geben Sie ohne zusätzliche Erklärungen ein klares Git-Diff-Format und Standard-Tool-Befehle zurück.

`

Die Rollendefinition des System-Prompts sollte als fester Text hinterlegt werden, während sich häufig ändernde Dateilisten oder Arbeitsanweisungen an das Ende des Prompts oder als Benutzernachricht übergeben werden müssen, um die Vorteile des anbieterseitigen Prompt-Cachings voll auszuschöpfen.

Daemon-Skript zur Abwehr von Netzwerkverzögerungen

Wenn der Agent das lokale Dateisystem durchsucht oder Unit-Tests ausführt und dabei von der externen LLM-API einen 504 Gateway Timeout oder einen vorübergehenden Socket-Abbruch erhält, stürzt der Prozess sofort ab. Es empfiehlt sich, ein Daemon-Skript im Hintergrund laufen zu lassen, das den Health-Check-Endpunkt überwacht und im Fehlerfall das Wiederholungsintervall schrittweise erhöht.

`bash
#!/usr/bin/env bash
set -euo pipefail

export DSH_HOME="HOME/.dsh"exportOMNIROUTEAPIKEY="{HOME}/.dsh" export OMNIROUTE_API_KEY="HOME/.dsh"exportOMNIROUTEA​PIK​EY="{OMNIROUTE_API_KEY:-sk-local-token}"
MAX_RETRIES=5
INITIAL_BACKOFF=2
Port=3080

launch_agent_daemon() {
local retry_count=0
local backoff=${INITIAL_BACKOFF}

until curl -s -f "http://127.0.0.1:${PORT}/api/health" > /dev/null 2>&1; do
    if [ ${retry_count} -ge ${MAX_RETRIES} ]; then
        echo "[ERROR] Start der Agenten-Laufzeit fehlgeschlagen. Maximale Anzahl an Wiederholungsversuchen erreicht." >&2
        exit 1
    fi

    echo "[INFO] Versuch zum Starten von DeepSeek Harness ($((retry_count + 1))/${MAX_RETRIES})..."
    npx --yes @deepseek-ai/dsh web --port ${PORT} --no-open >> "${DSH_HOME}/daemon.log" 2>&1 &
    local pid=$!

    sleep "${backoff}"

    if kill -0 ${pid} 2>/dev/null; then
        echo "[SUCCESS] DeepSeek Harness läuft ordnungsgemäß (PID: ${pid})"
        break
    else
        echo "[WARN] Prozess unerwartet beendet. Neuer Versuch in ${backoff} Sekunden."
        retry_count=$((retry_count + 1))
        backoff=$((backoff * 2))
    fi
done

}

launch_agent_daemon

`

Wird das Skript mit chmod +x daemon.sh mit Ausführungsrechten versehen und im Hintergrund belassen, erspart man sich den Aufwand, bei vorübergehenden API-Fehlern manuell ins Terminal zu eilen, um den Prozess neu zu starten.

Stapelweise Markdown-Konvertierung interner Dokumente mit AnyDoc

Dokumenten-Parsing-Pipelines auf Python-Basis neigen oft dazu, für DOCX-, XLSX- und PDF-Formate jeweils unterschiedliche Python-Bibliotheken zusammenzukleben, was häufig zu beschädigten Tabellenzellen oder komplett verlorenen komplexen Formeln führt.

AnyDoc, veröffentlicht von Firecrawl, verarbeitet 14 Formate sowie Text-PDFs rein über einen einzelnen Rust-Core, gänzlich ohne schwere externe Abhängigkeiten. Laut Firecrawl-Benchmarks liegt die Median-Konvertierungsgeschwindigkeit von AnyDoc bei 4,4 bis 4,7 ms. Im Vergleich zu den durchschnittlich 1.129 ms eines headless LibreOffice ist der Geschwindigkeitsunterschied enorm.

Dokumenten-Konvertierungs-Engine Anzahl unterstützter Formate Median-Konvertierungsgeschwindigkeit Systemabhängigkeiten & Laufzeiteigenschaften Erhaltungsgrad komplexer Layouts (Tabellen, Formeln)
Firecrawl AnyDoc 14 Standards + PDF 4,4 ~ 4,7 ms Keine externen Abhängigkeiten (einzelner Rust-Bytecode) Hoch (Normalisierung über einzelnes Serialisierungsmodell)
LibreOffice (Headless) 12 Standards 1.129 ms Schwere Systempakete (JVM, Font-Pakete) Mittel (häufig Formatierungsverzerrungen)
Mammoth (Python) 1 Standard (nur DOCX) 52 ms Reine Python-Bibliothek Gering (Beschädigung zusammengeführter Tabellen)
LangChain Unstructured Mehrere (externe Wrapper) 450 ~ 1.800 ms Betriebssystemabhängigkeiten wie Poppler, Tesseract Mittel bis Hoch (hoher Konvertierungs-Overhead)

Skript zur Stapelkonvertierung von 14 Bürodateiformaten

AnyDoc erkennt Text-PDFs und diverse Büroformate direkt auf Byte-Signatur-Ebene. Stößt es auf gescannte PDFs, bei denen Text als Bild vorliegt, wirft es anstelle der Generierung falschen Textes eine NeedsOcrError-Ausnahme.

`python
"""
Skript zur AnyDoc-basierten Multi-Format-Stapelkonvertierung und Korrektur von Bildpfaden
Installation: pip install firecrawl-anydoc
"""
import os
import re
from pathlib import Path
import anydoc

class BatchDocumentConverter:
SUPPORTED_EXTENSIONS = {
'.docx', '.doc', '.docm', '.xlsx', '.xls', '.xlsm',
'.pptx', '.ppt', '.rtf', '.odt', '.ods', '.odp',
'.epub', '.csv', '.pdf'
}

def __init__(self, input_dir: Path, output_dir: Path):
    self.input_dir = Path(input_dir)
    self.output_dir = Path(output_dir)
    self.output_dir.mkdir(parents=True, exist_ok=True)

def execute_batch(self):
    for root, _, files in os.walk(self.input_dir):
        for file in files:
            source_path = Path(root) / file
            if source_path.suffix.lower() in self.SUPPORTED_EXTENSIONS:
                self._process_single_document(source_path)

def _process_single_document(self, file_path: Path):
    relative_path = file_path.relative_to(self.input_dir)
    target_folder = self.output_dir / relative_path.parent / file_path.stem
    target_folder.mkdir(parents=True, exist_ok=True)
    assets_folder = target_folder / "assets"

    try:
        with open(file_path, "rb") as f:
            raw_bytes = f.read()

        format_hint = "csv" if file_path.suffix.lower() == ".csv" else None
        doc_model = (anydoc.to_document(raw_bytes, format_hint) 
                     if format_hint else anydoc.to_document(raw_bytes))

        image_mapping = {}
        if hasattr(doc_model, "assets") and doc_model.assets:
            assets_folder.mkdir(exist_ok=True)
            for idx, asset in enumerate(doc_model.assets):
                mime_ext = asset.media_type.split("/")[-1] if hasattr(asset, "media_type") else "png"
                img_name = f"extracted_img_{idx + 1}.{mime_ext}"
                with open(assets_folder / img_name, "wb") as img_file:
                    img_file.write(asset.bytes)
                image_mapping[getattr(asset, "id", f"asset_{idx}")] = f"./assets/{img_name}"

        raw_markdown = anydoc.to_markdown(str(file_path))
        normalized_markdown = self._sanitize_layout(raw_markdown, image_mapping)

        result_path = target_folder / f"{file_path.stem}.md"
        result_path.write_text(normalized_markdown, encoding="utf-8")
        print(f"[Erfolg] Konvertierung abgeschlossen: {file_path.name} -> {result_path}")

    except anydoc.NeedsOcrError:
        print(f"[OCR erforderlich] Scan-Dokument erkannt: {file_path.name}. Weiterleitung an gehostete OCR-Engine.")
        ocr_markdown = anydoc.to_markdown(str(file_path), ocr="hosted")
        (target_folder / f"{file_path.stem}.md").write_text(ocr_markdown, encoding="utf-8")
    except Exception as err:
        print(f"[Fehlgeschlagen] {file_path.name}: {str(err)}")

def _sanitize_layout(self, content: str, img_map: dict) -> str:
    lines = content.split("\n")
    repaired_lines = []
    for line in lines:
        trimmed = line.strip()
        if trimmed.startswith("|") and trimmed.endswith("|"):
            line = re.sub(r"\s+", " ", line)
        repaired_lines.append(line)
    sanitized = "\n".join(repaired_lines)

    for asset_id, local_rel_path in img_map.items():
        sanitized = sanitized.replace(f"![{asset_id}]", f"![Asset]({local_rel_path})")

    return sanitized

if name == "main":
converter = BatchDocumentConverter(Path("./raw_docs"), Path("./processed_md"))
converter.execute_batch()

`

AnyDoc hebt die GIL (Global Interpreter Lock) bei der Ausführung von Python-Bindings auf. Selbst ohne den Einsatz schwerer Multiprocessing-Bibliotheken lässt sich durch bloßes Hinzufügen von Pythons Standard-ThreadPoolExecutor eine parallele Konvertierung von Hunderten interner Richtliniendokumente realisieren.

API-Kosten durch den OmniRoute-Proxy senken

Die Angewohnheit, alle Prompt-Aufrufe an das teuerste Flaggschiff-Modell zu schicken, leert das interne API-Budget in kürzester Zeit. Mehr als die Hälfte der Programmierarbeiten besteht aus relativ leichten Aufgaben wie Grammatifehlerkorrekturen, dem Generieren von Docstrings oder dem Schreiben einfacher Testcodes.

Laut einer Forschungsarbeit von UC Berkeley und LMSYS (RouteLLM, 2024) lässt sich durch die dynamische Verzweigung von Modellen anhand der Aufgabenschwierigkeit die GPT-4-ähnliche Leistung auf Basis des MT-Benchmarks zu 95 % aufrechterhalten, während die Aufrufkosten um 85 % reduziert werden. Auch das Datenteam des US-Telekommunikationsriesen AT&T konnte durch den Einsatz eines Gateway-Proxies das Betriebsbudget für generative KI um 56 % senken.

JSON-Konfiguration für Routing-Regeln und Circuit Breakers

Wird das lokale Gateway OmniRoute auf einem lokalen Port (20128) betrieben, kann der Datenverkehr entsprechend der Art der Aufgabe aufgeteilt werden. Zudem wird eine Circuit-Breaker-Funktion unterstützt, die innerhalb einer Sekunde auf ein Backup-Modell umschaltet, falls ein bestimmter Anbieter-API den Status 429 (Rate Limit) zurückgibt oder ein Timeout auftritt.

`json
{
"name": "resilient-cost-saver",
"strategy": "priority",
"nodes": [
{
"provider": "anthropic",
"model": "claude-3-7-sonnet",
"priority": 1,
"timeoutMs": 10000
},
{
"provider": "deepseek",
"model": "deepseek-v4-pro",
"priority": 2,
"timeoutMs": 8000
},
{
"provider": "ollama-local",
"model": "qwen2.5-coder:32b",
"priority": 3,
"timeoutMs": 15000
}
],
"circuitBreaker": {
"errorThresholdPercentage": 50,
"recoveryTimeSec": 300,
"minimumRequests": 5
},
"compression": {
"enabled": true,
"engines": ["rtk", "caveman"]
}
}

`

Monatskostenvergleich auf Basis eines 10-köpfigen Entwicklerteams

Unter Annahme einer Umgebung, in der ein 10-köpfiges Team monatlich 400 Millionen (400M) Token verbraucht, wurden die Kostenunterschiede zwischen festem Flaggschiff-Aufruf und der Anwendung von OmniRoute-Routing-Regeln sowie Prompt-Kompression berechnet.

Routing-Szenario Anteil der Verkehrszuweisung je Modell Monatlicher Token-Verbrauch Effektiver Stückpreis pro Million Token Monatliche kumulierte Ausgaben Kosteneinsparungsrate
Festeinbindung eines Flaggschiff-Modells Flaggschiff 100% 400M $15.00 $6,000.00 Ausgangswert (0%)
OmniRoute-Verzweigungs-Routing Einfach 60%, Mittel 25%, Anspruchsvoll 15% 240M (Haiku)

100M (Sonnet)

60M (Opus) | $0.25

$3.00

$15.00 | $1,260.00 | 79,0% Einsparung |
| Routing + Prompt-Kompression | Smart Routing + 30% Token-Kompression | 280M (Effektive Token) | Anwendung des gewichteten Durchschnitts | $882.00 | 85,3% Einsparung |

Über den Browser unter http://localhost:20128/dashboard lassen sich Anfragen pro Sekunde, das Auslösen des Circuit Breakers sowie das verbleibende Kontingent in Echtzeit überwachen.

Claude of Tanks-Muster und Sperre destruktiver Befehle

Das 3D-Simulationsprojekt „Claude of Tanks“, das der Ingenieur Kevin Liu mit Three.js und Vite realisiert hat, erregte Aufsehen durch eine Architektur, bei der ein direkt codierender Arbeiter-Agent (Worker) und ein die Ergebnisse prüfender Bewerter-Agent (Critic) in Reihe geschaltet sind. Die Claudex-Architektur wiederum, die destructive Ausführungen auf Host-Ebene steuert anstatt sich nur auf Prompt-Richtlinien zu verlassen, bietet einen realistischen Maßstab für die Agentenkontrolle.

Behälterisolierung von Worker und Critic

Bei der UI- oder Grafikentwicklung bemerkt ein einzelner Agent oft nicht einmal, wenn Texturen auf dem Bildschirm verzerren, solange der geschriebene Code rein syntaktisch korrekt ist. Um zu verhindern, dass die Arbeitsergebnisse fehlschlagen, müssen der Worker-Container, der den Code verfasst, und der Critic-Container, der die Render-Ansicht mittels Headless Browser überprüft, über Docker getrennt werden.

`yaml

docker-compose.yml - Ausführungsumgebung mit isolierten Multi-Agenten

version: '3.8'

services:
omniroute-core:
image: diegosouzapw/omniroute:latest
container_name: omniroute-core
ports:
- "20128:20128"
environment:
- PORT=20128
- NODE_ENV=production
volumes:
- omniroute-storage:/app/data
restart: unless-stopped

agent-worker:
image: node:22-bookworm-slim
container_name: agent-worker-node
working_dir: /workspace
depends_on:
- omniroute-core
environment:
- OPENAI_API_BASE=http://omniroute-core:20128/v1
- OPENAI_API_KEY=sk-local-dummy
- CLAUDE_CODE_SUBAGENT_MODEL=auto/coding
volumes:
- ./project_workspace:/workspace
- ./agent_hooks:/root/.claude/hooks:ro
- execution-logs:/workspace/.agent_logs
entrypoint: ["/bin/bash", "-c", "npm install -g @anthropic-ai/claude-code && tail -f /dev/null"]

agent-critic:
image: python:3.11-slim-bookworm
container_name: agent-critic-node
working_dir: /evaluator
depends_on:
- agent-worker
volumes:
- ./project_workspace:/workspace:ro
- ./evaluation_scripts:/evaluator
- execution-logs:/workspace/.agent_logs
entrypoint: ["python", "run_evaluator.py"]

volumes:
omniroute-storage:
execution-logs:

`

Dem Worker-Container werden Schreibrechte für das Quellcode-Verzeichnis eingeräumt, wohingegen der Critic-Container schreibgeschützt (:ro) gemountet wird. Dies dient der systemischen Verhinderung von Szenarien, in denen beide Agenten gleichzeitig im selben Ordner Dateien überschreiben und dabei Code vernichten.

Ausführungssicherheitsvorkehrungen gesteuert durch Host-Hooks

Egal wie oft man in den Prompts anweist: „Committen Sie niemals direkt in den main-Branch“ – wenn eine Sitzung lang wird und eine Kontextkomprimierung stattfindet, vergisst der Agent die Regel. Nötig ist daher eine physische Verteidigungslinie, die Befehle auf Systemebene mittels Hook-Skripten abfängt.

`bash
#!/usr/bin/env bash

~/.claude/hooks/pre-bash - Hook zum Abfangen vor der Befehlsausführung

COMMAND="$1"

1. Blockierung von direkten Commits in den main-Branch

if echo "${COMMAND}" | grep -qE "git[[:space:]]+commit.*(main|master)"; then
echo "[Blockiert] Direkte Commits in den main-Branch sind untersagt. Erstellen Sie stattdessen einen Working-Branch." >&2
exit 1
fi

2. Blockierung der erzwungenen Löschung von Root- und übergeordneten Pfaden

if echo "${COMMAND}" | grep -qE "rm[[:space:]]+-rf[[:space:]]+(/|..)"; then
echo "[Blockiert] Befehl zum Löschen übergeordneter Verzeichnisse erkannt und abgebrochen." >&2
exit 1
fi

3. Aufzeichnung von Befehls-Logs zur Sitzungswiederherstellung

LOG_PATH="HOME/.agentlogs/executiontrace.jsonl"mkdir−p"{HOME}/.agent_logs/execution_trace.jsonl" mkdir -p "HOME/.agentl​ogs/executiont​race.jsonl"mkdir−p"(dirname "{LOG_PATH}")" echo "{\"timestamp\": \"(date -u +%Y-%m-%dT%H:%M:%SZ)", "command": "{COMMAND}\"}" >> "{LOG_PATH}"

exit 0

`

Wird dieses Skript hinterlegt, bricht das System auf Shell-Ebene Befehle ab, kurz bevor der Agent aus Versehen Code in den Main-Branch schiebt oder übergeordnete Projektordner löscht. Da sämtliche Tool-Aufrufe in einer reinen Append-JSONL-Protokolldatei erfasst werden, lässt sich die Arbeit selbst bei einem unerwarteten Prozessabsturz nahtlos ab dem Punkt fortsetzen, an dem sie unterbrochen wurde.