# pxpipe：通过图像化压缩输入token降低Claude Code成本

- 来源：Hacker News 热门（buzzing.cc 中文翻译）
- 作者：dimitropoulos
- 发布时间：2026-07-04 03:19
- AIHOT 分数：83
- AIHOT 标记：精选
- AIHOT 链接：https://aihot.virxact.com/items/cmr5cef1q017islc779xjrcy6
- 原文链接：https://github.com/teamchong/pxpipe

## 精选理由

pxpipe 通过把大量上下文渲染成图像来降低 token 开销，实测能削减 60-70% 的账单，对重度使用 Claude Code 的开发者很诱人，但它有损，精确值可能读错，适合容错高的编码场景。

## AI 摘要

pxpipe是一个本地代理，将系统提示、工具文档和历史记录等密集文本渲染为PNG图像，利用图像token成本取决于像素尺寸的特性压缩输入token。在Fable 5模型上，约25k文本token压缩为约2.7k图像token，端到端账单降低59–70%。SWE-bench Lite 10个实例全部通过，成本从$54降至$27；SWE-bench Pro 19对测试中18对判定一致，单次请求成本降低约60%。该方法有损（精确ID等需保持文本），默认仅处理`claude-fable-5`请求，可通过`PXPIPE_MODELS`变量控制。

## 正文

pxpipe

将庞大上下文渲染为图片，以此削减 Claude Code 的输入 token——同样的系统提示词、工具文档和历史记录，只需原来 token 数的一小部分。

一张图片的 token 成本由其像素尺寸决定，而非内含文本量。在真实的 Claude Code 流量中，密集内容（代码、JSON、工具输出）每个图片 token 约可容纳 3.1 个字符，而每个文本 token 仅约 1 个字符。pxpipe 是一个利用这一差异的本地代理：它在请求离开你的机器之前，将请求中的庞大部分（系统提示词、工具文档、较早的历史记录）重写为紧凑的 PNG 图片。

节省量取决于工作负载——pxpipe 在 token 密集内容上优势明显，而对稀疏/小型请求不做改动——因此这些是实测快照，并非固定值。主要且持久的结果是输入 token 的减少：密集的系统提示词、工具文档和历史记录以紧凑图片而非文本形式输入（上例中约 25k 文本 token 被渲染为约 2.7k 图片 token），每个请求都对照自身的 count_tokens 反事实进行测量。费用节省由此衍生——按当前 Fable 标价，token 削减带来约 59–70% 的整体账单降低（压缩请求上约 72–74%；完整定价计算见 FAQ）。但标价明天就可能变化，而 token 数量不会，因此应关注 token 而非美元。可从 ~/.pxpipe/events.jsonl 复现两者。

这就是模型看到的，而非文本：

约 4.8 万字符的系统提示词 + 工具文档（即本仓库自身的 README、FINDINGS 和源代码），作为文本约 25k token，作为此页面约 2.7k 图片 token。由真实的 transformRequest 管道生成：空白压缩，重新排列为满行，用 ↵ 标记原始换行，顶部叠加 OCR 指令横幅。模型在纯净评测中以 100/100 的成绩读取此类渲染（见基准测试）。

演示

Fable 5 演示（默认，阅读器得分 100/100）：

Fable-AB-Demo.mp4

双窗格演示（左侧为纯文本，右侧为 pxpipe），均在 Fable 5 上运行。

Fable 能读取 Opus 无法处理的内容。Opus 拒绝处理的图片化短语计数（见下方 Opus 演示）：pxpipe 分支在 39 个图片化填充文件中精确统计了 10/10 个 token（与 grep 真实结果逐行匹配），并正确完成了多步骤账本算术（8037 → … → 15,021）。

相同的答案，成本降低约7倍。两次演示后的会话总量：普通版本为42.21美元，上下文窗口已满96%（964.5k/1M——距离强制压缩仅差一个任务）；而pxpipe版本为6.06美元，上下文空间充足（73.5k/1M）。

诚实的提醒，视频片段中可见：pxpipe分支先回答了计数问题，但需要一次后续提示才能按要求的一行格式打印账本余额；普通分支首次尝试就遵循了格式。在Fable上可读性已解决——单次回复格式遵循是剩下的粗糙边缘。

Opus 4.8演示（Opus默认禁用）：

Opus-AB-Demo.mp4

