Phase 14 - Lesson 09

Hybrid Memory: Vector + Graph + KV (Mem0)

Mem0 (Chhikara et al., 2025) trata a memória como três armazenamentos em paralelo — vetorial para similaridade semântica, KV para busca rápida de fatos e grafo para raciocínio de entidade-relacionamento. Uma camada de pontuação funde os três na recuperação. Este é o padrão de produção de 2026 para memória externa.

Tipo: Build Linguagens: Python (stdlib) Pré-requisitos: Phase 14 · 07 (MemGPT), Phase 14 · 08 (Letta Blocks) Tempo: ~75 minutos

Objetivos de Aprendizado

  • Explicar por que um único armazenamento (apenas vetorial, apenas grafo, apenas KV) é insuficiente para a memória do agente.
  • Nomear os três armazenamentos paralelos do Mem0 e o que cada um otimiza.
  • Descrever a pontuação de fusão do Mem0 — relevância, importância, recência — e por que é uma soma ponderada, não uma hierarquia.
  • Implementar uma memória simples de três armazenamentos em stdlib com um add() que grava em todos os três e um search() que funde os resultados.

O Problema

Um único armazenamento é incorreto para uma de três classes de consulta:

  • Similaridade semântica — "o que discutimos sobre agent drift na semana passada?" O vetorial vence; KV e grafo falham.
  • Busca de fatos — "qual é o número de telefone do usuário?" O KV vence; o vetorial é um desperdício, o grafo é exagero.
  • Raciocínio de relacionamento — "quais clientes compartilham a mesma entidade de cobrança?" O grafo vence; vetorial e KV não conseguem responder.

Agentes em produção emitem todas as três classes em uma única sessão. Uma memória de armazenamento único estará sempre errada para duas delas. A contribuição do Mem0 é conectar as três sob uma única interface de add/search com uma função de pontuação que as funde.

O Conceito

Três armazenamentos em paralelo

Mem0 (arXiv:2504.19413, abril de 2025) no add(text, user_id, metadata):

  1. Extrai fatos candidatos a partir do texto (uma etapa orientada por LLM).
  2. Grava cada fato no armazenamento vetorial (embedding) para busca semântica.
  3. Grava cada fato no armazenamento KV indexado por (user_id, fact_type, entity) para busca O(1).
  4. Grava cada fato no armazenamento de grafo (Mem0g) como arestas tipadas para consultas de relacionamento.

No search(query, user_id):

  1. O armazenamento vetorial retorna os top-k pelo cosseno de embedding.
  2. O armazenamento KV retorna correspondências diretas indexadas pela consulta derivada (user_id, type, entity).
  3. O armazenamento de grafo retorna o subgrafo alcançável a partir das entidades da consulta.
  4. Uma camada de pontuação funde os três.

Pontuação de fusão

score = w_relevance * relevance(q, record)
      + w_importance * importance(record)
      + w_recency * recency(record)
  • Relevância — cosseno vetorial, correspondência exata de KV, peso de caminho de grafo.
  • Importância — marcada no momento da gravação ou aprendida (alguns fatos importam mais: nomes, IDs, políticas).
  • Recência — decaimento exponencial ao longo do tempo desde a última gravação ou leitura.

Os pesos são ajustados por produto. Maior w_recency para agentes de chat; maior w_importance para agentes de conformidade (compliance); maior w_relevance para agentes de busca.

Mem0g e raciocínio temporal

O Mem0g adiciona um detector de conflitos. Quando um novo fato contradiz uma aresta existente, a aresta existente é marcada como inválida, mas não é excluída. Consultas temporais ("qual era a cidade do usuário em março?") percorrem o subgrafo válido naquele momento.

Este é o comportamento de nível de conformidade que o padrão de invalidação do Letta generaliza.

Números de benchmark

O artigo do Mem0 relata (2025):

  • LoCoMo (memória de conversa longa): 91.6
  • LongMemEval (memória episódica de longo horizonte): 93.4
  • BEAM 1M (benchmark de memória de 1 milhão de tokens): 64.1

Linhas de base de comparação (LLM de contexto completo de 128k, armazenamento vetorial plano, KV plano) perdem por 10+ pontos. Os benchmarks por si só não justificam a escolha — o formato operacional sim —, mas os números mostram que o design de fusão não é um erro de arredondamento.

Taxonomia de escopo

