dexpipe-proxy
v0.11.5
Published
Token-saving proxy for Claude Code: renders bulky context (system prompt, tool docs, old history) as dense PNGs to cut input tokens. Runs on Node and Cloudflare Workers.
Maintainers
Readme
██████╗ ███████╗██╗ ██╗██████╗ ██╗██████╗ ███████╗
██╔══██╗██╔════╝╚██╗██╔╝██╔══██╗██║██╔══██╗██╔════╝
██║ ██║█████╗ ╚███╔╝ ██████╔╝██║██████╔╝█████╗
██║ ██║██╔══╝ ██╔██╗ ██╔═══╝ ██║██╔═══╝ ██╔══╝
██████╔╝███████╗██╔╝ ██╗██║ ██║██║ ███████╗
╚═════╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚══════╝Corte os tokens de entrada do Claude Code renderizando contexto volumoso como imagens — o mesmo system prompt, docs de tools e histórico, numa fração dos tokens.
O custo em tokens de uma imagem é fixado pelas dimensões em pixels, não pela
quantidade de texto dentro dela. Conteúdo denso (código, JSON, saída de tools)
rende ~3,1 caracteres por token de imagem contra ~1 caractere por token de
texto no tráfego real do Claude Code. O leitor é o mesmo canal de visão que o
computer use da Anthropic já usa para screenshots. O dexpipe é um proxy local
que usa esse canal para contexto: ele reescreve as partes volumosas de cada
requisição em PNGs compactos antes de saírem da sua máquina. Nos preços de
tabela atuais do Fable, isso resulta numa conta de ponta a ponta ~59–70%
menor — mas preços mudam e cargas de trabalho variam, então o número durável
é o corte de tokens em si, medido por requisição contra um contrafactual
gratuito de count_tokens em ~/.dexpipe/events.jsonl.
Isto é o que o modelo vê no lugar do texto:

