memory-v2
Servidor MCP de memória persistente inspirado no cérebro com busca híbrida BM25+vetorial, pontuação de ativação ACT-R, decaimento FadeMem e grafos de conhecimento — 17 ferramentas, totalmente local via Ollama, zero chaves de API.
Documentação
memory-v2
Memória Persistente Inspirada no Cérebro para Assistentes de Codificação com IA
Por que memory-v2?
pip install memory-v2-hx
A maioria dos sistemas de memória para IA são apenas bancos de dados com uma API de busca. memory-v2 é uma arquitetura cognitiva — ele modela como a memória humana realmente funciona.
| Recurso | memory-v2 | Arquivo plano / CLAUDE.md | Claude-brain | Zep / Graphiti |
|---|---|---|---|---|
| Busca | Híbrida BM25 + vetorial (fundida) | Nenhuma / grep | FTS5 por palavra-chave (automática) + vetorial (manual) | Vetorial + grafo |
| Ranqueamento | Ativação ACT-R (ciência cognitiva) | Nenhum | Rank FTS5 * recência | Recência + similaridade de embeddings |
| Esquecimento | Decaimento FadeMem (promoção MCP/MLP) | Nunca esquece, transborda | Nunca esquece | Expiração baseada em TTL |
| Estrutura de conhecimento | Grafo (comunidades Leiden, PPR) | Markdown plano | Tabelas planas | Grafo (Graphiti) |
| Consolidação | Compressão CogCanvas em 6 etapas | Manual | Nenhuma | Nenhuma |
| Governança | Memórias protegidas (imunes ao decaimento) | Nenhuma | Nenhuma | Nenhuma |
| Multiagente | Cadeias de autoridade, detecção de conflitos | Nenhuma | Nenhuma | Nenhuma |
| Privacidade | 100% local (Ollama, zero chaves de API) | Local | Local | Nuvem ou auto-hospedado |
| Ferramentas MCP | 17 | 0 | MCP somente leitura | Variável |
Comece a usar em 60 segundos:
# Install
pip install memory-v2
# Start the MCP server
memory-v2-server --db ~/memory.db
# Or add to Claude Code settings.json
{
"mcpServers": {
"memory": {
"command": "memory-v2-server",
"args": ["--db", "~/memory.db"]
}
}
}
Seu assistente de IA agora tem memória persistente que sobrevive a compactações, decai de forma graciosa e constrói um grafo de conhecimento enquanto você trabalha.
Resumo
memory-v2 é um sistema de memória persistente com base cognitiva, projetado para assistentes de codificação com IA que operam em fluxos de trabalho de longa duração e múltiplas sessões. Ele substitui o sistema de primeira geração claude-memory por uma reescrita completa que funde técnicas da psicologia cognitiva (teoria de ativação ACT-R, esquecimento por lei de potência), recuperação de informações (busca híbrida BM25/vetorial com Fusão de Rank Recíproco) e representação de conhecimento baseada em grafos (detecção de comunidades Leiden, Recuperação por PageRank Personalizado) em um único armazenamento baseado em SQLite.
O sistema atua como um servidor Model Context Protocol (MCP) expondo 17 ferramentas, permitindo que qualquer cliente de IA compatível com MCP — Claude Code, Claude Desktop ou agentes personalizados — armazene, busque, decaia, comprima e compartilhe memórias sem chamadas de API externas. Toda a inferência de embeddings e LLM é executada localmente por meio do Ollama, exigindo zero chaves de API e transmitindo zero dados para fora da máquina.
memory-v2 foi construído por um profissional que executou 59 ciclos de compactação no sistema v1 e decidiu que a arquitetura precisava ser repensada a partir dos primeiros princípios. O resultado é um sistema onde as memórias competem pela sobrevivência por meio de pontuações de ativação, onde o conteúdo protegido está isento de decaimento, onde múltiplos agentes coordenam por meio de cadeias de autoridade e onde um grafo de conhecimento descobre conexões que o índice de busca plano não consegue.
Sumário
- Por que memory-v2?
- Resumo
- Visão Geral da Arquitetura
- Fundamentos Teóricos
- Esquema do Banco de Dados
- Servidor MCP e Ferramentas
- Referência de Subsistemas
- Exemplos Práticos
- Instalação
- Configuração
- Uso
- Migração da v1 para a v2
- Estrutura do Repositório
- Trabalhos Relacionados
- Referências
- Construído Com
- Licença
Visão Geral da Arquitetura
+-----------------------------+
| MCP Client Layer |
| (Claude Code / Desktop / |
| any MCP-compatible agent) |
+-------------+---------------+
|
FastMCP Protocol (stdio)
|
+-------------v---------------+
| server.py (17 tools) |
| add | search | graph_search |
| extract | compact | decay |
| agent_sync | check_integrity |
+---+-----+-----+-----+------+
| | | |
+---------------+ | | +---------------+
| | | |
+----------v---------+ +------v-----v------+ +----------v---------+
| db.py | | scoring.py | | knowledge_graph.py |
| SQLite + sqlite-vec | | ACT-R activation | | NetworkX DiGraph |
| + FTS5 | | FadeMem decay | | Leiden communities |
| | | Cosine similarity | | PPR retrieval |
| memories (rows) | | | | |
| memory_fts (BM25) | | base_level_act() | | extract_entities() |
| memory_vec (768-d) | | spreading_act() | | detect_communities |
| graveyard | | importance_score()| | ppr_search() |
| agent_offsets | | decay_value() | | visualize_graph() |
| conflicts | | retrieval_prob() | | |
| compaction_receipts | | | | |
+----------+----------+ +-------------------+ +----------+---------+
| |
| +-------------------+ |
+--------------+ embeddings.py +---------------+
| Ollama |
| nomic-embed-text |
| 768-dim vectors |
| Local file cache |
+-------------------+
|
+-----------------------+-----------------------+
| | |
+----------v---------+ +---------v----------+ +---------v----------+
| extraction.py | | compaction.py | | multi_agent.py |
| 2-pass LLM pipeline| | CogCanvas 6-step | | Authority chain |
| Fact extraction | | Protected extract | | Consumer offsets |
| Novelty checking | | Selective deletion | | Conflict detection |
| Action decision | | Summary + verify | | Kafka-style sync |
+--------------------+ +--------------------+ +--------------------+
|
+----------v---------+ +--------------------+
| vault_indexer.py | | security.py |
| Markdown chunking | | 13 credential pats |
| SHA-256 delta detect| | 6 injection pats |
| Frontmatter parsing | | SHA-256 manifests |
| Incremental indexing| | Allowlist filtering |
+--------------------+ +--------------------+
A arquitetura segue um design em camadas onde o servidor MCP (server.py) atua como o único ponto de entrada para clientes de IA. Todas as 17 ferramentas delegam para subsistemas especializados. A camada de banco de dados (db.py) é dona do único arquivo SQLite, que contém três índices co-localizados: linhas relacionais em memories, busca de texto completo BM25 em memory_fts (FTS5) e embeddings vetoriais de 768 dimensões em memory_vec (sqlite-vec). A camada de pontuação aplica fórmulas de ativação cognitiva sobre os resultados da busca. O grafo de conhecimento vive em um arquivo pickle separado do NetworkX e fornece descoberta multi-saltos que o índice plano não consegue.
Toda chamada de embedding e LLM passa pelo Ollama, que roda localmente. O sistema nunca se comunica com o exterior.
Fundamentos Teóricos
Modelo de Ativação ACT-R
A estrutura Adaptive Control of Thought — Rational (ACT-R), desenvolvida por John Anderson e colegas na Carnegie Mellon, fornece a teoria central de como as memórias competem pela recuperação. A afirmação central é que a recuperação da memória humana é uma adaptação racional à estrutura estatística do ambiente: itens usados recentemente e com frequência têm maior probabilidade de serem necessários novamente (Anderson & Schooler, 1991).
memory-v2 implementa a equação de ativação ACT-R como uma camada de pontuação sobre os resultados da busca. Cada memória tem um valor de ativação que determina sua probabilidade de ser recuperada. A ativação tem três componentes: ativação de nível base (com que frequência e quão recentemente a memória foi acessada), ativação por propagação (priming contextual da consulta atual) e ruído (variação estocástica que impede comportamento determinístico).
Ativação de Nível Base
A ativação de nível base aproxima a análise racional completa usando a forma fechada otimizada:
B_i = ln(n / (1 - d)) - d * ln(L)
Onde:
n= contagem total de acessos da memóriad= parâmetro de decaimento (fixado em 0,5, o valor canônico do ACT-R)L= tempo de vida da memória em horas (tempo desde a criação)
Essa aproximação evita armazenar o histórico completo de acessos, preservando a propriedade principal: a ativação aumenta com a frequência e diminui com o tempo, seguindo uma lei de potência.
Ativação por Propagação
Tags de contexto da consulta atual ativam memórias associadas:
S_i = SUM_j [ W_j * (S_max - ln(fan_j)) ]
Onde:
W_j = 1 / |context_tags|(peso de atenção, dividido igualmente entre as fontes de contexto)S_max = 1.6(força associativa máxima)fan_j= número de memórias que compartilham a tagj(o "leque" da fonte)
A percepção principal: tags que aparecem em muitas memórias fornecem menos ativação (são menos discriminativas), enquanto tags raras fornecem mais. Este é o equivalente ACT-R da ponderação IDF.
Ruído
A ativação inclui um termo de ruído estocástico extraído da distribuição logística:
epsilon ~ Logistic(0, s) where s = 0.25
Gerado como:
epsilon = s * ln(u / (1 - u)) where u ~ Uniform(0, 1)
Esse ruído impede que o sistema se torne determinístico e permite recuperações ocasionalmente surpreendentes — uma propriedade que espelha a memória humana.
Ativação Completa e Probabilidade de Recuperação
A equação completa de ativação:
A_i = B_i + S_i + epsilon
A probabilidade de recuperação bem-sucedida dada a ativação:
P(retrieve) = 1 / (1 + exp(-(A_i - tau) / s))
Onde:
tau = -0.5(limiar de recuperação)s = 0.25(escala de ruído, igual ao parâmetro de ruído)
Esta é uma função sigmoide centrada no limiar. Memórias com ativação bem acima do limiar são quase certamente recuperadas; memórias bem abaixo são quase certamente esquecidas.
Piso protegido: Memórias marcadas como protegidas recebem um piso de ativação de tau + 1.0 = 0.5, garantindo que sejam sempre recuperáveis, independentemente da idade ou do padrão de acesso.
Re-Ranqueamento Final
Após a busca híbrida produzir uma lista ranqueada inicial, a ativação ACT-R é usada para re-ranquear:
final_score = 0.6 * hybrid_rrf_score + 0.4 * (activation / 10.0)
A ativação é dividida por 10 para normalizá-la na mesma faixa da pontuação RRF (tipicamente 0,0 a 0,03). A divisão 60/40 pondera a relevância lexical+semântica acima da ativação cognitiva, enquanto ainda permite que memórias acessadas com frequência e ativadas contextualmente subam.
Sistema de Decaimento FadeMem
Enquanto o ACT-R lida com a competição de recuperação no momento da consulta, o FadeMem lida com o ciclo de vida em segundo plano das memórias. Ele implementa uma arquitetura de memória de camada dupla (Memória de Curto Prazo e Memória de Longo Prazo) com decaimento por lei de potência, promoção/rebaixamento baseados em importância e arquivamento.
Pontuação de Importância
A importância de cada memória é uma combinação ponderada de três sinais:
I(t) = 0.4 * relevance + 0.3 * frequency + 0.3 * recency
Onde:
relevance= pontuação de relevância contextual (0,5 durante varreduras em segundo plano quando não há contexto de consulta disponível)frequency = log(access_count + 1) / log(max_access_count + 1)(frequência de acesso log-normalizada)recency = exp(-decay_rate * hours_since_access)(decaimento exponencial de recência)
Os pesos (0,4, 0,3, 0,3) refletem uma escolha de design: sobre o que uma memória trata importa ligeiramente mais do que com que frequência ou quão recentemente foi acessada.
Função de Decaimento por Lei de Potência
A função central de decaimento:
v(t) = v(0) * exp(-lambda * t^beta)
Onde:
v(0)= força inicial da memórialambda= taxa de decaimento por memória (padrão0.1)t= tempo desde o último acesso em horasbeta= expoente dependente da camada:beta_LTM = 0.8(sub-linear — memórias MLP decaem mais lentamente que exponencial)beta_STM = 1.2(super-linear — memórias MCP decaem mais rapidamente que exponencial)
O parâmetro beta é a principal inovação sobre o decaimento exponencial padrão. Em beta < 1, a curva de decaimento se curva para cima em relação ao exponencial, significando que memórias antigas decaem mais lentamente quanto mais velhas ficam — elas são "endurecidas" pelo tempo. Em beta > 1, a curva se curva para baixo, significando que novas memórias que falham em se consolidar decaem de forma acelerada.
Promoção e Rebaixamento de Camada Dupla
As memórias se movem entre camadas com base em limiares de importância:
Promotion: STM --> LTM when importance >= 0.7
Demotion: LTM --> STM when importance <= 0.3
Archive: STM --> grave when importance < 0.1 AND age > 30 days
A lacuna entre 0,3 e 0,7 é uma zona de histerese: memórias nessa faixa permanecem em sua camada atual. Isso evita oscilação no limite.
Tags Protegidas
Memórias marcadas com qualquer uma das seguintes tags são imunes ao decaimento e ao arquivamento:
correction, decision, identity, emotional_anchor,
commitment, exact_value, chain_of_command, person
Elas representam categorias de informação onde a perda seria prejudicial, independentemente da frequência de acesso.
Busca Híbrida com Fusão de Rank Recíproco
memory-v2 executa dois algoritmos de busca independentes e os funde:
- Busca por palavra-chave BM25 via SQLite FTS5 — excelente para correspondência exata de termos, nomes de arquivos, códigos de erro
- Busca por similaridade vetorial via sqlite-vec (768 dimensões, distância de cosseno) — excelente para similaridade semântica
A fusão usa Fusão de Rank Recíproco (Cormack et al., 2009), que demonstrou superar métodos de ranqueamento individuais e a fusão Condorcet:
score(d) = SUM_i [ 1 / (k + rank_i(d)) ]
Onde:
k = 60(a constante RRF; valores mais altos reduzem a influência dos resultados mais bem ranqueados)rank_i(d)= posição do documentodnai-ésima lista ranqueada (indexada a partir de 0)- A soma percorre tanto as listas de resultados BM25 quanto as vetoriais Documentos que aparecem em ambas as listas recebem pontuação de ambas. Documentos que aparecem em apenas uma lista recebem pontuação apenas dessa lista (o outro termo é 0). O resultado é uma classificação fundida que captura tanto a precisão lexical quanto a abrangência semântica.
Cada busca recupera limit * 3 candidatos antes da fusão para garantir recall adequado. Os resultados fundidos são então passados para a camada de pontuação ACT-R para reclassificação final.
Grafo de Conhecimento e PageRank Personalizado
O grafo de conhecimento é um grafo direcionado NetworkX (DiGraph) que representa entidades e relacionamentos extraídos dos documentos do vault. Ele fornece um caminho de recuperação complementar: enquanto a busca plana encontra documentos contendo palavras ou vetores semelhantes, a travessia do grafo descobre conceitos estruturalmente relacionados mesmo quando não compartilham similaridade lexical ou de embeddings.
Esquema
10 tipos de nós:
person, project, concept, decision, tool,
event, emotion, conversation, chunk, community
11 tipos de arestas:
discussed_in, decided, built, uses, part_of,
related_to, preceded_by, caused, felt, evolved_from, member_of
Entidades são normalizadas para minúsculas. Arestas carregam peso (incrementado em observação repetida), metadados temporais (valid_from, valid_until), pontuações de confiança e proveniência do arquivo de origem.
Extração de Entidades
A extração de entidades e relacionamentos usa um LLM local (padrão: qwen2.5:3b via Ollama) com um prompt estruturado que produz saída JSON. O modelo é instruído a normalizar nomes, pular relacionamentos triviais e usar formas canônicas. Os primeiros 4000 caracteres de cada documento são processados (respeitando a janela de contexto do modelo pequeno).
Detecção de Comunidades Leiden
O grafo é particionado usando o algoritmo Leiden (Traag et al., 2019), que garante comunidades bem conectadas — uma melhoria em relação ao método Louvain anterior que podia produzir comunidades arbitrariamente mal conectadas. A implementação usa python-igraph e leidenalg (dependências opcionais).
Atribuições de comunidade são armazenadas como atributos de nó e expostas através da ferramenta MCP list_topics, fornecendo um agrupamento automático da base de conhecimento sem taxonomia manual.
Recuperação PageRank Personalizada Estilo HippoRAG
A ferramenta graph_search implementa recuperação PageRank Personalizada (PPR) inspirada no HippoRAG (2024):
- Identificação de sementes: Extrai entidades da consulta; corresponde-as a nós do grafo por sobreposição de palavras. Se não houver correspondência direta, usa similaridade de embeddings contra nomes de nós.
- Vetor de personalização: Constrói uma distribuição uniforme sobre os nós semente (todos os outros recebem peso 0).
- Cálculo do PPR:
nx.pagerank(G_undirected, alpha=0.85, personalization=p) - Extração de resultados: Retorna os top-K nós por pontuação PPR, incluindo associação de comunidade, contagem de menções e proveniência da fonte.
A probabilidade de teletransporte alpha = 0.85 significa que 85% da caminhada aleatória segue arestas e 15% teletransporta de volta aos nós semente. Isso equilibra o padrão entre exploração e relevância.
A principal vantagem sobre a busca plana: PPR descobre nós alcançáveis por travessia multi-salto a partir das entidades da consulta, mesmo que esses nós não compartilhem similaridade de embeddings ou lexical com a consulta. Isso permite o raciocínio "o que mais está conectado a isso?".
Esquema do Banco de Dados
Todo o estado persistente (exceto o pickle do grafo de conhecimento) reside em um único arquivo de banco de dados SQLite.
Diagrama Entidade-Relacionamento
erDiagram
memories {
INTEGER id PK
TEXT content
TEXT content_type
TEXT source_file
INTEGER source_line
TEXT author
INTEGER authority_level
REAL confidence
INTEGER protected
TEXT tags
TEXT created_at
TEXT updated_at
TEXT last_accessed_at
INTEGER access_count
REAL activation_score
REAL importance_score
REAL decay_rate
INTEGER archived
INTEGER supersedes FK
TEXT content_hash
}
memory_fts {
TEXT content
TEXT tags
TEXT source_file
}
memory_vec {
INTEGER id PK
BLOB embedding
}
graveyard {
INTEGER id PK
INTEGER memory_id FK
TEXT content
TEXT metadata
TEXT archived_at
TEXT reason
REAL last_activation_score
}
agent_offsets {
TEXT agent_id PK
INTEGER last_read_line
TEXT last_read_time
}
file_hashes {
TEXT file_path PK
TEXT content_hash
TEXT indexed_at
INTEGER chunk_count
}
conflicts {
INTEGER id PK
INTEGER memory_id_a FK
INTEGER memory_id_b FK
TEXT agent_a
TEXT agent_b
TEXT description
INTEGER resolved
TEXT resolved_by
TEXT created_at
}
compaction_receipts {
INTEGER id PK
TEXT timestamp
INTEGER original_tokens
INTEGER compressed_tokens
REAL ratio
INTEGER protected_items_extracted
REAL verification_score
TEXT vault_files_updated
TEXT receipt_data
}
memories ||--o{ graveyard : "archived to"
memories ||--|| memory_fts : "FTS5 index"
memories ||--|| memory_vec : "vector index"
memories ||--o{ conflicts : "involved in"
memories ||--o| memories : "supersedes"
Detalhes das Tabelas
| Tabela | Propósito | Estratégia de Índice |
|---|---|---|
memories | Armazenamento principal. Uma linha por memória (ou chunk do vault). | Árvore B em content_type, archived, protected, source_file, created_at, activation_score |
memory_fts | Tabela virtual FTS5 sobre content, tags, source_file. Sincronizada automaticamente via gatilhos AFTER INSERT/UPDATE/DELETE. | Índice invertido (BM25) |
memory_vec | Tabela virtual vec0 contendo embeddings float32 de 768 dimensões. Uma linha por memória, chaveada por id. | NN aproximado estilo HNSW (interno do sqlite-vec) |
graveyard | Memórias arquivadas. Preserva conteúdo completo e metadados para possível reidratação. | Nenhum (log de auditoria somente anexação) |
agent_offsets | Offsets de consumidor estilo Kafka. Cada agente rastreia sua última posição lida no changelog. | Chave primária em agent_id |
file_hashes | Hashes SHA-256 para indexação incremental do vault. Ignora arquivos inalterados na reindexação. | Chave primária em file_path |
conflicts | Log de contradições. Registra quando dois agentes escrevem memórias conflitantes. | Varredura sequencial (baixo volume) |
compaction_receipts | Trilha de auditoria para cada execução de compactação. Armazena proporções, pontuações de verificação, contagens de itens protegidos. | Varredura sequencial |
Configuração do SQLite
PRAGMA journal_mode = WAL; -- Write-Ahead Logging for concurrent reads
PRAGMA foreign_keys = ON; -- Enforce referential integrity
A extensão sqlite-vec é carregada no momento da conexão via sqlite_vec.load(conn). O arquivo do banco de dados é protegido por um timeout de 10 segundos para contenção de bloqueio.
Servidor MCP e Ferramentas
memory-v2 expõe 17 ferramentas através do Model Context Protocol via FastMCP. O servidor roda sobre stdio (transporte MCP padrão) e pode ser registrado com qualquer cliente compatível com MCP.
Referência de Ferramentas
Operações CRUD
| Ferramenta | Parâmetros | Descrição |
|---|---|---|
add_memory | content, content_type?, tags?, source?, protected?, author?, confidence? | Armazena uma nova memória com embedding, verificação de novidade e varredura de credenciais. Retorna status memory_id, novelty, importance, protected. |
get | memory_id | Recupera uma única memória por ID. Atualiza timestamp e contagem de acesso (fortalecimento de recuperação). |
update | memory_id, content?, tags?, protected? | Atualiza conteúdo, tags ou status de proteção. Re-embedda se o conteúdo mudar. |
forget | memory_id, reason? | Arquiva para o cemitério. Memórias protegidas não podem ser esquecidas. |
Operações de Busca
| Ferramenta | Parâmetros | Descrição |
|---|---|---|
search | query, limit?, content_type? | Busca híbrida BM25 + vetorial com fusão RRF e reclassificação ACT-R. A ferramenta de busca principal. |
keyword_search | keywords, limit? | Busca por palavras-chave BM25 pura. Preferida para termos exatos, nomes de arquivos, códigos de erro. |
Operações de Grafo
| Ferramenta | Parâmetros | Descrição |
|---|---|---|
graph_search | query, top_k? | Travessia PageRank Personalizada. Descobre conceitos relacionados via caminhada multi-salto no grafo. |
graph_stats_tool | (nenhum) | Contagens de nós/arestas, distribuições de tipos, principais entidades por contagem de menções, densidade do grafo. |
Operações de Sistema
| Ferramenta | Parâmetros | Descrição |
|---|---|---|
stats | (nenhum) | Contagens totais de ativos, arquivados, protegidos, cemitério, arquivos indexados, distribuição de tipos. |
list_recent | hours?, limit? | Memórias criadas recentemente, ordenadas por created_at decrescente. |
list_topics | limit? | Agrupamentos de tópicos das comunidades Leiden (se o grafo for construído) ou fallback de estrutura de arquivos. |
reindex | force? | Reindexação incremental do vault. Processa apenas arquivos cujo hash SHA-256 mudou. force=True reconstrói tudo. |
Operações Avançadas
| Ferramenta | Parâmetros | Descrição |
|---|---|---|
extract_from_conversation | text, source?, author? | Pipeline LLM de duas passagens: extrai fatos, depois decide ADICIONAR/ATUALIZAR/EXCLUIR/NENHUM para cada um. |
compact_text | text, max_ratio?, verify? | Compressão CogCanvas em 6 etapas com extração de conteúdo protegido e verificação de fidelidade. |
decay_sweep | (nenhum) | Manutenção em segundo plano FadeMem: atualiza pontuações de importância, promove/rebaixa camadas, arquiva memórias mortas. |
agent_sync | agent_id | Sincronização de changelog estilo Kafka. Retorna entradas não lidas e atualiza o offset do consumidor do agente. |
check_conflicts | (nenhum) | Lista todos os conflitos de memória entre agentes não resolvidos. |
check_integrity | (nenhum) | Verifica arquivos do vault contra o manifesto SHA-256. Relata arquivos modificados, novos e ausentes. |
Inicialização do Servidor
Na inicialização, o servidor:
- Registra todas as 17 ferramentas com FastMCP
- Cria uma thread em segundo plano para pré-aquecer o modelo de embedding Ollama (evita penalidade de ~55 segundos de cold-start na primeira consulta)
- Inicializa lentamente a conexão SQLite na primeira chamada de ferramenta
- Roda sobre stdio com
mcp.run(show_banner=False)
Referência de Subsistemas
Camada de Embedding
Arquivo: src/memory_v2/embeddings.py
| Propriedade | Valor |
|---|---|
| Modelo | nomic-embed-text (via Ollama) |
| Dimensões | 768 |
| Backend | Inferência local Ollama |
| Cache | Cache de arquivo chaveado por SHA-256 em ~/.memory-v2/cache/ |
| API em lote | embed_batch(texts: list[str]) para indexação do vault |
A camada de embedding é intencionalmente fina: quatro funções (embed_text, embed_batch, embed_with_cache, get_client). A seleção do modelo de embedding é configurável via MEMORY_V2_EMBED_MODEL para usuários que desejam trocar por um modelo Ollama diferente.
A função get_embedder() em __init__.py fornece inicialização lenta com uma chamada de aquecimento descartável para evitar latência de cold-start na primeira consulta real.
Indexador do Vault
Arquivo: src/memory_v2/vault_indexer.py
O indexador do vault converte um diretório de arquivos markdown em chunks de memória pesquisáveis.
Estratégia de chunking:
- Alvo: 500 tokens por chunk (~2000 caracteres a 4 caracteres/token)
- Sobreposição: 50 tokens entre chunks consecutivos
- Hierarquia de divisão: limites de parágrafos primeiro, limites de frases para parágrafos superdimensionados
- Extração de frontmatter: metadados YAML (
type,tags,author) analisados e aplicados aos chunks
Indexação incremental:
- O hash SHA-256 de cada arquivo é armazenado em
file_hashes - Na reindexação, arquivos inalterados são completamente ignorados
- Arquivos alterados têm seus chunks antigos excluídos antes do re-chunking
- A flag
force=Trueignora a verificação de hash para reconstruções completas
Detecção de tipo de conteúdo:
- Derivada da estrutura de pastas do vault:
conversations/->episode,decisions/->decision,people/->person,origins/->identity - Substituível via campo de frontmatter
type:
Manuseio do changelog:
changelog.mdé indexado separadamente (uma memória por entrada datada)- Cada entrada correspondente a
[YYYY-MM-DD]torna-se uma memória do tipoepisode - Embeddado em lote para eficiência
Pipeline de Auto-Extração
Arquivo: src/memory_v2/extraction.py
O pipeline de extração converte texto de conversa não estruturado em memórias discretas e tipadas através de um processo LLM de duas passagens.
Passagem 1 — Extração de Fatos:
O LLM local (qwen2.5:3b) recebe o texto da conversa e um prompt estruturado visando 7 categorias:
- Preferências pessoais
- Detalhes pessoais (nomes, relacionamentos, datas)
- Planos e intenções
- Detalhes de projetos (status, arquitetura, decisões)
- Especificidades técnicas (caminhos de arquivos, portas, configurações, erros)
- Correções
- Momentos emocionais/relacionais
O prompt instrui explicitamente o modelo a extrair apenas de mensagens do usuário, produzir declarações autocontidas e pular conteúdo trivial.
Passagem 2 — Decisão de Ação de Memória:
Para cada fato extraído:
- Varredura de credenciais: Bloqueia armazenamento se credenciais forem detectadas (13 padrões)
- Embedding: Gera vetor de 768 dimensões via Ollama
- Verificação de novidade: Busca memórias existentes semelhantes
- Similaridade > 0.92:
NONE(duplicado, pular) - Similaridade 0.75--0.92: Invoca LLM para decidir
ADD,UPDATEouDELETE
- Similaridade > 0.92:
- Similaridade < 0.75:
ADD(suficientemente novo)
- Detecção de tipo de conteúdo: Automatizado via heurísticas de palavras-chave (
correction,decision,episode,fact) - Detecção emocional: 20 palavras-chave de emoção + 3 padrões regex; conteúdo emocional é automaticamente protegido
- Armazenamento: Execute a ação decidida com pontuação de importância apropriada
Pipeline de Compactação CogCanvas
Arquivo: src/memory_v2/compaction.py
Inspirado no framework CogCanvas para compressão cognitiva em agentes, este pipeline reduz texto verboso enquanto preserva informações críticas. Ele segue um processo de 6 etapas:
Etapa 1 -- Pré-extrair conteúdo protegido:
Examine cada linha em busca de padrões protegidos (correções, decisões, marcadores emocionais, valores exatos, compromissos, nomes configurados). Linhas correspondentes são extraídas literalmente e reservadas.
Etapa 2 -- Exclusão seletiva:
Remova conteúdo dispensável: listas numeradas de URLs, saída de comandos shell, marcadores de informação repetidos ("como mencionei"), texto padrão ("me avise se precisar de ajuda").
Etapa 3 -- Resumo estruturado:
Se o texto restante exceder 2000 caracteres, invoque o LLM local para resumir. O prompt preserva explicitamente afirmações factuais, nomes, datas, números, caminhos de arquivo e relações causais. A meta de compressão é limitada por max_ratio (padrão 3:1).
Etapa 4 -- Verificação de fidelidade:
Uma segunda passagem do LLM compara o resumo com o original, verificando:
- Alucinações (afirmações não presentes no original)
- Fatos ausentes (informações importantes omitidas)
- Pontuação geral de fidelidade (0.0 a 1.0)
Se alucinações forem detectadas e a pontuação cair abaixo de 0.7, o sistema reverte para a saída somente com exclusão em vez de confiar no resumo infiel.
Etapa 5 -- Geração de recibo:
Cada compactação produz um recibo auditável: contagens de tokens original/compactado, taxa de compressão, contagem de itens protegidos, pontuação de verificação, contagem de alucinações.
Etapa 6 -- Armazenamento de recibos:
Os recibos são persistidos na tabela compaction_receipts para análise histórica.
Etapa 7 (bônus) -- Reidratação:
A função rehydrate() pode tentar recuperar o conteúdo completo do vault ou do cemitério se a versão compactada for insuficiente.
Coordenação Multiagente
Arquivo: src/memory_v2/multi_agent.py
memory-v2 suporta múltiplos agentes de IA compartilhando um único banco de memória através de três mecanismos:
Cadeia de Autoridade
Uma hierarquia configurável determina quem pode sobrescrever quem:
{
"human": 1, # Manual edits -- highest authority
"primary_agent": 2, # Primary AI agent (e.g., Claude Code)
"coordinator": 3, # Coordinating agent
"worker": 4, # Subordinate worker agent
"indexer": 5, # Automated vault indexer
"extractor": 6, # Automated fact extraction
}
Número menor = maior autoridade. Quando uma escrita conflita com uma memória existente:
- Autoridade maior: sobrescreve a memória existente
- Autoridade igual ou menor: registra um conflito e armazena ambas as versões
A hierarquia pode ser sobrescrita via a variável de ambiente MEMORY_V2_AUTHORITY_CHAIN (formato JSON).
Offsets de Consumidor Estilo Kafka
Cada agente tem um offset de consumidor rastreado na tabela agent_offsets. A ferramenta agent_sync lê entradas não lidas do changelog e avança o offset -- o mesmo padrão usado por grupos de consumidores do Apache Kafka, adaptado a um changelog baseado em arquivo.
Isso permite que os agentes iniciem, se atualizem sobre o que outros agentes escreveram desde a última sessão e prossigam sem reler todo o histórico.
Detecção e Resolução de Conflitos
Quando uma memória recebida contradiz uma existente (detectada por pares de palavras-chave antônimas: "not"/"is", "false"/"true", "never"/"always", etc.), o sistema:
- Verifica níveis de autoridade
- Ou sobrescreve (autoridade maior) ou registra o conflito
- Conflitos aparecem através da ferramenta
check_conflictspara revisão humana
Módulo de Segurança
Arquivo: src/memory_v2/security.py
Varredura de Credenciais (13 Padrões)
Toda memória armazenada através de add_memory ou extract_from_conversation é verificada contra 13 padrões regex:
| Padrão | Alvo |
|---|---|
api_key/secret/token/password=... | Atribuições genéricas de credenciais |
| Strings Base64 (40+ caracteres) | Segredos codificados |
sk-[a-zA-Z0-9]{20,} | Chaves de API da OpenAI |
sk-ant-[a-zA-Z0-9-]{20,} | Chaves de API da Anthropic |
ghp_[a-zA-Z0-9]{36} | Tokens de Acesso Pessoal do GitHub |
gho_[a-zA-Z0-9]{36} | Tokens OAuth do GitHub |
bearer [token] | Tokens de autenticação Bearer |
xoxb-... / xoxp-... | Tokens de bot/usuário do Slack |
AKIA[0-9A-Z]{16} | Chaves de acesso da AWS |
-----BEGIN PRIVATE KEY----- | Chaves privadas RSA/EC |
mongodb://... | URIs de conexão MongoDB |
postgres://... | URIs de conexão PostgreSQL |
Uma lista de permissões evita falsos positivos em chaves redigidas (sk-abc...), placeholders de exemplo e hashes de conteúdo SHA-256 do próprio sistema.
Comportamento na detecção: A memória é bloqueada -- não armazenada. A ferramenta retorna uma mensagem de erro instruindo o chamador a remover dados sensíveis.
Detecção de Injeção (6 Padrões)
Conteúdo de fontes externas é verificado em busca de tentativas de injeção de prompt:
"ignore previous instructions"
"you are now a"
"system: you"
"forget everything/all/your"
"new instructions:"
"override previous/system/all"
O sistema avisa, mas não remove -- o chamador (o agente de IA) toma a decisão final.
Manifestos de Integridade
A ferramenta check_integrity gera e verifica manifestos SHA-256 para todos os arquivos markdown do vault, detectando:
- Arquivos modificados (incompatibilidade de hash)
- Arquivos novos (não no manifesto)
- Arquivos ausentes (no manifesto, mas não no disco)
Exemplos Práticos
Passo a Passo de Ativação ACT-R
Considere uma memória armazenada há 48 horas com 5 acessos, marcada com ["python", "debugging"]. O contexto da consulta atual inclui a tag "python", que aparece em 20 memórias no total.
Etapa 1: Ativação de nível base
n = 5 (access count)
L = 48 (hours since creation)
d = 0.5
B_i = ln(5 / (1 - 0.5)) - 0.5 * ln(48)
= ln(10) - 0.5 * ln(48)
= 2.3026 - 0.5 * 3.8712
= 2.3026 - 1.9356
= 0.3670
Etapa 2: Ativação por propagação
Tags de contexto: ["python"] (1 tag, então W_j = 1.0)
Tags de memória: ["python", "debugging"]
A tag "python" é compartilhada. Seu fan é 20.
S_i = 1.0 * (1.6 - ln(20))
= 1.0 * (1.6 - 2.9957)
= max(-1.3957, 0)
= 0.0
O fan de 20 é muito alto -- a força associativa é negativa, então ela é limitada a 0. Essa tag é comum demais para fornecer priming útil. Se tivéssemos usado uma tag mais rara como "asyncio" com um fan de 3:
S_i = 1.0 * (1.6 - ln(3))
= 1.0 * (1.6 - 1.0986)
= 0.5014
Etapa 3: Ruído
Sorteie u = 0.73 de Uniforme(0,1):
epsilon = 0.25 * ln(0.73 / 0.27)
= 0.25 * ln(2.7037)
= 0.25 * 0.9946
= 0.2487
Etapa 4: Ativação completa (usando a tag comum "python")
A_i = 0.3670 + 0.0 + 0.2487 = 0.6157
Etapa 5: Probabilidade de recuperação
P(retrieve) = 1 / (1 + exp(-(0.6157 - (-0.5)) / 0.25))
= 1 / (1 + exp(-1.1157 / 0.25))
= 1 / (1 + exp(-4.4628))
= 1 / (1 + 0.01155)
= 0.9886
Esta memória tem uma probabilidade de recuperação de 98.9% -- alta ativação devido ao acesso frequente e ruído favorável.
Passo a Passo de Decaimento FadeMem
Considere três memórias durante uma varredura de decaimento:
| Memória | Contagem de Acessos | Máx. Acesso (global) | Horas Desde o Acesso | Camada Atual |
|---|---|---|---|---|
| A | 12 | 50 | 2 | LTM |
| B | 3 | 50 | 168 (1 semana) | STM |
| C | 1 | 50 | 1440 (2 meses) | STM |
Memória A (memória LTM ativa):
frequency = log(12 + 1) / log(50 + 1) = log(13) / log(51) = 2.565 / 3.932 = 0.652
recency = exp(-0.1 * 2) = exp(-0.2) = 0.819
I(A) = 0.4 * 0.5 + 0.3 * 0.652 + 0.3 * 0.819
= 0.200 + 0.196 + 0.246
= 0.641
Importância 0.641 está na zona de histerese (0.3 -- 0.7). A memória A permanece na LTM. Nenhuma ação.
Memória B (memória STM negligenciada):
frequency = log(3 + 1) / log(51) = log(4) / log(51) = 1.386 / 3.932 = 0.352
recency = exp(-0.1 * 168) = exp(-16.8) ~ 0.0000005
I(B) = 0.4 * 0.5 + 0.3 * 0.352 + 0.3 * 0.0000005
= 0.200 + 0.106 + 0.000
= 0.306
Importância 0.306 está logo acima do limite de rebaixamento (0.3). Ainda na zona de histerese -- permanece na STM.
Memória C (antiga, pouco acessada):
frequency = log(1 + 1) / log(51) = log(2) / log(51) = 0.693 / 3.932 = 0.176
recency = exp(-0.1 * 1440) = exp(-144) ~ 0.0
I(C) = 0.4 * 0.5 + 0.3 * 0.176 + 0.3 * 0.0
= 0.200 + 0.053 + 0.000
= 0.253
Importância 0.253 está abaixo do limite de rebaixamento (0.3). A memória C é rebaixada para STM (já está lá). Como 0.253 > limite de arquivamento 0.1, ela ainda NÃO é arquivada. Mas se tivesse importância abaixo de 0.1 e idade > 30 dias (verdadeiro aos 60 dias), ela seria arquivada no cemitério.
Passo a Passo de Busca Híbrida
Consulta: "Python asyncio event loop configuration"
Resultados BM25 (FTS5 MATCH, ordenados por classificação BM25):
| Classificação | ID da Memória | Conteúdo (truncado) |
|---|---|---|
| 0 | 42 | "A configuração do event loop asyncio para..." |
| 1 | 88 | "Python 3.12 mudou o event loop padrão..." |
| 2 | 15 | "Arquivos de configuração devem usar o formato TOML..." |
Resultados vetoriais (sqlite-vec, ordenados por distância de embedding):
| Classificação | ID da Memória | Conteúdo (truncado) |
|---|---|---|
| 0 | 88 | "Python 3.12 mudou o event loop padrão..." |
| 1 | 42 | "A configuração do event loop asyncio para..." |
| 2 | 107 | "uvloop fornece uma substituição mais rápida para o event loop..." |
Fusão RRF (k = 60):
ID 42: BM25 contribution = 1/(60+0+1) = 0.01639
Vec contribution = 1/(60+1+1) = 0.01613
RRF score = 0.03252
ID 88: BM25 contribution = 1/(60+1+1) = 0.01613
Vec contribution = 1/(60+0+1) = 0.01639
RRF score = 0.03252
ID 15: BM25 contribution = 1/(60+2+1) = 0.01587
Vec contribution = 0 (not in vector top-K)
RRF score = 0.01587
ID 107: BM25 contribution = 0 (not in BM25 top-K)
Vec contribution = 1/(60+2+1) = 0.01587
RRF score = 0.01587
Os IDs 42 e 88 empatam em 0.03252. Ambos apareceram nos dois conjuntos de resultados, confirmando que são relevantes nos eixos lexical e semântico. Os IDs 15 e 107 apareceram cada um em apenas um, recebendo metade da pontuação máxima de RRF.
Após o reordenamento ACT-R (aplicando a fórmula 0.6 * hybrid + 0.4 * (activation / 10)), a memória 88 pode subir acima da 42 se tiver sido acessada com mais frequência, ou a 42 pode vencer se tiver sobreposição de tags contextuais mais forte.
Instalação
Pré-requisitos
- Python 3.9+
- Ollama rodando localmente com
nomic-embed-texte (opcionalmente)qwen2.5:3bbaixados - sqlite-vec (instalado automaticamente via pip)
A partir do PyPI
pip install memory-v2
A partir do Código Fonte
git clone https://github.com/Haustorium12/memory-v2.git
cd memory-v2
pip install -e .
Com Dependências de Grafo
A detecção de comunidades Leiden e a visualização PyVis exigem dependências opcionais:
pip install memory-v2[graph]
Com Dependências de Desenvolvimento
pip install memory-v2[all]
Configuração do Ollama
# Install Ollama (https://ollama.com/download)
ollama pull nomic-embed-text # Required: 768-dim embeddings
ollama pull qwen2.5:3b # Optional: fact extraction + compaction
O modelo de embedding é necessário para todas as operações de busca e armazenamento. O modelo LLM é necessário apenas para extract_from_conversation, compact_text e build_kg (extração de entidades do grafo de conhecimento).
Configuração
Variáveis de Ambiente
| Variável | Padrão | Descrição |
|---|---|---|
MEMORY_V2_DB | ~/.memory-v2/memory.db | Caminho para o arquivo de banco de dados SQLite |
MEMORY_V2_GRAPH | ~/.memory-v2/knowledge_graph.pickle | Caminho para o pickle do grafo NetworkX |
MEMORY_V2_CACHE | ~/.memory-v2/cache | Diretório para cache de arquivos de embedding |
MEMORY_V2_VAULT | ~/.memory-v2/vault | Diretório raiz do vault markdown |
MEMORY_V2_EMBED_MODEL | nomic-embed-text | Modelo Ollama para embeddings |
MEMORY_V2_LLM_MODEL | qwen2.5:3b | Modelo Ollama para extração/compactação |
MEMORY_V2_PROTECTED_NAMES | (vazio) | Nomes separados por vírgula para proteger da compactação |
MEMORY_V2_AUTHORITY_CHAIN | (veja abaixo) | Hierarquia de autoridade JSON |
MEMORY_V2_KG_HASHES | ~/.memory-v2/kg_file_hashes.json | Registro de hash de arquivos para builds incrementais de KG |
Configuração do Cliente MCP
Claude Code (settings.json)
{
"mcpServers": {
"memory-v2": {
"command": "memory-v2-server",
"env": {
"MEMORY_V2_DB": "C:\\Users\\you\\.memory-v2\\memory.db",
"MEMORY_V2_VAULT": "C:\\Users\\you\\vault"
}
}
}
}
Claude Desktop (claude_desktop_config.json)
{
"mcpServers": {
"memory-v2": {
"command": "memory-v2-server",
"args": [],
"env": {
"MEMORY_V2_DB": "/home/you/.memory-v2/memory.db",
"MEMORY_V2_VAULT": "/home/you/vault"
}
}
}
}
Cadeia de Autoridade Personalizada
export MEMORY_V2_AUTHORITY_CHAIN='{"human": 1, "primary_agent": 2, "coordinator": 3, "worker": 4}'
Uso
Como Servidor MCP
A interface principal. Inicie o servidor:
memory-v2-server
O servidor se comunica via stdio usando o protocolo MCP. Normalmente, você o configura nas configurações do seu cliente MCP em vez de executá-lo manualmente.
Como Ferramenta CLI
Para scripts e fluxos de trabalho não-MCP:
# Database statistics
memory-v2 stats
# Store a memory
memory-v2 add '{"content": "Python 3.12 uses per-interpreter GIL", "content_type": "fact", "tags": ["python", "concurrency"]}'
# Search
memory-v2 search "Python GIL changes"
# Keyword search
memory-v2 keyword "GIL"
# Get by ID
memory-v2 get 42
# Update
memory-v2 update '{"memory_id": 42, "content": "Python 3.13 makes per-interpreter GIL stable"}'
# Archive
memory-v2 forget '{"memory_id": 42, "reason": "outdated"}'
# Recent memories
memory-v2 recent
# Reindex vault
memory-v2 reindex
Construindo o Grafo de Conhecimento
O grafo de conhecimento é construído a partir dos arquivos do vault usando uma CLI independente que processa cada documento através da extração de entidades por LLM:
# Incremental build (skip unchanged files)
memory-v2-build-kg
# Full rebuild
memory-v2-build-kg --full
O construtor:
- Lê todos os arquivos markdown do vault
- Extrai entidades e relacionamentos via Ollama
- Adiciona-os ao grafo NetworkX (mesclando nós duplicados, incrementando pesos das arestas)
- Salva o progresso a cada 25 arquivos (checkpoint)
- Executa a detecção de comunidades Leiden
- Gera uma visualização HTML interativa PyVis (
graph.html) - Imprime estatísticas do grafo e principais entidades
Migração da v1 para a v2
memory-v2 é uma reescrita completa. Ele não compartilha nenhum código com claude-memory v1. A tabela abaixo resume todas as mudanças arquiteturais.
| Recurso | v1 (claude-memory) | v2 (memory-v2) |
|---|---|---|
| Armazenamento | ChromaDB (armazenamento de documentos embutido) | SQLite + sqlite-vec + FTS5 (arquivo único, modo WAL) |
| Busca | Vetor ponderado + BM25 (sistemas separados) | Fusão de Classificação Recíproca combinando BM25 e vetor em um único pipeline de consulta |
| Modelo de Decaimento | Ebbinghaus (5 mecanismos biológicos: curva de decaimento, isenções perenes, ponderação de saliência, fortalecimento de recuperação, consolidação) | FadeMem (decaimento de lei de potência com expoentes beta dependentes da camada, promoção/rebaixamento de STM/LTM com histerese, arquivamento ponderado por importância) |
| Ativação | Nenhum | ACT-R completo: nível base + ativação espalhada + ruído logístico + probabilidade de recuperação |
| Grafo de Conhecimento | Nenhum | Grafo direcionado NetworkX com detecção de comunidades Leiden e recuperação por PageRank Personalizado |
| Interface | Somente CLI | Servidor MCP (17 ferramentas) + CLI |
| Tipos de Memória | Somente blocos de arquivo | 6 tipos estruturados: fact, episode, decision, correction, identity, person |
| Multiagente | Nenhum | Cadeia de autoridade + offsets de consumidor estilo Kafka + detecção e registro de conflitos |
| Segurança | Nenhum | 13 padrões de credenciais + lista de permissões, 6 padrões de injeção, manifestos de integridade SHA-256 |
| Compactação | Processo observador externo | Pipeline integrado CogCanvas de 6 etapas com verificação de fidelidade e recibos auditáveis |
| Extração | Manual | Pipeline LLM de duas passagens com verificação de novidade, detecção de emoção e tipagem automática de conteúdo |
| Embeddings | SentenceTransformers / OpenAI | Ollama nomic-embed-text (local, zero chaves de API) |
| LLM | API OpenAI | Ollama qwen2.5:3b (local, zero chaves de API) |
| Dependências | chromadb, openai, sentence-transformers | sqlite-vec, fastmcp, ollama, networkx, numpy |
| Formato de Dados | Interno do ChromaDB (opaco) | SQLite (inspecionável, portátil, arquivo único) |
| Arquivo de Banco de Dados | Diretório ChromaDB | Arquivo único .db (tipicamente < 50 MB para ~1000 memórias) |
Por que a Reescrita?
O sistema v1 funcionou por 6 meses e sobreviveu a 59 ciclos de compactação. Suas limitações ficaram claras com o uso diário:
- Contenção de bloqueio do ChromaDB: Dois agentes tentando escrever simultaneamente entrariam em deadlock
- Sem tipos estruturados: Tudo era um "bloco" -- sem como distinguir decisões de fatos
- Sem relacionamentos em grafo: Não era possível responder "o que está relacionado a X?" sem similaridade de embeddings
- O decaimento de Ebbinghaus era simples demais: Sem arquitetura de camada dupla, sem sobrevivência ponderada por importância
- Somente CLI: Exigia acesso ao shell; não podia ser usado por Claude Desktop ou agentes baseados na web
- Dependências externas para funções principais: A compactação exigia um processo observador separado
- Dependência de chave de API: Embeddings exigiam OpenAI ou SentenceTransformers local (pesado)
Estrutura do Repositório
memory-v2/
|
+-- src/memory_v2/
| +-- __init__.py # Package init, lazy embedder warmup
| +-- db.py # SQLite + sqlite-vec + FTS5 (schema, CRUD, hybrid search)
| +-- server.py # FastMCP server (17 tools, background warmup thread)
| +-- embeddings.py # Ollama nomic-embed-text (embed, batch, cache)
| +-- scoring.py # ACT-R activation + FadeMem decay + cosine similarity
| +-- knowledge_graph.py # NetworkX graph, Leiden communities, PPR retrieval, PyVis viz
| +-- vault_indexer.py # Markdown vault indexing (chunk, embed, delta detect)
| +-- extraction.py # Two-pass LLM fact extraction pipeline
| +-- compaction.py # CogCanvas 6-step compression with verification
| +-- multi_agent.py # Authority chain, consumer offsets, conflict detection
| +-- security.py # 13 credential patterns, 6 injection patterns, manifests
| +-- build_kg.py # Standalone knowledge graph builder CLI
| +-- cli.py # CLI wrapper for non-MCP usage
|
+-- docs/ # Additional documentation
+-- examples/ # Usage examples
+-- tests/ # Test suite (pytest)
|
+-- pyproject.toml # Package metadata, dependencies, entry points
+-- CHANGELOG.md # Release history
+-- LICENSE # MIT License
+-- README.md # This file
Pontos de Entrada
Definidos em pyproject.toml:
| Comando | Alvo | Propósito |
|---|---|---|
memory-v2 | memory_v2.cli:main | Ferramenta CLI |
memory-v2-server | memory_v2.server:run | Servidor MCP |
memory-v2-build-kg | memory_v2.build_kg:main | Construtor de grafo de conhecimento |
Trabalhos Relacionados
memory-v2 baseia-se e é informado por um corpo crescente de trabalhos sobre sistemas de memória para agentes de modelos de linguagem:
- HippoRAG (2024) -- Arquitetura RAG neurobiológica usando grafos de conhecimento e PageRank Personalizado para recuperação. A ferramenta
graph_searchdo memory-v2 implementa esse padrão de recuperação. arXiv. - A-MEM (Workshop NeurIPS 2025) -- Estrutura de memória agêntica explorando memória estruturada para agentes LLM.
- CogCanvas -- Estrutura de compressão cognitiva para agentes. O pipeline de compactação do memory-v2 adapta sua metodologia "extrair, excluir, resumir, verificar".
- Focus (arXiv:2601.07190) -- Compressão ativa de contexto para grandes modelos de linguagem.
- ReadAgent -- Agente de memória focado em leitura para documentos longos.
- AgeMem -- Gerenciamento de memória ciente da idade para agentes de linguagem.
- EverMemOS -- Sistema operacional de memória persistente para agentes.
- Memoria -- Estrutura de agente aumentada por memória.
- PlugMem -- Módulos de memória plugáveis para agentes LLM.
- AriGraph -- Memória estruturada em grafo para agentes orientados a tarefas.
- Zep / Graphiti -- Infraestrutura de memória de produção para aplicações de IA, usando grafos de conhecimento.
- TITANS -- Treinamento de grandes modelos de linguagem com camadas de memória.
Referências
-
Anderson, J.R. & Schooler, L.J. (1991). Reflections of the environment in memory. Psychological Science, 2(6), 396--408.
-
Anderson, J.R., Bothell, D., Byrne, M.D., Douglass, S., Lebiere, C., & Qin, Y. (2004). An integrated theory of the mind. Psychological Review, 111(4), 1036--1060.
-
Ebbinghaus, H. (1885/1913). Memory: A Contribution to Experimental Psychology. (Trans. H.A. Ruger & C.E. Bussenius). New York: Teachers College, Columbia University.
-
Cormack, G.V., Clarke, C.L.A., & Buettcher, S. (2009). Reciprocal Rank Fusion outperforms Condorcet and individual Rank Learning Methods. SIGIR '09: Proceedings of the 32nd International ACM SIGIR Conference on Research and Development in Information Retrieval.
-
HippoRAG: Neurobiological RAG Architecture (2024). arXiv preprint.
-
A-MEM: Agentic Memory. NeurIPS 2025 Workshop.
-
CogCanvas: Cognitive Compression for Agents.
-
Focus: Active Context Compression. arXiv:2601.07190.
-
Traag, V.A., Waltman, L., & van Eck, N.J. (2019). From Louvain to Leiden: guaranteeing well-connected communities. Scientific Reports, 9, 5233.
Construído Com
| Componente | Função | Porquê |
|---|---|---|
| Ollama | Inferência LLM local (embedding + extração) | Zero chaves de API, zero exfiltração de dados, roda em hardware de consumo |
| SQLite | Banco de dados principal | Arquivo único, zero configuração, modo WAL para leituras concorrentes, universalmente implantado |
| sqlite-vec | Busca de similaridade vetorial | Incorpora busca ANN diretamente no SQLite, sem processo separado de banco vetorial |
| SQLite FTS5 | Busca de texto completo BM25 | Integrado ao SQLite, sincronizado automaticamente via triggers, implementação BM25 testada em batalha |
| FastMCP | Estrutura do servidor MCP | Registro limpo de ferramentas baseado em decoradores, lida com transporte stdio |
| NetworkX | Grafo de conhecimento | Biblioteca de grafos madura, PageRank integrado, serializável para pickle |
| python-igraph + leidenalg | Detecção de comunidades | O algoritmo Leiden garante comunidades bem conectadas |
| NumPy | Operações vetoriais | Similaridade de cosseno rápida, serialização de embeddings |
| PyVis | Visualização de grafos | Saída HTML interativa para exploração do grafo de conhecimento |
Licença
Licença MIT. Copyright (c) 2026 Haustorium12.
Veja LICENSE para o texto completo.
memory-v2 foi construído porque assistentes de IA merecem memórias que realmente funcionam como memórias.