并排对比——普通Claude（左）与pxpipe（右），两者均运行在Opus 4.8上（需手动启用；pxpipe针对Fable进行了调优——参见上方Fable片段）。点击图片观看（Google Drive）。

演示1——修复失败的测试套件：两者均通过；仪表盘显示pxpipe将请求压缩至token数的一小部分（真实的、服务端测量的上下文/token缩减）。

演示2——一个大型文件上下文（40个文件，约382k token）加上一个数学问题和一个“统计此短语”任务：数学答案（一个小的文本“针”）两者均可读取。短语计数需要读取图像填充内容——因此运行在Opus上的pxpipe无法读取，并诚实地表明它不会编造数字（有文档记载的有损限制：精确数值保持为文本形式）。与此同时，普通版本在逐文件计数时陷入困境。

尝试一下（30秒）

npx pxpipe-proxy # proxy on 127.0.0.1:47821
ANTHROPIC_BASE_URL=http://localhost:47821 claude # point Claude Code at it

打开 http://127.0.0.1:47821/ 查看实时仪表盘：节省的token数、每会话统计、每次文本到图像转换的并排对比、全局终止开关，以及包括GPT 5.6和GPT 5.5在内的运行时模型芯片。

其他一切不变。响应正常流式输出；pxpipe仅压缩请求（即你发送的上下文），绝不压缩模型的输出。最近的轮次保持文本形式；系统提示词、工具文档和较旧的批量历史被转换为图像。

诚实的部分，在依赖之前请先阅读。

它有损。pxpipe 属于 gist 层级存储，并非无损存储。在一项“大海捞针”式评测中，密集图像内容里的精确 12 字符十六进制字符串，在 Opus 上返回结果为 0/15，在 Fable 5 上返回结果为 13/15，且失败模式是无声的虚构：给出一个看似合理但错误的值，而非报错。任何需要字节级精确返回的内容（ID、哈希值、密钥、精确数字）都必须保持文本形式。最近的版本已经实现了这一点；但尚未内置专门的逐字风险防护。

精确召回逃生通道。pxpipe 仅对 Fable 请求进行图像化处理（PXPIPE_MODELS=claude-fable-5），因此任何使用非 Fable 模型的子智能体都会以文本形式通过。将需要字节级精确值的工作路由到这类模型——全局设置 CLAUDE_CODE_SUBAGENT_MODEL=claude-sonnet-4-6，或在智能体 frontmatter 中按智能体设置 model: sonnet。它从源文件（file/JSONL）读取，而非从图像化历史中读取。这覆盖了你有意路由的精确召回场景；但无法捕获你未预料到的无声误读——正是上面提到的那项尚未构建的防护。

它会破坏实际工作吗？在我们衡量的指标上具有一致性：一个包含 10 个实例的 SWE-bench Lite 试点（简单子集），两组均解决了 10/10，pxpipe 开启时 token 等价成本为 $27，关闭时为 $54；19 对 SWE-bench Pro（更困难、长周期）测试中，开启组解决了 14/19，关闭组解决了 15/19，每次请求成本降低 60%：两组在 18/19 个案例上判定一致，唯一的分歧（一个开启组失败案例）在复制测试中 3/3 重新解决，即属于运行间智能体方差，而非压缩问题。样本量较小，详细说明和注意事项见下文。

节省成本取决于工作负载。它在 token 密集内容（约 1 字符/token：代码、JSON、哈希值）上表现优异，而在稀疏的英文散文（约 3.5 字符/token）上则不划算。内置门控仅对数学计算上划算的内容进行图像化处理，并基于 N=391 条生产数据行进行了校准。

模型范围：一个 PXPIPE_MODELS CSV 文件控制着两个模型族中哪些底座会被成像——默认是 claude-fable-5、gpt-5.6（GPT 5.5 为可选加入；它在成像上下文上会降级）。将 PXPIPE_MODELS 设为 off 可完全禁用成像，或使用 ~/.config/pxpipe/config.json 并写入 { "models": "off" }（或一个列表）。对于 GPT，pxpipe 以原生 JSON 格式保存工具定义（只有冗长的模式描述会被放入图像），因此工具调用保持可靠；与 Claude 路径不同，GPT 路径不会添加或依赖 Anthropic 的 cache_control 提示缓存标记。仪表盘上的面板可以实时切换任何模型，无需修改客户端配置。Opus 4.7/4.8 是初始的 Claude 范围，但它在约 7% 的渲染中发生了误读（10200→9400），因此在 Fable 5 达到 100/100 且图像计费相同后，默认关闭了它——你可以通过 PXPIPE_MODELS 或仪表盘面板自行选择重新开启，风险自负。其他所有内容原样通过。

