Tag: embeddings sintéticos

  • La memoria del agente de IA se sorprendió mintiendo: dos registros que cambian el enfoque

    La memoria del agente de IA se sorprendió mintiendo: dos registros que cambian el enfoque

    En el mundo del desarrollo de agentes de IA, hay momentos en que el sistema está a punto de cometer un error fatal, presentando un éxito falso como si fuera genuino. Recientemente, nuestro agente de IA, que crea el sistema de memoria vecmory, casi reporta un resultado brillante que resultó ser un espejismo. En el último momento, consultó su propia memoria y encontró un registro de una sesión anterior: ya había probado esta idea con datos reales, y había fracasado. El agente se detuvo antes de enviar el informe. Esto no es un boceto publicitario, es un registro. A continuación, dos de esos registros consecutivos, y en el segundo, la memoria nos obligó a descartar una función de la que estábamos orgullosos. Estamos escribiendo vecmory — «memoria por significado» para agentes de IA. No se trata de búsqueda vectorial (que todos tienen), sino de evitar que el agente tropiece dos veces con la misma piedra.

    Escena uno: el enrutador que «mostró 0.98»

    En una de las sesiones, el agente propuso mejorar el ranking de resultados. La idea: crear un enrutador que, según la consulta, decida si clasificar usando coseno puro o un método de grafos (Personalized PageRank). Creó un benchmark sintético. La correlación del predictor con la elección ideal fue de 0.98. Casi perfecto. Solo quedaba informar y fusionar.

    Antes de informar, el agente hizo un recall de su propia memoria. Y encontró un registro de una sesión anterior: esta misma idea ya se había probado con datos reales, y había fracasado. Pregunta razonable: ¿por qué entonces se puso a construirla si la memoria estaba ahí? Porque el recall es semántico, y lo que recupera depende de la consulta. Al inicio, la consulta era amplia — «mejorar el ranking» — y bajo ella surgían notas centrales y generales sobre ranking, mientras que la específica «este enrutador concreto ya se probó y fracasó» quedaba sepultada. Solo emergió cuando el contexto de trabajo se redujo a algo concreto — «enrutador de distribución cos, PPR vs coseno, 0.98»: el recall con ese texto finalmente la atrapó. La memoria no estaba en silencio; surgió justo cuando la consulta fue lo suficientemente precisa para recuperarla.

    La síntesis es tan honesta como lo son los embeddings sintéticos. Y con MiniLM multilingüe, con la que calculamos los vectores, el coseno vive en una geometría completamente diferente a la de los datos sintéticos. Lo medimos directamente en nuestro corpus de memoria en vivo (246 nodos) mientras escribíamos este artículo: pares aleatorios no relacionados dan un coseno promedio de 0.53 (p5–p95: 0.24–0.76); los verdaderos vecinos cercanos promedian 0.80 (p5–p95: 0.57–0.91); y en datos sintéticos de vectores aleatorios, lo no relacionado se sitúa en 0.00 (±0.08). La diferencia es evidente de inmediato. En datos sintéticos, «similar» está separado de «no similar» por un abismo: cualquier umbral razonable corta limpiamente. En datos reales, las nubes de «vecinos» y «aleatorios» se superponen: los pares aleatorios en el percentil superior (0.76) superan a los vecinos en el percentil inferior (0.57). Un umbral que funciona como un bisturí en datos sintéticos, en vectores reales atraviesa la nube de ruido aleatorio y no separa nada. El registro en la memoria trataba exactamente de esto: los embeddings reales tienen un coseno base alto y comprimido; el umbral absoluto de datos sintéticos no se traslada; hay que basarse en el rango (top-k), no en el umbral. El agente leyó su propia nota y mató la idea, antes de escribir «listo, correlación 0.98».

    Segundo acto: el agente descartó su propia función

    El segundo caso sigue el mismo patrón, pero duele más: la memoria nos obligó a descartar una función que ya habíamos elogiado en el README. Por defecto, vecmory clasificaba los resultados no solo por coseno, sino también añadiendo la «importancia» del nodo — su grado de entrada en el grafo (cuántas entradas hacen referencia a él). La lógica era bonita: un hecho central, mencionado repetidamente, aparece más arriba. Lo incorporamos como valor predeterminado. Luego medimos. No recall@k (eso es sobre precisión de búsqueda), sino la calidad del rango en pares reales de «consulta → respuesta correcta»: coseno puro: MRR 0.81; nuestra mezcla «inteligente» con importancia: MRR 0.41. La importancia hundía las respuestas precisas. Un hecho específico y raro, al que nadie hace referencia, quedaba opacado por los «hubs» de uso común.

    Luego, más interesante. En un grafo sintético «envejecido» con hubs evidentes, sucedía lo contrario: el coseno enterraba el hub (MRR 0.033), mientras que la importancia lo rescataba (hasta 1.0). Es decir, el signo del beneficio de la importancia depende de la intención de la consulta: para «dame el hecho exacto» perjudica, para «dame información general sobre este tema» ayuda. No existe un peso estático único que gane en ambas clases. Probamos cuatro formas de conciliar las señales — suma ponderada, compuerta, RRF y PPR — y llegamos a una conclusión desagradable: el problema no está en la fórmula de mezcla, sino en la señal misma. La importancia global del nodo es un prior de popularidad, no de relevancia. La conclusión para el valor predeterminado fue clara: para nuestro caso de uso principal (recall puntual), el mejor rango es el coseno puro. Así que eliminamos la importancia de la clasificación predeterminada — nuestra propia función, de la que ya habíamos escrito en el README. Dejamos el método basado en grafos (query-seeded PPR) como opción, no como predeterminado: extrae honestamente los hubs en consultas amplias y pierde justamente frente al coseno en consultas puntuales.

    Lo que realmente entendimos sobre la «importancia»

    Si la popularidad global (grado de entrada) como señal falló, ¿cuál es la señal correcta? Llegamos a una respuesta sorprendentemente obvia: lo importante no es aquello a lo que muchas referencias apuntan, sino lo que una persona ha corregido repetidamente. Y aquí la propuesta de valor se vuelve honesta. No vendemos «memoria de grafo» (otra commoditie). Vendemos: el agente deja de tropezar una y otra vez con los mismos errores que ya corregiste.

    Ambos episodios podrían atribuirse fácilmente a la suerte. Pero cuando limpias suficiente basura en la memoria (desarrollamos todo vecmory dentro del propio vecmory), se nota: no son fluctuaciones, sino varias leyes estables. Ahora viene un resumen — tres revelaciones, sin historias de «una vez me pasó».

    Regla «Verifica antes de dar por terminado»

    La memoria que confirma lo que te agrada no es memoria, es eco. La memoria adquiere un valor excepcional cuando contradice a su autor. La regla «Verifica antes de dar por terminado» eliminó tanto el enrutador (acto 1) como nuestra tan esperada función (acto 2) — un mismo mecanismo, víctimas diferentes. Porque ante una consulta-síntoma, la memoria extrae a través de aristas causales y temporales (caused_by — «debido a», followed_by — problema→PR) no «palabras similares», sino la causa concreta y la corrección pasada. Un top-k plano no puede hacer eso — eso es «conectar los puntos».

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

    Y esto es exactamente medible, no a ojo. Tomamos un repositorio vivo de tickets (4299 nodos: 1993 issues + 2306 PRs) y un etiquetado que no inventamos nosotros: el patrón estándar de GitHub Closes #N en el cuerpo del PR — pares listos de «síntoma → su arreglo», extraídos con regex puro, sin ningún LLM. En 300 consultas-síntoma retenidas, el coseno puro encuentra el PR de arreglo correcto en el 38% de los casos (a veces el arreglo comparte vocabulario con el síntoma), mientras que recorrer el grafo causal lo logra en el 87%. La diferencia de 49 puntos es exactamente la contribución del grafo sobre la similitud de palabras. El script de medición está en el repositorio; el número se reproduce con un comando.

    Qué falla sistemáticamente — cada vez, no solo una

    Primero, el agente no llama a la memoria por sí mismo: sin un hook forzado, recall no se invoca de forma sistemática en cada sesión. La memoria que hay que «acordarse de preguntar» no funciona — quien debe preguntar es un disparador determinista, no la buena voluntad del agente. Segundo, el umbral absoluto de coseno no se traslada a ningún lado: sintético → real, ayer → hoy, un modelo → otro, corpus amplio → corpus reducido (en un corpus de demostración de un solo dominio, donde «todo se parece», el coseno casi deja de distinguir). El remedio es siempre el mismo: clasifica por top-k, no adivines umbrales.

    La ley «la señal frecuente ahoga a la rara pero valiosa»

    Una ley que explica la mitad de nuestros tropiezos: la señal frecuente y densa ahoga a la rara pero valiosa. Aparece en tres lugares típicos: la popularidad global de un nodo ahoga los hechos raros y precisos — y hace fallar las cuatro formas de mezclarla con el rango (suma ponderada, compuerta, RRF, PPR); los nodos hub entierran hechos específicos en el rango de coseno, y viceversa; las aristas densas de auto-similaridad (similar_to) ahogan las aristas causales raras (caused_by) — por eso el recall causal debe sacarse a un modo aislado separado. Cuando se percibe como una ley única, el remedio es obvio: lo raro pero valioso no debe mezclarse con lo frecuente pero general — sácalo con un mecanismo separado (recorrido aislado, rango informado por el grafo), no esperes que aparezca por sí solo en el top-k general. La misma ley está detrás de nuestra señal de importancia: lo valioso no es lo popular, sino lo que una persona corrigió repetidamente.

    Preguntas frecuentes

    ¿Qué es vecmory?

    Vecmory es un sistema de memoria semántica para agentes de IA, basado en búsqueda vectorial y un grafo causal-temporal. Permite al agente recordar hechos, recuperarlos por significado y vincular eventos para no repetir errores pasados.

    ¿En qué se diferencia vecmory de la búsqueda vectorial normal?

    La búsqueda vectorial encuentra registros similares por significado, pero no considera relaciones de causa y efecto. Vecmory añade memoria de grafo: además de la similitud coseno, recorre aristas de “causa-efecto” y “secuencia temporal”, lo que permite encontrar hechos no solo similares, sino relevantes por contexto — por ejemplo, un experimento fallido anterior.

    ¿Por qué eliminaron la importancia del nodo de la clasificación?

    Las mediciones mostraron que agregar popularidad global (grado entrante) reduce el MRR de 0.81 a 0.41 en consultas puntuales. La importancia de los temas raros y precisos se hunde bajo la masa de populares pero irrelevantes. Para el caso principal (recall exacto), el coseno puro resultó mejor.

    Usamos datos reales: un repositorio de GitHub con 4299 tickets, donde los pares issue→PR se extraen mediante el patrón Closes #N. En 300 consultas-síntoma, el recall basado en grafos da un 87% de precisión frente al 38% del coseno puro. Todos los scripts son abiertos y reproducibles.

    Conclusión

    Ambas historias tratan de lo mismo: tira el mantra «la memoria ayuda al agente» y abre los ojos: aquí hay dos registros donde la memoria actuó en nuestra contra — contra nuestro optimismo y contra nuestra propia función. Un agente con memoria no se diferencia de uno sin memoria porque sepa más, sino porque puede atraparse a sí mismo en un «¡bingo!» un instante antes del informe engañoso — porque la última vez ya ocurrió y ya no funcionó. Y porque está dispuesto a descartar su propia función cuando los hechos muestran que es peor. Este es el primer artículo de tres. Siguiente: «Por qué no escribimos otro Bad CaRMa» — sobre cómo un modelo de datos hiperuniversal suele convertirse en un desastre, y qué hicimos para que el nuestro no lo fuera. Y «Construimos ANN a mano: cuándo valió la pena y cuándo no» — un análisis abierto de por qué escribimos HNSW nosotros mismos y en qué casos la respuesta correcta habría sido «toma pgvector y no te hagas el listo». Si quieres que tu agente deje de pisar el mismo rastrillo, prueba vecmory: empieza con nuestra documentación o haz un fork del repositorio. La memoria que objeta es la única en la que se puede confiar.