A memória de agentes é um dos problemas de infraestrutura mais difíceis na IA aplicada no momento, e o ecossistema de benchmarks em torno dela ainda está tomando forma. Este é um artigo em duas partes. A Parte 1 aborda o que estábamos usando como parâmetro, como o medimos e como o pipeline é construído. A Parte 2 aborda o que os experimentos realmente mostraram. Estamos publicado ambos porque as decisões envolvidas na avaliação são tão consequentes quanto as decisões do sistema, e essa parte raramente é posta no papel.
O que é a memória de agentes e por que ela não é apenas RAG?
A memória do agente é o que faz com que um agente de IA não pareça ter amnésia.
Os agentes de IA tradicionais não têm estado. Cada conversa começa do zero. Por exemplo, um bot de atendimento ao cliente resolve um chamado, o usuário liga novamente dois dias depois, e o bot não tem registro da interação anterior. Um assistente de programação explica o mesmo conceito duas vezes na mesma semana porque não tem memória da primeira conversa. Um assistente de compras recomenda algo que o usuário já comprou.
A memória do agente resolve isso mantendo uma camada persistente que armazena o que um agente aprende sobre um usuário entre sessões e torna isso recuperável em interações futuras. O agente aprende hoje que um usuário é vegetariano e alérgico a crustáceos, e recorre a esse contexto em outubro, quando o usuário pede recomendações de jantar.
Se você já trabalhou com geração aumentada por recuperação (RAG) antes, isso pode parecer familiar. Os mecanismos superficiais são semelhantes: armazenar coisas em um banco de dados vetorial, recuperar trechos relevantes no momento da consulta e passá-los para um LLM. Mas a memória de agentes é um problema fundamentalmente diferente de três maneiras.
Primeiro, o corpus é pessoal e dinâmico. No RAG de documentos, o corpus é geralmente uma coleção estática, uma base de conhecimento, um conjunto de PDFs e uma base de código. Na memória do agente, o corpus é todo o histórico de conversas de um usuário. Ele cresce a cada sessão e é diferente para cada usuário.
Segundo, as consultas são autobiográficas em vez de informacionais. Uma pesquisa em base de conhecimento é uma consulta sobre o mundo. Uma consulta de memória é uma consulta sobre o usuário, coisas que ele disse, preferências que expressou e experiências que mencionou. “Qual é a capital da França?” e “O que eu disse sobre minhas restrições alimentares?” não são o mesmo problema de recuperação.
Em terceiro lugar, o tempo é uma dimensão de primeira classe. O mesmo fato pode aparecer de forma contraditória entre sessões, e a recência determina qual versão está correta. Se um usuário mencionou dois gatos em março e três gatos em junho, a resposta correta para “Quantos gatos eu tenho?” depende inteiramente de quando a pergunta está sendo feita. Um sistema de recuperação de documentos não precisa raciocinar sobre isso. Um sistema de memória de agente, sim, e constantemente.

