Gleiches Modell, vier Harnesses: Was sich wirklich ändert, wenn nur der Wrapper wechselt
Diese Woche habe ich denselben Coding-Task durch vier AI-Coding-Tools laufen lassen – opencode, Pi, GitHub Copilot in VS Code und Claude Code –, alle

Diese Woche habe ich denselben Coding-Task durch vier AI-Coding-Tools laufen lassen – opencode, Pi, GitHub Copilot in VS Code und Claude Code –, alle angetrieben vom selben lokalen Modell auf einem 64-GB-M1-Max, erreichbar über unser internes VPN. Immer derselbe Prompt, wortgleich. Nicht „welches Tool ist das beste" – bei gleichbleibendem Modell: Was ändert der Wrapper wirklich?
Die Aufgabe war ein kleiner, edukativer CLI-RAG-Chatbot in Python: einen Ordner voller Dokumente indexieren, embedden und chunken, per Ähnlichkeit retrieven und Fragen in einem REPL beantworten – mit Pytest-Tests für Chunking und Retrieval. Einfach genug, damit ein lokales Modell das plausibel in einem Durchgang schafft, real genug, um echte Unterschiede bei Tool-Calling, Context-Handling und Autonomie sichtbar zu machen. Die Inferenz-Maschine selbst ist ein M1 Max, der oMLX betreibt und eine OpenAI-kompatible API über unser Tailnet bereitstellt (ein VPN-interner Endpoint, von außen nicht erreichbar).
Das Modell über alle vier Tools hinweg: Qwen3.6-35B-A3B, das einzige Modell in diesem Stack, das zuverlässig eine Agent-Loop antreibt. Diese Einschränkung ist wichtig – ich habe auch Qwen2.5-Coder-32B ausprobiert, und trotz des „Coder"-Labels konnte es in diesem oMLX/MLX-4bit-Setup überhaupt nicht tool-callen. Ob das an der Quantisierung liegt, am Function-Call-Template des Servers oder am Modell selbst, kann ich aus einem einzigen Stack heraus nicht sagen. Ich würde „Qwen2.5-Coder kann nicht tool-callen" nicht über diese exakte Kombination hinaus verallgemeinern – das ist ein Datenpunkt zu diesem Deployment, kein Urteil über das Modell.
Bevor irgendein Tool das Modell antreiben kann, muss man es erst einmal dorthin verweisen. Schon dieser Schritt allein hat mir etwas gezeigt:
| Tool | Wie das Modell angebunden wird | Reibung |
|---|---|---|
| opencode | Custom Provider in opencode.json, OpenAI-kompatibel | Trivial – eine Config-Datei |
| Pi | ~/.pi/agent/models.json, api: openai-completions | Trivial – eine Config-Datei |
| GitHub Copilot (VS Code) | GUI „Custom Endpoint", plus ein separates Utility-Modell und manuelles Context-Window-Sizing | Mittel – mehrere GUI-Schritte, aber in sich abgeschlossen |
| Claude Code | Nativer Anthropic-Endpoint auf derselben oMLX-Maschine | Niedrig – ein nativer Endpoint, kein Shim nötig |
Die Claude-Code-Zeile stellte sich als die einfachste der vier heraus, sobald ich wusste, wo ich hinschauen musste: oMLX bringt einen nativen Anthropic-/v1/messages-Endpoint mit, bestätigt durch einen einfachen HTTP-Request. Man verweist Claude Code mit auf den Launch-Befehl beschränkten Umgebungsvariablen darauf, und nichts davon bleibt global bestehen:
1ANTHROPIC_BASE_URL=http://<oMLX-host>:8000 \
2ANTHROPIC_AUTH_TOKEN=<token> \
3ANTHROPIC_DEFAULT_SONNET_MODEL=Qwen3.6-35B-A3B-UD-MLX-4bit \
4claude
Das normale, Cloud-gestützte Claude Code – im Terminal wie in VS Code – bleibt davon komplett unberührt.
Mit dem Modell überall angebunden, beginnt der interessante Teil.
opencode hat die Aufgabe über sein TUI durchlaufen lassen, und separat über seine eigene Desktop-UI (Chat-/Build-/Plan-Modus, die die CLI spiegelt). Es kam mit einem eher kleinen Kontextfenster zurecht, brauchte eine Handvoll Anstöße, um es auf Fehler hinzuweisen, die es selbst nicht bemerkt hatte, und produzierte am Ende eine funktionierende App.
Pi ist pures CLI, das schlankste der vier, und sein Kontext hat sich ohne Drama bei rund 28.000 Tokens komprimiert. Der eine echte Defekt: Das Modell hat Pis write-Tool wiederholt nur mit {content} und ohne path-Argument aufgerufen, und Pis Harness hat jeden dieser Aufrufe mit „Validation failed for tool write" zurückgewiesen. Es hat sich nach mehreren Versuchen erholt, und die App lief am Ende – aber ich habe denselben Fehler mehrfach wiederholen sehen, bevor sich das Modell von selbst korrigiert hat.
GitHub Copilot in VS Code hatte die schönste UI der vier und war angenehm Schritt für Schritt zu verfolgen. Es hat sich aber auch in eine echte Schleife bei einem 32k-Kontextfenster verfangen – der Großteil des Budgets ging für Tool-Definitionen drauf, bevor überhaupt Platz zum Nachdenken blieb. Sobald ich ihm ein größeres Fenster gegeben und es explizit gebeten habe, die App selbst auszuführen und zu testen, hat es genau das getan – autonom – und sich zu einem Ergebnis durchgearbeitet. Von den vieren hat es sein eigenes CLI-Tooling am zuverlässigsten genutzt – es hat kaum einen Tool-Call vermasselt. Es war aber auch das Tool mit dem meisten Konfigurationsaufwand beim initialen Setup.
Claude Code war mit deutlichem Abstand das autonomste. Es hat eigene Explore- und Plan-Subagenten laufen lassen, ist durch den üblichen Plan-Modus mit Freigabe-Gate gegangen, hat eine Task-Liste erstellt und dann Ende-zu-Ende danach gearbeitet: alle 12 Dateien geschrieben, Pytest laufen lassen, einen fiesen Bug getroffen (re.split, das None zurückgab, wo der Code eine Liste erwartete), und sich selbst durch mehrere Fixes debuggt, bis 24 von 24 Tests durchliefen – und danach die App selbst end-to-end verifiziert, praktisch ohne Anstöße von mir. Der Preis war Zeit: rund 40 Minuten insgesamt, davon allein mehr als 11 Minuten reine Planung, bevor auch nur eine Zeile Anwendungscode geschrieben wurde. Das ist der Trade-off, den mir dieser Stack abverlangt hat: ein lokales Modell plus eine Plan-first-Harness ist langsam.
Für die anderen drei Runs habe ich keine präzisen Zeitangaben, die ich den 40 Minuten gegenüberstellen könnte – das ist eine Lücke in dem, was ich gemessen habe, keine Behauptung, die ich mit einem erfundenen Multiplikator zukleistern will. Was ich direkt sagen kann: Claude Code war spürbar, nicht nur geringfügig, das langsamste der vier auf dem Weg zu einem funktionierenden Ergebnis.
Der Embedding-Dimension-Mismatch. opencode, Pi und Copilot sind jeweils in irgendeine Version desselben Bug-Typs gelaufen: eine Diskrepanz zwischen der Embedding-Dimension, die nomic-embed-text tatsächlich zurückgibt, und dem, worauf die ChromaDB-Collection konfiguriert war. Gleiches Fehlerbild, drei verschiedene Harnesses, dasselbe zugrunde liegende Modell. Das ist der Fingerzeig – das ist eine Modellschwäche, die durch die Harness durchschlägt, nicht etwas, das einer der drei Wrapper falsch gemacht hat. Claude Code ist dem in der Praxis entgangen, was ich auf das Ausmaß der Planung und den End-to-End-Verifikationsdurchlauf zurückführe, den es vor dem Abschluss der Aufgabe gemacht hat – nicht auf ein spezielles Bewusstsein für Embedding-Dimensionen im Tool selbst. Eine ehrliche Einschränkung dazu: Claude Codes eigene Pytest-Suite mockt Ollama und den Vector Store, „24 von 24 grün" beweist also für sich genommen nicht, dass die Embeddings tatsächlich Ende-zu-Ende funktionieren – der separate Lauf, bei dem das Indexieren tatsächlich ausgeführt wurde und reale 768-dimensionale Vektoren zurückkamen, ist der Teil, der das wirklich zeigt.
Pis fehlendes path-Argument. Das ist eine Geschichte über Harness-Strenge, keine Modell-Geschichte. Pis Tool-Calling ist minimal und, wie sich zeigt, weniger nachsichtig gegenüber einem leicht fehlerhaften Aufruf – es hat den write-Call rundheraus abgelehnt, statt die Absicht zu erraten. Copilots Tool-Definitionen sind reichhaltiger und strenger, und in diesem Vergleich war Copilot das Tool, das sein eigenes Tooling am zuverlässigsten aufgerufen hat. Ein strengeres, genauer spezifiziertes Tool-Schema scheint mehr von der Schlampigkeit eines kleinen lokalen Modells abzufangen, bevor daraus ein verschwendeter Zug wird.
Kleine Kontextfenster lokaler Modelle und schwerer Tool-Definitions-Overhead verstärken sich auf unschöne Weise. opencode und Pi haben beide anmutig bei rund 28.000 bis 32.000 Tokens komprimiert – ihre eigenen Tool-Oberflächen sind schlank, da gab es von vornherein nicht viel wegzukomprimieren. Copilots Agent dagegen verbrennt rund 60 Prozent seines Kontextbudgets für Tool-Definitionen, bevor das Modell auch nur eine Zeile der eigentlichen Aufgabe sieht. Bei einem deklarierten Fenster von 32k war dieser Overhead genug, um eine Schleife auszulösen. Das Modell selbst unterstützt einen 256k-Kontext (max_model_len 262144 serverseitig) – Copilots deklariertes Fenster Richtung 128k anzuheben hat die Schleife sofort behoben. Die Obergrenze war nie das Modell. Sie war das, was der Wrapper dem Modell als seine Obergrenze mitgeteilt hat.
Ich bin mit der Erwartung reingegangen, dass die schlankesten Tools auch die robustesten sind, weil weniger Konfiguration meist weniger gibt, das man falsch einstellen kann. Das ist nicht das, was passiert ist. opencode und Pi waren trivial auf das Modell auszurichten – je eine Config-Datei – und beide brauchten echte Betreuung, um zu einer funktionierenden App zu kommen: Anstöße bei Fehlern, wiederholte Tool-Calls, ein Defekt in Pis eigener Validierung. Copilot brauchte einen GUI-Flow, ein separates Utility-Modell und manuelles Context-Sizing – tatsächlich das konfigurationsintensivste der vier – und hat sich das mit dem zuverlässigsten Tool-Calling zurückgezahlt, und war neben Claude Code das einzige Tool, das sich selbst autonom getestet hat, sobald es dafür Raum bekam.
Claude Code sitzt an beiden Enden der Skala zugleich: die strukturierteste Harness (Plan-Modus, Subagenten, eine explizite Task-Liste) und, mit deutlichem Abstand, das autonomste Ergebnis – ein selbst debuggter Fix für einen echten Regex-Bug, 24 von 24 Tests und ein Ende-zu-Ende verifizierter Lauf, praktisch ohne Anstöße von mir. Es hat auch mit klarem Abstand am längsten gedauert, selbst ohne eine exakte Zahl, die man den anderen drei gegenüberstellen könnte.
Das Muster, das ich daraus mitnehme: Der eigentliche Trade-off in diesem Stack ist Autonomie gegen Geschwindigkeit, nicht schlank gegen schwer. Je mehr Struktur eine Harness auferlegt, bevor sie das Modell handeln lässt – Planung, Subagenten, strengere Tool-Schemas –, desto autonomer wird tendenziell das Endergebnis, und desto langsamer kommt es dorthin. Der konfigurationsintensivste Wrapper in diesem Test (Copilot) hat das autonomste praktische Ergebnis für den Aufwand geliefert, den das Setup gekostet hat. Die strukturierteste Harness (Claude Code) hat insgesamt das autonomste Ergebnis geliefert, zu realen Zeitkosten.
opencode, wenn ich ein TUI oder eine kleine Desktop-UI auf einem Custom-Endpoint mit nahezu null Setup will, und mir egal ist, ein kleineres lokales Modell selbst über die gelegentliche Unebenheit hinweg anzustoßen.
Pi, wenn ich das schlankeste mögliche CLI will und schnell prototypen möchte – nur einplanen, hin und wieder einen schlampigen Tool-Call zu wiederholen, besonders bei einem kleineren oder stärker quantisierten Modell.
GitHub Copilot, wenn ich das zuverlässigste Tool-Calling aus einem lokalen Modell herausholen will und bereit bin, das GUI-Setup selbst zu machen und das Kontextfenster selbst zu dimensionieren, statt dem Default zu vertrauen.
Claude Code, wenn ich maximale Autonomie will und bereit bin, dafür Zeit einzutauschen – und wenn ich einen nativen Anthropic-kompatiblen Endpoint habe oder direkt ansteuern kann.
Das war eine Aufgabe, größtenteils ein Modell, eine Maschine, eine Quantisierung. Die Erkenntnisse hier sind richtungsweisend, nützlich, um zu entscheiden, was man im eigenen Stack als Nächstes ausprobiert – keine endgültige Rangliste von vier Tools. Das Tool-Calling-Versagen von Qwen2.5-Coder ist spezifisch für diese Quantisierung und diesen Server – dieses Urteil würde ich nicht auf ein anderes Deployment desselben Modells übertragen.
Wer gerade lokale Modelle für agentisches Coding evaluiert – oder einen ähnlichen Vergleich gegen die eigene Hardware, das eigene Modell, die eigenen Tools fahren möchte –, meldet sich gerne. Genau das ist die Art von Hands-on-Arbeit, die wir bei Infralovers machen.
Sie interessieren sich für unsere Trainings oder haben einfach eine Frage, die beantwortet werden muss? Sie können uns jederzeit kontaktieren! Wir werden unser Bestes tun, um alle Ihre Fragen zu beantworten.
Hier kontaktieren