๐ฏ Por que usar outro modelo
Claude no loop principal, Gemini Flash no background. Divisao de papeis inteligente.
๐ง Por que Gemini Flash
Caracteristicas ideais para resumo:
- โขRapido (3-5s por sumario tipico)
- โขBarato ($0.075/1M tokens input, $0.30/1M output)
- โขJanela 1M tokens โ cabe sessoes inteiras
- โขInstrucoes simples funcionam bem (structured output)
- โขAlternativa: GPT-4o-mini, Claude Haiku, DeepSeek โ todos funcionam
๐ Lendo o JSONL da sessao
Payload do SessionEnd inclui transcript_path. Claude Code ja salva, voce so le.
๐ Preparacao do transcript
def load_transcript(path, max_tokens=50_000):
if not path.exists(): return ""
lines = []
total = 0
for line in path.read_text().splitlines():
msg = json.loads(line)
role = msg.get('role')
content = msg.get('content', '')
if role not in ('user', 'assistant') or not content:
continue
text = content if isinstance(content, str) else str(content)[:2000]
lines.append(f'[{role}] {text}')
total += len(text) // 4
if total > max_tokens:
lines.append('[... truncado ...]')
break
return '\n\n'.join(lines)๐ก Filtre tool calls ruidosos
Ler arquivo grande gera payload gigante no transcript. Filtre tool_use results que nao agregam contexto: bash exit codes, file metadata.
โ๏ธ Prompt para o Gemini
Prompt estruturado = saida previsivel. Markdown formatado para inserir direto em context.md.
๐ Prompt template
prompt = f"""Resuma essa sessao de coding em 150 palavras, no formato markdown:
## Projeto ativo
[nome]
## Decisoes tomadas
- [uma linha cada]
## Bloqueios atuais
- [se houver]
## Proximo passo
[acao concreta, uma frase]
## Hipoteses descartadas
- [para Claude nao sugerir de novo]
Regras:
- Portugues brasileiro
- Frases curtas
- Evite jargao
- Se informacao nao consta na sessao, omita o campo
Transcript:
{transcript}
"""๐ก Teste com 3-5 sessoes
Rode prompt em 5 sessoes diferentes e leia saidas. Se formato varia, ajuste prompt ate ficar reproducible.
๐พ Atualizando context.md
Output do Gemini vai direto em context.md. Proxima sessao abre atualizada.
๐ Update simples
def update_context(summary):
ctx = Path('~/.memory/context.md').expanduser()
header = f'# Contexto critico โ atualizado em {datetime.now():%Y-%m-%d %H:%M}\n\n'
ctx.write_text(header + summary + '\n')
# Ou append com timestamp (preserva historia)
def append_to_context(summary):
ctx = Path('~/.memory/context.md').expanduser()
existing = ctx.read_text() if ctx.exists() else ''
ctx.write_text(f'{existing}\n\n---\n## {datetime.now():%Y-%m-%d}\n{summary}\n')๐ก Overwrite vs append
Overwrite: contexto sempre fresco, sem historia. Append: historia preservada, mas cresce. Comeco: overwrite.
๐๏ธ Entry em long-term
Mesmo sumario tambem arquiva em long-term. Pesquisavel no futuro.
๐ Append em sessions archive
def append_session_archive(summary):
today = datetime.now().strftime('%Y-%m-%d')
archive = Path(f'~/.memory/long-term/sessions/{today}.md').expanduser()
archive.parent.mkdir(parents=True, exist_ok=True)
existing = archive.read_text() if archive.exists() else ''
archive.write_text(f'{existing}\n\n---\n## Sessao {datetime.now():%H:%M}\n{summary}')
# Resultado:
# ~/.memory/long-term/sessions/2026-04-23.md
# Multiplas sessoes do dia, separadas por ---.
# Indexavel: 'o que decidi em abril sobre webhooks?'๐ก Time-travel facil
6 meses depois: grep -r 'webhook' ~/.memory/long-term/sessions/. Retorna contexto de dias especificos.
โ ๏ธ Gotchas: JSONL grande, timeout, API key
Tres falhas comuns que anulam a automacao silenciosamente.
โ Solucoes
- โJSONL grande: truncar em 50k tokens antes de enviar
- โGemini lento: timeout 20s; se estourar, sem update
- โAPI key ausente: log em stderr, nao crash
- โResposta vazia: fallback 'sessao sem decisoes claras'
โ Armadilhas
- โHook trava esperando API infinito
- โErro de API derruba SessionEnd com exception
- โcontext.md sobrescrito com string vazia
- โCusto explodindo por transcript gigante nao-truncado
๐ Resumo do Modulo
Proximo:
6.5 โ Memoria por agente e projeto