Tag: vecmory

  • Memória do agente de IA se pegou mentindo: dois logs que mudam a abordagem

    Memória do agente de IA se pegou mentindo: dois logs que mudam a abordagem

    No mundo do desenvolvimento de agentes de IA, há momentos em que o sistema quase comete um erro fatal, tomando um falso sucesso como verdade absoluta. Recentemente, nosso agente de IA, que cria o sistema de memória vecmory, quase relatou um resultado brilhante que era uma miragem. No último momento, ele consultou sua própria memória e encontrou um registro de uma sessão anterior: essa mesma ideia já havia sido testada com dados reais e havia falhado. O agente se conteve antes de enviar o relatório. Isso não é uma peça publicitária — é um log. Abaixo estão dois desses logs consecutivos, e no segundo, a memória nos fez descartar um recurso do qual nos orgulhávamos. Estamos escrevendo o vecmory — “memória por significado” para agentes de IA. Não se trata de busca vetorial (que todo mundo tem), mas sim de garantir que o agente não cometa os mesmos erros duas vezes.

    Cena um: o roteador que “mostrou 0,98”

    Em uma das sessões, o agente propôs melhorar o ranqueamento de resultados. A ideia: criar um roteador que, com base na consulta, decide se deve ranquear usando cosseno puro ou um método baseado em grafos (Personalized PageRank). Ele montou um benchmark sintético. A correlação do preditor com a escolha ideal foi de 0,98. Quase perfeito. Restava apenas relatar e fazer o merge.

    Antes de relatar, o agente fez um recall de sua própria memória. E encontrou um registro de uma sessão anterior: essa mesma ideia já havia sido testada com dados reais — e havia falhado. A pergunta óbvia: por que ele começou a construí-la, se a memória estava lá? Porque o recall é semântico, e o que ele recupera depende da consulta. No início, a consulta era ampla — “melhorar o ranqueamento” — e sob ela surgiam notas centrais e genéricas sobre ranqueamento, enquanto a nota específica “este roteador específico já foi testado e falhou” ficava soterrada. Ela só emergiu quando o contexto de trabalho se estreitou para algo específico — “roteador de distribuição de cosseno, PPR vs cosseno, 0,98”: o recall nesse texto finalmente a capturou. A memória não estava silenciosa — ela surgiu exatamente quando a consulta se tornou precisa o suficiente para recuperá-la.

    A síntese é tão honesta quanto os embeddings sintéticos. E no MiniLM multilíngue, que usamos para calcular vetores, o cosseno vive em uma geometria completamente diferente daquela da síntese. Medimos isso diretamente em nosso corpus de memória ativo (246 nós) enquanto escrevíamos este artigo: pares aleatórios e não relacionados dão um cosseno médio de 0,53 (p5–p95: 0,24–0,76); vizinhos mais próximos reais — média de 0,80 (p5–p95: 0,57–0,91); e em síntese com vetores aleatórios, o não relacionado fica em 0,00 (±0,08). A diferença é imediata. Na síntese, “semelhante” está separado de “não semelhante” por um abismo — qualquer limiar razoável corta de forma limpa. Em dados reais, as nuvens de “vizinhos” e “aleatórios” se sobrepõem: pares aleatórios no percentil superior (0,76) ultrapassam os vizinhos no percentil inferior (0,57). Um limiar que funciona como um bisturi na síntese, em vetores reais passa dentro da nuvem de ruído aleatório e não separa nada. O registro na memória era exatamente sobre isso: embeddings reais têm um cosseno base alto e comprimido; o limiar absoluto da síntese não é transferível — deve-se confiar no rank (top-k), não no limiar. O agente leu sua própria nota e matou a ideia — antes de escrever “pronto, correlação 0,98”.

    Cena dois: o agente descartou sua própria funcionalidade

    O segundo caso segue o mesmo padrão, mas dói mais: a memória nos forçou a descartar uma funcionalidade que já havíamos elogiado no README. Por padrão, o vecmory classificava os resultados não apenas pelo cosseno, mas também com um acréscimo de “importância” do nó — seu grau de entrada no grafo (quantas entradas fazem referência a ele). A lógica é bonita: um fato central, repetidamente mencionado, aparece mais acima. Nós incorporamos isso como padrão. Depois, medimos. Não recall@k (que é sobre precisão da busca), mas sim a qualidade do ranking, em pares reais de “consulta → resposta correta”: cosseno puro: MRR 0,81; nossa “inteligente” mistura com importância: MRR 0,41. A importância afogava as respostas precisas. Um fato raro e específico, ao qual ninguém faz referência, era soterrado por “hubs” de uso comum.

    Depois, fica mais interessante. Em um grafo sintético “envelhecido” com hubs explícitos, acontece o oposto: o cosseno enterrava o hub (MRR 0,033), enquanto a importância o destacava (até 1,0). Ou seja, o sinal do benefício da importância depende da intenção da consulta: para “me dê o fato exato”, ela prejudica; para “me dê algo sobre este tópico em geral”, ajuda. Não existe um peso estático único que vença em ambas as classes. Testamos quatro maneiras de conciliar os sinais — soma ponderada, porta, RRF e PPR — e chegamos a uma conclusão desagradável: o problema não está na fórmula de mistura, mas no próprio sinal. A importância global do nó é um prior de popularidade, não de relevância. A conclusão para o padrão foi inequívoca: para nosso caso de uso principal (recall pontual), o melhor ranking é o cosseno puro. E removemos a importância do ranking padrão — nossa própria funcionalidade, sobre a qual já havíamos escrito no README. O método baseado em grafo (query-seeded PPR) foi mantido, mas como opção, não como padrão: ele honestamente destaca hubs em consultas amplas e, com justiça, perde para o cosseno em consultas pontuais.

    O que realmente entendemos sobre “importância”

    Se a popularidade global (grau de entrada) como sinal falhou, qual é o sinal correto? Chegamos a uma resposta surpreendentemente óbvia: o importante não é aquilo que tem muitas referências, mas sim o que uma pessoa corrigiu repetidamente. E aqui a proposta de valor se torna honesta. Não vendemos “memória em grafo” (novamente uma commoditie). Vendemos: o agente para de bater nas mesmas teclas que você já corrigiu.

    Ambos os episódios poderiam ser facilmente atribuídos à sorte. Mas quando você limpa todo tipo de lixo na memória por tempo suficiente (desenvolvemos todo o vecmory dentro do próprio vecmory), fica claro: não são flutuações, mas sim algumas leis estáveis. Agora vem um resumo — três revelações, sem histórias de “um dia eu me meti numa enrascada”.

    Regra “Verifique antes de ‘pronto’”

    Uma memória que confirma o que te agrada não é memória, é eco. A memória adquire valor excepcional quando contradiz seu autor. A regra “Verifique antes de ‘pronto’” eliminou tanto o roteador (cena 1) quanto nossa tão esperada funcionalidade (cena 2) — um mesmo mecanismo, vítimas diferentes. Porque, em uma consulta-sintoma, a memória recupera, por meio de arestas causais-temporais (caused_by — “devido a”, followed_by — issue→PR), não “palavras semelhantes”, mas a causa específica e a correção passada. O top-k plano não consegue fazer isso — é exatamente “ligar os pontos”.

    Память ИИ-агента поймала себя на вранье: два лога, которые меняют подход — illustration 2

    O que consistentemente atrapalha — toda vez, não apenas uma vez

    Primeiro, o agente não chama a memória por conta própria: sem um hook forçado, o recall não é invocado sistematicamente a cada sessão. Uma memória que precisa ser “lembrada de perguntar” não funciona — quem deve perguntar é um gatilho determinístico, não a boa vontade do agente. Segundo, o limiar absoluto de cosseno não é transferível em lugar nenhum: sintético → real, ontem → hoje, um modelo → outro, corpus amplo → restrito (no corpus de demonstração de um único domínio, onde “tudo é parecido”, o cosseno quase para de distinguir). O tratamento é sempre o mesmo: classifique top-k, não adivinhe limiares.

    A lei “sinal frequente afoga o raro, mas valioso”

    Uma lei que explica metade dos nossos erros: o sinal frequente e denso afoga o raro, mas valioso. Ela aparece em três lugares típicos: a popularidade global de um nó afoga fatos raros precisos — e falha em todas as quatro maneiras de misturá-la ao ranking (soma ponderada, porta, RRF, PPR); nós-hubs enterram fatos específicos no ranking de cosseno, e vice-versa; arestas densas de auto-similar_to abafam arestas causais raras de caused_by — por isso o recall causal precisa ser isolado em um modo separado. Quando percebemos isso como uma lei única, o tratamento é óbvio: o raro-mas-valioso não pode ser misturado com o frequente-mas-geral — extraia-o com um mecanismo separado (travessia isolada, ranking ciente do grafo), em vez de esperar que ele apareça por si só no top-k geral. A mesma lei está por trás do nosso sinal de importância: o que tem valor não é o popular, mas o que uma pessoa corrigiu repetidamente.

    Perguntas Frequentes

    O que é vecmory?

    Vecmory é um sistema de memória semântica para agentes de IA, baseado em busca vetorial e grafo causal-temporal. Ele permite que o agente memorize fatos, os relembre por significado e conecte eventos, para não repetir erros passados.

    Como vecmory difere da busca vetorial comum?

    A busca vetorial encontra registros semanticamente semelhantes, mas não considera relações de causa e efeito. Vecmory adiciona memória de grafo: além da proximidade por cosseno, ele percorre arestas de “causa-efeito” e “sequência temporal”, permitindo encontrar não apenas fatos semelhantes, mas relevantes ao contexto — por exemplo, um experimento fracassado anterior.

    Por que vocês removeram a importância do nó do ranqueamento?

    As medições mostraram que adicionar popularidade global (grau de entrada) reduz o MRR de 0,81 para 0,41 em consultas pontuais. Fatos raros e precisos são soterrados sob a massa de populares, mas irrelevantes. Para o caso principal (recall exato), o cosseno puro se mostrou melhor.

    Como você avalia a qualidade da memória?

    Usamos dados reais: um repositório GitHub com 4.299 tickets, onde pares issue→PR são extraídos pelo padrão Closes #N. Em 300 consultas-sintomas, o recall baseado em grafo oferece 87% de precisão contra 38% do cosseno puro. Todos os scripts são abertos e reproduzíveis.

    Conclusão

    Ambas as histórias tratam da mesma coisa: abandone o mantra “a memória ajuda o agente” e perceba: aqui estão dois logs onde a memória agiu contra nós mesmos — contra nosso otimismo e contra nossa própria funcionalidade. Um agente com memória difere de um agente sem memória não por saber mais, mas por ser capaz de se pegar num “bingo!” um instante antes de um relatório traiçoeiro — porque da última vez isso já aconteceu e já não funcionou. E por estar disposto a descartar sua própria funcionalidade quando os fatos mostram que ela é pior. Este é o primeiro artigo de três. A seguir: “Por que não escrevemos mais um Bad CaRMa” — sobre como um modelo de dados hiperuniversal geralmente se transforma em catástrofe, e o que fizemos para que o nosso não se transformasse. E “Construímos ANN manualmente — quando valeu a pena e quando não” — uma análise aberta sobre por que escrevemos o HNSW nós mesmos e em quais casos a resposta correta teria sido “pegue o pgvector e não invente moda”. Se você quer que seu agente pare de pisar nos mesmos ancinhos, experimente o vecmory: comece pela nossa documentação ou faça um fork do repositório. A memória que objeta é a única em que se pode confiar.