Lokale Large Language Models werden für Softwareentwicklung zunehmend interessant. Mit LM Studio lassen sich aktuelle Open-Source-Modelle lokal betreiben, während Bionic direkt als Coding-Agent auf Projekte zugreifen, Dateien analysieren und Änderungen durchführen kann.
In meinem Test ging es vor allem um eine Frage: Welches Modell eignet sich auf einem normalen Desktop-PC sinnvoll für agentisches Coding, und wie lassen sich Prompt-Verarbeitung und Generierung optimieren?
Als Testsystem kam folgende Hardware zum Einsatz:
CPU: Ryzen 7 5700X
RAM: 32 GB DDR4
GPU: AMD Radeon RX 9060 XT
VRAM: 16 GB
Dabei zeigte sich schnell: Nicht nur die Qualität des Modells ist entscheidend. Gerade bei Coding-Agenten spielen Modellgröße, Kontextfenster, KV-Cache und Prompt Processing eine mindestens ebenso große Rolle.
Modelle mit einer einheitlichen Testaufgabe vergleichen
Um verschiedene lokale LLMs in OpenCode sinnvoll miteinander zu vergleichen, sollte jedes Modell möglichst dieselbe klar definierte Aufgabe erhalten. Als praktische Testaufgabe eignet sich beispielsweise die Entwicklung eines kleinen Tetris-Clones als Webseite mit PHP, HTML, CSS und JavaScript. Die Anwendung soll ein klassisches 10×20-Spielfeld, alle sieben Tetrominos, Bewegung und Rotation, Hard Drop, das Entfernen vollständiger Reihen, Punkte und Level sowie eine Vorschau auf den nächsten Stein enthalten. Zusätzlich sollen Start, Pause und Neustart sowie eine Tastatursteuerung umgesetzt werden. Externe Frameworks sind nicht erlaubt, und der Code soll sauber in sinnvolle Dateien gegliedert werden.
Eine solche Aufgabe eignet sich gut als Benchmark, weil sie mehrere Fähigkeiten gleichzeitig testet: Das Modell muss eine kleine Softwarearchitektur planen, Spiellogik implementieren, Zustände verwalten, eine Benutzeroberfläche erstellen und mehrere Dateien konsistent miteinander verbinden. Zusätzlich lässt sich anschließend überprüfen, ob das Ergebnis tatsächlich funktioniert oder ob beispielsweise Rotation, Kollisionsprüfung, Reihenlöschung oder Levelsystem fehlerhaft umgesetzt wurden. Für einen aussagekräftigen Vergleich sollten die Modelle möglichst mit denselben OpenCode-Einstellungen, demselben System-Prompt und einem leeren Projektverzeichnis starten.
Ein geeigneter System-Prompt für lokale Coding-Modelle
Neben dem eigentlichen Modell beeinflusst auch der System-Prompt die Qualität eines Coding-Agenten. Gerade bei kleineren lokalen Modellen sollte dieser möglichst kurz und eindeutig gehalten werden. OpenCode stellt dem Modell bereits eigene Informationen über Werkzeuge, Dateien und Arbeitsumgebung zur Verfügung. Ein umfangreicher zusätzlicher System-Prompt verbraucht daher nicht nur Kontext, sondern kann im ungünstigsten Fall auch mit den Agentenanweisungen von OpenCode konkurrieren.
Für lokale Coding-Modelle hat sich deshalb ein kompakter Prompt mit wenigen klaren Regeln angeboten:
You are a senior software engineer working autonomously in an existing project.
Inspect the relevant code before editing it.
Use the available tools to search, read, edit, build, and test.
Make the smallest correct change that solves the user's request.
Follow the existing architecture and coding style.
Do not invent APIs, files, or dependencies.
Do not modify unrelated code.
After changes, build or test the project when possible.
Fix errors caused by your changes.
Never claim success unless it was verified.
If the task is clear, proceed without asking unnecessary questions.
Besonders wichtig sind dabei vier Grundregeln: erst analysieren, dann verändern; die verfügbaren Tools verwenden; Änderungen möglichst klein halten; und das Ergebnis anschließend bauen oder testen. Diese Vorgaben adressieren typische Schwächen kleinerer lokaler Modelle, etwa das Erfinden nicht vorhandener APIs, unnötig große Refactorings oder das vorschnelle Melden einer erfolgreichen Lösung ohne tatsächliche Überprüfung.
LM Studio mit OpenCode verbinden
LM Studio stellt einen OpenAI-kompatiblen API-Server bereit. Dadurch können externe Programme wie OpenCode lokale Modelle verwenden.
Der API-Endpunkt lautet standardmäßig:
http://127.0.0.1:1234/v1
Eine mögliche OpenCode-Konfiguration sieht beispielsweise so aus:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"lmstudio": {
"npm": "@ai-sdk/openai-compatible",
"name": "LM Studio",
"options": {
"baseURL": "http://127.0.0.1:1234/v1"
},
"models": {
"MODEL-ID": {
"name": "Lokales Modell"
}
}
}
}
}
Damit kann OpenCode LM Studio praktisch wie einen lokalen OpenAI-Server verwenden.
Bionic oder OpenCode?
LM Studio besitzt mit Bionic inzwischen selbst einen Coding-Agenten. Beide Lösungen verfolgen grundsätzlich denselben Ansatz:
LLM
↓
Coding-Agent
↓
Dateien suchen und lesen
↓
Code verändern
↓
Terminalbefehle ausführen
↓
Tests und Builds durchführen
OpenCode bietet dabei sehr viele Konfigurationsmöglichkeiten und eignet sich besonders gut für komplexe Entwicklungsworkflows.
Bionic hat dagegen einen wichtigen Vorteil: Es ist direkt auf die Nutzung lokaler und offener Modelle innerhalb von LM Studio zugeschnitten.
Gerade beim Tool Calling kann dies relevant sein. Ein Modell kann zwar guten Code erzeugen, muss für einen Coding-Agenten aber zusätzlich zuverlässig entscheiden können:
- welche Dateien gelesen werden müssen,
- wann ein Terminalbefehl notwendig ist,
- welche Änderungen durchgeführt werden sollen,
- wie Testergebnisse zu interpretieren sind.
Für lokale Modelle ist Bionic deshalb eine sehr interessante Alternative zu OpenCode.
Erster Versuch: Qwen3.6 35B A3B
Zunächst wurde folgendes Modell verwendet:
Qwen3.6 35B A3B Q4_K_M
Dabei handelt es sich um ein Mixture-of-Experts-Modell. Obwohl insgesamt etwa 35 Milliarden Parameter vorhanden sind, werden pro Token nur ungefähr 3 Milliarden Parameter aktiviert.
Das klingt zunächst ideal für lokale Nutzung.
In der Praxis war das Modell auf einem System mit 16 GB VRAM und 32 GB RAM allerdings zu groß.
Die quantisierte Modelldatei benötigt bereits ungefähr 20 GB Speicher. Damit passt das Modell nicht komplett in den VRAM.
Die Folge:
GPU
16 GB VRAM
│
├── Teil des Modells
├── KV Cache
│
System-RAM
│
└── restliches Modell
Dadurch müssen Teile der Berechnung zwischen GPU und Arbeitsspeicher aufgeteilt werden.
Das Modell funktionierte zwar, war für einen interaktiven Coding-Agenten aber deutlich zu schwergewichtig.
Context Size Exceeded
Ein weiteres Problem trat relativ schnell auf:
Engine protocol predict stream returned an error:
Context size has been exceeded.
Bei einem normalen Chat besteht der Kontext hauptsächlich aus:
System Prompt
+ Benutzerfrage
+ bisherige Antworten
Bei einem Coding-Agenten kommt wesentlich mehr hinzu:
System Prompt
+ Chatverlauf
+ Projektinformationen
+ eingelesene Quelldateien
+ Tool Calls
+ Terminalausgaben
+ Compilerfehler
+ Git-Diffs
+ Reasoning
Dadurch können selbst kleine Coding-Aufgaben schnell mehrere zehntausend Tokens erzeugen.
Ein Kontextfenster von beispielsweise:
8192 Tokens
ist deshalb für einen Coding-Agenten kaum ausreichend.
Als sinnvoll erwiesen sich mindestens:
32768 Tokens
Für größere Aufgaben sind:
65536 Tokens
deutlich komfortabler.
Die bessere Lösung: Gemma 4 12B QAT
Als Alternative wurde anschließend:
Gemma 4 12B QAT
verwendet.
Das Modell erwies sich als wesentlich besser passend für die vorhandene Hardware.
QAT steht für:
Quantization-Aware Training
Während bei normaler Quantisierung ein fertig trainiertes Modell nachträglich beispielsweise auf 4 Bit reduziert wird, berücksichtigt Quantization-Aware Training die geringere Präzision bereits während des Trainings.
Dadurch können relativ kleine Modellvarianten erzeugt werden, ohne so viel Qualität wie bei einer einfachen nachträglichen Quantisierung zu verlieren.
Gemma 4 12B QAT benötigt auf dem Testsystem ungefähr:
9–10 GB VRAM
Damit bleibt auf einer 16-GB-Grafikkarte noch ausreichend Speicher für:
KV Cache
Context
Runtime
Batch Processing
übrig.
Gute LM-Studio-Einstellungen für Gemma 4 12B QAT
Als guter Ausgangspunkt haben sich folgende Werte ergeben:
Context Length: 32768–65536
GPU Offload: Maximum
CPU Thread Pool: 8
Evaluation Batch Size: 4096
Physical Batch Size: 1024
Max Concurrent: 1
Flash Attention: ON
Reasoning Budget: 4096–8192
Preserve Thinking: OFF
KV Cache GPU: ON
Unified KV Cache: ON
K Cache: Q8_0
V Cache: Q8_0
Context Checkpoints: 16–32
Keep Model in Memory: ON
mmap: ON
Bei den Sampling-Einstellungen kann man für Gemma ungefähr mit folgenden Werten beginnen:
Temperature: 1.0
Top K: 64
Top P: 0.95
CPU Thread Pool
Der Ryzen 7 5700X besitzt:
8 Kerne
16 Threads
Für LLM-Inferenz bedeutet mehr Threads nicht automatisch mehr Geschwindigkeit.
Ein sinnvoller Ausgangspunkt ist deshalb:
CPU Thread Pool Size = 8
also ungefähr die Anzahl der physischen Kerne.
In meinem Test spielte die CPU allerdings kaum eine Rolle, da das Modell vollständig beziehungsweise nahezu vollständig auf der GPU ausgeführt wurde.
Flash Attention
Eine Einstellung sollte für moderne Modelle praktisch immer aktiviert werden:
Flash Attention = ON
Flash Attention optimiert die Attention-Berechnung und kann sowohl:
- Speicherverbrauch reduzieren
- als auch die Geschwindigkeit erhöhen.
Gerade bei großen Kontextfenstern macht sich dieser Effekt bemerkbar.
Max Concurrent Predictions
LM Studio erlaubt mehrere parallele Inferenzanfragen.
Standardmäßig kann beispielsweise eingestellt sein:
Max Concurrent Predictions = 4
Für einen einzelnen Coding-Agenten ist das allerdings unnötig.
Sinnvoller ist:
Max Concurrent Predictions = 1
Damit steht die komplette Rechenleistung einer einzigen Bionic-Anfrage zur Verfügung.
Evaluation Batch und Physical Batch
Eine der wichtigsten Einstellungen für das Prompt Processing ist der Evaluation Batch.
Ursprünglich wurden folgende Werte verwendet:
Evaluation Batch = 2048
Physical Batch = 512
Nach einer Erhöhung auf:
Evaluation Batch = 4096
Physical Batch = 1024
stieg die Prompt-Verarbeitung deutlich.
Ein größerer Evaluation Batch bedeutet vereinfacht, dass mehr Prompt-Tokens gemeinsam durch das Modell verarbeitet werden.
Der Nachteil ist ein höherer Speicherbedarf.
Da Gemma 4 12B auf einer 16-GB-GPU noch genügend VRAM-Reserve besitzt, ist ein größerer Batch hier sinnvoll.
KV Cache
Der KV Cache speichert bereits berechnete Attention-Zustände des bisherigen Kontexts.
Ohne ihn müsste ein Modell bei jeder neuen Anfrage große Teile des bisherigen Gesprächs erneut vollständig berechnen.
Für einen Coding-Agenten sollte deshalb möglichst gelten:
KV Cache → GPU
Auf dem Testsystem funktionierten folgende Einstellungen gut:
Offload KV Cache to GPU = ON
K Cache Quantization = Q8_0
V Cache Quantization = Q8_0
Q8 reduziert den Speicherbedarf des Caches, ohne direkt auf eine sehr aggressive Q4-Quantisierung zurückgreifen zu müssen.
Preserve Thinking
Ein interessantes Feature moderner Reasoning-Modelle ist:
Preserve Thinking
Dadurch kann das Reasoning früherer Agenten-Schritte erneut in den Kontext aufgenommen werden.
Für komplexe Agentenketten kann das hilfreich sein.
Bei begrenztem Kontext hat es allerdings einen großen Nachteil:
mehr Thinking
→ mehr Tokens
→ größerer Kontext
→ längeres Prompt Processing
Deshalb wurde für Bionic:
Preserve Thinking = OFF
verwendet.
Reasoning Budget
Auch das Reasoning Budget sollte nicht unnötig groß gewählt werden.
Eine sinnvolle Abstufung ist:
kleine Coding-Aufgabe:
2048–4096 Tokens
normales Coding:
4096–8192 Tokens
komplexes Debugging:
8192–16384 Tokens
Für den normalen Entwicklungsalltag haben sich etwa:
4096 Tokens
als guter Ausgangspunkt erwiesen.
Der große Unterschied: Prompt Processing und Token Generation
Bei der Geschwindigkeit eines lokalen LLM muss man zwei völlig unterschiedliche Werte betrachten.
Token Generation
Das ist die Geschwindigkeit, mit der das Modell seine Antwort erzeugt.
Beispielsweise:
29,84 Tokens/s
Prompt Processing
Das ist die Geschwindigkeit, mit der der Eingabekontext verarbeitet wird.
Beispielsweise:
372,95 Tokens/s
Für Coding-Agenten ist der zweite Wert besonders wichtig.
Warum?
Weil ein Agent einen enorm großen Prompt erzeugen kann.
Erste Messung
Eine erste Messung mit Gemma 4 ergab:
Prompt:
1775 Tokens
Prompt Processing:
65,56 Tokens/s
Generierung:
23,32 Tokens/s
Die eigentliche Token-Generierung war bereits akzeptabel.
Das Prompt Processing erschien dagegen ausgesprochen langsam.
Optimierte Messung
Nach Anpassung der Einstellungen ergab sich:
Prompt:
33220 Tokens
Prompt Processing:
372,95 Tokens/s
Generierung:
29,84 Tokens/s
Damit war das Prompt Processing etwa:
5,7 × schneller
und auch die eigentliche Generierung verbesserte sich um ungefähr:
28 %
Die Hardware wurde währenddessen sehr gut ausgelastet:
GPU Compute: ca. 95 %
VRAM: ca. 9,6 / 16 GB
CPU: ca. 8 %
RAM: ca. 17 / 32 GB
GPU-Temperatur: ca. 55 °C
Damit war klar:
Die CPU war nicht der Flaschenhals. Das Modell lief effizient auf der GPU.
Trotzdem dauerte das Prompt Processing 89 Sekunden
Der Log zeigte:
prompt eval time =
89072 ms / 33220 tokens
372,95 tokens/s
Das entspricht ungefähr:
33220 / 372,95
≈ 89 Sekunden
Die hohe Wartezeit entstand also nicht mehr durch schlechte Hardwareauslastung.
Das eigentliche Problem war:
Bionic schickte mehr als 33.000 Tokens an das Modell.
Selbst eine schnelle GPU benötigt bei solchen Promptgrößen Zeit.
Warum Coding-Agenten so viel Kontext benötigen
Ein Coding-Agent arbeitet nicht nur mit dem eigentlichen Benutzerprompt.
Eine typische Aufgabe kann beispielsweise so aussehen:
Benutzeranfrage
↓
Projekt durchsuchen
↓
5 Dateien lesen
↓
Abhängigkeiten analysieren
↓
Quellcode ändern
↓
Build starten
↓
Compilerfehler lesen
↓
weitere Datei öffnen
↓
Code erneut ändern
↓
Tests starten
All diese Informationen können Teil des Agentenkontexts werden.
Dadurch wächst eine Session sehr schnell auf:
20.000
30.000
40.000
oder mehr Tokens
an.
Größerer Kontext ist deshalb nicht immer besser
Ein Modell kann beispielsweise:
256k Context
unterstützen.
Das bedeutet aber nicht, dass man diesen Wert unbedingt verwenden sollte.
Bei lokalem Coding gilt:
größerer Kontext
↓
mehr Speicher
↓
mehr Prompt Processing
↓
längere Wartezeit
Für das Testsystem hat sich deshalb folgende Einordnung ergeben:
32k → sehr guter Daily Driver
64k → für größere Coding-Aufgaben
128k+ → technisch möglich,
aber lokal oft nicht sinnvoll
Neue Sessions können schneller sein
Wenn eine Coding-Aufgabe abgeschlossen ist, kann es sinnvoll sein, für die nächste größere Aufgabe eine neue Bionic-Session zu öffnen.
Statt:
alte Session
35.000 Tokens
+ neue Aufgabe
beginnt man beispielsweise wieder mit:
neue Session
5.000–10.000 Tokens
Das kann die Wartezeit beim Prompt Processing massiv reduzieren.
Wichtig ist allerdings:
Wenn Bionic bereits für die erste Aufgabe wieder große Teile des Projektes einliest, entsteht natürlich erneut ein großer Prompt.
Prompts möglichst konkret formulieren
Auch die Aufgabenstellung beeinflusst die Menge des eingelesenen Codes.
Ungünstig:
Analysiere das gesamte Projekt und finde mögliche Probleme.
Besser:
Untersuche OrderService.cs und die direkt davon verwendeten Klassen.
Finde heraus, warum beim Speichern eines Auftrags eine
NullReferenceException auftritt.
Ändere nur die dafür notwendigen Dateien und führe anschließend
die relevanten Tests aus.
Je genauer der Auftrag formuliert ist, desto weniger unnötigen Projektkontext muss der Agent sammeln.
Modellgröße ist nicht alles
Eine der wichtigsten Erkenntnisse des Tests war:
Das größte Modell ist nicht automatisch das beste Modell für lokales Coding.
Qwen3.6 35B A3B besitzt deutlich mehr Parameter und ist grundsätzlich leistungsfähiger als Gemma 4 12B.
Für einen Coding-Agenten muss ein Modell aber möglicherweise dutzende Male hintereinander aufgerufen werden.
Dann macht die Geschwindigkeit einen enormen Unterschied.
Vereinfacht:
Großes Modell
1 Agenten-Schritt = langsam
30 Agenten-Schritte = sehr langsam
gegen:
kleineres Modell
1 Agenten-Schritt = schnell
30 Agenten-Schritte = akzeptabel
Für agentisches Coding ist deshalb häufig ein etwas kleineres Modell mit hoher Inferenzgeschwindigkeit produktiver.
Fazit
Mit LM Studio und Bionic lässt sich inzwischen eine erstaunlich leistungsfähige lokale Coding-Umgebung aufbauen.
Für einen Rechner mit:
Ryzen 7 5700X
32 GB RAM
16 GB VRAM
erwies sich ein 35B-Modell allerdings als unnötig schwergewichtig.
Gemma 4 12B QAT bietet dagegen einen deutlich besseren Kompromiss aus:
- Modellqualität,
- Coding-Fähigkeiten,
- Geschwindigkeit,
- VRAM-Verbrauch,
- großem Kontextfenster.
Mit optimierten Einstellungen wurden auf dem Testsystem etwa:
Prompt Processing:
~373 Tokens/s
Generation:
~30 Tokens/s
erreicht.
Der wichtigste Flaschenhals war am Ende nicht mehr das Modell oder die GPU, sondern die Menge an Kontext, die Bionic bei komplexen Aufgaben erzeugt.
Die wichtigste Erkenntnis lautet deshalb:
Bei lokalen Coding-Agenten sollte man nicht nur auf Tokens pro Sekunde achten. Mindestens genauso wichtig ist, wie viele Tokens der Agent bei jedem Schritt überhaupt an das Modell übergibt.
Ein gut gewähltes 9B- bis 14B-Modell, vollständig auf der GPU, mit sinnvoll begrenztem Kontext kann im Entwicklungsalltag daher deutlich angenehmer sein als ein wesentlich größeres Modell, das permanent zwischen VRAM und Arbeitsspeicher ausgelagert werden muss.
