MÓDULO 3.2

🧠 Memória e contexto

A avalanche diária — mensagens, e-mails, reuniões, commits — vira contexto útil para o LLM porque atravessa uma pipeline cuidadosa: comprimir, resumir, indexar, recuperar. Sem essa engenharia, qualquer agente quebra na primeira semana.

6
Tópicos
55
Minutos
Intermed.
Nível
Teoria+
Tipo
1

🗺️ Arquitetura da memória

A memória do OpenHuman não é um banco — é uma cadeia de domínios Rust que cooperam. Cada etapa tem uma responsabilidade nítida e pode ser depurada em isolamento.

Domínios envolvidos

memory          ← coordenação
memory_queue    ← fila de ingest
memory_tree     ← chunks + summaries hierárquicos
memory_store    ← persistência
memory_entities ← canonização (pessoa, projeto, etc.)
memory_graph    ← relações entre entidades
memory_sync     ← reconciliação
memory_archivist← housekeeping
embeddings      ← vetores
tokenjuice      ← compressão pré-LLM

🔄 Pipeline em uma frase

Mensagem chega → TokenJuice comprime → tree summarizer cria chunks e nós de resumo → embeddings indexam → store persiste → entities ligam o conteúdo a "Maria", "Projeto X" → fica pronto para recall.

CHAVE
Pipeline de domínios
CHAVE
Memory tree
CHAVE
Entities canônicas
CHAVE
Recall barato
2

💤 Subconscious — o loop de fundo

O subconscious é o motor que faz o agente continuar pensando depois que você fechou o chat. A cada tick (mínimo 5 min), ele carrega tarefas pendentes, avalia uma a uma com o modelo local, e decide: skip, act ou escalate.

1

Heartbeat dispara

Timer roda; se o tick anterior ainda está em execução, o novo assume e cancela o antigo. Ticks nunca empilham.

2

Engine monta situação

Combina memória + estado do workspace dentro do context budget e passa para o modelo local avaliar.

3

Decisão por tarefa

Skip = log "nada novo". Act = executa (local ou cloud). Escalate = handoff para agente cloud (com gate de aprovação se write inesperado).

4

Activity log registra

Cada avaliação aparece em Intelligence → Subconscious com cor (azul, verde, cinza, âmbar, coral) e status.

✓ Quando aprovação NÃO é precisa

  • Tarefa write-intent ("envie digest no Slack") — você já pediu
  • Tarefa read-only que só lê e reporta
  • Skip — não faz nada

✗ Quando aprovação É precisa

  • Tarefa read-only descobre algo e quer escrever sem você pedir
  • Escalation para cloud com write não solicitado
  • Caso vire card amber em "Approval Needed"

💡 Dica prática

Estenda as system tasks listando uma por linha em HEARTBEAT.md no workspace. Não precisa redeploy.

CHAVE
Heartbeat
CHAVE
Skip/Act/Escalate
CHAVE
Approval gate
CHAVE
Local + cloud
3

🌳 Tree summarizer

O memory tree resolve um problema clássico: como recuperar contexto sem despejar tudo no prompt. A solução é uma árvore de resumos — folhas com chunks brutos, nós intermediários com resumos, raiz com visão global.

Estrutura conceitual