可复现的基准测试

使用模型无法记住的新颖随机数问题进行测量：

测试 样本数 文本 pxpipe（图像） token数

新颖算术，claude-fable-5 100 100% 100% –38%

新颖算术，claude-opus-4-8 100 100% 93% –38%

要点回忆A/B（决策、数值、路径、名称、否定；含干扰项；15k-45k字符会话），Fable 5 98/arm 98/98 98/98 –

状态跟踪（值变化3次，最终/首次/计数），Fable 5 18/arm 18/18 18/18 –

对从未陈述的事实的虚构（越低越好），Fable 5 16/arm 0/16 0/16 –

逐字12字符十六进制回忆，密集渲染，Opus 15 15/15 0/15 –

逐字12字符十六进制回忆，密集渲染，Fable 5 15 – 13/15 –

SWE-bench Lite 试点（端到端任务质量）

10个SWE-bench Lite实例，Claude Code + Fable 5，通过pxpipe开启与关闭进行配对运行，使用官方swebench Docker框架评分：

pxpipe 开启 关闭

解决 10/10 10/10

请求大小与自身未压缩主体对比 –65% ±0

–65% 是每次请求（压缩前对每个主体进行count_tokens探测）的数据，因此没有轮次混淆。n=10/arm，Lite偏向简单。运行总计、收据、注意事项：eval/swe-bench/。

SWE-bench Pro 基准测试（更难，长期）

两次运行共完成19对（2对放弃：两个分支检出失败），相同设置，官方SWE-bench_Pro-os Docker框架：

pxpipe 开启 关闭

解决 14/19 15/19

请求大小 vs 自身未压缩的响应体 −60% ±0

在 19 个实例中，18 个的评价结果一致（三个实例的两端均失败，其中一个是两端字节完全相同的补丁）。唯一的分歧（navidrome，ON 端失败）在 ON 端重复了 3 次：三次运行均产生了相同的补丁并成功解决，因此最初的损失是运行间智能体方差造成的，与压缩无关。凭证：eval/swe-bench-pro/。

我们还运行了 GSM8K：获得了 96% 的成像结果。但 GSM8K 存在于训练数据中，因此模型会通过自身误读来回忆已记忆的答案，从而虚增分数，所以我们改用干净的新数字评测作为主要依据。复现方式：eval/gsm8k/ · eval/needle-haystack/ · eval/gist-recall/ · 完整分析见 FINDINGS.md。

常见问题

这个数据是端到端的，还是仅针对你处理过的请求？是端到端的，涵盖全部费用。大多数压缩工具只报告它们所处理的输入部分的节省量，这会让数字更好看。端到端的分母是所有生产请求：包括 pxpipe 正确保留的小请求、所有缓存写入和读取、以及所有输出 token（代理从不压缩输出）。在 13,709 个请求的快照中，节省了 59%（100 美元 → 约 41 美元）；后续一个 8,904 个压缩请求的跟踪测得约 70%。仅压缩部分则更高（约 72–74%），并单独列出，从不作为标题数据。具体数据取决于工作负载——请在自己的日志上复现。

这个数学计算是如何完成的？对同一个请求的两端，在同一时刻进行。对于每个 /v1/messages POST，代理会并行地对原始未压缩体（反事实情况）发出一个免费的 count_tokens 探测，同时进行实际转发，并从响应中读取 Anthropic 实际计费的使用情况块。两端都会记录在 ~/.pxpipe/events.jsonl 的同一行中，因此不存在轮次或运行间混淆。美元换算使用 Fable 5 列表比率：输入 ×1.0，缓存写入 ×1.25，缓存读取 ×0.1，输出 ×5。缓存定价对两端相同，因此缓存折扣相互抵消，不会重复计算为“节省”。您可以从事件日志中自行推导：公式和字段名称在 src/core/baseline.ts 中有文档说明。

它实际上压缩了什么？三种输入块，每种都经过一个盈利性门控：

大型工具结果体（文件读取、命令输出、日志）中，超过约 6k 字符的密集 token 内容。

较早折叠的历史记录：位于实时尾部之后的轮次会被重新渲染为图像页面，而最近的轮次始终保留为文本。

静态系统提示词 + 工具文档模块。

