Skip to content

CH 10 · Log de Sessão como Fonte da Verdade

Contagem de palavras~2.340 palavrasTempo~12 minPré-requisitosFluxo de mensagem do CH 09NívelConceitual

Objetivo do Capítulo

O CH 09 cobriu o "livro-razão" (sessão); este capítulo o desdobra: por que ele é a fonte da verdade da máquina inteira — o que o modelo lembra, a trajectory que você vê, a transcrição que você pode exportar, o novo branch que você pode abrir em fork, todos derivados deste único log, que por si só apenas cresce, nunca edita.

Uma Frase: Log de Sessão = Razão, Memória e Arquivo do Agent

A definição oficial de Session é direta, dividida em três pontos:

  1. Append-only: apenas adicione registros na cauda, sem modificação, sem exclusão dos antigos.
  2. Eventos tipados: cada linha não é texto de forma livre, mas um tipo de "evento" — turn/start, user/message, assistant/message, tool/result, turn/end...
  3. Fonte única da verdade: o histórico inteiro de interação do agent, este é o único que é real; todo o resto é uma projeção dele.

Conectando ao CH 09 fica bem suave: o "fluxo de mensagem" que você viu no capítulo anterior, cada step na verdade está escrevendo um evento neste logturn/start abre o turn, step/start inicia uma step, user/message registra o que você enviou, assistant/message registra o que o modelo respondeu, tool/result registra quais ferramentas rodaram, turn/end fecha o turn.

Mnemônica: o fluxo é "o que está acontecendo", o log é "o registro do que aconteceu", um-para-um entre eles.

Por Que é a "Fonte da Verdade"

Palavras oficiais:

O histórico de mensagens do modelo é derivado do log, nunca armazenado separadamente.

Significado: no dsh, não há segunda cópia do registro de conversa. Você pensa "o modelo lembra o que foi dito antes", mas o histórico que o modelo vê é projetado a partir do log; a visão de Trajectory que você vê, as transcrições que você pode exportar, os forks que você pode abrir — todos renderizados a partir deste mesmo log:

Log de sessão = fonte da verdade: tudo derivado dele (ilustração)

  • Histórico de conversa do modelo: deriveMessages() projeta o Message[] que o modelo vê a partir do log — então "o que o modelo lembra" = "o que está no log";
  • Visão de Trajectory: a timeline ASSISTANT / TOOL que você viu no CH 04, é apenas uma visualização do log;
  • Transcrição / exportação: texto completo da conversa, reproduzido a partir do log;
  • Branch de fork: cresce uma nova sessão em algum nó histórico;
  • Telemetria / estatísticas: uso de tokens, tempo gasto, computado a partir do log;
  • Arquivo de persistência: o session.jsonl.zstd em $DSH_HOME/sessions.

Por que deve ser projetado assim? Porque apenas uma fonte da verdade significa que você nunca tem "o que é mostrado na UI, o que o modelo lembra, e o que é exportado — três cópias que não batem". Outras visões são todas projeções do mesmo log, com regras consistentes, sempre consistentes.

"O Que o Modelo Vê é o Que é Registrado": O Eixo do Design

Esta é uma regra rígida no dsh, mencionada no capítulo anterior, expandida aqui:

Qualquer coisa que chegue a uma requisição de modelo deve ser reconstruível a partir do log, e o runtime verifica isso com um invariante.

Isso leva a dois corolários diretos:

  1. Para adicionar algo novo para o modelo ver, você deve adicionar um novo tipo de evento. Por exemplo, se você quer que o Agent veja um pedaço injetado de contexto, você não pode contornar o log e enfiá-lo diretamente na requisição — em vez disso, defina um novo evento de sessão, escreva-o no log, e projete-o a partir do log. Isso torna cada step rastreável, e é a garantia subjacente daquela frase da homepage "cada execução é rastreável".
  2. O log é sem perdas. Até mesmo os chunks brutos de streaming retornados pelo modelo são preservados (assistant/chunk), então a reprodução pode ser fiel token por token, e a UI pode restaurá-lo exatamente.

Uma frase: este design torna "rastreável" não um slogan, mas uma inevitabilidade arquitetural.

Uma referência cruzada rápida com o CH 04: o comando /compact que você usou para comprimir contexto, por baixo dos panos, apenas registra uma ação "eu comprimi" no log (evento compaction/*), e projeta uma forma mais refinada para o modelo a partir do log. Ele não reescreve o histórico — os eventos originais ainda estão no log, apenas a projeção que o modelo vê é rearranjada. É também por isso que o Agent "lembra" uma versão mais refinada após a compressão, mas o registro original ainda está completo.

Como é na Real: Logs de Sessão Locais

De volta à sua própria máquina — tome este computador como exemplo (depois que o CH 05 rodou headless, isto existe aqui):

C:\Users\mortal\.dsh\
├─ profiles\            ← lista de profiles (os "cards" do CH 08)
├─ sessions\            ← logs de sessão aqui
│  ├─ --E-software-workspace-DeepSeek~0020harness~0020demo--\
│  │  └─ session-307edce2-...\session.jsonl.zstd   ← o registro do headless do CH 05
│  └─ --E-software-workspace-doubaowork-DeepSeekHarnessGuide--\
│     └─ session-f417b4dd-...\session.jsonl.zstd   ← sessões usadas neste projeto
├─ storages\
├─ settings.yaml
└─ .credentials.yaml

Alguns pontos:

  • Diretórios por workspace: nomes de diretório são escapes de caminhos de workspace (espaços viram ~0020), então você pode ver de relance qual sessão foi produzida enquanto trabalhava onde;
  • Uma pasta por sessão, dentro está session.jsonl.zstd — um arquivo de persistência JSONL linha por linha append + comprimido com zstd;
  • Ecoando o "Sem agrupamento" do CH 05: esses arquivos são armazenados por workspace, mas a lista de sessões da Web UI agrupa execuções headless em Sem agrupamento — não confunda as duas dimensões;
  • Esses arquivos são o "arquivo de memória" da sessão, não os delete por aí. Delete-os, e a "memória" daquela sessão se foi de verdade.

fork: Crescendo uma Nova Sessão a partir do Log

Como o log pode ser reproduzido por inteiro, naturalmente você pode "regredir a partir de uma certa posição" — a equipe oficial chama isso de fork: clone todos os eventos antes de uma posição estável como a abertura de uma nova sessão, então siga caminhos separados. O uso é direto: quer tentar um novo caminho em algum nó histórico sem mexer na sessão original. Os detalhes de como usá-lo, vamos chegar nos capítulos práticos posteriores; por agora, apenas saiba "existe, e a razão de poder existir é precisamente que o log pode ser reproduzido por inteiro".

O que você aprendeu neste capítulo

  • [ ] Afirmar as três características do log de sessão (append-only / eventos tipados / fonte única da verdade)
  • [ ] Emparelhar o fluxo de mensagem do CH 09 com eventos do log um-para-um (turn/start, user/message, assistant/message, tool/result, turn/end)
  • [ ] Explicar "o histórico do modelo é derivado do log, nunca armazenado separadamente", e por que isso evita três cópias que não batem
  • [ ] Afirmar os dois corolários de "o que o modelo vê é o que é registrado" (adicionar coisas novas = adicionar novos tipos de evento; log sem perdas pode ser reproduzido token por token)
  • [ ] Saber onde estão os logs de sessão locais ($DSH_HOME/sessions com diretórios por workspace, session.jsonl.zstd), e a diferença com o "Sem agrupamento" da Web UI

Open Source · MIT · Community Driven