É por isso que um sistema RAG não pode simplesmente ser rebatizado como “memória de agente”. As decisões de projeto são diferentes, os modos de falha são diferentes e, como descobrimos, os benchmarks também são diferentes. Os sistemas de recuperação de documentos são avaliados com base na capacidade de encontrar o trecho correto em um corpus fixo. Os sistemas de memória de agente precisam lidar com um corpus que é pessoal, está em constante crescimento e repleto de contradições. Os benchmarks existentes para o RAG não revelam os modos de falha que são relevantes para a memória de agente. Tivemos que encontrar aqueles que o fazem.
Os benchmarks: o que existe e por que importa
Antes de medir qualquer coisa, tivemos que decidir sobre o que medir.
O cenário de benchmarks de memória de agentes ainda é relativamente jovem. Nós trabalhamos com dois deles: LoCoMo e LongMemEval.
O LoCoMo (Long-term Conversation Memory) é baseado em 10 registros de conversas longas – conversas naturalistas entre duas pessoas que divagam, fazem referência a eventos passados e contêm contexto implícito. A partir desses 10 registros, o benchmark gera 1.540 perguntas distribuídas em quatro categorias:
- Salto Único: Uma única informação, declarada diretamente em algum lugar. “O que a Caroline pesquisou?” -> “agências de adoção.”
- Multi-salto: A resposta exige conectar informações de dois ou mais lugares. “Para que a corrida beneficente conscientizou?” -> você precisa descobrir tanto que houve uma corrida beneficente quanto que era para a saúde mental.
- Temporal: Perguntas sobre quando as coisas acontecem. “Quando a Melanie pintou um nascer do sol?” -> “2022.”
- Domínio Aberto: Questões que exigem raciocínio em vez de recuperação. “Caroline ainda gostaria de buscar aconselhamento se não tivesse recebido apoio enquanto crescia?” -> a resposta não está declarada em lugar nenhum, ela precisa ser inferida.
O LoCoMo testa a memória naturalista de longo prazo. As conversas são confusas, da mesma forma que as conversas reais são confusas. As respostas estão inseridas no contexto, em vez de serem claramente rotuladas.
O LongMemEval é construído de forma diferente. Ele consiste em 500 perguntas, cada uma inserida em um palheiro de sessões de conversação. Os tipos de perguntas são mais granulares e, sob a perspectiva de design de sistemas, mais reveladores:
- Usuário de Sessão Única (SSU): Algo que o usuário disse em uma sessão. “Quanto tempo dura o meu trajeto para o trabalho?” -> “45 minutos.”
- Assistente de Sessão Única (SSA): Algo que o assistente disse em uma sessão. “Você pode me lembrar o nome do restaurante em Roma que eu gostei?” -> “Roscioli.” Essa categoria é importante porque a resposta está nos próprios registros anteriores do assistente, e não nos do usuário.
- Preferência de Sessão Única (SSP): Uma preferência que o usuário expressou. “Você pode sugerir acessórios que complementem meu equipamento de fotografia?” -> o sistema precisa ter retido a preferência do usuário por equipamentos compatíveis com Sony.
- Multissessão (MS): A resposta exige a síntese de informações provenientes de várias sessões diferentes.
- Atualização de Conhecimento (KU): A informação foi alterada. “Quantas bicicletas eu tenho atualmente?” -> “4.” Mas, anteriormente no histórico, a resposta era 3. O sistema precisa reconhecer que a informação foi sobrescrita.
- Raciocínio Temporal (TR): Perguntas que exigem aritmética temporal. “Quantos meses se passaram desde a minha última visita ao museu?” -> o sistema deve identificar quando a visita ocorreu, quando a pergunta está sendo feita e calcular a diferença.
A categoria Knowledge Update é particularmente bem projetada porque a maioria dos *benchmarks* não testa se um sistema lida com contradições no histórico de conversas. Um sistema de memória de agente que não consegue lidar com KU retornará com confiança informações desatualizadas, o que é um dos modos de falha mais graves em produção.
LoCoMo vs. LongMemEval: o que os torna genuinamente diferentes
Estes dois benchmarks testam coisas diferentes, e entender a diferença importa antes de olhar para os resultados.
O LoCoMo usa conversas reais e não roteirizadas entre duas pessoas. O sistema de memória precisa lidar com ambos os lados, o que Caroline disse e o que Melanie disse. O pipeline de ingestão reflete isso com uma extração de ponto de vista duplo: cada troca cria dois blocos de memória, cada um associado a um locutor. Isso não é apenas uma convenção de formatação. As perguntas do LoCoMo podem ser feitas a partir de qualquer perspectiva, e o sistema precisa da versão dos fatos de cada locutor disponível no momento da recuperação.
O LongMemEval utiliza conversas entre um usuário e um assistente de IA, com perguntas feitas pelo usuário sobre seu próprio histórico. Na configuração LME-M, também usamos o ponto de vista dual (um bloco da perspectiva do usuário e um bloco da perspectiva do assistente por troca), porque o tipo de pergunta SSA pergunta especificamente o que o assistente disse. No LME-S, simplificamos para um único ponto de vista sequencial e alcançamos pontuações idênticas com metade da latência. Essa troca é abordada em Parte 2.
A outra diferença estrutural é a escala. O LoCoMo tem 10 conversas. O LongMemEval tem 500 perguntas, cada uma com seu próprio palheiro. O LoCoMo testa a profundidade de recuperação ao longo de um único relacionamento estendido. O LongMemEval testa se o sistema de recuperação consegue trazer à tona a memória correta em uma coleção grande e crescente de sessões.
As duas escalas do LongMemEval, e por que isso importa
O LongMemEval vem em duas variantes: LME-S e LME-M. Mesmas 500 perguntas, mesma distribuição de tipos de perguntas. A diferença é o quão difícil o sistema precisa pesquisar.
O LME-S coloca cada resposta em um "palheiro" de aproximadamente 46 sessões (cerca de 115.000 tokens por problema). O LME-M coloca a mesma resposta em cerca de 500 sessões, aproximadamente 1,5 milhão de tokens por problema. Isso representa uma expansão de 20 vezes no espaço de busca com a mesma "agulha" a ser encontrada.
Isso acabou se revelando uma das descobertas mais importantes do projeto. A configuração que funciona bem no LME-S não é transferida para o LME-M. Se um sistema for otimizado no LME-S e implantado em escala de produção, é provável que esteja mal configurado de maneiras que são difíceis de detectar sem avaliar em ambas as escalas.
O exemplo mais claro é a profundidade de recuperação. O k ideal no LME-S é 10. Na escala LME-M, k=20 é necessário. Com mais sessões no palheiro, a memória relevante fica mais diluída, e um conjunto de recuperação mais profundo é necessário para trazê-la à tona de forma confiável. O Raciocínio Temporal, que não mostra praticamente nenhuma sensibilidade a k no LME-S, beneficia-se significativamente de um k mais alto no LME-M, porque o contexto de data relevante está espalhado por mais sessões.
As variantes de prompt também apresentam divergências. O prompt de resposta que apresenta melhor desempenho no LME-S tem um desempenho visivelmente pior no LME-M. Observamos uma diferença de 11,8 pontos entre as variantes de prompt no LME-M (72,41 TP3T contra 60,61 TP3T).
O LME-S é um benchmark de desenvolvimento útil. O LME-M está mais próximo de como a produção realmente se parece. Avaliar em ambos, e prestar atenção quando os resultados divergem, vale o esforço.
Como medimos o desempenho
Monitoramos três métricas em todos os experimentos.
A pontuação BLEU conta sobreposições de n-gramas entre a resposta gerada e a resposta de referência. Para um exemplo simples: Se a resposta esperada for “bob likes pancakes” e o sistema retornar “bob likes pancakes, cakes, and mustard,” a pontuação BLEU será 0,4 porque apenas dois dos cinco pares de palavras na saída correspondem à resposta esperada. O BLEU é uma verificação de sanidade útil, mas penaliza paráfrases e premia correspondências textuais de uma maneira que nem sempre reflete se uma resposta está substantivamente correta.
O escore F1 mede a sobreposição em nível de palavra sem exigir ordem das palavras, calculando a precisão (qual fração das palavras geradas aparece na referência) e a revocação (qual fração das palavras de referência aparece na saída). Para o mesmo exemplo, o escore F1 é 0,67. Melhor, mas ainda puramente lexical.
O Juiz LLM (pontuação J) é a métrica principal. Um LLM lê a resposta esperada e a resposta gerada e julga se a resposta gerada está semanticamente correta. Para “bob gosta de panquecas” versus “bob gosta de panquecas, bolos e mostarda”, o juiz atribui a nota 1; a resposta gerada contém as informações corretas, mesmo com conteúdo adicional. Esta é a métrica em que mais confiamos para avaliar se o sistema está realmente funcionando.