~48 mil caracteres de system prompt + docs de tools: ≈25 mil tokens como texto, ≈2,7 mil tokens de imagem como esta página. Saída real do pipeline; o modelo lê renders como este a 100/100 (ver benchmarks).
![gráfico: caracteres que uma janela de contexto de fronteira comporta, 2018–2026; a sobreposição laranja medida é Fable 5 [1m] + dexpipe ~18M (4,6×)](docs/assets/context-window-chars.png)
Oito anos de crescimento de contexto, em caracteres. Toda linha de texto
estaciona perto de ~4M de caracteres (janela de 1M de tokens a ~4
caracteres/token). A sobreposição laranja é a mesma janela de 1M do Fable 5 lida
através de imagens do dexpipe — ~18M de caracteres na densidade Anthropic
medida (4,6× o teto do texto). A densidade é medida de um render ao vivo
na hora da geração, não digitada à mão: regenere com
npx tsx scripts/gen-context-chart.ts
(fonte).
Demo
Fable 5 (o padrão, leitor 100/100) — sem proxy à esquerda, dexpipe à direita:
https://github.com/user-attachments/assets/1c8ee63a-fcd7-4958-917b-da788d718349
O dexpipe conta um token exato 10/10 em 39 arquivos de preenchimento
imageados (bate com o grep linha por linha), acerta a aritmética de
múltiplas etapas do razonete, e termina a sessão a US$ 6,06 com contexto
de sobra (73,5k/1M) contra US$ 42,21 a 96% de ocupação. Uma ressalva
visível no clipe: o braço com dexpipe precisou de um empurrão para seguir o
formato de saída de uma linha pedido.
Opus 4.8 (desligado por padrão) — mesmo layout:
https://github.com/user-attachments/assets/f4e50137-31b5-426f-a6ed-b83f829b4a2c
Agulhas em texto leem bem nos dois braços; a contagem de frases imageada não lê no Opus — e o dexpipe diz isso em vez de fabricar um número. Essa taxa de erro de leitura é o motivo do Opus ser opt-in.
Instalação
Publicado no npm como dexpipe-proxy. Requer Node.js ≥ 18.
# uso direto, sem instalar nada
npx dexpipe-proxy
# ou instalação global (recomendado — habilita os comandos `dexpipe` e `claudex`)
npm i -g dexpipe-proxyPara atualizar mais tarde: npm i -g dexpipe-proxy@latest.
Para conferir a versão instalada: dexpipe --version.
A instalação global registra dois comandos em qualquer terminal (PowerShell, CMD, bash/zsh, WSL, macOS, Linux, terminal integrado do VS Code — o npm gera o atalho certo para cada plataforma automaticamente):
| comando | o que é |
|---|---|
| claudex | uso diário em um comando: sobe o proxy se preciso, abre o dashboard e lança o claude já roteado pelo proxy |
| dexpipe | o CLI completo: proxy, diagnóstico, estatísticas, export, CPT |
Experimente (30 segundos)
Com a instalação global, basta um comando — em qualquer terminal:
claudexEle detecta se o proxy já está de pé em 127.0.0.1:47821 (sobe em background
se não estiver, com log em ~/.dexpipe/proxy.log), abre o dashboard no seu
navegador e entrega o terminal ao claude com ANTHROPIC_BASE_URL já
apontado para o proxy. Argumentos extras vão direto para o claude
(ex.: claudex -c continua a última conversa). Flags próprias:
--dashboard, --no-dashboard, --proxy-only, -h.
O dashboard abre em toda execução do claudex, mesmo quando o proxy já
estava rodando. Use claudex --no-dashboard ou
DEXPIPE_NO_DASHBOARD=1 para impedir a abertura. No Windows, os processos
auxiliares do proxy e do navegador são iniciados sem criar uma janela de CMD;
somente o terminal interativo onde o Claude Code está rodando permanece aberto.
Sem instalação global (via npx), o caminho manual:
npx dexpipe-proxy # proxy em 127.0.0.1:47821
ANTHROPIC_BASE_URL=http://127.0.0.1:47821 claude # aponte o Claude Code pra eleNo PowerShell (Windows), a variável de ambiente é definida assim:
npx dexpipe-proxy
$env:ANTHROPIC_BASE_URL = "http://127.0.0.1:47821"; claudeCom a instalação global, o passo a passo manual completo (o que o claudex
automatiza):
# 1. Configure — cria ~/.config/dexpipe/config.json + mostra os passos de ativação
dexpipe init
# 2. Diagnostique — valida porta, env, config, conectividade com o upstream, render
dexpipe doctor
# 3. Suba o proxy (fica em 127.0.0.1:47821)
dexpipe start
# 4. Em outro terminal, aponte o Claude Code para o proxy
ANTHROPIC_BASE_URL=http://127.0.0.1:47821 claude # bash/zsh
$env:ANTHROPIC_BASE_URL = "http://127.0.0.1:47821"; claude # PowerShell
# 5. Acompanhe a economia acumulada, direto no terminal
dexpipe statsUso opcional com Codex / OpenAI
O mesmo processo do dexpipe atende Claude Code e Codex ao mesmo tempo. As
rotas e credenciais ficam separadas: Claude usa /v1/messages com a
Anthropic; Codex usa /v1/responses com a OpenAI. Para manter a compressão
ativa nos dois, inclua os dois IDs exatos em DEXPIPE_MODELS:
# Terminal 1 — proxy compartilhado para Fable e Codex
$env:DEXPIPE_MODELS = "claude-fable-5,gpt-5.3-codex"
dexpipe startNo Codex, adicione um provider ao arquivo ~/.codex/config.toml (no Windows,
C:\Users\<usuario>\.codex\config.toml):
model = "gpt-5.3-codex"
model_provider = "dexpipe"
[model_providers.dexpipe]
name = "DexPipe"
base_url = "http://127.0.0.1:47821/v1"
env_key = "OPENAI_API_KEY"
wire_api = "responses"Depois, inicie o Codex em outro terminal que tenha a chave da API:
$env:OPENAI_API_KEY = "sk-proj-..."
codexEm bash/zsh, os comandos equivalentes são:
DEXPIPE_MODELS=claude-fable-5,gpt-5.3-codex dexpipe start
OPENAI_API_KEY=sk-proj-... codexUse um modelo disponível no seu projeto OpenAI e repita o mesmo ID em
model e DEXPIPE_MODELS. O endpoint Responses funciona em passthrough para
modelos fora da allowlist, mas eles não são imageados. Se
DEXPIPE_MODELS contiver apenas o modelo GPT, o Fable continua funcionando,
porém passa como texto sem compressão; inclua claude-fable-5 para preservar
os dois caminhos.
Cobrança: esse provider usa
OPENAI_API_KEYe consumo da API OpenAI. O login do Codex por assinatura ChatGPT não é automaticamente reutilizado pelo proxy. No Codex Desktop, reinicie o aplicativo após alterarconfig.tomle garanta que o processo recebaOPENAI_API_KEY.
Confirme no dashboard em http://127.0.0.1:47821/ que as requisições Codex
aparecem com o caminho /v1/responses. Para testar primeiro sem transformação,
inicie o proxy com DEXPIPE_MODELS=off; depois habilite o modelo exato.
Sem chave de licença, sem código de ativação — o dexpipe é MIT. Guia completo de uso: docs/COMO_USAR.md.
Dashboard em http://127.0.0.1:47821/: tokens economizados, cada conversão texto→imagem lado a lado, kill switch, chips de modelo ao vivo e o painel de decisões do gate (RFC-001a) — cada bloco aceito ou rejeitado, com o motivo. As respostas fazem streaming normal — o dexpipe comprime só a requisição, nunca a saída do modelo. Turnos recentes ficam em texto; o system prompt, as docs de tools e o histórico antigo volumoso são imageados.
Desde a v0.11.3, a prévia informa por PNG os caracteres renderizados, a
estimativa de tokens de visão, a densidade em caracteres/token e o tamanho do
factsheet de identificadores exatos. Esses números também são agregados no
JSONL sem persistir o texto da imagem. No cartão de quota, percentuais semanais
continuam sendo os valores oficiais reportados nos headers da Anthropic. Os
rótulos seguem o painel /usage do Claude: Sessão atual, Todos os modelos
e Fable (bucket 7d_oi).
Desde a v0.11.5, o cabeçalho do dashboard ocupa duas faixas compactas: na
primeira ficam marca, restauração, tema e compressão; na segunda, os modelos
Claude e GPT que podem ser imageados. Os textos auxiliares completos aparecem
ao passar o mouse sobre os avisos curtos. Os chips alteram somente o escopo do
processo em execução; use DEXPIPE_MODELS para persistir a seleção. O botão
Restaurar DexPipe limpa apenas a telemetria local, religa a compressão e
volta o escopo runtime ao padrão seguro, somente claude-fable-5; ele não
altera nem apaga a quota real informada pela Anthropic.
Métricas ao vivo: o dashboard é o benchmark
Dois painéis no topo do dashboard transformam a alegação de economia em algo
auditável enquanto você trabalha — os mesmos acumuladores do
/api/stats.json, sem conta refeita no cliente:
Savings em tempo real — gasto real vs. baseline contrafactual. Para cada
requisição com usage, o dexpipe mede um contrafactual gratuito: quanto a
mesma requisição custaria sem o proxy, via probe de count_tokens e
baseline cache-aware (detalhes em
docs/CACHING_AND_SAVINGS.md). O painel mostra
os dois lados em tokens-equivalentes (input × 1 + output × 5 — as unidades
que o limite semanal da Anthropic realmente mede) e em dólares no preço
assumido de tabela. O número-título é saved_pct_of_all_spend: Σ economizado
÷ conta contrafactual total, com TODAS as linhas pagas no denominador —
passthrough, probe-failed e turnos que o gate recusou incluídos. Isso
responde "o dexpipe moveu minha conta real?", não "ele ajudou nas linhas em
que rodou?" (a segunda pergunta é cherry-pick). O número pode ficar
negativo quando flap de cache em turnos passthrough supera o ganho do
colapso — o painel mostra isso em vez de esconder.
Cache hits ao longo do tempo. Uma barra por janela de 5 minutos (o mesmo
TTL do prompt cache da Anthropic, então uma barra ≈ uma janela de cache);
altura = % de requisições da janela que leram cache morno. "Hit" é
observado no servidor (cache_read_tokens > 0 na resposta real — o mesmo
predicado da coluna "Cache hits" da tabela de recentes), nunca inferido.
Série de 24h no JSON (cache_hit_series), últimas 4h no gráfico. Quedas
súbitas de taxa são o sintoma clássico de flap de prefixo (algo mudou no
início do contexto e invalidou o cache) — cruze com o painel de decisões do
gate para achar o culpado.
Ambos os painéis sobrevivem a restart: o estado é reconstruído do
~/.dexpipe/events.jsonl pelos mesmos caminhos de código do modo ao vivo,
então números restaurados e números ao vivo nunca divergem.
Comandos e variáveis essenciais
CLI
| comando | para que serve |
|---|---|
| claudex | tudo-em-um: garante o proxy de pé, abre o dashboard e lança o claude pelo proxy |
| claudex --proxy-only | só garante proxy + dashboard, sem lançar o claude |
| claudex --no-dashboard | como claudex, mas nunca abre o navegador (env: DEXPIPE_NO_DASHBOARD=1) |
| dexpipe | sobe o proxy local; equivalente ao uso sem subcomando |
| dexpipe start | sobe o proxy em 127.0.0.1:47821 |
| dexpipe init | cria ~/.config/dexpipe/config.json sem sobrescrever arquivo existente |
| dexpipe doctor | valida porta, ambiente, config, upstream, render e Fidelity Probe local |
| dexpipe stats | mostra economia acumulada no terminal a partir de events.jsonl |
| dexpipe export [...] | renderiza arquivos/diff em PNGs e gera relatório de custo; use dexpipe export --help |
| dexpipe cpt | ajusta chars-per-token a partir da telemetria gravada |
| dexpipe cpt --dry-run | calcula o ajuste CPT sem gravar estado |
| dexpipe cpt --show | mostra o estado CPT aprendido |
| dexpipe --version | mostra a versão instalada |
Modelos: DEXPIPE_MODELS
DEXPIPE_MODELS é a variável mais importante depois do ANTHROPIC_BASE_URL.
Ela define quais bases de modelo podem ser imageadas. Se o modelo não estiver
nessa lista, o dexpipe deixa a requisição passar como texto normal.
# padrão recomendado: só Fable 5
DEXPIPE_MODELS=claude-fable-5 dexpipe start
# habilitar um modelo Anthropic extra
DEXPIPE_MODELS=claude-fable-5,claude-opus-4-8 dexpipe start
# habilitar o caminho GPT/Sol opt-in
DEXPIPE_MODELS=claude-fable-5,gpt-5.6-sol dexpipe start
# desligar todo imageamento, mantendo o proxy como passthrough
DEXPIPE_MODELS=off dexpipe startNo PowerShell:
$env:DEXPIPE_MODELS = "claude-fable-5,gpt-5.6-sol"; dexpipe startPara persistir sem depender do terminal, use dexpipe init e edite
~/.config/dexpipe/config.json:
{
"models": ["claude-fable-5", "gpt-5.6-sol"]
}Os chips de modelo no dashboard mudam o escopo ao vivo, mas só em memória:
reiniciar o proxy volta para DEXPIPE_MODELS ou para config.json.
Variáveis de ambiente essenciais
| variável | uso |
|---|---|
| ANTHROPIC_BASE_URL=http://127.0.0.1:47821 | aponta Claude Code para o proxy |
| OPENAI_BASE_URL=http://127.0.0.1:47821/v1 | aponta clientes OpenAI-compatíveis para o proxy |
| PORT=47821 | muda a porta local |
| HOST=127.0.0.1 | interface de bind; mantenha loopback por segurança |
| DEXPIPE_MODELS=claude-fable-5 | controla a allowlist de modelos imageáveis |
| DEXPIPE_CONFIG=... | muda o caminho do config.json |
| DEXPIPE_LOG=... | muda o caminho de events.jsonl |
| DEXPIPE_DUMP_DIR=... | debug: grava PNGs renderizados no disco |
| DEXPIPE_RENDER_CACHE_DISK=on | ativa cache persistente de render em disco |
| DEXPIPE_ADAPTIVE_CPT_ONLINE=on | ativa atualização CPT incremental opt-in |
Suporte por modelo e provedor
O alvo principal do dexpipe continua sendo Claude Fable 5. Ele é o único modelo habilitado por padrão porque é o perfil com melhor evidência no projeto para leitura de páginas densas de contexto:
DEXPIPE_MODELS=claude-fable-5Outros modelos da Anthropic podem funcionar tecnicamente, mas são opt-in. O proxy falha fechado: se o modelo não estiver na allowlist, a requisição passa como texto byte-idêntico, sem tentar imagear. Isso evita aplicar compressão de imagem em modelos que aceitam a API mas leem contexto denso pior.
DEXPIPE_MODELS=claude-fable-5,claude-opus-4-8O caminho OpenAI/GPT também existe. O dexpipe reconhece /v1/chat/completions
e /v1/responses, usa blocos image_url/Responses, mantém tools em JSON
nativo e tem collapse de histórico específico para pares
function_call/function_call_output. Esses modelos também são opt-in:
DEXPIPE_MODELS=claude-fable-5,gpt-5.6-solO que foi verificado nesta implementação: rotas, transformação de payload,
allowlist, perfis de render, sidecars, fallback, planner, métricas e testes
locais para os caminhos Anthropic/OpenAI. O que não foi feito aqui: chamada
real aos provedores com chaves de API. Para isso, a Fidelity Probe expõe
modelReader, permitindo que um runner de release ou host chame o modelo real
e confirme se ele ainda lê os identificadores exatos.
A parte honesta
- É lossy (com perda). Strings hex exatas de 12 caracteres em conteúdo denso imageado: 13/15 no Fable 5, 0/15 no Opus e 0/15 no Sol — os erros são confabulações silenciosas, não avisos. Valores byte-exatos (IDs, hashes, segredos) precisam ficar em texto; turnos recentes ficam. É exatamente o gap que o Verbatim Guard fecha: identificadores críticos viajam como texto puro ao lado da imagem.
- Válvula de escape: subagentes em modelos fora da allowlist passam
direto como texto — roteie trabalho byte-exato para lá
(
CLAUDE_CODE_SUBAGENT_MODEL=claude-sonnet-4-6, oumodel: sonnetno frontmatter do agente). - Trabalho real: piloto SWE-bench Lite 10/10 nos dois braços com −65%
no tamanho das requisições; SWE-bench Pro 14/19 ON vs 15/19 OFF com
−60%, veredictos concordam em 18/19, e o único caso divergente re-resolveu
3/3 na replicação — variância entre execuções, não compressão. N pequeno;
recibos em
eval/. - Depende da carga de trabalho. Ganha em conteúdo denso em tokens (~1 caractere/token), perde dinheiro em prosa esparsa (~3,5 caracteres/token); um gate de lucratividade (calibrado em N=391 linhas de produção) só imageia onde a matemática ganha.
- Depende do cliente, não do nome do produto. A economia acompanha o
volume não-cacheado que o cliente re-envia como texto. O Claude Code
re-envia system + tools + histórico em
/anthropic/messagese tipicamente fica em ~60–70%. O Codex em/v1/responsesé suportado; quando o prompt já está ~98% emcached_tokens, só resta imagear o slab estático (e raros colapsos de histórico), então o Saved pode honestamente ficar perto de 1%. O mesmo caminho Responses economiza dezenas de pontos percentuais quando o colapso de histórico dispara, e um cliente OpenAI que re-envia a transcrição inteira como texto puro a cada turno está na mesma classe de alta economia do Claude Code. Detalhes e medições: docs/CACHING_AND_SAVINGS.md. - Escopo de modelos: padrão
DEXPIPE_MODELS=claude-fable-5. Sol, Opus 4.7/4.8 e GPT 5.5 são somente opt-in (chips do dashboard ouDEXPIPE_MODELS) — não são bons o suficiente como padrão silencioso para contexto imageado. O id exato do Sol ainda importa: variantes irmãs comogpt-5.6-terranão herdam a allowlist nem o perfil de render do Sol.DEXPIPE_MODELS=offdesliga o imageamento. Todo o resto passa byte-idêntico. No caminho GPT, as definições de tools ficam em JSON nativo e nenhum marcadorcache_controlda Anthropic é usado. A compressão de histórico do Responses reconhece paresfunction_call/function_call_outputadjacentes completos: só pares antigos fechados são imageados; os seis pares completos mais novos, toda chamada aberta e estados malformados/órfãos ficam nativos. O orçamento padrão de histórico é 32 imagens; cobertura opt-in para sessões longas pode subir (teto defensivo de 100) comDEXPIPE_GPT_HISTORY_MAX_IMAGES=48, após validar o limite de requisição do provedor. - Render por modelo: o
gpt-5.6-sol(opt-in) usa perfil Spleen 5×8 de 152 colunas; o Claude mantém o perfil Spleen 5×8 de 312 colunas. Os perfis são selecionados pelo id exato do modelo, incluindo páginas de histórico e a matemática de lucratividade. Qualidade do Sol: o 5×8 de produção marcou 98/100 em aritmética, 79/93 em gist completado, 18/18 em estado, 4/15 em confabulações de fatos nunca ditos e 0/15 em hex denso. IDs exatos, portanto, usam o factsheet verbatim, e estado recente/aberto de tools fica nativo. Recibos do Sol e evidência dos perfis.
Benchmarks (reproduzíveis)
Qualidade por modelo (o modelo lê as imagens?)
Toda linha de modelo abaixo usa a mesma receita de produção, salvo quando um braço de pesquisa puro-imagem é indicado: Spleen 5×8 + bloco IDS + factsheet textual adjacente. Os números do Claude são problemas inéditos que o modelo não pode ter memorizado. Qualidade de Sol usa o provedor Responses do Codex; Fable/Opus usam Claude. Deltas de tokens comparam braços de entrada pareados: negativo economiza tokens; positivo custa mais. A execução histórica do GSM8K mediu −38%, mas é outro corpus e não é usada nestas linhas de aritmética inédita.
| teste | modelo | N | texto | dexpipe (imagem) | tokens |
|---|---|---:|---:|---:|---|
| aritmética inédita | claude-fable-5 | 100 | 100% | 100% | não medido |
| aritmética inédita | gpt-5.6-sol | 100 | 100% | 98% | +32% |
| aritmética inédita | claude-opus-4-8 | 100 | 100% | 93% | não medido |
| A/B de gist recall (decisões, valores, paths, nomes, negações; distratores; sessões de 15k–45k chars) | Fable 5 | 98/braço | 98/98 | 98/98 | não medido |
| mesmo corpus de gist, imagens de produção + factsheet | gpt-5.6-sol | 98 | não medido | 79/93 completados; 1 erro de sessão | não medido |
| rastreamento de estado (valor mutado 3×, final/primeiro/contagem) | Fable 5 | 18/braço | 18/18 | 18/18 | não medido |
| mesmo corpus de estado | gpt-5.6-sol | 18 | não medido | 18/18 no mais recente | não medido |
| confabulação de fatos nunca ditos (menor é melhor) | Fable 5 | 16/braço | 0/16 | 0/16 | não medido |
| mesmas sondas de fatos nunca ditos (menor é melhor) | gpt-5.6-sol | 16 | não medido | 4/15 completados; 1 erro de sessão | não medido |
| hex verbatim de 12 chars, render denso | Opus | 15 | 15/15 | 0/15 | não medido |
| hex verbatim de 12 chars, render denso | Fable 5 | 15 | não medido | 13/15 | não medido |
| hex verbatim de 12 chars, mesmas páginas densas | gpt-5.6-sol | 15 | não medido | 0/15 | não medido |
Divisão de harness: as linhas de qualidade Fable/Opus e SWE-bench usam
Claude; qualidade de Sol usa o provedor Responses do Codex
(OPENAI_BASE_URL, tipicamente ocproxy).
Recibos do Sol: eval/sol-profile/QUALITY_RESULTS.md.
O SWE-bench não foi replicado no Sol: o runner é específico do Claude
Code/Fable (ANTHROPIC_BASE_URL, CLI do Claude, correção oficial via Docker),
e ainda não existe execução ON/OFF do Sol. Puro-imagem não é nível Fable
em leitores experimentais ao vivo.
Capacidade / densidade (quantos caracteres por token de visão?)
Medido renderizando a fixture densa deste repositório pelo pipeline real e precificando pixels na taxa de visão de cada família. Multiplicador = caracteres/token-de-visão medidos ÷ 4 (baseline de prosa em texto). Não é nota de qualidade de modelo.
| família | janela | como texto (@4 c/tok) | como imagens dexpipe | densidade | multiplicador |
|---|---:|---:|---:|---:|---:|
| claude-fable-5[1m] (padrão) | 1M | ~4,0M | ~18,3M | ~18,3 c/vt (px÷750) | ~4,6× |
Regenerar: npx tsx scripts/gen-context-chart.ts · PNG do gráfico:
docs/assets/context-window-chars.png.
Totais das execuções SWE-bench, recibos e ressalvas:
eval/swe-bench/ ·
eval/swe-bench-pro/ ·
eval/needle-haystack/ ·
eval/gist-recall/ ·
eval/sol-profile/ · análise em
FINDINGS.md. (O GSM8K marcou 96% imageado, mas está nos
dados de treino — respostas memorizadas sobrevivem a erros de leitura — então
lideramos com as avaliações de números inéditos.)
Como funciona
id do modelo ──► perfil de render ──► reflow do contexto volumoso ──► PNG[] + factsheet de tokens exatosO proxy intercepta /v1/messages, reescreve o volume elegível em blocos de
imagem, recoloca tudo de forma amigável ao cache (prefixo estático preservado,
prompt caching continua funcionando) e encaminha. Todo modelo habilitado
recebe a mesma pilha de produção: páginas Spleen 5×8, bloco IDS dentro da
imagem e factsheet textual adjacente. O Claude usa páginas de 1568×728; o GPT
5.6 Sol usa tiras retrato de 768 px de largura. Um estimador por requisição usa
esse mesmo perfil resolvido, então prosa esparsa fica em texto. Eventos logam em
~/.dexpipe/events.jsonl.
Etapas do pipeline
- Aplicabilidade e allowlist de modelo. O proxy identifica rota, provedor
e modelo. Fable 5 é padrão; outros modelos Anthropic e GPT/Sol só são
comprimidos quando
DEXPIPE_MODELShabilita explicitamente. - Análise de segurança. Secret Guard procura credenciais e bloqueia imageamento de blocos sensíveis. Logs, dashboard, erros 4xx, recoverable data e cache persistente evitam armazenar secrets.
- Análise de precisão. Verbatim Guard extrai IDs, SHAs, paths, URLs,
portas, UUIDs e números críticos para sidecars por página. Se algum
identificador ficaria fora do sidecar (
dropped > 0), o bloco não é imageado. - Gate de economia. O gate compara custo estimado do texto contra custo de imagem. Adaptive CPT pode ajustar chars-per-token por workload, primeiro por regressão offline e depois por EWMA online opt-in.
- Decision Engine.
CompressionDecisioné criado antes da execução e comanda se o bloco será texto, imagem ou passthrough. Isso centraliza o motivo técnico da decisão. - Execution Plan. Cada decisão executada vira uma etapa auditável: escopo, estratégia, motivo, páginas, sidecars, fallback e intenção de cache. O tracker persiste uma forma compacta sem conteúdo bruto.
- Render e fallback. O texto elegível é reflowed, renderizado em PNG e acompanhado do sidecar da página. Se o sidecar estoura, o pipeline tenta páginas menores antes de cair para texto integral.
- Cache e recuperação. Render Cache evita rerenderizar páginas iguais em memória e, opcionalmente, em disco. Recoverable Store permite guardar originais imageados com TTL, limite de espaço, hash e bloqueio de secrets.
- Medição e dashboard. Eventos registram economia, decisões, planos,
cache, fallbacks, segurança e contadores de fidelidade para
dexpipe statse dashboard. - Sondas de fidelidade.
dexpipe doctorroda uma probe local de render. Runners externos podem plugarmodelReaderpara readback real dos modelos.
Verbatim Guard: SHAs nunca viram pixels
A leitura de imagem é lossy, e falha em silêncio: um modelo que lê errado um SHA de commit numa página densa confabula um valor de aparência plausível em vez de sinalizar a falha. Para identificadores de redundância zero (SHAs, UUIDs, IPs, portas, frames de stack trace, endereços de memória), quase certo é pior que inútil.
O Verbatim Guard fecha esse gap: antes de qualquer bloco ser rasterizado,
todo identificador crítico de precisão é extraído para sidecars por página
que viajam ao lado da imagem correspondente — o volume mantém o desconto de
tokens de imagem (~5% dos caracteres da fonte vão para sidecars), os
identificadores permanecem texto byte-exato, e nenhum bloco é imageado se
algum identificador crítico ficar fora do orçamento (dropped > 0). Quando
uma página estoura, o pipeline tenta páginas menores antes de cair para texto.
Um bloco IDS rotulado também é renderizado dentro do PNG como defesa em
profundidade. Roda automaticamente em todo caminho imageado; também disponível
como biblioteca:
import { guardVerbatim } from "dexpipe-proxy/verbatim-guard";
const { sidecar, entries, dropped } = guardVerbatim(textoVolumoso);O dexpipe estende o motor de fact-sheet original com IPv4/IPv6 (mantidos
inteiros, porta opcional), literais hex 0x e frames de stack trace com
linha:coluna intactos. Escrita completa:
docs/VERBATIM_GUARD.md.
Uso como biblioteca (sem proxy)
import { renderTextToImages, transformAnthropicMessages } from "dexpipe-proxy";
const { pages } = await renderTextToImages(toolResultText); // pages[i].png: Uint8Array
const { body, applied, info } = await transformAnthropicMessages({
body: requestBytes,
model: "claude-fable-5",
});options.keepSharp(block) fixa blocos como texto; options.emitRecoverable
retorna os originais dos blocos imageados. Runtime JS puro (Node e
edge/Workers); @napi-rs/canvas é só de build. API completa:
src/core/index.ts.
Desenvolvimento
pnpm install && pnpm test
pnpm run build # regenera dist/FAQ
O número de destaque é de ponta a ponta ou só das requisições tocadas? De ponta a ponta, a conta inteira. A maioria das ferramentas de compressão reporta economia só na fatia de entrada que tocou, o que infla o número. O denominador de ponta a ponta é toda requisição de produção: as pequenas que o dexpipe corretamente deixou intactas, todas as escritas e leituras de cache, e todos os tokens de saída (que o proxy nunca comprime). Num snapshot de 13.709 requisições deu 59% (US$ 100 → ~US$ 41); um traço posterior de 8.904 requisições comprimidas mediu ~70%. Só-comprimidas dá mais (~72–74%) e é citado separadamente, nunca como destaque. O número exato depende da carga — reproduza no seu próprio log.
Como a matemática é medida?
Os dois lados da mesma requisição, no mesmo instante. Para todo POST em
/v1/messages, o proxy dispara uma sonda gratuita de count_tokens no corpo
original sem compressão (o contrafactual) em paralelo com o encaminhamento
real, e lê o bloco de uso efetivamente cobrado pela Anthropic na resposta. Os
dois caem na mesma linha de ~/.dexpipe/events.jsonl, então não há confusão
de contagem de turnos nem entre execuções. A conversão em dólar usa as razões
de tabela do Fable 5: entrada ×1,0, escrita de cache ×1,25, leitura de cache
×0,1, saída ×5. O preço de cache é aplicado identicamente aos dois lados,
então o desconto de cache se cancela e não pode ser contado duas vezes como
"economia". Re-derive você mesmo a partir do log de eventos: a fórmula e os
nomes dos campos estão documentados em src/core/baseline.ts.
O que ele comprime, na prática? Três tipos de blocos de entrada, cada um atrás de um gate de lucratividade:
- corpos grandes de
tool_result(leituras de arquivo, saída de comandos, logs) acima de ~6 mil caracteres de conteúdo denso em tokens - histórico antigo colapsado: turnos atrás da cauda viva são re-renderizados como páginas de imagem; turnos recentes sempre ficam em texto
- o slab estático de system prompt + docs de tools
Todo o resto passa byte-idêntico: suas mensagens, turnos recentes, a saída do modelo (é a resposta — o proxy nunca a toca), prosa esparsa e qualquer coisa pequena demais para valer a pena. O Fable 5 é o único padrão embutido. Sol, Opus e GPT 5.5 seguem como opt-ins explícitos. A execução 5×8 de produção do Sol marcou 98/100 em aritmética, 79/93 em gist completado, 18/18 em estado, 4/15 em confabulações de fatos nunca ditos e 0/15 em hex denso.
Já falhou de verdade, fora dos benchmarks? Sim, uma vez em semanas de uso diário: o modelo recuperou o nome de uma pessoa do histórico de chat imageado e errou com confiança. Sem erro, só um nome plausível e errado. Esse é o modo de falha documentado: strings exatas em conteúdo imageado não são byte-seguras. Sessões de código toleram isso porque o agente relê os arquivos antes de editar; recall de chat puro não tem essa checagem. Esse modo de falha é medido, não anedótico: a auditoria de legibilidade quantifica o recall de strings exatas em páginas renderizadas (leituras cegas param em 63% em identificadores densos, com cada erro previsto por uma matriz de confusão de glifos) e documenta as mitigações entregues — geometria de página grampeada no teto de resample da API para os pixels cobrados realmente chegarem ao encoder de visão, e identificadores exatos (SHAs, números) viajando ao lado como texto.
Por que os erros são confabulações silenciosas em vez de erros de leitura? Porque a visão do modelo não é OCR: a imagem vira embeddings de patches, nunca caracteres discretos, então não existe confiança por glifo para falhar com barulho. Quando os pixels subdeterminam um glifo, o prior de linguagem preenche a lacuna com algo plausível. Mecanismo e recibos: docs/NOT-OCR.md.
O DeepSeek-OCR não mostrou que isso não se sustenta na prática? Não: ele provou que o canal funciona, usando um par encoder/decoder treinado para a tarefa. O ceticismo data de outubro de 2025, quando nenhum modelo de produção de prateleira lia renders densos; isso mudou com o Fable 5 (0/15 em hex verbatim no Opus 4.8 vs 13/15 no Fable 5, mesmas páginas). Linha do tempo e números por modelo: docs/NOT-OCR.md.
Por que o README parece escrito por uma IA? Porque foi. A maioria dos commits deste repositório — código e docs — foi autorada por sessões de agente Opus/Fable rodando atrás do próprio dexpipe, lendo o próprio histórico colapsado como páginas de imagem enquanto trabalhavam.
Limitações
- Lossy (acima); recall verbatim de imagens não é confiável.
- A codificação PNG adiciona latência a requisições grandes antes da saída.
- ASCII/Latin-1 bem testados; CJK funciona, mas de forma conservadora.
Estado do projeto
Disponível hoje
- Decision Engine executável:
CompressionDecisioné criado antes da execução e usado para comandar os caminhos principais de compressão, em vez de apenas registrar o que o gate já decidiu. - Execution Plan auditável: cada bloco processado registra uma etapa imutável com escopo, estratégia, motivo, páginas, sidecars, fallback e intenção de cache. O tracker persiste uma versão compacta, sem conteúdo bruto.
- Verbatim Guard forte: identificadores críticos viajam em sidecars por
página;
dropped > 0bloqueia imageamento; o fallback tenta páginas menores antes de manter tudo em texto. - Secret Guard em superfícies principais: render, logs de eventos, dashboard, erros 4xx e dados recuperáveis passam por redaction ou bloqueio para reduzir vazamento acidental.
- Fidelity Probe no
doctor: uma sonda local valida que os perfis de renderização ainda geram PNGs legíveis estruturalmente, sem glyph drops e sem perda de sidecar. Hosts e runners de release também podem plugar ummodelReaderpara readback real de modelo sobre identificadores exatos. - Render Cache em memória e disco opt-in: cache determinístico de render
dentro do processo; a camada persistente em disco é opcional
(
DEXPIPE_RENDER_CACHE_DISK=on) e recusa entradas com secrets. - Recoverable Store opcional: além de
emitRecoverable, hosts podem persistir originais imageados em storage local com TTL, limite de espaço, hash de integridade, permissões restritas e bloqueio para secrets. - Métricas operacionais:
statse dashboard expõem decisões, plano de execução, páginas, sidecars, fallbacks e blocos mantidos em texto por segurança. - Adaptive CPT offline + incremental: além do ajuste por regressão offline,
a API expõe atualização EWMA conservadora para nudges online a partir de
eventos com baseline confiável e bucket dominante. No host Node, o wiring
operacional é opt-in por
DEXPIPE_ADAPTIVE_CPT_ONLINE=one só atualiza estados já criados pordexpipe cpt. - Analyzer Framework e Render Planner base: Safety, Fidelity,
Profitability, Cache e Risk têm interface comum; o planner conhece as
estratégias atuais (
TEXT,IMAGE,MULTI_PAGE,PASSTHROUGH) e mantémHYBRID/PARTIAL_IMAGEexplícitas como futuras, ainda sem execução. - Classificador de risco em observação: conteúdo é classificado como semântico, estruturado, exato, secreto ou desconhecido para orientar o planner sem alterar sozinho decisões de produção.
Experimental
- Adaptive CPT incremental: disponível e ligado no host Node como opt-in; ainda deve ser acompanhado em observação antes de virar padrão.
- Analyzer/Planner: a base pública existe, mas a integração completa do pipeline ainda é incremental; hoje o pipeline continua usando as mesmas regras explícitas enquanto o planner fornece contrato estável para evolução.
- Fidelity Probe: útil como canário de release/doctor e já aceita readback real via host, mas ainda não substitui uma avaliação completa de tarefas longas.
- Execution Plan: já guia e audita os caminhos principais, mas ainda não é um planner central com todas as estratégias futuras.
Planejado
- Runner periódico da Fidelity Probe: automatizar chamadas reais aos provedores em releases/auditorias e registrar regressões por modelo.
PARTIAL_IMAGEeHYBRIDexecutáveis: comprimir a parte semântica e manter trechos exatos em texto, com testes de economia e segurança antes de habilitar no pipeline.
Impacto na redução de tokens
As melhorias recentes não são só organização interna. Elas aumentam ou preservam economia de forma concreta:
- Sidecar por página +
dropped === 0: mantém identificadores exatos em texto sem desistir de imagear o restante do bloco. - Fallback para páginas menores: recupera casos que antes cairiam cedo demais para texto integral.
- Adaptive CPT: ajusta o gate ao workload real, imageando mais quando o texto está caro e evitando imagem quando a economia não fecha.
- Render Cache persistente: não reduz tokens diretamente, mas reduz CPU e latência para contexto repetido, tornando a compressão mais prática em uso contínuo.
- Fidelity Probe: evita manter modelo habilitado quando a leitura de imagem regrediu, protegendo a economia contra erro silencioso.
- Analyzer Framework / Planner: prepara estratégias futuras como
PARTIAL_IMAGE, que tende a economizar mais ao imagear conteúdo semântico e manter apenas trechos exatos em texto.
Roadmap
A pesquisa de renderização está pausada desde 2026-07-05: erros de leitura verbatim são limitados por capacidade, não por truque, então nenhuma mudança de fonte/cor/layout conserta o recall de strings exatas em densidade lucrativa. O porquê está em docs/NOT-OCR.md; a análise datada e as três linhas de investigação documentadas (A/B de estilo de glifo com páginas bancadas, canário de runtime + re-busca, pré-voo com leitor substituto) estão em FINDINGS.md, entrada de 2026-07-05. Condição de vigília: repetir a varredura de resolução a cada lançamento de modelo; a densidade legível moveu ~4× em área de glifo do Opus 4.8 para o Fable 5, e um modelo que leia células de produção perto de 100% significa economia subindo de graça.
Segue em aberto, inalterado: se volume imageado estica o contexto efetivo (~2× o conteúdo real na mesma janela de 1M), e se um contexto ativo menor melhora a precisão em tarefas longas. Hipóteses, não afirmações — ou saem como números com um n, ou são cortadas.
Créditos
O dexpipe é um fork do pxpipe de teamchong (MIT) — o proxy de compressão visual, o motor do fact-sheet verbatim, os benchmarks e as escritas honestas de limitações se originam todos lá. Todo o crédito e agradecimento aos autores originais.
Todo o trabalho do fork dexpipe é de Ricardo Soares:
- Verbatim Guard — nomear o mecanismo, a API pública e as extensões de
cobertura (IPv4/IPv6 inteiros, literais
0x, frames de stack trace comlinha:colunaintactos). Ver docs/VERBATIM_GUARD.md para a história completa. - CLI
init/doctor/start/stats. - RFC-001a (CompressionDecision) — decisões estruturadas antes da execução, usadas para comandar o pipeline, auditar motivos e alimentar o painel de decisões no dashboard.
- RFC-001b — golden tests de replay do gate sobre tráfego gravado.
- Execution Plan — plano auditável de execução por bloco, incluindo páginas, sidecars, fallback e intenção de cache.
- Secret Guard — bloqueio/redaction de credenciais nas superfícies principais: render, logs, dashboard, erros e dados recuperáveis.
- Render Cache determinístico — cache em memória e camada persistente opt-in em disco, com recusa de entradas com secrets.
- Recoverable Store — armazenamento local opcional de originais imageados com TTL, limite de espaço, hash e permissões restritas.
- Fidelity Probe — sonda local no
doctore interfacemodelReaderpara readback real por modelo em runners externos. - Adaptive CPT — ajuste por-sistema de chars-per-token via OLS e atualização incremental EWMA opt-in no host Node.
- Analyzer Framework e Render Planner base — analyzers de Safety, Fidelity, Profitability, Cache e Risk, mais planner para estratégias atuais e futuras.
- Fail-open global — falhas internas do proxy preservam a requisição original em vez de interromper o cliente.
- Compatibilidade Windows, dashboard e documentação em português (pt-BR).
Copyright © 2026 Ricardo Soares. Todos os direitos reservados sobre as contribuições do fork, licenciadas sob MIT.
Licença
MIT. Copyright © 2026 Ricardo Soares (contribuições do dexpipe) e os contribuidores originais do pxpipe. Veja LICENSE.
