arandu¶
Memória de longo prazo para agentes de IA. Extraia fatos de conversas, resolva entidades, reconcilie conhecimento ao longo do tempo e recupere contexto relevante - tudo com PostgreSQL e pgvector.
O nome "Arandu" vem da palavra Guarani que significa "sabedoria adquirida pela experiencia" - literalmente "ouvir o tempo." Assim como o conceito Guarani descreve o conhecimento construido atraves da vivencia, o Arandu da ao seu agente de IA a capacidade de acumular, consolidar e recuperar conhecimento ao longo do tempo.
Por que arandu?¶
A maioria dos agentes de IA é stateless. Eles esquecem tudo entre sessões. O arandu dá ao seu agente uma memória persistente e estruturada que fica mais inteligente com o tempo:
- Extração automática de fatos - O write pipeline usa LLMs para extrair entidades, fatos e relacionamentos de linguagem natural.
- Entity resolution - Reconhece que "minha esposa Ana", "Ana" e "ela" se referem à mesma pessoa, usando um resolver de 3 fases (exact → fuzzy → LLM).
- Reconciliação de conhecimento - Decide se uma informação nova deve ADD, UPDATE ou DELETE fatos existentes. Sem duplicatas, sem dados obsoletos.
- Retrieval multi-signal - Combina busca semântica (pgvector), keyword matching, graph traversal e scoring de recência para encontrar os fatos mais relevantes.
- Manutenção em background - Clustering, consolidation e importance scoring mantêm a memória organizada e atualizada - como o cérebro consolida durante o sono.
- Provider-agnostic - Traga seu próprio LLM e embedding provider via protocolos Python simples. Providers OpenAI e Anthropic (Claude) incluídos.
Instalação¶
Com suporte a OpenAI (recomendado):
Requisitos¶
- Python 3.11+
- PostgreSQL com a extensão pgvector
Quick Start¶
import asyncio
from arandu import MemoryClient
from arandu.providers.openai import OpenAIProvider
async def main():
# 1. Configurar providers
provider = OpenAIProvider(api_key="sk-...")
# 2. Criar client
memory = MemoryClient(
database_url="postgresql+psycopg://user:pass@localhost/mydb",
llm=provider,
embeddings=provider,
)
# 3. Inicializar tabelas (idempotente)
await memory.initialize()
# 4. Write — extrai fatos automaticamente
result = await memory.write(
agent_id="user_123",
message="I live in São Paulo and work at Acme Corp as a backend engineer.",
)
print(f"Added {len(result.facts_added)} facts, resolved {len(result.entities_resolved)} entities")
# 5. Retrieve — encontra contexto relevante
context = await memory.retrieve(
agent_id="user_123",
query="where does the user live and work?",
)
print(context.context)
# 6. Cleanup
await memory.close()
asyncio.run(main())
Como Funciona¶
Write Pipeline¶
Toda mensagem passa por quatro estágios: o LLM extrai fatos estruturados, entidades são resolvidas para registros canônicos, novos fatos são reconciliados contra o conhecimento existente, e as decisões (ADD/UPDATE/NOOP/DELETE) são executadas.
Read Pipeline¶
Queries passam por um planner deterministico (sem LLM) que decide a estratégia de retrieval, depois três sinais paralelos são combinados, opcionalmente rerankeados, e comprimidos em uma string de contexto.
Background Jobs¶
Jobs periódicos em background mantêm a memória organizada e atualizada - como o processamento durante o sono no cérebro.
Arquitetura¶
O arandu é projetado em torno de três princípios:
- DI baseada em Protocol - LLM e embedding providers são injetados via
typing.Protocol. Sem vendor lock-in. - Fail-safe por padrão - Toda chamada LLM tem timeouts e fallbacks. Uma extração falha ainda registra o evento. Uma reconciliação falha tem default ADD.
- Composição sobre herança - Módulos pequenos e focados compostos em pipelines. Sem hierarquias profundas de classes.
Próximos Passos¶
-
Primeiros Passos
Guia completo de setup: PostgreSQL, pgvector, primeiro write e retrieve.
-
Conceitos
Deep dive em como cada pipeline funciona e por quê.