Uma observação importante sobre o J-score: as instruções dadas ao avaliador são tão importantes quanto o próprio sistema que está sendo avaliado. O avaliador do LoCoMo está configurado para ser generoso – “desde que a resposta aborde o mesmo tema, considere-a correta”. O LongMemEval utiliza variantes específicas para cada categoria: uma para raciocínio temporal (permite erros de “off-by-one” na contagem de dias), uma para atualização de conhecimento (considera correta a resposta atualizada, mesmo que informações antigas também sejam mencionadas), uma para preferências (baseada em critérios de avaliação) e uma para precisão direta. Executar nosso sistema com um avaliador muito mais rigoroso reduz as pontuações em vários pontos, independentemente de qualquer alteração no sistema. Comparações entre avaliadores alteram as pontuações em 5 a 10 pontos e não são interpretáveis. Quando executamos o LoCoMo com instruções de avaliação usadas por outras soluções de memória, obtivemos uma pontuação 100% teoricamente impossível, o que indicou imediatamente que a comparação foi inflacionada pela instrução, em vez de refletir a qualidade da recuperação. Relatar uma pontuação J sem especificar a instrução do avaliador é como relatar uma nota de prova sem especificar qual prova foi aplicada.
Como o pipeline funciona
Quando um turno de conversa entra no sistema, ele passa por uma extração de ponto de vista duplo antes que qualquer coisa seja gravada no banco de dados. O código de ingestão emparelha cada mensagem do usuário com a resposta seguinte do assistente e cria dois blocos de memória, um indexado para o usuário, outro indexado para o assistente. “Usuário disse X, Assistente disse Y” produz um bloco a partir da perspectiva do usuário e um bloco separado a partir da perspectiva do assistente.
Com context_required=True configurado em cada pipeline, o sistema dispara uma chamada de LLM durante a ingestão para extrair um resumo em prosa e uma lista de fatos discretos de cada troca. O que é gravado no Couchbase são três coisas: o texto bruto da mensagem, o resumo e uma lista de contextos de strings de fatos. Os carimbos de data/hora são anexados como anotações em formato legível por humanos (“1:10 pm on 27 March, 2023”) para que o modelo possa raciocinar sobre eles naturalmente no momento da recuperação.
Um bloco de memória se parece mais ou menos com isto:
{
"message": "User: When did I start the job? Assistant: You mentioned starting in March 2023.",
"summary": "O usuário está perguntando sobre a data de início do seu trabalho; o assistente confirmou março de 2023.",
"contexts": [
"O usuário começou seu trabalho em março de 2023",
"O usuário expressou incerteza sobre a data exata de início"
],
"annotations": {
"time": "1:10 pm on 27 March, 2023",
"conversation_id": "abc123"
}
}
A chamada de ingestão retorna em aproximadamente 251ms no p50, cobrindo validação, geração de embeddings e a gravação no Couchbase. A extração de contexto do LLM (resumo e lista de contextos) ocorre de forma assíncrona em segundo plano e leva aproximadamente 3,6 segundos em média. O chamador não espera por isso. Esse desacoplamento, por meio de uma fila de despacho que separa a latência de ingestão da latência de extração, é o que torna o sistema prático em escala. Um modo síncrono está disponível quando a pesquisabilidade imediata é necessária, ao custo da espera de 3,6 segundos.
A pesquisa funciona de maneira diferente. A chamada get_memory() incorpora a consulta (aproximadamente 305ms no p50) e executa uma busca de similaridade vetorial contra os blocos armazenados no Couchbase (aproximadamente 5ms no p50). A latência total voltada para o cliente é de cerca de 298ms no p50. O gargalo é a etapa de incorporação, não a recuperação em si. A busca de texto completo (FTS) do Couchbase é rápida.

Especificamente para o pipeline de avaliação: as memórias são ingeridas uma vez e persistem no Couchbase. As etapas de busca e avaliação são executadas no banco de dados ativo com diferentes parâmetros de configuração, sem necessidade de nova ingestão entre as varreduras de parâmetros.
O pipeline está construído. Os benchmarks estão selecionados. As métricas estão definidas. Tudo isso é trabalho de base. A verdadeira pergunta é o que realmente acontece quando você executa o sistema contra benchmarks reais em grande escala, em várias configurações experimentais diferentes. É isso que Parte 2 é sobre.

Deixe um comentário
Você precisa fazer o login para publicar um comentário.