其他所有内容都原样逐字节通过：你的消息、最近轮次、模型输出（它就是响应本身，代理从不触碰它）、稀疏的散文，以及任何太小以至于不值得转换的内容。非 Fable 模型则完全原样通过。

在真实场景中（基准测试之外）它真的失败过吗？是的，在数周的日常使用中发生过一次：模型从图像化的聊天历史中回忆了一个人的名字，并自信地给出了错误答案。没有报错，只是一个看似合理但错误的名字。这就是文档中记录的错误模式：图像化内容中的精确字符串不具备字节安全性。编码会话可以容忍这种情况，因为代理在编辑前会重新读取文件；纯聊天回忆则没有这样的检查。

工作原理

tool_result string ──► wrap at 1928px-wide columns ──► pack ~92,000 chars/page ──► PNG[]

代理拦截 /v1/messages，将符合条件的批量历史记录重写为图像块，然后以缓存友好的方式将它们拼接回去（保留静态前缀，使提示缓存继续工作），并转发。每次请求的事件记录到 ~/.pxpipe/events.jsonl。

经济性计算：一张 1928×1928 的图像需要约 4,761 个视觉 token，最多可容纳约 92,000 个字符（在观察到的密度下约相当于 48,000 个文本 token），因此纯文本只有在密度超过约 19 字符/token 时才更便宜。Claude Code 的转录内容远低于该密度（观察值为 1.91 字符/token，N=391）。运行时估算器（estimateImageCount）加上一个字符/token 阈值决定每次请求的处理方式；稀疏散文则保留为文本。

库使用（无代理）

同样的引擎，无代理。将文本渲染为 PNG，或运行完整的缓存安全转换：

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) 将某些块强制保留为文本（覆盖对 ID、哈希值、路径的启发式判断）；options.emitRecoverable 返回已图像化块的原始内容，以便有状态的调用方可以恢复它们——这是针对下面有损限制的保真契约的两个部分。运行环境为纯 JS（Node 和 edge/Workers）；@napi-rs/canvas 仅在构建时使用。完整 API、类型和常量参见：src/core/index.ts。

开发

pnpm install && pnpm test # 376 tests
pnpm run build # regenerates dist/

限制

有损：请参阅上方“诚实的一面”。从图像中逐字回忆是不可靠的。

渲染延迟：编码 PNG 会为大型请求在离开前增加额外时间（部分被模型消耗更少 token 所抵消）。响应正常流式输出。

ASCII/Latin-1 已充分测试；CJK（中日韩字符）可用但处理较保守。

运行时是纯 JavaScript——可在 Node 和边缘/ Workers 上运行。@napi-rs/canvas 仅在构建时作为开发依赖使用（用于重新生成字形图集），不是运行时依赖。

仅支持 Fable 5。

路线图

以上所有内容均已实测。以下内容尚未实测。这些是假设，而非声明；它们要么作为带 n 前缀的数字发布，要么被砍掉。

更清晰的字形。13/15 逐字差距部分是由于字体可读性，而不仅仅是模型本身。跨渲染风格的逐字符混淆矩阵正在运行中（eval/glyph-matrix/）；如果某种零成本风格能降低阅读错误，那么在相同保真度下，门控压缩会更激进。

有效上下文。密集文本作为图像传输时，token 消耗约为直接使用图像的 1/3。如果这一结论在实时窗口中成立（而不仅仅是账单层面），那么 1M token 实际上能承载约 2 倍的真实内容。开放问题：当一个需要约 2M 原始上下文的任务在 Fable 的 1M 上下文中运行时，如果大部分内容已被图像化，是否仍能执行？

更少的活跃文本，更锐利的模型。长上下文会随着填充而降低推理能力。将旧的大块内容图像化，可以缩小模型主动读取的范围，同时使其仍可访问。假设：相同信息，更小的活跃上下文，更好的长任务准确率。

一个赌注：更长的有效上下文和更锐利的长任务模型，来自同一个 Fable 5。要么出数字，要么撤回，中间不炒作。

许可证

MIT。

关于

通过将文本上下文渲染为图像来降低 Fable 5 的 token 用量

资源

Readme

许可证

MIT 许可证

动态

55 个 Star

观察者

0 人关注

2 个 Fork

举报仓库

发布版本 2 个

v0.7.1 最新版

2026 年 7 月 3 日

+ 1 个发布版本

包

贡献者

语言

TypeScript 96.1%

JavaScript 1.8%

Shell 1.1%

Python 1.0%
