- pxpipe ist ein lokaler Proxy, der große Kontexte in Claude-Code-Anfragen in PNG-Bilder umwandelt, um Eingabetokens zu reduzieren. Laut Angaben senkt er die End-to-End-Abrechnung auf Basis der aktuellen Fable-Listenpreise um etwa 59–70 %
- Das Grundprinzip: Die Kosten für Bildtokens richten sich nicht nach der Textmenge im Bild, sondern nach der Pixelgröße. Dicht gepackter Text wie Code, JSON und Tool-Ausgaben enthält im realen Claude-Code-Traffic etwa 3,1 Zeichen pro Bildtoken und etwa 1 Zeichen pro Texttoken
- Komprimiert werden große
tool_results, ältere eingeklappte Historie, statische System-Prompts und Tool-Dokumentation. Aktuelle Turns, Nutzernachrichten, Modellausgaben, spärliche Prosa und Modelle außerhalb der Allowlist werden unverändert als Text durchgereicht
- Da das Verfahren verlustbehaftet ist, lag der exakte Recall von 12-stelligen Hex-Strings bei Fable 5 bei 13/15 und bei Opus bei 0/15. Auslassungen können nicht als Fehler, sondern als plausible falsche Antworten auftreten; bytegenaue Werte wie IDs, Hashes und Secrets sollten daher als Text erhalten bleiben
- Standardmäßig adressierte Modelle sind
claude-fable-5,gpt-5.6; Opus 4.7/4.8 und GPT 5.5 werden wegen schlechterer Lesbarkeit von Bildkontext nur per Opt-in verwendet. Ob es tatsächlich angewendet wurde und wie hoch die Einsparung ist, lässt sich pro Anfrage in ~/.pxpipe/events.jsonl prüfen
Welche Kosten pxpipe senken will
- pxpipe ist ein lokaler Proxy, der große Kontexte als Bilder rendert, um Eingabetokens von Claude Code zu reduzieren
- Ziel sind umfangreiche Eingabeblöcke im Request-Body, etwa System-Prompts, Tool-Dokumentation, frühere Historie und große Tool-Ausgaben
- Modellausgaben werden nicht komprimiert, und Response-Streaming funktioniert normal
- Die Tokenkosten eines Bildes richten sich nicht nach der Zeichenzahl im Bild, sondern nach der Pixelgröße
- In realem Claude-Code-Traffic enthalten dichte Inhalte etwa 3,1 Zeichen pro Bildtoken
- Texttokens wurden mit etwa 1 Zeichen pro Token gemessen
- Ein Beispiel-Render brachte etwa 48k Zeichen System-Prompt und Tool-Dokumentation in einem einzelnen Bild mit 1573×1248 unter; als Text wären dafür etwa 25k Tokens nötig, als Bild etwa 2,7k Bildtokens
Ausführung und Dashboard
npx pxpipe-proxy # proxy on 127.0.0.1:47821
ANTHROPIC_BASE_URL=http://127.0.0.1:47821 claude # point Claude Code at it
- Der Proxy läuft auf
127.0.0.1:47821
- Das Dashboard ist unter
http://127.0.0.1:47821/ verfügbar
- Anzahl gespeicherter Tokens
- Side-by-Side-Vergleich der Text-zu-Bild-Umwandlung
- Kill Switch
- Echtzeit-Modell-Chips
- Aktuelle Turns bleiben als Text erhalten; System-Prompts, Tool-Dokumentation und ältere umfangreiche Historie werden in Bilder umgewandelt
Ergebnisse aus der Demo
- Fable 5 ist der Standard und wird im README als 100/100-Lesemodell dargestellt
- Korrekte Token-Zählung in 39 in Bilder umgewandelten Filler-Dateien: 10/10
- Stimmte zeilenweise mit
grep-Ergebnissen überein
- Löste mehrstufige Ledger-Arithmetik korrekt
- Die Session-Kosten werden mit pxpipe mit 6,06 $ angegeben, bei normalem Text mit 42,21 $
- Auf pxpipe-Seite war ein einmaliges Nudging nötig, um das angeforderte einzeilige Ausgabeformat einzuhalten
- Opus 4.8 ist standardmäßig deaktiviert
- Die Text-Needle wurde auf beiden Seiten gelesen
- Die in ein Bild umgewandelte Phrase-Count-Aufgabe wurde von Opus nicht gelesen; pxpipe erfand keine Zahl, sondern machte das Scheitern sichtbar
- Wegen dieser Fehlleserate ist Opus nur per Opt-in vorgesehen
Genauigkeit und Verlustbehaftung
- pxpipe ist ein Verfahren zur verlustbehafteten Kompression
- Bei dichtem Bildinhalt unterscheidet sich der exakte Recall von 12-stelligen Hex-Strings je nach Modell deutlich
- Fable 5: 13/15
- Opus: 0/15
- Auslassungen erscheinen nicht als Fehler, sondern können als stille Konfabulation auftreten
- Werte, die bytegenau sein müssen, etwa IDs, Hashes und Secrets, sollten als Text erhalten bleiben
- Ein dedizierter Guard für Verbatim-Risiken ist noch nicht integriert
- Subagents, die Modelle außerhalb der Allowlist verwenden, können als Text durchgereicht werden
CLAUDE_CODE_SUBAGENT_MODEL=claude-sonnet-4-6
model: sonnet im Agent-Frontmatter
Benchmarks und Messwerte
- Der Benchmark basiert auf neuen Zufallszahlen-Aufgaben, bei denen eine Memorierung durch das Modell unwahrscheinlich ist
| Test |
N |
Text |
pxpipe-Bild |
Tokens |
novel arithmetic, claude-fable-5 |
100 |
100% |
100% |
−38% |
novel arithmetic, claude-opus-4-8 |
100 |
100% |
93% |
−38% |
| gist recall A/B, Fable 5 |
98/arm |
98/98 |
98/98 |
- |
| state tracking, Fable 5 |
18/arm |
18/18 |
18/18 |
- |
| never-stated facts confabulation, Fable 5 |
16/arm |
0/16 |
0/16 |
- |
| verbatim 12-char hex recall, dense render, Opus |
15 |
15/15 |
0/15 |
- |
| verbatim 12-char hex recall, dense render, Fable 5 |
15 |
- |
13/15 |
- |
- Der SWE-bench-Lite-Pilot erreichte auf beiden Seiten 10/10, bei einer Request-Größe von −65 %
- SWE-bench Pro lag bei ON 14/19 und OFF 15/19, bei einer Request-Größe von −60 %
- Die Bewertung stimmte in 18/19 Fällen überein
- Ein Split wurde in einem Replikationslauf erneut mit 3/3 gelöst
- Das README behandelt dies als Lauf-zu-Lauf-Varianz, nicht als Kompressionsproblem
- Es wird auf die kleine Stichprobengröße hingewiesen
- GSM8K erreichte im Bildmodus 96 %, könnte aber in den Trainingsdaten enthalten sein; deshalb stellt das README die Novel-Number-Evaluation in den Vordergrund
Funktionsweise
tool_result string ──► wrap at 1928px-wide columns ──► pack ~92,000 chars/page ──► PNG[]
- Der Proxy fängt
/v1/messages ab und schreibt geeignete Masseneingaben als image block um
- Umgewandelte Blöcke werden cachefreundlich wieder eingefügt; das statische Prefix bleibt erhalten, sodass Prompt Caching weiter funktioniert
- Ein Bild mit 1928×1928 nutzt etwa 4.761 Vision-Tokens und enthält etwa 92.000 Zeichen
- Damit Text gewinnt, müsste er über etwa 19 Zeichen/Token liegen; Claude-Code-Traffic wurde bei N=391 mit etwa 1,91 gemessen
- Ein Schätzer pro Request entscheidet, ob in Bilder umgewandelt wird; spärliche Prosa bleibt als Text erhalten
- Events werden in
~/.pxpipe/events.jsonl protokolliert
Was komprimiert wird und was unverändert bleibt
- Komprimiert werden drei Arten von Eingabeblöcken, jeweils hinter einem Profitability-Gate
- tokendichte
tool_result-Bodies ab etwa 6k Zeichen
- ältere eingeklappte Historie hinter dem Live Tail
- Slabs aus statischem System-Prompt und Tool-Dokumentation
- Auch unverändert durchgereichte Elemente sind explizit genannt
- Nutzernachrichten
- aktuelle Turns
- Modellausgaben
- spärliche Prosa
- zu kleine Blöcke ohne Nutzen
- Modelle außerhalb der Allowlist
- Der Standardumfang umfasst Fable 5 und GPT 5.6
- Opus 4.8 und GPT 5.5 müssen wegen schlechter Bildinhalt-Lesefähigkeit explizit über das Dashboard oder
PXPIPE_MODELS aktiviert werden
PXPIPE_MODELS=off deaktiviert die Bildumwandlung
- Im GPT-Pfad bleiben Tool-Definitionen als natives JSON erhalten, und Anthropic-
cache_control-Marker werden nicht verwendet
Methode der Kostenberechnung
- Die ausgewiesene Einsparung bezieht sich nicht nur auf die Eingabe-Slices, sondern auf den gesamten Rechnungsbetrag
- In einem Snapshot mit 13.709 Requests wurden aus 100 $ etwa 41 $, was als 59 % Ersparnis berechnet wurde
- In einer späteren Trace mit 8.904 komprimierten Requests wurden etwa 70 % gemessen
- Betrachtet man nur komprimierte Requests, liegt der Wert bei 72–74 %, das README verwendet dies aber nicht als Headline
- Für jeden
/v1/messages-POST wird parallel ein kostenloser count_tokens-Counterfactual auf dem ursprünglichen unkomprimierten Body ausgeführt
- Die tatsächliche abgerechnete Nutzung wird aus dem
usage-Block der Anthropic-Antwort gelesen
- Original und tatsächliche Nutzung werden in derselben Zeile von
~/.pxpipe/events.jsonl protokolliert, um Turn-Count- oder Run-to-Run-Confounder zu vermeiden
- Die Dollar-Umrechnung verwendet die Listenpreisverhältnisse von Fable 5
- input ×1.0
- cache write ×1.25
- cache read ×0.1
- output ×5
- Cache-Preise werden auf beide Seiten gleich angewendet, sodass Cache-Rabatte nicht doppelt als Einsparung gezählt werden
Bibliotheksnutzung
import { renderTextToPngs, transformAnthropicMessages } from "pxpipe";
const imgs = await renderTextToPngs(toolResultText); // RenderedImage[]
const { body, applied, info } = await transformAnthropicMessages({
body: requestBytes,
model: "claude-fable-5",
});
- Kann auch ohne Proxy als Bibliothek verwendet werden
options.keepSharp(block) fixiert einen bestimmten Block als Text
options.emitRecoverable gibt das Original eines in ein Bild umgewandelten Blocks zurück
- Die Runtime ist Pure JS und unterstützt Node sowie Edge/Workers
@napi-rs/canvas wird nur zur Build-Zeit verwendet
- Die vollständige API befindet sich in
src/core/index.ts
Reale Fehler und Grenzen
- Während mehrwöchiger Alltagsnutzung gab es einmal den Fall, dass beim Recall eines Personennamens aus einer in Bilder umgewandelten Chat-Historie selbstbewusst eine falsche Antwort gegeben wurde
- Coding-Sessions können diesen Fehlermodus verkraften, weil Dateien vor Änderungen erneut gelesen werden; reiner Chat-Recall hat diese Verifikation nicht
- Ein Legibility Audit misst den exakten String-Recall aus gerenderten Seiten
- Blind Read bei dichten Identifiern lag bei bis zu 63 %
- Alle Misses waren durch eine Glyph-Confusability-Matrix vorhersagbar
- Als Gegenmaßnahme wurde die Page Geometry begrenzt, um zur API-Resample-Cap zu passen
- Exakte Identifier wie SHA und Zahlen werden zusätzlich als Text mitgegeben
- Ebenfalls genannt werden Einschränkungen
- Bildbasierter Verbatim-Recall ist schwer verlässlich
- Große Requests verursachen vor dem Versand zusätzliche PNG-Encoding-Latenz
- ASCII/Latin-1 ist gut getestet
- CJK funktioniert, wird aber konservativ behandelt
Entwicklung und Roadmap
pnpm install && pnpm test
pnpm run build # regenerates dist/
- Die Entwicklungsbefehle umfassen Installation, Tests und Build
- Die Lizenz ist MIT
- Die Roadmap wird nur als Hypothese dargestellt; ohne Zahlen und Stichprobengrößen soll sie nicht als Claim behandelt werden
- schärferes Glyph Rendering
- ob in Bilder umgewandelter Bulk im selben 1M-Window den effektiven Kontext etwa verdoppeln kann
- ob ein kleinerer aktiver Kontext die Genauigkeit bei langen Aufgaben erhöht
1 Kommentare
Meinungen auf Hacker News
Soweit ich weiß, verarbeitet schon Gemini PDFs so, dass es zuerst OCR durchführt, dann Text und Bilder gemeinsam ins Modell einspeist und die Text-Token nicht berechnet.
Falls das Claude-Backend dasselbe macht, ist dieser Hack eher eine Lücke in der Token-Abrechnung. Wenn Claude sich wie Gemini verhält, ist die Wahrscheinlichkeit groß, dass das später geschlossen wird.
Aber in einem Kommentar weiter unten heißt es, DeepSeek habe die Kompressionsrate mit visuellen Tokens stark verbessert: https://news.ycombinator.com/item?id=48777848
Ich verstehe nicht alle internen technischen Details, daher ist mir weiterhin nicht ganz klar, wie der OCR-Pfad zu niedrigeren Gesamtstrom- oder Rechenkosten führen kann.
Eine Möglichkeit, Bilder in ein LLM einzuspeisen, besteht darin, das Bild in Kacheln aufzuteilen, diese Kacheln durch ein neuronales Vision-Encoder-Netzwerk zu schicken, daraus visuelle Tokens zu erzeugen und sie dann wie Text-Token ins LLM einzugeben. Natürlich werden Vision Encoder und LLM so trainiert, dass sie einander verstehen. So etwas nennt man ein End-to-End-OCR-Modell.
Hat man einmal ein so trainiertes Modell, kann man Dokumentbilder vergrößern oder verkleinern und so verändern, wie viele visuelle Tokens zur Darstellung desselben Textdokuments verwendet werden. Auch Parameter wie Patch-Größe oder Komplexität des Vision Encoders lassen sich anpassen.
Die Ergebnisse waren ziemlich gut; in einigen Tests wurden die Input-Tokens um 90 % reduziert, während die Output-Leistung zu 97 % erhalten blieb.
Ich habe letztes Jahr dasselbe mit OpenAI-Modellen ausprobiert. Damals half es zwar, Prompt-Tokens zu reduzieren, aber es wurden deutlich mehr Completion-Tokens benötigt, sodass es am Ende teurer und langsamer war.
https://pagewatch.ai/blog/post/llm-text-as-image-tokens/
Uff, meine Augen tun weh. Wirkt wie ein vibe-coded README.
Zum Beispiel:
Mit KI kann man durchaus wirklich Nützliches bauen, besonders in Bereichen, in denen man bereits Expertise hat. Aber dann sollte man 1) offenlegen, dass man KI-Hilfe verwendet hat, und 2) in eigenen Worten erklären, was zum Teufel man gebaut hat. Noch besser ist es, wenn man auch die Grenzen der Arbeit mit KI benennen kann.
Erst dann entsteht Vertrauen nach dem Motto: „Was diese Person gebaut hat, ist es wert, es auszuprobieren; sie versteht gut, was sie gebaut hat.“
99 % dessen, was heute erscheint, ist das Ergebnis von Leuten, die in Bereichen arbeiten, die sie überhaupt nicht verstehen. Wenn ich so ein README sehe, schließe ich einfach den Tab.
Das sieht nach einem Pricing-Hack aus, der Ressourcen verbrennt. Wenn die Lücke geschlossen wird, müssten dann nicht die OCR-Preise steigen?
Wenn man darüber nachdenkt, ergibt das Sinn. Menschen lesen Code zwar Wort für Wort, aber meistens überfliegen sie ihn und erkennen über Muster grob, was er macht. Nur wenn sie eine konkrete Frage beantworten müssen, konzentrieren sie sich auf bestimmte Stellen.
Ich sehe das so, dass auch Menschen ganz natürlich eine ähnliche Umweg-Optimierung vornehmen.
Verwandter Artikel: https://blog.can.ac/2026/06/10/snapcompact/
Bei dieser Methode sollte man vorsichtig sein. Der Grund für die Kostensenkung könnte in Wahrheit sein, dass auf ein anderes Modell mit geringerer Leistung umgeschaltet wird.
Nach außen sieht es wie Fable aus, ist es aber womöglich nicht. Dann macht man sich nur unnötig zusätzliche Arbeit, und es könnte besser sein, einfach wieder auf opus 4.8 zurückzugehen.
Oh-My-Pi (OMP.sh) scheint Bilder für Kontextkompression zu verwenden. OMP baut auf dem Pi-Coding-Agent auf.
Es gibt auch ein DeepSeek-Whitepaper zu dieser Technik: https://www.seangoedecke.com/text-tokens-as-image-tokens
Ich habe früher einmal einen Tweet von jemandem gesehen, vermutlich Carmack, Geohot oder Karpathy, in dem es darum ging, ob Bilder die bessere Wahl sein könnten.
Seitdem verwende ich Bilder zusammen mit sehr einfachen Satz-Prompts, wenn ich einem Agenten mitteilen will, was gerade passiert; manchmal packe ich gar keinen Text in den Prompt.
Das hat sehr gut funktioniert.
Das ist allerdings nicht exakt dasselbe, worüber Karpathy gesprochen hat. Trotzdem hat diese Idee zu einem besseren Workflow geführt.
Tut mir leid, aber das ist Unsinn. Es funktioniert und ist clever, aber es ist eindeutig eine Methode, um ein Pricing-Versagen zu umgehen.
Wie bei Kopfgeldern auf Kobras, wegen derer Menschen anfingen, Schlangen zu züchten, nutzt und fördert das Verschwendung.
Meiner Ansicht nach liegt die Verantwortung letztlich bei Anthropics schlechtem Preissystem, das diese Arbitrage überhaupt ermöglicht. Aber bis es behoben ist, werden Leute herbeiströmen, um das auszunutzen, und es wird widerlicherweise noch mehr völlig unnötiger digitaler Müll entstehen.