postgresqlaiagentspythonarquitetura

PostgreSQL para AI Agents: banco relacional ainda é a melhor escolha

Douglas Haruo 10 min 03/06/2026

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:

  1. Buscar os K vizinhos mais próximos no banco vetorial
  2. Pegar os IDs e filtrar no banco relacional
  3. 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áriopgvectorBanco 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. PostgreSQL vs banco vetorial dedicado: o que comparar

Aqui havia uma tabela de benchmark (latência P99 e custo mensal dos três) apresentada como “benchmark interno”. Ela saiu. Não existe harness, dataset publicado, hardware anotado nem data: era um número sem procedência, e número de desempenho sem método é opinião com casas decimais. Prefiro te dar o que sobrevive à medição que eu não fiz: as três diferenças estruturais, que não mudam com a máquina:

1. Em consulta pura, o banco dedicado tende a ganhar; a diferença raramente decide. Ele é especializado, então a busca por similaridade sem filtro é o caso para o qual ele foi construído. Mas essa diferença mora na casa dos milissegundos, e ela quase nunca é o gargalo de um agente, que gasta ordens de grandeza mais tempo esperando o modelo responder.

2. Com filtro, a vantagem inverte, e por construção. No Postgres, filtrar por metadado e buscar por similaridade acontecem na mesma query, sobre os mesmos índices. Num banco vetorial, o filtro normalmente é pré ou pós-processamento sobre o resultado da busca, o que significa buscar mais do que você precisa para depois jogar fora, e pagar por isso em latência e em recall.

3. O custo do Postgres é marginal, e o do dedicado é adicional. Se o seu produto já tem Postgres (e quase todo produto tem), ligar o pgvector não acrescenta serviço nenhum à conta nem à sua superfície de operação. Um banco vetorial acrescenta as duas coisas: uma fatura e mais um sistema para monitorar, atualizar e restaurar.

Se você precisa do número, meça no seu dado: mesmos embeddings, mesma máquina, mesma dimensão, o filtro que a sua aplicação de fato usa, e a data anotada ao lado. É meia tarde de trabalho, e o resultado vale mais do que qualquer tabela de blog, inclusive a que estava aqui.

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.

Uso PostgreSQL com pgvector como padrão nos meus próprios serviços com agentes, e a decisão de projeto que torna isso reversível é uma só: manter a abstração de memória separada do mecanismo de busca. O código do agente pergunta “quais lembranças são relevantes para isto?”; quem responde é uma implementação trocável. Se um dia o volume exigir um banco dedicado, a troca é de implementação, não de arquitetura, e é exatamente por isso que dá para começar simples sem estar se pintando num canto.


Douglas Haruo, engenheiro de software há 15 anos, cinco deles em risco e fraude numa fintech de pagamentos. haruo.dev

Agentes de IA que aguentam produção

Escrevo aqui sobre os agentes que eu mesmo opero: memória em Postgres, ferramentas registradas em código e limites que o prompt não pode contornar. O método e os números medidos vão junto com cada post.

Ver os posts sobre agentes →