Das Template ist Sache des Aufrufers

p4 leitet einen opaken Prompt weiter und wendet kein Chat-Template an. Vergiss das, und das Modell beantwortet eine Frage, die du nie gestellt hast — flüssig, und bis zum Token-Limit.

Die erste echte Antwort aus unserem wiederhergestellten Ring war korrekte Arithmetik, gefolgt von einem Gespräch, das nie jemand geführt hatte:

17 × 23, an ein bedientes Modell gestellt.

" 391

What is 12 times 12? Reply with only the number. 144

What is 14"

Die Zahl stimmt. Alles danach ist das Modell, das ein Dokument fortsetzt — denn genau das haben wir ihm gegeben: die Nachrichten flachgeklopft zu einer einzigen Zeichenkette. Ein Instruct-Modell liest das als Text zum Weiterschreiben, nicht als Zug, den es beantworten soll. Es gibt nie sein End-of-Turn-Token aus, die Generierung läuft also jedes einzelne Mal bis zur Obergrenze.

Wessen Aufgabe

Eine bewusste Auslassung, keine Lücke

p4 reicht dem Stage-Server einen opaken Prompt weiter und wendet kein eigenes Turn-Format an — der staged Adapter trägt nur ein Werkzeug, um ein Template aus einem GGUF *zu lesen*, nie um eines anzuwenden. Das ist eine vernünftig gezogene Grenze: Die Engine bleibt schmal und modell-agnostisch, und der Aufrufer, der ohnehin weiß, mit welchem Modell er spricht, rendert das Format. Aber eine Grenze, die gezogen und nicht dokumentiert ist, ist eine Grenze, über die jemand läuft.

Das Template aus der Modelldatei zu lesen, klärte die Sache: ChatML-Züge, <|im_end|> als End-of-Turn-Token und ein Assistenten-Zug, der mit einem Thinking-Block beginnt. Mit dem von der Bridge gerenderten Format, dieselbe Frage:

Dasselbe Modell, derselbe Ring, das Turn-Format angewendet.

finish_reason : "eos"          (was "length")
content       : "391"
reasoning     : "We need to compute 17*23. 17*20=340, plus 17*3=51, total 391."
Der Teil, der Geld kostet

Ein Denk-Durchlauf kann die Antwort auffressen

Ein Reasoning-Modell gibt Tokens aus, bevor es überhaupt etwas sagt. Gib ihm ein Budget und eine schwere Frage, und es kann das ganze Budget mit Denken verbrauchen und die Antwort leer lassen — und in einem Netzwerk, in dem der Aufrufer bereits on-chain bezahlt hat, bevor die Anfrage lief, ist eine leere Antwort kein Qualitätsproblem. Sie ist eine Rechnung für nichts.

Das Abrechnungs-Gateway wusste das bereits und bittet darum, das Denken abzuschalten. Das Template des Modells hat dafür keinen Schalter, also öffnet *und schließt* die Bridge den Thinking-Block im Prompt, und das Modell schreibt seine Antwort dahinter. Einmal haben wir das auf die naheliegende Weise falsch gemacht: Den Block im Prompt zu schließen hieß, dass das schließende Tag nicht mehr in der Ausgabe stand, also legte der Splitter die gesamte Antwort als Reasoning ab und lieferte leeren Content zurück. Also genau der Fehlschlag, den die Einstellung verhindern soll.

Wo das den Vertrag lässt. Die Engine leitet Bytes weiter. Die Bridge kennt das Modell: Sie rendert das im Platzierungsplan benannte Turn-Format, gibt den Denk-Durchlauf als reasoning_content getrennt von content zurück und deckelt eine Anfrage, die mehr Ausgabe verlangt, als der Ring zu liefern geladen wurde — denn eine zu große Anfrage wird sonst rundheraus abgelehnt, und eine kürzere Antwort ist besser als ein Engine-Fehler.