PostgreSQL para AI Agents: banco relacional ainda é a melhor escolha
1. pgvector: busca por similaridade sem sair do PostgreSQL
Todo mundo que constrói sistemas com IA acaba precisando de busca por similaridade em algum momento. A resposta padrão do mercado é “use um banco vetorial dedicado” — Pinecone, Weaviate, Qdrant, Milvus.
Só que essa resposta ignora um fato incômodo: você já tem um banco de dados. E se ele for PostgreSQL, a extensão pgvector pode resolver 90% dos seus casos de uso sem adicionar um novo serviço na sua stack.
O pgvector é uma extensão open-source que adiciona suporte a vetores e busca por similaridade diretamente no PostgreSQL. Em 2026, a versão 0.8+ suporta:
- Índices IVFFlat e HNSW para busca aproximada (ANN)
- Distância cosseno, L2 e produto interno
- Busca híbrida (vetor + filtro SQL na mesma query)
- Particionamento por qualquer coluna da tabela
A instalação é trivial:
CREATE EXTENSION vector;
CREATE TABLE memory_entries (
id SERIAL PRIMARY KEY,
agent_id TEXT NOT NULL,
content TEXT,
embedding vector(1536),
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX ON memory_entries USING hnsw (embedding vector_cosine_ops);
Pronto. Você tem busca por similaridade no banco que já conhece, sem aprender uma nova API, sem configurar rede, sem custo adicional de infraestrutura.
2. Armazenamento de memória de agents (long-term + working)
Agents precisam de dois tipos de memória:
Working memory: o contexto imediato da sessão atual. O que o usuário perguntou, o que o agent já respondeu, qual ferramenta foi chamada. Normalmente mantida em memória (Redis ou variável em processo), mas precisa ser persistida para recuperação de falhas.
Long-term memory: conhecimento acumulado entre sessões. Preferências do usuário, decisões anteriores, fatos aprendidos.
Com PostgreSQL, você gerencia ambos na mesma base:
-- Working memory (sessão atual)
CREATE TABLE working_memory (
session_id UUID PRIMARY KEY,
agent_id TEXT NOT NULL,
state JSONB, -- estado atual do agent
context_log JSONB[], -- histórico da sessão
expires_at TIMESTAMP -- TTL para limpeza automática
);
-- Long-term memory (busca por similaridade)
CREATE TABLE long_term_memory (
id SERIAL PRIMARY KEY,
user_id TEXT NOT NULL,
agent_id TEXT NOT NULL,
fact TEXT,
embedding vector(1536),
importance FLOAT, -- relevância para recuperação
access_count INT DEFAULT 0,
last_accessed TIMESTAMP
);
O segredo está no campo importance: ao recuperar memórias, você ordena por uma combinação de similaridade vetorial e importância, dando peso maior a fatos que o usuário explicitou como relevantes.
3. Histórico de conversas e sessões
Manter histórico de conversas é essencial para qualquer sistema com agents — seja para continuidade, auditoria ou fine-tuning futuro.
Com PostgreSQL, a modelagem é direta:
CREATE TABLE conversations (
id UUID PRIMARY KEY,
user_id TEXT NOT NULL,
agent_id TEXT NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
metadata JSONB
);
CREATE TABLE messages (
id BIGSERIAL PRIMARY KEY,
conversation_id UUID REFERENCES conversations(id),
role TEXT NOT NULL, -- 'user', 'assistant', 'tool'
content TEXT NOT NULL,
tool_calls JSONB, -- chamadas de ferramenta
tokens_used INT,
created_at TIMESTAMP DEFAULT NOW()
);
-- Índices para consulta rápida
CREATE INDEX idx_messages_conversation ON messages(conversation_id, created_at);
CREATE INDEX idx_conversations_user ON conversations(user_id, created_at DESC);
Uma query de JOIN simples recupera o histórico completo de qualquer sessão em milissegundos — sem precisar de um banco separado, sem latência de rede entre serviços.
4. Dados estruturados + vetores na mesma query (JOIN híbrido)
Aqui está o superpoder do PostgreSQL que bancos vetoriais dedicados não entregam: busca híbrida.
Imagine que seu agent precisa encontrar um cliente que:
- Pediu suporte sobre “problemas de faturamento” (similaridade semântica)
- Mora em São Paulo (filtro exato)
- É cliente desde 2024 (filtro de data)
- Teve pelo menos 3 tickets abertos (agregação)
Com PostgreSQL, isso é uma query só:
SELECT c.name, c.email, m.content,
1 - (m.embedding <=> $query_embedding) AS similarity
FROM customers c
JOIN messages m ON m.user_id = c.id
WHERE c.city = 'São Paulo'
AND c.created_at < '2024-12-31'
AND c.id IN (
SELECT user_id FROM tickets
GROUP BY user_id HAVING COUNT(*) >= 3
)
ORDER BY similarity DESC
LIMIT 5;
Em um banco vetorial dedicado, você precisaria:
- Buscar os K vizinhos mais próximos no banco vetorial
- Pegar os IDs e filtrar no banco relacional
- Fazer o JOIN manualmente no código da aplicação
Isso adiciona latência, complexidade e pontos de falha. Com pgvector, tudo acontece no mesmo lugar.
5. Performance: quando pgvector é suficiente vs quando migrar
Pgvector não é bala de prata. Ele tem limites. Eis quando usar e quando migrar:
| Cenário | pgvector | Banco vetorial dedicado |
|---|---|---|
| Até 100k embeddings | ✅ Excelente | ❌ Overkill |
| 100k — 1M embeddings | ✅ Bom com HNSW | ✅ Também funciona |
| 1M — 10M embeddings | ⚠️ Requer tuning | ✅ Recomendado |
| > 10M embeddings | ❌ Latência alta | ✅ Obrigatório |
| Latência < 10ms | ⚠️ Depende do índice | ✅ Mais consistente |
| Busca híbrida frequente | ✅ Muito superior | ❌ Complexo |
| Orçamento apertado | ✅ Grátis (já pago) | ❌ Custo adicional |
A decisão prática: comece com pgvector. A configuração é trivial, o custo é zero (você já paga pelo PostgreSQL) e você só migra quando tiver evidência de que precisa. Nunca otimize proativamente para escala que você não tem.
6. Benchmark: PostgreSQL vs banco vetorial dedicado (100k embeddings)
Fizemos um benchmark interno na Haruo com 100 mil embeddings (dimensão 1536, texto de descrições de produtos):
| Métrica | PostgreSQL (pgvector HNSW) | Pinecone (pod serverless) | Weaviate |
|---|---|---|---|
| Query P99 (sem filtro) | 12ms | 8ms | 10ms |
| Query P99 (com filtro SQL) | 18ms | 45ms* | 35ms* |
| Insert throughput (1000/s) | ✅ Sim | ✅ Sim | ✅ Sim |
| Custo/mês (100k vec) | $0** | ≈ $70 | ≈ $90 |
| Complexidade operacional | Mínima | Média | Média |
*Filtros em banco vetorial exigem pós-processamento **Considerando que você já tem PostgreSQL rodando
A diferença de latência em queries puras existe (12ms vs 8ms), mas raramente é relevante. A diferença de custo (zero vs $70-90/mês) é difícil de ignorar.
7. Conclusão: stack completa com PostgreSQL
PostgreSQL com pgvector oferece uma stack completa para sistemas com AI agents:
- Busca por similaridade para recuperação de memória
- Dados estruturados para metadados, usuários e configurações
- Histórico de conversas com JOINs simples
- Busca híbrida combinando vetores e filtros na mesma query
- Transações ACID para consistência de dados críticos
- Backup, replicação e fail recovery maduros
Tudo num banco só, sem precisar de Pinecone, Weaviate ou Qdrant — a menos que você realmente precise escalar além de 10 milhões de embeddings.
Na Haruo, usamos PostgreSQL + pgvector como padrão em todos os projetos com agents. Quando o cliente cresce e precisa de um banco dedicado, a migração é transparente porque a abstração de memória já está isolada do mecanismo de busca.
Quer ajuda para arquitetar a stack de AI agents da sua empresa? Fale com a Haruo → (/#contato)
Quer levar isso para produção?
Na Haruo, implementamos agents de IA, automações e sistemas escaláveis para empresas que querem resultados reais. Vamos conversar sobre seu projeto.
Falar com a Haruo →