Alain Lilic

DemoDrei Prototypen, ein Sicherheitsmuster

Agenten mit echten Folgen absichern

Problem

Sobald ein Agent nicht nur Text schreibt, sondern Dateien ablegt oder Orders vorbereitet und ausführt, reicht ein guter Prompt nicht. Ich wollte ein Muster, bei dem die Grenzen im Code liegen: was der Agent lesen darf, was schreiben, wer freigibt und wie man alles stoppt. Als Testfeld dienten Marktdaten und Demo-Konten, weil dort jede Aktion eine sichtbare Folge hat, ohne echtes Geld.

Meine Rolle

Ich habe festgelegt, welche Rolle was darf, wie freigegeben und wie gestoppt wird, und die Prüftore abgenommen. Dazu kamen Spezifikation, Review, Tests und die Prüfung, ob die Grenzen im Code wirklich greifen.

Vorgehen

In cctrader startet ein FastAPI-Orchestrator den Coding-Agenten headless per CLI (-p, stream-json). Die Allowlist erlaubt nur die eigenen MCP-Tools, Skills, Subagenten, Read und Grep, also kein Bash und kein Write. Geschrieben wird nur über MCP-Tools, die per Umgebungsvariable an genau eine Analyse-ID gebunden sind. Aus dem Stream speichert der Orchestrator pro Lauf Tokens, Cache-Treffer, Kosten und jeden Tool-Aufruf.

Im Trading-Framework von stratlab hat der MCP-Server drei Stufen: 0 lesen, 1 vorschlagen und Not-Aus, 2 ausführen. Die Stufe kommt aus der Prozessumgebung, der Agent läuft auf 0. Vor jedem Tool außer Journal-Abfrage und Not-Aus prüft ein Guard den Kill-Switch, zurücksetzen kann ihn nur ein Mensch. Vorschläge gehen per Telegram mit APPROVE und REJECT raus und verfallen nach 30 Minuten. Im MT5-Gateway zwingt tool_choice das Modell in ein einziges Werkzeug mit JSON-Schema, submit_trade_intent. Danach prüft eine Policy Symbol, Volumen und Stop-Loss, Standard ist der Dry-Run.

Architektur

  1. Auslöser

    API-Aufruf mit Token oder Event-Watcher mit 15 Minuten Entprellung und höchstens 4 Läufen pro Stunde

  2. Headless-Agent

    CLI mit -p und stream-json, Allowlist: eigene MCP-Tools und Lesewerkzeuge, kein Bash, kein Write

  3. Eigener MCP-Server

    Stufe 0/1/2 aus der Umgebung, Kill-Switch-Guard, Schreib-Tools an eine Analyse-ID gebunden

  4. Deterministische Prüfung

    Risk-Engine bzw. Policy: Symbol, Volumen, Stop-Loss, Auto-Execute standardmäßig aus

  5. Mensch gibt frei

    Telegram APPROVE oder REJECT, offene Vorschläge verfallen nach 30 Minuten

  6. Ausführung und Protokoll

    Erneute Risikoprüfung, nur Demo-Konto oder Fake-Backend, Journal plus Tokens und Kosten pro Lauf

Entscheidung

Rechte gehören in den Prozess, nicht in den Prompt

Ein Prompt wie 'führe nie selbst aus' ist eine Bitte. Deshalb liest der MCP-Server seine Stufe beim Start aus der Umgebung, und die Konfiguration des Agenten setzt sie auf 0. Ausführen kann nur ein anderer Prozess, nachdem ein Mensch freigegeben hat, und auch der prüft das Risiko noch einmal. Kein Tool, das der Agent aufrufen darf, kann die Stufe ändern. Der Preis: mehr bewegliche Teile und eine Freigabe, die nach 30 Minuten verfällt, wenn niemand reagiert.

Code-Auszug

ai-trading-framework/mcp_server/server.py (gekürzt)Seitlich scrollenpython
TIER = int(os.environ.get("TRADING_TIER", "0"))

def require_tier(min_tier: int):
    def deco(fn):
        @functools.wraps(fn)
        def wrapper(*a, **kw):
            if TIER < min_tier:
                return json.dumps({"error": "permission_denied", "required_tier": min_tier, "current_tier": TIER})
            return fn(*a, **kw)
        return wrapper
    return deco

def _killswitch_guard() -> str | None:
    if killswitch_is_active():
        return json.dumps({"error": "killswitch_active"})
    return None

# ...
@mcp.tool()
@require_tier(2)
@_safe
def trade_execute(proposal_id: str) -> str:
    guard = _killswitch_guard()
    if guard:
        return guard
Die Stufe wird beim Start aus der Umgebung gelesen, nicht vom Modell gesetzt. Jedes Tool trägt seine Mindeststufe als Decorator; Ausführen braucht Stufe 2 und prüft zuerst den Kill-Switch.

Ergebnisse

  • 25Backend-Tests in cctrader, am 18.10.2026 grün
  • 28Tests für Stufen, Kill-Switch und Freigabe, am 18.10.2026 grün
  • 0,17 $für einen kompletten Testlauf mit Haiku in 47 s
  • 30 minbis ein offener Vorschlag verfällt
4
Bedingungen, bevor das MT5-Gateway wirklich ausführt

Was ich daraus gelernt habe

Nicht jede Grenze war durchgesetzt. In cctrader stehen ein Lauf gleichzeitig und zwölf pro Stunde in der Config, aber kein Code prüft das. Im MT5-Gateway sagt die Doku Policy vor Auth, der Code prüft bei Ausführungen zuerst das Token, und ist keins gesetzt, prüft er gar nicht. Der Telegram-Callback prüft nicht, wer den Knopf gedrückt hat. Heute schreibe ich zu jeder Grenze zuerst einen Test, der sie zu brechen versucht, und fehlende Konfiguration scheitert geschlossen. Offen ist noch der Nachweis gegen ein echtes Demo-Konto, dafür fehlten die Demo-Schlüssel.