[Root summary]
    │
    ├── [Source: Slack]
    │       ├── [Channel: #produto]
    │       │      ├── chunk (mensagem bruta)
    │       │      └── chunk
    │       └── [Channel: #engenharia]
    │              └── chunk
    └── [Source: Gmail]
            ├── [Thread: lançamento Q1]
            │      ├── chunk
            │      └── chunk
            └── [Thread: contrato cliente Y]
                   └── chunk

📊 Por que árvore (e não lista plana)

  • Granularidade adaptativa: o agente puxa só o galho necessário
  • Recall top-down: resume → desce → resume → desce
  • Custo controlado: não embed-a o universo inteiro toda hora
  • Atualização local: mensagem nova invalida só o ramo dela
CHAVE
Chunks folha
CHAVE
Summary nodes
CHAVE
Top-down recall
CHAVE
Invalidação local
4

🧮 Embeddings e busca semântica

Cada chunk vira um vetor. Quando o agente quer "tudo sobre o lançamento de Q1", ele compara o vetor da pergunta contra os vetores dos chunks e ranqueia por similaridade. Isso é recall semântico. Já search é keyword pura.

Tools expostas via MCP / JSON-RPC

memory.search       → keyword (FTS-style)
memory.recall       → semântico (vetor)
tree.read_chunk     → ler 1 chunk pelo id
tree.browse         → listar com filtros (source, entity, tempo)
tree.top_entities   → entidades mais referenciadas
tree.list_sources   → fontes ingeridas + contagens

✓ Use recall quando

  • Conceito difuso ("clima do time esta semana")
  • Idiomas misturados, sinônimos importam
  • Pergunta longa em linguagem natural

✗ Recall NÃO é mágica

  • ID, número de pedido, código exato → use search
  • Filtro temporal duro → use browse com since_ms
  • Top-k grande não compensa qualidade ruim
CHAVE
Vetor por chunk
CHAVE
Recall vs search
CHAVE
Top-k
CHAVE
Browse com filtros
5

💬 Threads vs conversations

Pós-unificação /chat, a unidade canônica de diálogo é thread. Conversations legadas, agentes separados, accounts em rotas próprias — tudo foi absorvido em uma única superfície.

Modelo de uma thread

  • Mensagens ordenadas
  • Participantes (humanos + agente)
  • Canal de origem (Slack, e-mail, web)
  • Contexto vinculado (chunks de memória)
  • Estado (ativa, arquivada)

O que NÃO existe mais

  • • Rota /conversations
  • • Rota /accounts (virou parte de /chat)
  • • Rota /agents
  • • Rota /login ou /mnemonic

💡 Dica prática

Se você ainda vê referências a "conversation" no código frontend, é dívida. O store novo é thread (em app/src/store/).

CHAVE
Thread canônica
CHAVE
/chat unificado
CHAVE
Origem do canal
CHAVE
Contexto ligado
6

🧃 Token compression (TokenJuice)

TokenJuice é o que torna economicamente viável processar 6 meses de e-mail. Roda no caminho de execução de tools, comprime a saída antes de entrar no LLM, e usa regras JSON sobrepostas em 3 camadas.

Camadas de regra (later wins)

1. Builtin   ← shipped com o binário (git, npm, cargo, docker, kubectl)
2. User      ← ~/.config/tokenjuice/rules/   (overrides pessoais)
3. Project   ← .tokenjuice/rules/            (overrides do repo)

📊 Estratégias de redução

  • truncate — cortar após N linhas / N tokens
  • dedup lines — eliminar repetições
  • fold whitespace — colapsar espaços/quebras
  • drop regex — remover linhas que casam pattern
  • summarize sections — agrupar e resumir blocos

Debug — ver o que está casando

RUST_LOG=openhuman_core::openhuman::tokenjuice=debug \
  ./target/debug/openhuman-core serve

Mostra qual regra matchou cada tool call e quanto da saída foi cortado.

💡 Dica prática

Quando um git status em monorepo enche o contexto, escreva uma regra de projeto cortando paths irrelevantes. ROI imediato em $ e em qualidade da resposta.

CHAVE
3 camadas
CHAVE
Classify→reduce
CHAVE
JSON, sem recompile
CHAVE
Custo << sem ele

🧠 Resumo do módulo

Pipeline de domínios — memory + memory_tree + memory_store + embeddings + tokenjuice cooperam.
Subconscious pensa por você — loop de fundo decide skip/act/escalate a cada tick.
Árvore de resumos — chunks folha + summaries hierárquicos permitem recall barato.
Recall vs search — semântico para conceito difuso, keyword para ID/exato.
Thread é a unidade — pós-unificação /chat, esqueça /conversations.
TokenJuice = $$ economizado — 3 camadas de regras JSON cortam ruído antes do LLM.

Próximo módulo:

3.3 — 🧩 Skills e tools