Como a I.A guarda e busca conhecimento no nosso sistema. Regra de ouro: o tipo de armazenamento segue o tipo de pergunta que a I.A vai fazer ao dado.
| Pergunta do agente | Camada | Onde vive |
|---|---|---|
| "Qual o prazo final do filing?" · "Quantos docs faltam?" | 1 · SQL | tabelas do Supabase, via tool |
| "Me explica esse caso" · "Qual a estratégia e por quê?" | 2 · CAG | case context pack no system prompt |
| "Quais os requisitos legais de um EB2-NIW?" | 3 · RAG | pgvector (AILA · 227k chunks) |
| "O que combinamos na conversa da semana passada?" | 4 · Memória | case_agent_messages + fatos consolidados |
O que guarda: todo fato operacional — status, prazos, responsáveis, verdicts, contagens. As tabelas que já existem (cases, documents, petition_filings, client_appointments...).
Como a I.A lê: por tool (função que roda a query) via espelho do backend — nunca "de memória" e nunca por embedding. Embedding aproxima; SQL é exato.
Como se escreve: pelo fluxo normal do sistema (telas, agentes, sync). A I.A nunca é a única guardiã de um fato: se um verdict do agente importa, ele vira coluna (documents.verdict), não só texto num chunk.
Regra: fato exato → tabela. Se a resposta precisa estar certa até o último dígito (prazo, contagem), a camada é esta.
A sacada: o conhecimento de UM caso é pequeno (resumos da triagem, kickoff, threads, docs — dezenas de blocos). Cabe inteiro na janela de contexto do modelo. Então, para agentes que trabalham num caso, não buscamos "os top-5 pedaços" — entregamos o caso completo.
Como funciona o ciclo:
Hoje: o intake/chat.py já injeta os últimos N chunks do caso — é um proto-pack. A evolução é materializar o pack consolidado (1 por caso) e regenerá-lo por evento.
Ganhos: zero retrieval-miss · o agente enxerga o caso INTEIRO (conexões entre fontes) · latência menor · citação de origem preservada (cada bloco do pack tem source_type).
O que guarda: corpus grande demais para o contexto. No nosso caso: a AILA (25.197 documentos, 227k chunks com embeddings no pgvector) — e, no futuro, o próprio acervo interno se um caso acumular dezenas de transcrições longas.
Como se escreve (pipeline de ingestão): resumir/estruturar (nunca conteúdo cru/PII — COMP-04) → gerar embedding (text-embedding-3-small, 1536 dims) → upsert idempotente por (case_id, source_type) em case_knowledge_chunks / já pronto na base AILA.
Como a I.A lê: a pergunta vira embedding → busca por similaridade (top-k) → os trechos mais próximos entram no prompt com a fonte citada. Na AILA: RPC aila_search_chunks.
Limite honesto: RAG pode "não achar" o trecho certo (por isso não é a camada do caso) e não sabe contar/agregar (por isso não é a camada de fatos). É imbatível para conhecimento aberto e volumoso: requisitos legais, jurisprudência, manuais.
O que guarda: a memória episódica (o histórico: case_agent_messages, já existe) e a semântica (fatos destilados: "cliente prefere reunião de manhã", "advogado rejeitou a estratégia X em 12/08").
Como funciona a consolidação: periodicamente (ou ao fechar uma conversa), um job resume o histórico em fatos atômicos com data e origem, que são gravados numa tabela de memória e entram no case context pack (camada 2). O histórico bruto continua no banco; o agente carrega só o destilado.
Por que não um framework de memória pronto: nosso escopo é por caso e o volume é baixo — uma tabela + um job de resumo resolvem, sem dependência nova. Reavaliar só se surgirem agentes de longa duração fora do escopo de caso.
Advogado pergunta ao agente do caso: "Quais documentos faltam para o filing e tem algum requisito que a gente esqueceu?"