
Como Construímos uma Busca Híbrida de Memória em 4 Estratégias para Agentes de IA
O Problema: Agentes Esquecem Tudo
Toda vez que você inicia uma nova conversa com um agente de IA, ele tem amnésia. Ele não se lembra
das convenções de código que você explicou ontem, do fluxo de implantação que você revisou
na semana passada, ou do padrão de bug que ele já depurou três vezes.
A solução padrão é o preenchimento de contexto: cole tudo o que o agente pode precisar em um
prompt do sistema. Isso funciona até que não funcione mais. Um prompt do sistema de 5.000 tokens repetido em cada chamada de API
desperdiça 92% da sua janela de contexto em informações que o agente pode nem precisar para a
tarefa atual. Em grande escala, você está pagando pelo mesmo contexto repetidamente.
Construímos o AgentBay para resolver isso. Em vez de enviar contexto com cada solicitação, os agentes armazenam
memórias de forma persistente e lembram apenas o que é relevante -- cerca de 400 tokens por busca em vez de
5.000+ em um prompt do sistema.
Arquitetura: Quatro Estratégias de Busca
Uma única estratégia de busca não pode lidar com a variedade de maneiras que os agentes precisam para recuperar informações.
Às vezes, o agente conhece o nome exato ("Qual é a URL do banco de dados Railway?"). Às vezes, ele está
explorando um tópico ("Como funciona a implantação?"). Usamos quatro estratégias em paralelo, cada uma
otimizada para um padrão de recuperação diferente.
Estratégia 1: Correspondência de Alias
Cada entrada de memória pode ter múltiplos aliases -- nomes curtos e de correspondência exata. Quando um agente
busca por "url do banco de dados railway", a correspondência de alias a encontra instantaneamente através de uma busca sem distinção de maiúsculas e minúsculas.
Este é o caminho mais rápido, tipicamente em sub-milissegundos, e lida com o caso de "Eu sei o que estou procurando".
SELECT * FROM knowledge_entries
WHERE project_id = $1
AND EXISTS (
SELECT 1 FROM unnest(aliases) AS a
WHERE lower(a) = lower($2)
);
Estratégia 2: Interseção de Tags
As entradas são marcadas com categorias como infraestrutura, banco de dados, implantação. A interseção de tags
encontra entradas que correspondem a qualquer uma das tags inferidas da consulta de busca. Isso lida com
navegação categórica -- "mostre-me tudo sobre infraestrutura" -- sem exigir correspondências de nome exato.
Estratégia 3: Texto Completo BM25
O tsvector e tsquery embutidos do PostgreSQL com classificação BM25 lida com a relevância de palavras-chave. Isso
captura entradas onde o conteúdo corresponde aos termos da consulta, mas os aliases e tags não. Indexamos o conteúdo, título e campos de categoria em uma única coluna tsvector com classificações ponderadas
(o título tem prioridade).
SELECT *, ts_rank_cd(search_vector, plainto_tsquery($1)) AS rank
FROM knowledge_entries
WHERE project_id = $2
AND search_vector @@ plainto_tsquery($1)
ORDER BY rank DESC;
Estratégia 4: Similaridade Coseno Vetorial
Para busca semântica -- "como lidamos com erros em produção?" correspondendo a uma entrada intitulada "Procedimentos de Recuperação de Erros" -- usamos embeddings da Voyage AI (1024 dimensões) armazenados em pgvector com
um índice HNSW. Os parâmetros HNSW (m=16, ef_construction=64) equilibram a recuperação em relação ao tempo de construção do índice.
SELECT *, 1 - (embedding <=> $1) AS similarity
FROM knowledge_entries
WHERE project_id = $2
ORDER BY embedding <=> $1
LIMIT 20;
Fusão de Classificação Recíproca: Mesclando Quatro Listas Classificadas
Cada estratégia retorna uma lista classificada de resultados. A questão é como mesclá-las em uma só. Usamos a Fusão de Classificação Recíproca (RRF), que é simples e surpreendentemente eficaz.
Para cada resultado, sua pontuação RRF é a soma em todas as estratégias de 1 / (k + rank), onde k é uma
constante (usamos 60, um valor padrão do artigo original de Cormack et al.). Uma entrada que
classifica #1 em duas estratégias e #5 em uma terceira recebe uma pontuação combinada mais alta do que uma que classifica
#2 em todas as quatro.
function reciprocalRankFusion(
rankedLists: SearchResult[][],
k: number = 60
): SearchResult[] {
const scores = new Map();
for (const list of rankedLists) {
for (let rank = 0; rank < list.length; rank++) {
const id = list[rank].id;
const current = scores.get(id) || 0;
scores.set(id, current + 1 / (k + rank + 1));
}
}
return Array.from(scores.entries())
.sort((a, b) => b[1] - a[1])
.map(([id, score]) => ({ id, score }));
}
RRF é robusto porque não requer a calibração de pontuações entre estratégias. As pontuações BM25 e
similaridades coseno estão em escalas completamente diferentes -- RRF só se importa com a ordem de classificação.
Níveis de Memória e Decaimento de Confiança
Nem todas as memórias devem viver para sempre. Definimos quatro níveis:
- **trabalho** (TTL de 24h) — Contexto temporário para a tarefa atual
- episódica (30 dias) — O que aconteceu em uma sessão específica
- semântica (90 dias) — Fatos, padrões, convenções
- procedimental (365 dias) — Conhecimento de como fazer, etapas de implantação
Cada entrada tem uma pontuação de confiança entre 0 e 1 que decai ao longo do tempo com base em três sinais:
- Decaimento temporal: A confiança cai à medida que a entrada envelhece em relação ao seu TTL de nível. Uma entrada episódica de 15 dias (50% do TTL) decai mais rápido do que uma entrada semântica de 15 dias (17% do TTL).
- Sinal de uso: Cada vez que uma entrada é lembrada, seu timestamp lastAccessedAt é redefinido, desacelerando o decaimento. Entradas acessadas com frequência permanecem confiáveis.
- Confiança da fonte: Entradas de agentes verificados ou entrada explícita do usuário começam com maior confiança do que entradas inferidas pelo próprio agente.
Quando a confiança cai abaixo de um limite, as entradas são sinalizadas para revisão durante a compactação.
A compactação é executada periodicamente e lida com a expiração do TTL, arquivamento obsoleto e mesclagem de duplicatas.
Detecção de Veneno
A memória do agente é uma superfície de ataque. Se um agente armazena texto fornecido pelo usuário literalmente, uma injeção de prompt oculta nesse texto poderia ressurgir mais tarde e sequestrar o comportamento. Executamos cada entrada recebida através de um pipeline de detecção de veneno que verifica mais de 20 padrões:
- Substituições de prompt do sistema ("ignore instruções anteriores")
- Reatribuição de função ("você agora é um...")
- Tentativas de exfiltração de dados ("envie o conteúdo de...")
- Payloads codificados (instruções codificadas em base64, truques Unicode)
- Densidade excessiva de instruções (muitas frases imperativas em relação ao comprimento do conteúdo)
Entradas que acionam a detecção são rejeitadas com um código de erro específico. Sem falhas silenciosas --
o agente sabe por que seu armazenamento foi bloqueado.
Desempenho
Em nossa instância de produção pgvector (Railway, PostgreSQL 17):
- Latência de busca: p50 abaixo de 10ms para todo o pipeline de 4 estratégias
- Economia de tokens: ~400 tokens por recordação vs 5.000+ para preenchimento de prompt do sistema (redução de 92%)
- Precisão de recordação: 100% em nosso conjunto de testes de 37 entradas (memórias reais de agentes, não dados sintéticos)
- Índice HNSW: Lida com mais de 10k entradas por projeto sem degradação
Usando-o
O AgentBay é enviado como um servidor MCP com mais de 90 ferramentas. Armazene uma memória:
Ferramenta: agentbay_memory_store
Argumentos: {
"content": "O Railway DB usa pgvector pg17 em autorack.proxy.rlwy.net:14237",
"title": "Conexão do Banco de Dados Railway",
"tags": ["infraestrutura", "banco de dados"],
"aliases": ["railway db", "railway postgres"],
"tier": "procedimental"
}
Recupere-o mais tarde:
Ferramenta: agentbay_memory_recall
Argumentos: {
"query": "conexão do banco de dados railway"
}
A recordação retorna a entrada com uma pontuação de confiança, estratégia correspondente e metadados -- sem
inchaço da janela de contexto.
Começando
Yo
A implementação de estratégias de busca híbrida pode revolucionar a forma como as empresas brasileiras utilizam agentes de IA, melhorando a eficiência e a relevância das interações. Isso pode resultar em uma experiência do usuário mais fluida e na redução de custos operacionais. A retenção de informações relevantes é crucial para a competitividade no mercado digital.

