Pular para o conteúdo
MÓDULO 1.1

📂 Onde Vivem as Conversas e a Anatomia de uma Sessão

Para minerar o ouro, primeiro você precisa encontrar a mina. Neste módulo: o caminho no disco, o formato JSONL, a anatomia de um evento, os blocos de conteúdo, o campo message.model e a unidade certa de medida — o turno lógico.

6
Tópicos
25
Minutos
Básico
Nível
Teoria
Tipo
~/.claude/projects raiz dos logs <projeto>/ uma pasta por projeto 2f3a…-9c.jsonl (sessão 1) 7b1c…-4e.jsonl (sessão 2) …milhares no total
1

📁 Onde vivem os logs

Tudo começa num único lugar. O Claude Code grava cada conversa em ~/.claude/projects/<projeto>/<sessão>.jsonl: um arquivo por sessão, organizado em uma pasta por projeto. Some isso por meses de uso e você tem milhares de arquivos — uma mina inteira de comportamento, esperando para ser garimpada.

🗺️ Conceito principal

Não há banco de dados, nem servidor: é só o sistema de arquivos. Isso é uma boa notícia — você pode varrer tudo com ferramentas comuns.

  • Pasta raiz: ~/.claude/projects/
  • Uma subpasta por projeto (caminho saneado).
  • Um arquivo .jsonl por sessão.
~/.claude/projects/
├── -home-voce-projetos-fablelite/
│   ├── 2f3a…-9c.jsonl   # sessão 1
│   └── 7b1c…-4e.jsonl   # sessão 2
└── -home-voce-projetos-portal/
    └── a01d…-22.jsonl
Caminho

~/.claude/projects

Granularidade

1 arquivo = 1 sessão

Escala

milhares de arquivos

Acesso

só o filesystem

2

📜 JSONL = um evento JSON por linha

Cuidado com a armadilha: o arquivo não é um único objeto JSON gigante. JSONL significa JSON Lines — cada linha é um objeto JSON completo e independente, anexado conforme a conversa avança. É um formato de streaming, append-only.

{"type":"user","message":{...},"timestamp":"2026-06-10T14:00:01Z"}
{"type":"assistant","message":{"model":"claude-fable-5",...}}
{"type":"assistant","message":{"model":"claude-fable-5",...}}
{"type":"system","subtype":"hook",...}

✓ O que FAZER

  • Ler linha a linha (for line in f).
  • Fazer json.loads por linha.
  • Tolerar linha quebrada (pular, não abortar).

✗ O que NÃO fazer

  • json.load(arquivo_inteiro) — quebra.
  • Assumir que a última linha está completa.
  • Carregar tudo na memória de uma vez.

💡 Dica prática

Como é append-only, uma sessão interrompida ainda é legível até a última linha completa. Sempre processe defensivamente: try/except em volta do json.loads de cada linha.

Formato

JSON Lines

Escrita

append-only

Leitura

linha a linha

Robustez

tolera interrupção

3

🧬 Anatomia de um evento

Cada linha carrega um punhado de campos previsíveis. Os principais: type (user/assistant/system/summary), message (o conteúdo de fato), timestamp, uuid, cwd e gitBranch. Conhecer esses campos é o que destrava filtrar, agrupar e medir.

type

Classifica o evento: user (você), assistant (modelo), system (harness/hooks), summary (resumo de contexto).

message

O payload: role, model (só no assistente) e content (a lista de blocos).

timestamp · uuid · cwd · gitBranch

Metadados de contexto: ordem temporal, identidade do evento, diretório de trabalho e branch git. Dão o "onde" e "quando".

🔎 Por que isso importa

O timestamp ordena os turnos; o type separa quem falou; e o cwd/gitBranch ajudam a reconstruir o que estava acontecendo. Sem esses campos, o log seria texto sem estrutura.

type

quem falou

message

o conteúdo

timestamp

a ordem

cwd/branch

o contexto

4

🧱 Os blocos de conteúdo do assistente

O assistente não fala em texto corrido — fala em blocos: text (o que você lê), thinking (raciocínio), tool_use (chamada de ferramenta) e tool_result (a resposta da ferramenta). E aqui está o detalhe crucial: o Claude Code grava CADA bloco numa LINHA separada.

🧩 Os quatro blocos

  • text — a fala visível do modelo.
  • thinking — o raciocínio (cifrado nos logs — voltamos a isso no 1.2).
  • tool_use — o modelo decide chamar uma ferramenta.
  • tool_result — a saída da ferramenta volta (gordura, no 1.2).

⚠️ A pegadinha que dilui o sinal

Como cada bloco vira uma linha, contar "por linha" infla artificialmente os números. Um único turno do assistente pode virar 5 linhas (1 thinking + 1 text + 3 tool_use). Se você medir por linha, perde a noção de "quanto o modelo fez em resposta a um prompt". A correção vem no tópico 6: agrupar em turnos lógicos.

text

fala visível

thinking

raciocínio

tool_use

decisão de agir

1 bloco

= 1 linha

5

🏅 message.model — o campo de OURO

De todos os campos, um é o coração do curso: message.model. Ele diz exatamente qual modelo escreveu cada turnoclaude-fable-5, claude-opus-4-8, claude-haiku-4-5... É o que permite filtrar o log por modelo e separar o corpus de cada um.

{"type":"assistant","message":{
    "role":"assistant",
    "model":"claude-fable-5",
    "content":[ {"type":"thinking",...}, {"type":"text",...} ]
}}

📊 O que ele destrava

  • Filtrar por modelo: isolar tudo que o Fable-5 fez vs tudo que o Opus-4.8 fez.
  • Comparar: medir cada corpus separadamente e tirar o delta.
  • Atribuir: cada turno tem dono — não há ambiguidade.

💡 Dica prática

Só eventos de assistant têm model. Eventos de usuário e de sistema não. Ao agrupar em turnos lógicos, o modelo do turno é o do(s) evento(s) de assistente dentro dele.

Onde

message.model

Quem tem

só o assistente

Para quê

filtrar por modelo

Resultado

corpus por modelo

6

🔗 Turno físico (linha) vs turno lógico

A última peça antes de medir qualquer coisa: a unidade certa. Um turno físico é uma linha do arquivo. Um turno lógico é tudo entre um prompt humano e o próximo — o pensamento, o texto e todas as ferramentas que o modelo usou para responder àquele prompt.

prompt 1 turno lógico linha: thinking linha: text linha: tool_use (Read) linha: tool_use (Edit) linha: tool_use (Bash) próximo prompt

✓ Medir por turno lógico

  • "O modelo pensou antes de agir neste turno?"
  • "Quantas ferramentas usou para responder?"
  • Reflete o ritmo de trabalho real.

✗ Medir por linha física

  • Infla a contagem (5 linhas = 1 resposta).
  • Dilui a presença de raciocínio.
  • Mistura blocos de turnos diferentes.
Turno físico

1 linha

Turno lógico

prompt → prompt

Agrupa por

prompt humano

Revela

o ritmo

🪙 Resumo do Módulo

Os logs vivem em ~/.claude/projects — um arquivo .jsonl por sessão.
JSONL = um evento por linha — streaming append-only, lido linha a linha.
Cada evento tem type/message/timestamp/uuid/cwd/gitBranch — a estrutura para filtrar e medir.
O assistente fala em blocos, 1 por linha — por isso contar "por linha" dilui o sinal.
message.model é o campo de ouro — separa Fable de Opus.
O turno lógico é a unidade certa — de prompt a prompt.

Próximo Módulo:

1.2 — Gordura vs Ouro, e o Mito do Raciocínio Minerável