O Mem0 divide a memória por escopo:

  • Memória de usuário (User memory) — persiste entre sessões, indexada em user_id.
  • Memória de sessão (Session memory) — persiste dentro de uma thread de conversa.
  • Memória de agente (Agent memory) — estado da instância por agente.

Cada gravação escolhe um escopo. A recuperação pode consultar entre escopos com pesos por escopo. Misturar escopos sem critério é a receita para incidentes do tipo "o assistente contou a Alice sobre o projeto do Bob".

Onde este padrão falha

  • Desvio de embedding (Embedding drift). Os resultados vetoriais que parecem corretos nas primeiras cem consultas degradam conforme o corpus cresce. Adicione re-embedding periódico dos top-N registros mais usados.
  • Crescimento desordenado do esquema KV (KV schema creep). (user_id, type, entity) parece simples até que cada equipe adicione seu próprio type. Faça uma auditoria do conjunto de tipos trimestralmente.
  • Explosão de grafo (Graph explosion). Um extrator ruidoso adiciona 50 arestas por mensagem. Limite as gravações de grafo por chamada add; descarte arestas de baixa confiança.

Build It

code/main.py implementa o padrão de três armazenamentos na biblioteca padrão (stdlib):

  • VectorStore — similaridade ingênua de sobreposição de tokens como um substituto para embeddings.
  • KVStore — dict indexado por (user_id, fact_type, entity).
  • GraphStore — arestas tipadas (sujeito, relação, objeto, válido).
  • Mem0 — fachada de alto nível com add(), search(), pontuação de fusão e recuperação ciente de escopo.
  • Uma simulação passo a passo de uma conversa com múltiplos usuários e sessões.

Execute:

python3 code/main.py

A saída mostra três caminhos de recuperação separados mais os top-k fundidos. Altere os pesos de pontuação no topo de main() e assista à classificação mudar.

Use It

  • Mem0 (Apache 2.0) — pronto para produção. Hospete por conta própria com Postgres + Qdrant + Neo4j, ou use a nuvem gerenciada.
  • Letta — núcleo de três níveis (core/recall/archival); traga seus próprios backends vetoriais e de grafos.
  • Zep — alternativa comercial com KG temporal e extração de fatos.
  • Builds personalizados — para quando você precisa de controle exato sobre o extrator (conformidade) ou pesos de fusão (agentes de voz onde a recência domina).

Ship It

outputs/skill-hybrid-memory.md gera uma estrutura de memória de três armazenamentos com um pontuador de fusão, taxonomia de escopo e invalidação temporal integrados.

Exercises

  1. Substitua a similaridade vetorial simulada por um modelo de embedding real (sentence-transformers, Ollama, OpenAI embeddings). Meça o recall@10 em uma conversa longa sintética. A classificação sofre desvio ao longo de 1000 gravações?
  2. Adicione uma consulta temporal: search(query, as_of=timestamp). Retorne apenas registros válidos na data/hora especificada ou antes dela. Qual armazenamento precisa de mais trabalho?
  3. Implemente um detector de conflitos: se um fato recebido contradiz uma aresta do grafo, invalide a aresta antiga e registre ambos. Teste com "usuário mora em Berlim" -> "usuário mora em Lisboa."
  4. Adapte o pontuador de fusão para incluir uma dimensão de feedback do usuário (user_feedback, ex: polegar para cima nos registros recuperados). Como evitar manipulações (ex: o agente retornar apenas registros que ele já curtiu)?
  5. Leia os documentos do Mem0 (docs.mem0.ai). Adapte a simulação para chamadas de cliente mem0. Compare a qualidade da recuperação nas mesmas 20 consultas de teste.

Key Terms

Term What people say What it actually means
Hybrid memory "Vetor mais grafo mais KV" Três armazenamentos gravados em paralelo, fundidos na recuperação
Fact extraction "Ingestão de memória" Etapa do LLM que divide o texto em tuplas (entidade, relação, fato)
Fusion scoring "Classificação de relevância" Soma ponderada de relevância, importância e recência
Scope "Namespace de memória" user / session / agent — determina quem vê o quê
Mem0g "Grafo de memória" Arestas tipadas com validade temporal para consultas de relacionamento
Temporal invalidation "Exclusão lógica (soft delete)" Marcar arestas contraditas como inválidas; nunca excluir
Embedding drift "Rot de recuperação (retrieval rot)" A qualidade do vetor degrada conforme o corpus cresce; faça re-embedding periodicamente

Further Reading

0 lifetime access. Curriculum based on AI Engineering from Scratch by Rohit Ghumare (MIT, used under attribution).