🍔 O problema: logs pesados
Abra uma sessão JSONL real e a primeira coisa que salta aos olhos é o peso. A maior parte não é conversa:
é tool_result com a saída ecoada de volta para o contexto, dumps de arquivo inteiros,
saída de comando e anexos em base64. Carregar o cru no contexto para analisá-lo é desperdício puro — você paga tokens por bytes opacos.
⚖️ De onde vem o peso
- •
tool_result— a saída de Read/Bash/Grep ecoada por inteiro de volta ao log. - •Dumps de arquivo — o conteúdo completo de cada arquivo aberto.
- •Saída de comando — stdout/stderr de tudo que rodou.
- •Anexos — imagens/arquivos em
base64(megabytes por linha).
{"type":"user","message":{"content":[{"type":"tool_result",
"content":"…3.412 linhas do arquivo inteiro ecoadas aqui…"}]}}
{"type":"user","message":{"content":[{"type":"tool_result",
"content":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUg…"}]}}
tool_result ecoado
arquivos inteiros
base64
contexto à toa
💎 O que o debloat MANTÉM
A regra do debloat é cirúrgica: guarde o que revela comportamento, jogue fora o que só pesa. O que fica é exatamente o ouro — seus prompts, o texto do assistente, o modelo que escreveu cada turno, uma linha enxuta por chamada de ferramenta, e a presença de raciocínio (marcada com 🧠, já que o texto vem cifrado nos logs).
✓ O que MANTÉM (o ouro)
- ✓Meus prompts de usuário.
- ✓O texto do assistente.
- ✓O modelo (
message.model). - ✓1 linha por
tool_use(nome + alvo curto). - ✓A PRESENÇA de raciocínio (marca 🧠).
✗ O que NÃO guarda
- ✗A saída completa da ferramenta.
- ✗O conteúdo do arquivo lido.
- ✗O texto literal do
thinking(vem cifrado).
💡 Por que só a PRESENÇA de raciocínio
O bloco thinking chega aos logs vazio/cifrado — só com a signature. Você não tem o pensamento literal, mas sabe que ele existiu. O debloat registra isso como uma marca 🧠: o suficiente para medir "pensou antes de agir?" sem inventar conteúdo.
## 👤 humano refatora o parser e roda os testes ## 🤖 claude-fable-5 🧠 Vou ler o arquivo antes de mexer. → Read parser.py → Edit parser.py → Bash pytest -q
🗑️ O que o debloat DESCARTA
O outro lado da regra: tudo que é peso sem sinal vai embora. Os payloads de tool_result,
os blobs de anexo e a contabilidade do harness — usage, uuids,
isMeta, sidechain. Nada disso muda o ritmo medido, então pode sair sem culpa.
tool_result (payload)
A saída ecoada da ferramenta. O fato de que a ferramenta rodou fica (a linha do tool_use); a saída em si, não.
Blobs de anexo
Imagens e arquivos em base64. Megabytes que não dizem nada sobre como o modelo trabalha.
Contabilidade do harness
usage (tokens), uuids, isMeta, sidechain — escrituração interna, não comportamento.
🔎 O teste mental
Para cada campo, pergunte: "isso muda a resposta de 'o modelo pensou antes? quantas ferramentas usou? em que ordem?'". Se não muda o ritmo, é gordura. Essa pergunta é toda a lógica do debloat_jsonl.py.
payload fora
blobs base64
harness
muda o ritmo?
🐍 O script debloat_jsonl.py
A teoria vira prática num único comando. Sem argumentos, o debloat_jsonl.py roda no
demo_session.jsonl que mora ao lado dele, imprime o tamanho antes/depois e abre a
transcrição limpa — exatamente o fluxo do curso para você conferir o formato na primeira vez.
# roda no demo_session.jsonl (ao lado do script) python debloat_jsonl.py # num arquivo seu, escolhendo a saída python debloat_jsonl.py minha_sessao.jsonl -o limpa.md # sem a marca de raciocínio, sem abrir o editor python debloat_jsonl.py s.jsonl --no-thinking --no-open
🎛️ As flags
- •
(sem args)— usa odemo_session.jsonle abre o resultado. - •
-o ARQUIVO— escolhe onde gravar a transcrição leve. - •
--no-thinking— omite a marca 🧠 de raciocínio. - •
--no-open— não tenta abrir no editor (útil em pipeline).
💡 Dica prática
É stdlib pura — sem dependências para instalar. Comece pelo demo para ver o formato; depois aponte para uma sessão sua em ~/.claude/projects/<projeto>/. Em automação, sempre use --no-open.
demo_session.jsonl
escolhe saída
antes/depois
stdlib pura
📉 O resultado: ~74% de redução
O número que o script imprime quase sempre surpreende: numa sessão típica, o debloat corta cerca de 74% do peso. A gordura era mesmo a maior parte do arquivo — o que resta, o ouro, cabe num arquivo pequeno e legível de cabo a rabo.
$ python debloat_jsonl.py antes: 1.84 MB depois: 0.48 MB # ~74% menor escrito em: demo_session.clean.md
💡 O que esperar
O exato % varia com quanta saída de ferramenta a sessão tinha — sessões cheias de leitura de arquivo encolhem ainda mais. Mas a faixa dos ~74% é típica: o sinal vive numa fração pequena do arquivo.
100% (cru)
~26%
~74%
o ouro
🧩 A pegadinha do schema
Ao abrir a transcrição leve pela primeira vez, um detalhe estranha: o assistente aparece em vários cabeçalhos seguidos. Não é bug. Cada bloco do assistente é uma LINHA separada no JSONL, e o debloat preserva a ordem — então um único turno de resposta vira várias entradas. É exatamente por isso que a análise (no próximo módulo) agrupa tudo em turno lógico.
## 👤 humano — o prompt## 🤖 claude-fable-5 🧠 — thinking## 🤖 claude-fable-5 — text→ Read / → Edit / → Bash — tool_use## 👤 humano — próximo prompt → fecha o turno✓ Por que está certo
- ✓Preserva a ordem real dos eventos.
- ✓Não inventa fronteiras de turno cedo demais.
- ✓Deixa o agrupamento para a análise (turno lógico).
✗ O erro comum
- ✗Achar que "5 cabeçalhos = 5 respostas".
- ✗Contar por cabeçalho infla os números.
- ✗Medir sem agrupar por prompt humano.
= 1 linha
preservada
= 1 turno
turno lógico
🧪 Resumo do Módulo
debloat_jsonl.py roda no demo por padrão — flags -o, --no-thinking, --no-open; stdlib pura.Próximo Módulo:
2.2 — Corpus, Números e o Delta Fable vs Opus