- pxpipe は、Claude Code リクエスト内の大きなコンテキストをローカルプロキシで PNG 画像に変換して入力トークンを削減し、Fable の現行定価ベースでエンドツーエンドの請求額を約 59〜70%削減 するとしている
- 中核となる原理は、画像トークンのコストが中に含まれるテキスト量ではなく ピクセルサイズ で決まる点にあり、コード・JSON・ツール出力のような高密度テキストは、実際の Claude Code トラフィックで画像トークンあたり約 3.1 文字、テキストトークンあたり約 1 文字を収められる
- 圧縮対象は大きな
tool_result、古い折りたたまれた履歴、静的なシステムプロンプトとツールドキュメントで、最近のターン・ユーザーメッセージ・モデル出力・疎な prose・許可リスト外モデルは そのままテキスト で通過する
- 非可逆方式のため、正確な 12 文字の hex 文字列の想起は Fable 5 で 13/15、Opus で 0/15 であり、取りこぼしはエラーではなく もっともらしい誤答 として現れうるため、ID・ハッシュ・シークレットのようなバイト単位で正確さが必要な値はテキストのまま維持すべき
- デフォルト対象モデルは
claude-fable-5,gpt-5.6 で、Opus 4.7/4.8 と GPT 5.5 は画像コンテキストの読解性能低下のためオプトインでのみ使用し、実際に適用されたかどうかと削減量は ~/.pxpipe/events.jsonl でリクエストごとに確認できる
pxpipe が削減しようとするコスト
- pxpipe は、Claude Code の入力トークンを減らすために大きなコンテキストを画像としてレンダリングするローカルプロキシ
- 対象は、システムプロンプト、ツールドキュメント、過去の履歴、大きなツール出力のように、リクエスト本文で容量の大きい入力ブロック
- モデル出力は圧縮せず、レスポンスストリーミングは通常どおり動作する
- 画像のトークンコストは、画像内の文字数ではなく ピクセルサイズ によって決まる
- 実際の Claude Code トラフィックでは、高密度コンテンツは画像トークンあたり約 3.1 文字を収める
- テキストトークンは約 1 文字程度と測定されている
- 例として、約 4.8 万文字のシステムプロンプトとツールドキュメントを 1573×1248 の画像 1 枚に収め、テキストでは約 2.5 万トークン、画像では約 2.7k 画像トークンが必要になる
実行とダッシュボード
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
- プロキシは
127.0.0.1:47821 で動作する
- ダッシュボードは
http://127.0.0.1:47821/ で提供される
- 保存されたトークン数
- テキスト→画像変換の左右比較
- キルスイッチ
- リアルタイムモデルチップ
- 最近のターンはテキストのまま保持され、システムプロンプト・ツールドキュメント・古い大量履歴は画像化される
デモで示された結果
- Fable 5 がデフォルトで、README では 100/100 の読解モデルとして示されている
- 画像化された 39 個の filler ファイルで正確なトークン数を 10/10 で的中
grep の結果と行単位で一致
- 多段の ledger 算術を正しく処理
- セッションコストは pxpipe 使用時 $6.06、通常テキストでは $42.21 とされる
- pxpipe 側は要求された 1 行出力形式に合わせるため 1 回の nudging が必要だった
- Opus 4.8 はデフォルトで無効化されている
- テキストの needle は両方で読めた
- 画像化された phrase-count は Opus では読めず、pxpipe は数字を捏造せず失敗を表面化させた
- この誤読率のため Opus はオプトイン対象となっている
精度と非可逆性
- pxpipe は 非可逆圧縮 方式
- 高密度な画像コンテンツでの正確な 12 文字 hex 文字列の想起結果はモデルごとに大きく異なる
- Fable 5: 13/15
- Opus: 0/15
- 取りこぼしはエラーとしてではなく 静かな confabulation として現れうる
- ID、ハッシュ、シークレットのようにバイト単位の正確性が必要な値はテキストで保持すべき
- 専用の verbatim-risk guard はまだ組み込まれていない
- 許可リスト外モデルを使う subagent はテキストで通過させられる
CLAUDE_CODE_SUBAGENT_MODEL=claude-sonnet-4-6
- agent frontmatter の
model: sonnet
ベンチマークと測定値
- 新しいランダム数値問題ベースのベンチマークでは、モデルが記憶していた可能性の低い問題を使用している
| テスト |
N |
テキスト |
pxpipe 画像 |
トークン |
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 |
- |
- SWE-bench Lite パイロットは両方とも 10/10 で、リクエストサイズは −65% だった
- SWE-bench Pro は ON 14/19、OFF 15/19 で、リクエストサイズは −60% だった
- 判定は 18/19 で一致
- 1 件の split は複製実行で 3/3 として再解決された
- README はこれを圧縮の問題ではなく実行間変動として扱っている
- サンプル数が小さいという注意書きがある
- GSM8K は画像化状態で 96% だったが、学習データに含まれている可能性があるため、README は novel-number 評価を前面に出している
仕組み
tool_result string ──► wrap at 1928px-wide columns ──► pack ~92,000 chars/page ──► PNG[]
- プロキシは
/v1/messages を横取りし、適した大量入力を image block に書き換える
- 変換されたブロックはキャッシュしやすい形で再挿入され、静的プレフィックスが保たれるため prompt caching は引き続き機能する
- 1928×1928 の画像は約 4,761 vision token を使い、約 92,000 文字を収める
- テキストが有利になるには約 19 文字/token を超える必要があるが、Claude Code トラフィックは N=391 基準で約 1.91 と測定された
- リクエストごとの推定器が画像化するかどうかを決め、疎な prose はテキストのまま保持される
- イベントは
~/.pxpipe/events.jsonl に記録される
何を圧縮し、何をそのままにするか
- 圧縮対象は 3 種類の入力ブロックで、いずれも収益性ゲートの後ろにある
- 約 6k 文字以上のトークン高密度な
tool_result 本文
- live tail より後方にある古い折りたたみ済み履歴
- 静的なシステムプロンプトとツールドキュメントの slab
- そのまま通過する項目も明示されている
- ユーザーメッセージ
- 最近のターン
- モデル出力
- 疎な prose
- 小さすぎて得にならないブロック
- 許可リスト外モデル
- デフォルト範囲は Fable 5 と GPT 5.6
- Opus 4.8 と GPT 5.5 は画像コンテンツの読解性能が低いため、ダッシュボードまたは
PXPIPE_MODELS で明示的に有効化する必要がある
PXPIPE_MODELS=off は画像化を無効化する
- GPT 経路ではツール定義は native JSON のまま維持され、Anthropic の
cache_control マーカーは使わない
コスト計算方法
- 見出しの削減率は入力スライスだけでなく 総請求額 ベース
- 13,709 件のリクエストスナップショットで $100 が約 $41 になり、59% 削減と計算された
- その後の 8,904 件の圧縮リクエスト trace では約 70% と測定された
- 圧縮されたリクエストだけを見ると 72〜74% 水準だが、README はこれを見出しには使っていない
- 各
/v1/messages POST ごとに、元の非圧縮本文に対する無料の count_tokens counterfactual を並列実行する
- 実際の課金使用量は Anthropic レスポンスの usage block から読み取る
- 元の使用量と実使用量は同じ
~/.pxpipe/events.jsonl の行に記録され、ターン数や run-to-run の混同を避ける
- ドル換算は Fable 5 の定価比率を使う
- input ×1.0
- cache write ×1.25
- cache read ×0.1
- output ×5
- キャッシュ価格は両側に同じように適用されるため、キャッシュ割引は削減額として二重計上されない
ライブラリ利用
import { renderTextToPngs, transformAnthropicMessages } from "pxpipe";
const imgs = await renderTextToPngs(toolResultText); // RenderedImage[]
const { body, applied, info } = await transformAnthropicMessages({
body: requestBytes,
model: "claude-fable-5",
});
- プロキシなしでもライブラリとして利用できる
options.keepSharp(block) は特定ブロックをテキストに固定する
options.emitRecoverable は画像化されたブロックの元データを返す
- ランタイムは Pure JS で、Node と edge/Workers をサポートする
@napi-rs/canvas はビルド時にのみ使われる
- 全 API は
src/core/index.ts にある
実際の失敗例と限界
- 数週間の日常使用の中で一度、画像化されたチャット履歴から人名を想起する際に、自信満々に誤った事例があった
- コーディングセッションでは編集前にファイルを読み直すためこの失敗モードに耐えられるが、純粋なチャット想起には同じ検証がない
- legibility audit ではレンダーページ上の正確な文字列想起を測定している
- 高密度 identifier の blind read は最大 63% だった
- すべての miss は glyph-confusability matrix で予測できた
- API の resample cap に合わせて page geometry を制限する緩和策が適用されている
- SHA や数字のような正確な identifier はテキストで併記する
- 制限事項も明記されている
- 画像ベースの verbatim recall は信頼しにくい
- 大きなリクエストでは送信前に PNG エンコード遅延が追加される
- ASCII/Latin-1 は十分にテストされている
- CJK も動作するが保守的に扱われる
開発とロードマップ
pnpm install && pnpm test
pnpm run build # regenerates dist/
- 開発コマンドはインストール・テスト・ビルドで構成される
- ライセンスは MIT
- ロードマップは仮説としてのみ示されており、数値やサンプル数が付かない限り claim としては扱わない
- より鮮明な glyph rendering
- 画像化された bulk が同じ 1M window で有効コンテキストを約 2 倍に増やせるか
- より小さい active context が長い作業の精度を高めるか
1件のコメント
Hacker News の意見
Gemini を見る限り、PDF を処理するときは OCR を行ったうえでテキストと画像をモデルに一緒に入れ、テキストトークンの費用は請求していないのだと思う。
Claude のバックエンドも同じことをしているなら、このハックはトークン課金方式の抜け穴に近く、Claude が Gemini のように動作するなら後で塞がれる可能性が高い。
ところが下のコメントで、DeepSeek が 視覚トークンで圧縮率を大きく改善したという話が出ている: https://news.ycombinator.com/item?id=48777848
内部の技術的詳細をすべて理解しているわけではないので、OCR 経路が全体の電力や計算コストの削減につながり得るという点は、今でもあまり腑に落ちていない。
画像を LLM に入れる方法の一つは、画像をタイルに分割し、それらのタイルを ビジョンエンコーダのニューラルネットワークに通して 視覚トークンを作り、テキストトークンのように LLM に入力するというもの。当然、ビジョンエンコーダと LLM が相互に理解できるように学習させる。こうした方式はエンドツーエンド OCR モデルと呼ばれる。
いったんこのように学習されたモデルがあれば、文書画像を拡大・縮小して、同じテキスト文書を表現するのに使われる視覚トークン数を変えてみることができ、パッチサイズやビジョンエンコーダの複雑さといったパラメータも調整できる。
結果はかなり良好で、一部のテストでは入力トークンを 90% 減らしながらも、出力性能は 97% を維持していた。
昨年 OpenAI のモデルで同じことを試したが、当時はプロンプトトークンを減らすには効果があったものの、補完トークンがずっと多く必要になり、結局はより高くて遅かった。
https://pagewatch.ai/blog/post/llm-text-as-image-tokens/
ああ、目が痛い。バイブコーディングされた README みたいだ。
例えば:
AI で本当に有用なものを作ることはできるし、すでに専門性を持つ分野ならなおさらだ。だがその場合は、1) AI の助けを使ったことを明かし、2) いったい何を作ったのかを自分の言葉で説明すべきだ。AI と作業するときの限界まで語れるなら、なおよい。
そうして初めて「この人が作ったものは触ってみる価値がありそうだし、作ったものをよく理解しているのだな」という信頼が生まれる。
最近出てくるものの 99% は、人々がまったく理解していない領域で作業した結果なので、そういう README が見えたらそのままタブを閉じてしまう。
これはリソースを燃やす 価格設定ハックのように見える。抜け穴が塞がれたら、OCR の価格は上がるべきではないのか?
考えてみれば筋が通る。人間もコードを単語単位で読むことは読むが、たいていはざっと眺めてパターン認識で何をしているのか大まかにつかむ。特定の質問に答える必要があるときだけ、特定の部分に集中する。
人間も自然に似たような 迂回的な最適化をしているのだと思う。
関連記事: https://blog.can.ac/2026/06/10/snapcompact/
この方式には注意が必要だ。コストが下がる理由は、実は性能の低い別のモデルに切り替わっているからである可能性が高い。
表向きは Fable のように見えても、実際にはそうではないかもしれない。そうなると余計な作業をしているだけで、むしろモデルを opus 4.8 に戻したほうがよいかもしれない。
Oh-My-Pi(OMP.sh)はコンテキスト圧縮に画像を使っているようだ。OMP は Pi コーディングエージェントの上に作られている。
この手法についての DeepSeek のホワイトペーパーもある: https://www.seangoedecke.com/text-tokens-as-image-tokens
以前、誰かのツイートを見た。おそらく Carmack、Geohot、Karpathy のうちの誰かで、画像のほうがより良い選択肢になり得るのではないか、という内容だった。
それ以来、エージェントに今何が起きているのかを伝えるとき、ごく単純な文のプロンプトと一緒に画像を使ってきたし、ときにはプロンプトにテキストをまったく入れないこともある。
効果は非常によかった。
ただし、これは Karpathy が言っていたことと厳密に同じではない。それでも、その考えのおかげで、より良いワークフローにつながった。
悪いが、これは馬鹿げている。動くし賢くはあるが、明らかに 価格設定の失敗を迂回する方法だ。
毒蛇の報奨金のせいで人々がヘビを飼育し始めたように、これは無駄を利用し、助長している。
結局、こうした裁定取引を可能にした Anthropic の悪い料金体系に責任があると思う。だが修正されるまで、これを悪用する人々が押し寄せ、完全に不要なデジタルゴミがさらに大量に生み出されることにも嫌悪感を覚える。