资讯中心

pxpipe 历史图片压缩的缓存模型:量化边界、一次性燃尽与 cache mark 搬迁

📅 2026/10/25 19:47:49
pxpipe 历史图片压缩的缓存模型:量化边界、一次性燃尽与 cache mark 搬迁
【免费下载链接】pxpipecut Claude Code token usage by rendering text context as images项目地址https://gitcode.com/gh_mirrors/px/pxpipe点击查看免费下载本指南解析 pxpipe将 Claude Code 文本上下文渲染为图片以削减 token 用量在对话不断增长、新内容不断变旧的前提下如何保证历史图片压缩始终开启却不破坏 Anthropic 前缀提示缓存。读完本文你将理解 pxpipe 的量化折叠边界quantized boundary为何是阶梯而非斜坡、一次性cache_create燃尽one-time burn如何被双重门控约束以及调用方的cache_control标记如何被搬迁relocate而非新增add从而让缓存断点恰好落在稳定与易变内容的接缝上。本文是 CACHING_AND_SAVINGS.md承载定价数学的概念伴侣。二者若有不一致以代码为准src/core/history.ts —collapseHistory、量化边界、blocksToTextsrc/core/transform.ts — splice、cache-mark 搬迁、收益门控src/core/baseline.ts —CACHE_CREATE_RATE 1.25、CACHE_READ_RATE 0.10. 本文要回答的问题如果我们把过去的轮次turn转成图片前缀不就改变了吗——缓存不就失效了吗而且既然新内容迟早会变成旧内容边界岂不是每一轮都在移动导致持续不断地重新成像、重新换缓存 key短答案pxpipe 确实把历史成像它是缓存安全的旧由一个量化quantized边界定义因此重新换 key 是罕见的一次性事件而非每轮抖动。缓存断点即mark正是让这份成本变成一次性的接缝。1. 是的——我们始终开启历史成像collapseHistorysrc/core/history.ts始终开启、无条件下发transform.ts 中标注为 Variant C history-image compression. ALWAYS-ON, unconditional。它遍历messages[]找出最大的工具调用已闭合的前缀段tool-closed prefix run用blocksToText将其序列化为文本——该函数会包含 assistant 回复、tool_use参数与tool_result内容——然后把这段文本渲染成 PNG 图片块放入一条前置的合成 user 消息中。从 src/core/history.ts 源码看blocksToText对块类型的处理如下块类型序列化行为text原文文本tool_use[tool_use name]\n 紧凑 JSONJSON.stringify不缩进——美化会放大文本约 5 倍且渲染器是按行感知的tool_result[tool_result错误时附 (error)]\n 内部文本内部图片块折叠为[image]占位符避免双重编码image[image]占位符thinking及其它静默丢弃——只有最近一条 assistant 轮次需要逐位bit-perfect往返而它天然位于 live tail 中保持为文本的是活尾巴live tail最后keepTail轮加上任何处于未闭合工具序列内的内容以及最近一条 assistant 的 thinking 签名它必须逐位往返。所以过去的 assistant 回复绝对会变成图片。本文其余部分探讨的是为什么这样做是安全的。2. 老化问题真实存在每一轮活尾巴增长最旧的尾巴轮次变得有资格成为旧内容。因此文本↔图片边界倾向于随时间前移。危险在于如果旧意味着*除了最后 keepTail 轮之外的一切*——一个每轮移动的窗口——那么边界每轮都会前进一条消息。被折叠的集合每轮都会改变 → 渲染出的 PNG 字节每轮都会改变 →每轮都是新的缓存 key → 每轮都在整个历史上付一次cache_create1.25×。这并非假设。它就是2026-05-19 的回归bug #28定价文档引用它作为−250% savings的例子。移动边界是缓存粉碎机cache shredder。3. 修复方案旧是量化的而非移动窗口边界被吸附到以collapseChunk条消息默认50为单位的固定网格上。摘自 src/core/history.tsconst rawCutoff messages.length - o.keepTail; const cutoff o.collapseChunk 0 ? Math.min(rawCutoff, Math.max(minCollapsePrefix protectedPrefix, Math.floor(rawCutoff / o.collapseChunk) * o.collapseChunk)) : rawCutoff; const boundary findClosedPrefixBoundary(messages, cutoff);Math.floor(rawCutoff / collapseChunk) * collapseChunk是整个技巧所在成像资格以离散跳跃前进而非连续前进。随后findClosedPrefixBoundary将其拉回到最近的工具已闭合点确保图片永远不会拆散一对开着的tool_use/tool_result。从 src/core/history.ts 的实现细节看findClosedPrefixBoundary通过openSet追踪跨消息的tool_useid 与tool_result配对并特殊处理并行工具调用相邻的 assistant-call/user-result 对被视作一轮工具调用一些 Anthropic 客户端会以 A-call/A-result、B-call/B-result 的序列化方式发出并行批次因此两个相邻 pair 之间的看似闭合的空隙不是安全的折叠边界。它是一个阶梯不是斜坡。设keepTail 4、collapseChunk 50messages.lengthrawCutoff量化后的cutoff被成像的内容545050msgs[0..50)807650msgs[0..50) ←相同1039950msgs[0..50) ←相同104100100msgs[0..100) ←跳跃在大约 50 轮内被折叠集合是一组固定的消息→ 字节完全一致的 PNG → 前缀全程读取为热缓存cache_read0.1×。新内容堆积在文本尾巴里只有当对话越过下一个 50 的倍数时它才跨入已成像区域。historyImageSha8src/core/transform.ts按请求记录图片哈希正是为了让这一点可从events.jsonl验证边界保持期间相邻的折叠轮次必须报告相同的history_image_sha8。一个逐轮移动的哈希正是 bug 复发的信号。注意该函数通过合成消息的 banner 文本HISTORY_SYNTHETIC_INTRO定位历史图片消息而不是假设它是messages[0]——当存在 slab 锚点protectedPrefix slabAnchorIdx 1时messages[0]是受保护的 slab 消息按位置硬编码哈希会错测成slab 稳定性#11 归因问题。相关测试见 tests/history.test.tsquantizes the collapse boundary onto a stable grid — image bytes stay byte-identical within a chunk windowmk(20)与mk(22)两次折叠的图片字节完全一致而mk(70)跨越网格窗口后允许改变与 tests/cache-bust-attribution.test.ts。4. 一次性燃尽以及控制它的门控一次块跨越chunk crossing会改变成像区域的字节一次 → 那一轮支付一次新的cache_create。这就是一次性燃尽one-time burn。它每个稳定窗口一次性而非每轮——大约每collapseChunk轮一次 create分摊在其间的热读之上。双向门控只在能回本时才发生对称燃尽项isCompressionProfitablesrc/core/transform.tsburnImageSide priorWarmTokens × (CACHE_CREATE_RATE − CACHE_READ_RATE) // ≈ 1.15× 被放弃的热前缀 compress iff imageTokens burnImageSide textTokens burnTextSide该燃尽项是对称的burnTextSide priorWarmImageTokens × (1.25 − 0.10)切换模式会使当时处于热缓存的一侧失效、支付一次 cache_create。燃尽项加在将会翻转的那一侧——把会话钉在当前模式直到每轮节省超过燃尽成本反抖动 / anti-flapping。历史摊销门控isCompressionProfitableAmortizedaccept iff I × (CC CR×(N−1)) T × CR × N CC 1.25, CR 0.10其中N historyAmortizationHorizon假设此前缀还会被复用 N 次。默认N 1这是刻意保守的——N 1时折叠几乎从不获胜因此宿主一旦观察到其缓存活得足够长、足以摊销 create就提高N。N ≈ 10时只要图片低于约 0.7× 文本折叠就获胜。源码注释给出的参考阈值N5 → I 0.30×TN10 → I 0.47×Tsrc/core/transform.tsisCompressionProfitableAmortized。当horizon 1时回退到逐轮冷门控。相关测试见 tests/history.test.ts 的 isCompressionProfitableAmortized — multi-turn horizon gate。冷启动免费。在第 1 轮 / 全新对话中priorWarmTokens与priorWarmImageTokens默认为0燃尽项完全归零——没有可失去的热缓存因此从一开始就成像不会破坏任何东西。5. 统一原则cache mark 就是接缝以上所有内容都归结为一条规则字节稳定的内容放在 cache mark 之前每轮易变的内容放在它之后。一次性是相对该 mark 定义的。pxpipe从不新增断点——Task #21它把调用方已有的cache_control标记搬迁到由该标记覆盖的内容所产生的最后一张静态图片上src/core/transform.ts 的relocateAnchorToHistoryImage文档表述为mark 骑在最后一张图片上。于是断点恰好落在稳定↔易变接缝处[ intro / static slab image(s) ] ← 稳定 [ last static image ] ← cache_control ◄── mark搬迁而非新增 ─────────────── cache 断点 ─────────────── [ end-marker dynamic env billing line ] ← 每轮都变 [ history image, current user content ] ← 在 mark 之后从 src/core/transform.ts 的relocateAnchorToHistoryImage实现看搬迁是纯搬迁只有当 slab 图片已携带锚点时它才动作因此总标记数永不增加。它通过 banner 文本识别合成历史消息把 mark 钉在carryOverImageOrdinalcollapseHistory报告的、最后一个完全网格对齐的字节稳定历史图片上而非最新、仍在增长的最末块——后者正是 #11 的翻车点钉在最后一帧会导致每次窗口前进都换 key。落点兜底为合成消息的最后一张图片slab 锚点则通过[End of rendered context.]边界文本定位找不到锚点时直接返回绝不新增标记。两个条件使燃尽成为一次性布局同时满足两者到 mark 为止的一切在轮次间字节完全一致——由量化边界§3保证。所有易变内容都在 mark 之后——billing line、动态env、当前 user 消息都被 splice 到断点之后永不污染前缀缓存 key。当两者都成立时到 mark 为止的前缀每轮都读热缓存前缀仅在 mark 处/之前的字节真正改变时即初始的文本→图片翻转与每次块跨越才重新换 key。这就是一次性 create其间的每一轮都是热读。为什么 slab 受到保护承载 slab 的头部 user 消息通过protectedPrefixsrc/core/transform.tsslabAnchorIdx 1免于折叠。如果历史折叠将其卷入blocksToText会把 system-prompt/tool-docs 图片降级为[image]占位符slab 的cache_control锚点就会消失——于是每次网格跨越都会使整个前缀失效。把它排除在折叠范围之外将其钉在前端作为稳定的缓存锚点并把历史图片放在它之后。测试 tests/anthropic-cache-align.test.ts 与 tests/history.test.ts 均断言messages[0]是承载 slab 的 user 消息而非合成历史消息且 slab 图片真实存在。6. 这正是 Claude Code 自身的模型Claude Code 原生就带一个大稳定前缀system prompt、tool docs、system-reminder、较早的历史以cache_control断点收尾后面跟着一段薄薄的每轮尾部。pxpipe 保留了这一精确形态。它只是交换稳定前缀的表示——冗长文本 → 字节稳定的图片。带着 mark 一起移动搬迁而非新增使接缝保持在相同的逻辑位置且 pxpipe 不消耗 4 个断点预算中的任何一个测试 tests/anthropic-cache-align.test.ts 断言输出标记数 ≤ 输入标记数且搬迁后恰好为 1 个。量化历史边界使成像区域的字节只在块跨越时改变保持 Claude Code 赖以工作的原生字节稳定性。一次性不是运气——它由把 mark 锚定到最后一张稳定图片、并把所有每轮抖动推到它之后来强制执行。7. 默认参数真源HISTORY_DEFAULTSsrc/core/history.ts选项默认含义keepTail4最近轮次总是保持为文本活尾巴。minCollapsePrefix10少于这么多轮就不值得折叠。collapseChunk50边界吸附的网格 → 阶梯之间图片字节稳定。protectedPrefix0开头的消息永不被折叠运行时设为 slab 锚点 1。cols100软换行列数提示历史渲染为密集单列。相关位于TransformOptionssrc/core/transform.ts选项默认含义HISTORY_CHARS_PER_TOKEN2.0历史 cpt 拟合Opus 4.7 / Fable 5 tokenizer。historyAmortizationHorizon1摊销门控中的N一旦证明缓存长寿就调高。旋钮直觉更大的collapseChunk→ 更少的翻转/燃尽缓存更便宜但尾巴中未成像的文本更多压缩更少。更小的collapseChunk→ 更激进的压缩但燃尽更频繁。更大的historyAmortizationHorizon→ 更愿意为未来的热读现在吃一次 create仅当缓存确实能活那么久时才安全。8. 一段话总结我们始终开启地成像历史轮次但旧是一个量化边界floor((len − keepTail) / collapseChunk) × collapseChunk并吸附到工具闭合点因此成像区域的字节在整个collapseChunk窗口内保持一致前缀每轮都读热缓存。新内容只在块跨越时老化进图片每次跨越花费一次单独的cache_create由对称燃尽项与摊销视野双重门控只在热读能回本时触发。整件事之所以成立是因为调用方的cache_control标记被搬迁从不新增到最后一张稳定图片上把每个字节稳定的东西放在接缝之前、每个每轮易变的东西放在它之后——这正是 Claude Code 已经依赖的前缀缓存形态。延伸阅读定价数学与诚实核算见 docs/CACHING_AND_SAVINGS.md含 warm/cold 工作示例与baseline_eff − actual_eff推导缓存对齐契约的 TDD 测试见 tests/anthropic-cache-align.test.ts 与 tests/cache-bust-attribution.test.ts缓存稳定性端到端验证见 tests/cache-stability-e2e.test.ts。赞分享【免费下载链接】pxpipecut Claude Code token usage by rendering text context as images项目地址https://gitcode.com/gh_mirrors/px/pxpipe点击查看免费下载相关推荐Awesome-KV-Cache-Compression优化大型语言模型KV缓存压缩的利器Awesome KV Cache Compression优化大型语言模型KV缓存压缩的利器 在大型语言模型LLM的推理过程中如何有效管理内存和计算资源是掌握OpenCode多项目并发处理现代开发者的终极效率提升方案掌握OpenCode多项目并发处理现代开发者的终极效率提升方案 在当今快节奏的软件开发环境中开发者往往需要同时处理多个项目前端React应用、后端API服人工智能AI 应用AI Agent代码智能体CLI开发者工具1688-customer-opportunity5大核心功能彻底提升店铺客群运营效率1688 customer opportunity5大核心功能彻底提升店铺客群运营效率 1688 customer opportunity是一款专为1688平上一篇如何使用BERT uncased L-12 H-256 A-4进行文本分类任务终极实战教程下一篇NLP研究者指南multilingual-MiniLMv2-L6-mnli-xnli-openmind的5大局限性与偏见分析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

看完文章,想为自己的企业也做一次专业网站诊断?

尧图顾问免费为您评估现有网站,并给出建站/改版建议与报价方案。

免费获取方案