A Fable 5 session that cost $42.21 finished for $6.06. Same task. Same model. The only change was a local proxy that turned most of the prompt into pictures before it left my machine.
That proxy is
pxpipe
, an MIT-licensed TypeScript project from Steven Chong (teamchong). It hit thousands of GitHub stars in days because it exploits a pricing quirk every agent builder eventually feels: images bill by pixels, not characters, and dense code packs more meaning per image-token than plain text tokens on real Claude Code traffic.
I have written about agent cost routing before. pxpipe is not routing models. It is routing representation. That is weirder, and more useful, than it sounds.
The core trick
Anthropic's multimodal models already read screenshots for computer use. pxpipe uses that same vision channel for context that would otherwise be a wall of text:
- System prompt and tool definitions
- Older conversation history (recent turns stay text)
- Large
tool_resultbodies (file reads, logs, command output)
On dense content, pxpipe's README cites roughly 3.1 characters per image-token versus about 1 character per text-token for Claude Code traffic. English prose is the opposite (images lose money), so pxpipe's profitability gate keeps sparse text as text.
npx pxpipe-proxy ANTHROPIC_BASE_URL=http://127.0.0.1:47821 claude
Dashboard at http://127.0.0.1:47821/ shows tokens saved, each text-to-image conversion, and a kill switch to pass through byte-identical.
pxpipe.dev documents the same flow and links to a demo walkthrough.
What the numbers actually claim
pxpipe is careful to measure end-to-end cost, not "savings on the slice we touched." Events log to ~/.pxpipe/events.jsonl with a per-request count_tokens counterfactual.
| Trace | Reported outcome |
|---|---|
| 13,709-request production snapshot | ~59% lower bill ($100 to $41) |
| Denser follow-up trace | Closer to 70% |
| Single Fable 5 demo session | $42.21 to $6.06 |
| System prompt + tool docs slab | ~25k text tokens vs ~2.7k image tokens (one page) |
Default model allowlist is conservative: claude-fable-5 and gpt-5.6. Opus and GPT-5.5 require opt-in because imaging can hurt on models with weaker vision gist.
Set PXPIPE_MODELS=off to disable imaging entirely.

What stays text (and why that matters)
pxpipe compresses the request only, never the model's output. Streaming responses behave normally.
Passes through unchanged:
- Your latest messages
- Small blocks and sparse prose
- Models outside the allowlist
- Recent conversation tail (configurable per model profile)
Gets imaged when profitable:
- Static system prefix (cache-friendly splice on Anthropic)
- Tool documentation slabs
- Older collapsed history
- Large tool results above density thresholds
That split is the product design. An image holds the gist of old context. It does not hold exact spelling.
The catch nobody should skip
pxpipe is lossy for exact strings.
AlphaSignal's coverage and independent reviews flag the same failure mode: hex strings, hashes, UUIDs, and secrets can be silently misread. One benchmark cited Fable 5 reading hex correctly 13 of 15 times while Opus got 0 of 15 in a harsh test. Your mileage will vary. The point is not the score. The point is do not image byte-sensitive values.
My rule when testing proxies like this:
| Content type | Send as |
|---|---|
| Narrative context, file summaries, old decisions | Image (if dense) |
| IDs, hashes, API keys, exact config values | Text only |
| Current user instruction | Always text |
Most context-trimming tools hide what they dropped. pxpipe makes the trade visible in the dashboard: you see each conversion before you trust the bill.
When I would actually run it
pxpipe pays on token-dense, repetitive agent loops:
- Long-running Claude Code sessions on big repos
- Agents that re-read the same tool docs every turn
- SWE-bench style workloads with fat system prompts
It probably does not pay on:
- Short chats with little history
- Prose-heavy planning threads
- Tasks where a single misread ID causes an outage
Treat the 60% headline as a ceiling on ideal traffic. Run one real session, read ~/.pxpipe/events.jsonl, and compare against your actual invoice.
npx pxpipe-proxy export src/ cat prompt.txt | npx pxpipe-proxy export --stdin npx pxpipe-proxy export --git
The library APIs (renderTextToImages, transformAnthropicMessages) also let you embed the same transform in custom harnesses.
How this fits my cost stack
I already route models by task tier (see agentic coding model routing). pxpipe routes encoding within a tier. The two compose:
- Default agent loop on a mid-tier or Fable-class model
- pxpipe on the proxy for dense context
- Frontier escalation only when tests fail twice or novelty flags fire
That is three levers on one bill. Most teams only pull one.
Imaging context is not compression in the gzip sense. It is betting the model can read a screenshot of your history well enough to act, while you accept that exact strings might not survive.
If you want help auditing an agent harness (model routing, context policy, and whether a proxy like pxpipe is safe for your workload), book a free discovery call.

