Warum die Antwort mitten im Satz abbricht
Die Ausgabe hört auf, als hätte jemand den Stecker gezogen - mitten im Wort, mitten in der Codezeile. Vier Ursachen kommen dafür infrage, und sie sehen im Ergebnis fast gleich aus.
29. Juli 2026token · abbruch · betrieb
Die Antwort läuft, wird lang, wird länger - und endet dann mit return calcul.
Kein Fehler, keine Meldung, nur ein Text, der aufhört. Das ist fast nie ein
Aussetzer des Modells. Es ist eine Grenze, gegen die etwas gelaufen ist, und die
Anzeige verrät meistens nicht, welche.
1. Das Ausgabelimit ist erreicht
Der häufigste Fall. Jeder Aufruf hat eine Obergrenze für die Ausgabe
(max_tokens, je nach Anbieter auch anders benannt), und wenn die erreicht ist,
hört die Generierung auf - egal wo im Satz. Das Modell weiß davon nichts: Es gibt
Token für Token aus, und irgendwann nimmt der Server keins mehr entgegen.
Erkennbar ist es am Abschlussgrund der Antwort. Steht dort length statt
stop, ist genau das passiert. Dieses Feld ist der wichtigste Hinweis überhaupt
und wird in vielen Integrationen schlicht nicht ausgewertet - weshalb ein
abgeschnittener Text dann als vollständiger Text weiterverarbeitet wird.
Der LLM-Call
Ein Request, eine Antwort - der rohe Baustein, aus dem alles andere entsteht. Und die wichtigste Erkenntnis gleich zu Beginn: Das Gehirn ist nicht im Agenten. Es ist am anderen Ende der Leitung.
Wir rufen zum ersten Mal ein Sprachmodell auf: eine Nachricht hin, eine Antwort zurück - und danach ist die Leitung tot. Kein Zustand, kein Gedächtnis, keine Werkzeuge. Genau dieses Auflegen erklärt fast alles, was später kommt. Und wir rufen nicht irgendein Modell: Wir sprechen mit unserem eigenen - qwen3.8-27b-fast, das auf unserem Inferenz-Stack läuft. Wie man so ein Modell selbst betreibt, ist Thema von Block III; hier gehen wir erst einmal davon aus, dass es irgendwo eines gibt.
Chat + GPT: wer macht hier eigentlich was?
Der Name ChatGPT verrät die Arbeitsteilung, um die es in diesem ganzen Block geht: GPT ist das Modell - es läuft irgendwo auf GPUs und kann genau eines: Text rein, Text raus. Chat ist die Software drumherum - sie merkt sich das Gespräch, gibt dem Modell eine Rolle, reicht Werkzeuge an. Diesen Software-Teil bauen wir hier nach, Schicht für Schicht - nur eben nicht als Chat, sondern als Agent. Der Harness ist der Chat-Teil. Das Modell mieten wir an - oder betreiben es, wie in unserem Fall, gleich selbst.
Ein Anruf, kein Abo
Nachdem wir nach dem Video nun wissen, dass die ganze Magie bei "KI" und ChatGPT eigentlich im LLM steckt, werden wir uns zunächst damit genauer befassen. Wir gehen jetzt also zunächst davon aus, dass wir Zugang zu einem Sprachmodell haben. Wie wir Sprachmodelle selber betreiben, lernen wir in Block 3 (Inferenz). Wie wir an eine API kommen, sehen wir unter anderem in unserem Tutorial zum OpenRouter-Key.
Versuchen wir einmal darauf zuzugreifen: die allereinfachste Form ist ein nackter Web-Request - curl reicht. Adresse des Endpunkts (LLM_BASE_URL, bei uns die eines selbst betriebenen vLLM-Servers) und Schlüssel (LLM_API_KEY) kommen aus der Umgebung - dort trägst du ein, welchen Anbieter oder eigenen Server du ansprichst. Im Aufruf selbst geben wir an, welches Modell wir sprechen wollen (model), wie lang die Antwort höchstens werden darf (max_tokens), und was gesagt werden soll (messages):
curl "$LLM_BASE_URL"/chat/completions \
-H "Authorization: Bearer $LLM_API_KEY" \
-H "content-type: application/json" \
-d '{
"model": "qwen3.8-27b-fast",
"max_tokens": 200,
"messages": [
{ "role": "user", "content": "Erkläre in 2 Sätzen, was ein KI-Agent ist." }
]
}'
Zurück kommt - ebenfalls nur JSON, und deutlich technischer als alles, was ChatGPT je anzeigt:
{
"choices": [
{
"message": { "role": "assistant", "content": "Ein KI-Agent ist ein Programm, das …" },
"finish_reason": "stop"
}
],
"usage": { "prompt_tokens": 23, "completion_tokens": 61 }
}
Drei Felder bestimmen alles Weitere: choices[0].message ist die Antwort. finish_reason sagt, warum das Modell aufgehört hat zu reden - stop heißt „von alleine fertig“, length heißt „abgeschnitten“. Und usage zählt die Tokens - die Währung, in der Inferenz gerechnet wird, auch auf der eigenen Hardware.
Aus Software heraus macht man denselben Aufruf mit ein paar Zeilen Python oder JavaScript - Bibliothek braucht es dafür keine, ein HTTP-Client genügt. In den Experimenten unten siehst du bei jedem Lauf den rohen Request und die rohe Response; weiter unten gibt es beides als fertige Referenz-Dateien und als Prompt für deinen Coding-Agenten zum Selberbauen.
Der Brieffreund mit dem Kurzzeitgedächtnis
Das Überraschendste am ersten Call ist, was nicht passiert: Das Modell merkt sich nichts. Der zweite Aufruf ist für das Modell eine Anfrage wie jede andere - es weiß nicht, dass es je einen ersten gab, auch wenn er nur Millisekunden her ist. Stell es dir wie einen Brieffreund vor, der sich zwischen zwei Anrufen an nichts erinnert: Jedes Mal, wenn wir anrufen, müssen wir alles noch einmal erzählen, was je passiert ist - und sobald er geantwortet hat, legen wir auf.
Ein LLM-Call ist nichts Magisches: JSON rein, JSON raus. Kein Login, keine Sitzung, kein Konto-Stand auf der Gegenseite - nur ein Request und eine Antwort.
Und der Call ist zustandslos: Der nächste Anruf beginnt bei null, die Stimme am anderen Ende erinnert sich an nichts - technisch ist sie ein riesiger, schlauer Zufallsgenerator ohne jedes Gedächtnis. Alles, was ein Agent später kann - Gespräch, Rolle, Werkzeuge - muss der Harness bei jedem Anruf neu mitbringen. Das Gehirn ist nicht im Agenten. Es ist am anderen Ende der Leitung - und wir bauen in den nächsten Bauteilen alles drumherum.
Warum passiert das gerade bei Agenten so oft? Weil die Voreinstellungen aus einer Zeit stammen, in der Antworten kurz waren. 1024 Token sind für einen Chat viel und für eine generierte Datei wenig. Und es fällt spät auf: Der abgeschnittene Text sieht bis zur letzten Zeile richtig aus.
2. Das Kontextfenster ist voll
Ein Modell hat ein Gesamtbudget für Eingabe und Ausgabe. Wenn der
Nachrichtenverlauf 190 000 Token belegt und das Fenster 200 000 fasst, bleiben
für die Antwort 10 000 - selbst wenn max_tokens viel höher steht. Der Effekt
ist derselbe wie oben, aber die Ursache liegt woanders: nicht am Limit, sondern
am Verlauf.
Das erklärt ein Verhalten, das viele beobachten: Ein Agent liefert am Anfang eines Laufs ordentliche Antworten und schneidet sie gegen Ende reihenweise ab. Der Verlauf ist einfach größer geworden. Wer den Grund dahinter genauer wissen will: Er ist derselbe, aus dem der zehnte Turn so viel mehr kostet als der erste - der Verlauf fährt bei jedem Aufruf vollständig mit.
3. Eine Stoppsequenz kam im Text vor
Stoppsequenzen sagen dem Modell, es solle aufhören, sobald eine bestimmte
Zeichenfolge auftaucht. Sinnvoll, um Rollenmarken wie \nUser: abzuschneiden -
und tückisch, wenn die Sequenz mitten im gewünschten Inhalt legitim vorkommt.
Klassiker: ``` als Stoppsequenz, während die Antwort einen Codeblock
enthält. Der Abschlussgrund lautet dann meist stop, weil aus Sicht des Servers
alles nach Plan lief - nur eben zu früh.
4. Die Verbindung ist gestorben
Beim Streaming kommt die Antwort in vielen kleinen Häppchen über eine offene Verbindung. Alles, was dazwischenliegt, kann sie kappen: ein Proxy mit Zeitlimit, ein Load Balancer, der stille Verbindungen schließt, ein Neustart. Für die Anwendung sieht das aus wie ein Ende - der Text bricht ab, und ein Abschlussgrund kommt nie an.
Das ist der einzige der vier Fälle, bei dem tatsächlich etwas kaputt ist. Man
erkennt ihn daran, dass kein finales Ereignis eintrifft: kein
finish_reason, keine Verbrauchsangabe, kein Abschluss-Chunk. Wer nur den
gesammelten Text betrachtet, sieht denselben Stummel wie in Fall 1.
Die Reihenfolge beim Nachsehen
- Abschlussgrund auslesen.
length→ Ausgabelimit.stopbei offensichtlich unfertigem Text → Stoppsequenz. Gar keiner → abgerissene Verbindung. - Verbrauch anschauen. Liegen die Ausgabe-Token exakt auf dem Limit, ist der Fall klar. Sind Eingabe-Token plus Limit größer als das Fenster, ist es Fall 2.
- Erst dann am Prompt drehen. „Fasse dich kürzer“ behebt keinen der vier Fälle, es verschiebt nur, wann sie eintreten.
Und für den Betrieb die eine Regel, die den meisten Ärger erspart: Eine Antwort
mit Abschlussgrund length ist ein Fehlerfall, kein Ergebnis. Behandle sie so -
abbrechen, erneut anfordern, fortsetzen lassen. Nur nicht so tun, als wäre sie
vollständig.