Stand: 2026-02-25 · Autor: Dagobert 🦆
OpenClaw sendet jeden LLM-Request mit einem tools-Array (40+ Tool-Definitionen).
Das AcademicAI-Backend lehnt den tools-Parameter mit HTTP 400 ab ("Extra inputs are not permitted").
Der Proxy strippt tools bereits vor dem Weiterleiten — das Modell antwortet also, aber ohne Möglichkeit, Tools aufzurufen. Damit sind academicai-Modelle auf reine Text-Generierung beschränkt: kein web_search, kein exec, kein memory_search, kein Modellwechsel via session_status.
Tool-Definitionen als Text in den System-Prompt injiziert, Modell aufgefordert <tool_call>{"name":..., "arguments":...}</tool_call> auszugeben. Ergebnis: Alle getesteten Modelle (gpt-4o, gpt-5, gpt-5-mini, Mistral-Large-3) verweigern die Ausgabe des Tags. Sie beschreiben stattdessen, was sie tun würden, oder beantworten die Frage direkt.
- RLHF-Training: GPT- und Mistral-Modelle sind darauf trainiert, Tool-Calls nur über den nativen
tools-Parameter auszulösen. Ohne registrierte Tools wechseln sie nicht in den "function calling mode". - Safety-Layer: Die Modelle unterscheiden zwischen "ich habe Tools" und "jemand beschreibt mir Tools im Prompt". Im zweiten Fall verhalten sie sich beratend statt ausführend.
- Kein
tool_choice-Signal: Ohne nativentool_choice-Parameter fehlt dem Modell das Signal, dass es einen strukturierten Output produzieren soll.
Idee: Statt XML-Tags den JSON-Mode (response_format: {type: "json_object"}) nutzen, um das Modell zu zwingen, strukturierten Output zu produzieren.
Ablauf:
- Proxy erkennt
toolsim Request - Tool-Definitionen + Entscheidungsschema als System-Prompt injizieren
response_format: {type: "json_object"}an Backend senden- Modell antwortet mit JSON:
{"action": "tool_call", "name": "...", "arguments": {...}}oder{"action": "respond", "content": "..."} - Proxy parst JSON → entweder OpenAI
tool_calls-Response oder normaler Text-Response
Vorteile:
- JSON-Mode ist gut trainiert bei GPT-Modellen
- Erzwingt strukturierten Output (kein Freitext-Escape)
- Einfaches Parsing (kein Regex)
Risiken:
- Unklar ob AcademicAI
response_formatunterstützt (muss getestet werden) - Modell könnte trotzdem
{"action": "respond", ...}wählen statt Tool zu callen - Jeder Response wird JSON → Overhead für normale Antworten
- Verschachtelte Tool-Calls (multiple) werden komplex
Aufwand: Mittel · Erfolgswahrscheinlichkeit: Mittel-Hoch (falls JSON-Mode unterstützt)
Idee: Zwei aufeinanderfolgende LLM-Calls pro User-Request. Erster Call entscheidet ob ein Tool nötig ist und welches. Zweiter Call füllt die Parameter oder generiert die Text-Antwort.
Ablauf:
- Pass 1 — Router: Komprimierte Frage an das Modell: "Gegeben diese Tools und diese User-Nachricht: Brauchst du ein Tool? Wenn ja, welches? Antworte nur mit dem Tool-Namen oder NONE."
- Verwendetes Modell: das günstigste (
gpt-5-nano, $0.06/M Input) - Minimaler Prompt → wenige Tokens
- Verwendetes Modell: das günstigste (
- Pass 2a — Tool-Call: Falls Tool erkannt: gezielter Prompt mit nur einem Tool-Schema → Parameter extrahieren. Output: JSON mit den Argumenten.
- Pass 2b — Text: Falls NONE: Original-Messages ohne Tool-Injection an das Backend → normale Antwort.
Vorteile:
- Router-Call ist billig (~100 Tokens, nano-Modell)
- Zweiter Call hat klaren, engen Scope (ein Tool, Parameter füllen)
- Funktioniert auch ohne
response_format: json_object - Gesamtlatenz nur +200-400ms für den Router-Call
Risiken:
- Doppelte Latenz bei jedem Request (auch wenn kein Tool gebraucht wird)
- Router kann falsch liegen → entweder verpasster Tool-Call oder unnötiger zweiter Call
- Conversation-State wird komplexer (Proxy muss internen State managen)
- Kosten: ~50% mehr Tokens pro Request (aber nano ist billig)
Optimierung: Router-Call nur wenn tool_choice != "none". Bei tool_choice: "none" direkt Text-Antwort.
Aufwand: Hoch · Erfolgswahrscheinlichkeit: Hoch
Idee: Kein strukturierter Output vom Modell erzwingen. Stattdessen die natürliche Text-Antwort analysieren und Tool-Intents heuristisch erkennen.
Ablauf:
- Tool-Definitionen als Kontext in den System-Prompt (wie bisher)
- Zusätzliche Instruktion: "Wenn du ein Tool verwenden willst, beschreibe den Aufruf in diesem Format:
TOOL: tool_name(param1=value1, param2=value2)" - Proxy parst die Antwort mit Regex auf
TOOL: ...-Pattern - Match → OpenAI
tool_calls-Response bauen - Kein Match → normaler Text-Response
Vorteile:
- Ein einziger LLM-Call
- Minimale Änderung am Prompt
TOOL: name(args)ist einfacher als XML und näher an natürlicher Sprache
Risiken:
- Gleiche RLHF-Problematik wie bisheriger Ansatz — Modell könnte
TOOL:verweigern - Parsing von Freitext-Argumenten fehleranfällig (Strings mit Kommas, verschachtelte JSON-Werte)
- Kein Zwang zu strukturiertem Output → Modell kann Mischformen produzieren
- Argument-Typen (number, boolean, array) müssen erraten werden
Aufwand: Niedrig · Erfolgswahrscheinlichkeit: Niedrig (gleiche Root Cause wie bisheriger Ansatz)
Idee: Der Proxy wird selbst zum Mini-Agenten. Er führt bestimmte Tools lokal aus, anstatt sie an OpenClaw zurückzugeben.
Ablauf:
- Proxy erkennt Tool-Intent im Modell-Output (via Strategie A, B oder C)
- Statt
tool_calls-Response an OpenClaw: Proxy führt das Tool selbst aus - Ergebnis wird als Kontext in einen Folge-Call an AcademicAI gegeben
- Finale Text-Antwort geht an OpenClaw
Vorteile:
- OpenClaw sieht nur Text-Responses → keine Kompatibilitätsprobleme
- Bestimmte Tools sind einfach zu implementieren (
web_searchvia Brave API)
Nachteile:
- Dupliziert OpenClaw-Infrastruktur — jedes Tool muss im Proxy reimplementiert werden
- Sicherheitsmodell wird umgangen (Proxy hat keine Permissions-Checks)
exec,browser,memory_searchetc. sind nicht sinnvoll im Proxy implementierbar- Proxy wird komplex und fragil
- OpenClaw verliert Kontrolle über Tool-Aufrufe (Logging, Rate-Limiting, Audit)
Aufwand: Sehr hoch · Erfolgswahrscheinlichkeit: Mittel (nur für Subset von Tools)
Fazit: Nicht empfohlen. Widerspricht der Architektur (Proxy = Adapter, nicht Agent).
Idee: Tool-Calls sind mit AcademicAI nicht möglich. Das wird sauber dokumentiert und OpenClaw so konfiguriert, dass academicai-Modelle nur für passende Use-Cases verwendet werden.
Ablauf:
- Proxy strippt
toolsweiterhin (Status Quo) - Keine Tool-Emulation
- OpenClaw-Konfiguration: academicai-Modelle nicht als Default-Modell (kein Tool-Support)
- Explizite Nutzung via
session_status(model=academicai/gpt-5)für reine Text-Tasks - Dokumentation: "Kein Tool-Support" in README, TOOLS.md, Agent-Config
Vorteile:
- Kein zusätzlicher Code
- Keine Latenz- oder Kosten-Overhead
- Kein Risiko durch fehlgeschlagene Emulation
- Saubere Erwartungshaltung
Nachteile:
- academicai-Modelle sind Zweite-Klasse-Bürger in OpenClaw
- Kein
web_search,execetc. → viele Aufgaben nicht möglich - Modellwechsel zur Laufzeit via Tool funktioniert nicht (Henne-Ei: man braucht Tools um das Modell zu wechseln)
Aufwand: Minimal · Erfolgswahrscheinlichkeit: 100% (kein Emulationsversuch)
| Strategie | Aufwand | Latenz | Kosten | Erfolgswahrsch. | Wartbarkeit |
|---|---|---|---|---|---|
| A: JSON-Mode | Mittel | +0ms | +0% | Mittel-Hoch¹ | Gut |
| B: Zwei-Pass | Hoch | +200-400ms | +30-50% | Hoch | Mittel |
| C: Regex/Heuristik | Niedrig | +0ms | +0% | Niedrig | Schlecht |
| D: Agent-in-Middle | Sehr hoch | +variabel | +variabel | Mittel | Schlecht |
| E: Graceful Degrad. | Minimal | +0ms | +0% | N/A | Sehr gut |
¹ Abhängig davon ob AcademicAI response_format unterstützt
Warum: Geringster Aufwand mit höchster Chance auf Erfolg. Ein einziger API-Call, keine Architektur-Änderung. Muss nur getestet werden ob response_format: {type: "json_object"} vom Backend akzeptiert wird.
Konkreter Test-Plan:
- Request an AcademicAI mit
response_format: {type: "json_object"}senden - Wenn HTTP 400 → Strategie A fällt raus, weiter mit B
- Wenn akzeptiert: minimalen Prompt testen der Tool-Entscheidung als JSON erzwingt
Prompt-Entwurf für JSON-Mode:
You have access to the following tools:
- web_search(query: string, count?: number) — Search the web
- memory_search(query: string) — Search memory files
[...]
Respond with a JSON object. Choose ONE:
1. If you need a tool: {"action": "tool_call", "name": "tool_name", "arguments": {"param": "value"}}
2. If you can answer directly: {"action": "respond", "content": "your answer here"}
Falls JSON-Mode nicht unterstützt oder unzuverlässig: Zwei-Pass mit nano als Router. Höhere Komplexität, aber robuster weil der Router-Call ein eng begrenztes Klassifikationsproblem löst (Tool-Name oder NONE) statt freier Text-Generierung.
Unabhängig von A oder B sollte der Proxy graceful degradieren wenn die Emulation fehlschlägt. Kein Hard-Fail, sondern: Tool-Calls werden ignoriert, Modell antwortet als Text. OpenClaw muss damit umgehen können.
- Testen ob
response_format: {type: "json_object"}von AcademicAI akzeptiert wird - Testen ob GPT-5-mini im JSON-Mode zuverlässig
{"action": "tool_call", ...}produziert - Testen mit 3-5 verschiedenen Prompts (eindeutiger Tool-Fall, Grenzfall, kein Tool)
-
tool_emulation.pyüberarbeiten: JSON-Mode statt XML-Tags -
server.py:response_formatnur setzen wenn Tools vorhanden - Response-Parser: JSON → OpenAI
tool_calls-Format oder Text-Response - Streaming-Anpassung: JSON-Response als SSE-Chunks (tool_calls oder Text)
- Bestehende Tests anpassen (Test 1-4 aus
test_tool_emulation.py) - Neue Tests: Edge Cases (leere Tools, tool_choice=none, mehrere Tool-Calls)
- Integration mit OpenClaw: academicai-Modell setzen, Tool-Aufrufe testen
- Fallback wenn JSON-Parsing fehlschlägt → Text-Response
- Logging: Tool-Call-Erkennung, Parse-Fehler, Fallback-Trigger
- Metriken: Erfolgsrate der Tool-Emulation
- Unterstützt AcademicAI
response_format? → Muss getestet werden. Wenn nein, fällt Strategie A weg. - Wie verhält sich das Modell bei ambigen Fällen? → "Wie wird das Wetter?" könnte web_search brauchen oder direkt beantwortet werden. Hängt vom Prompt-Design ab.
- Multiple Tool-Calls? → OpenClaw sendet manchmal Requests die mehrere parallele Tool-Calls erwarten (z.B.
read+exec). JSON-Mode kann das via Array abbilden, aber die Zuverlässigkeit sinkt. - Tool-Call-Ketten? → Modell ruft Tool A auf → bekommt Ergebnis → ruft Tool B auf. Funktioniert mit allen Strategien, weil OpenClaw die Schleife managed.
- Kontakt zum AcademicAI-Team? → Langfristig wäre nativer
tools-Support die sauberste Lösung. Lohnt sich die Anfrage?