Aplicaciones de IA con capacidad de agencia

Lo que aprendimos al evaluar la memoria de los agentes: La configuración (Parte 1) 

Lectura de 12 minutos

La memoria de los agentes es uno de los problemas de infraestructura más difíciles en la IA aplicada en este momento, y el ecosistema de evaluaciones al respecto aún está tomando forma. Este artículo consta de dos partes. La Parte 1 abarca qué estábamos evaluando, cómo lo medimos y cómo está construido el conducto. La Parte 2 cubre lo que los experimentos mostraron en realidad. Publicamos ambos porque las decisiones que intervienen en la evaluación son tan trascendentales como las decisiones del sistema, y esa parte rara vez se pone por escrito.

¿Qué es la memoria de un agente y por qué no es solo RAG?

La memoria de los agentes es lo que hace que un agente de IA no parezca tener amnesia.

Los agentes de IA tradicionales no tienen estado. Cada conversación comienza desde cero. Por ejemplo, un bot de atención al cliente gestiona un ticket, el usuario vuelve a llamar dos días después y el bot no tiene registro de la interacción anterior. Un asistente de programación explica el mismo concepto dos veces en la misma semana porque no tiene memoria de la primera conversación. Un asistente de compras recomienda algo que el usuario ya ha comprado.

La memoria del agente aborda esto manteniendo una capa persistente que almacena lo que un agente aprende sobre un usuario a lo largo de las sesiones y hace que se pueda recuperar en interacciones futuras. El agente aprende hoy que un usuario es vegetariano y alérgico a los mariscos, y recurre a ese contexto en octubre cuando el usuario pide recomendaciones para cenar.

Si has trabajado antes con la generación aumentada por recuperación (RAG), esto te puede sonar familiar. Los mecanismos superficiales son similares: almacenar elementos en una base de datos vectorial, recuperar fragmentos relevantes al momento de la consulta y pasarlos a un LLM. Pero la memoria de los agentes es un problema fundamentalmente diferente de tres maneras.

Primero, el corpus es personal y dinámico. En el RAG de documentos, el corpus suele ser una colección estática, una base de conocimiento, un conjunto de PDF y una base de código. En la memoria de los agentes, el corpus es todo el historial conversacional de un usuario. Crece con cada sesión y es diferente para cada usuario.

En segundo lugar, las consultas son autobiográficas en lugar de informativas. Una búsqueda en una base de conocimientos es una consulta sobre el mundo. Una consulta de memoria es una consulta sobre el usuario, cosas que dijo, preferencias que expresó y experiencias que mencionó. “¿Cuál es la capital de Francia?” y “¿Qué dije sobre mis restricciones dietéticas?” no son el mismo problema de recuperación.

Tercero, el tiempo es una dimensión de primera clase. El mismo hecho puede aparecer de forma contradictoria entre sesiones, y la recencia determina qué versión es la correcta. Si un usuario mencionó dos gatos en marzo y tres gatos en junio, la respuesta correcta a “¿Cuántos gatos tengo?” depende enteramente de cuándo se hace la pregunta. Un sistema de recuperación de documentos no necesita razonar sobre esto. Un sistema de memoria de un agente sí, constantemente.

Por esto un sistema RAG no puede simplemente ser rebautizado como memoria de agente. Las decisiones de diseño son diferentes, los modos de fallo son diferentes y, como descubrimos, las pruebas de rendimiento también lo son. Los sistemas de recuperación de documentos se evalúan según su capacidad para encontrar el fragmento correcto en un corpus fijo. Los sistemas de memoria de agentes necesitan manejar un corpus que es personal, está en crecimiento y está lleno de contradicciones. Las pruebas de rendimiento existentes para RAG no revelan los modos de fallo que importan para la memoria de agentes. Tuvimos que encontrar los que sí lo hacen.

Los puntos de referencia: qué existe y por qué importa

Antes de medir cualquier cosa, tuvimos que decidir sobre qué medir.

El panorama de las pruebas comparativas de memoria para agentes sigue siendo relativamente joven. Trabajamos con dos de ellas: LoCoMo y LongMemEval.

LoCoMo (Memoria de Conversación a Largo Plazo) se basa en 10 registros de conversaciones largas: conversaciones naturalistas entre dos personas que divagan, hacen referencia a eventos pasados y contienen contexto implícito. A partir de esos 10 registros, el punto de referencia genera 1,540 preguntas distribuidas en cuatro categorías:

  • Salto simple: Un dato, establecido directamente en alguna parte. “¿Qué investigó Caroline?” -> “agencias de adopción”.”
  • Multi salto: La respuesta requiere conectar información de dos o más lugares. “¿Para qué creó conciencia la carrera benéfica?” -> tienes que encontrar tanto que hubo una carrera benéfica como que fue para la salud mental.
  • Temporal: Preguntas sobre cuándo ocurrieron las cosas. “¿Cuándo pintó Melanie un amanecer?” -> “2022.”
  • Dominio abierto: Preguntas que requieren razonamiento en lugar de recuperación. “¿Caroline aún querría buscar asesoramiento si no hubiera recibido apoyo al crecer?” -> la respuesta no se establece en ninguna parte, tiene que inferirse.

LoCoMo evalúa la recuperación naturalista a largo plazo. Las conversaciones son desordenadas de la manera en que las conversaciones reales son desordenadas. Las respuestas están incrustadas en el contexto en lugar de estar etiquetadas ordenadamente.

LongMemEval está construido de otra manera. Son 500 preguntas, cada una ubicada en un pajar de sesiones de conversación. Los tipos de preguntas son más granulares y, desde una perspectiva de diseño de sistemas, más reveladores:

  • Usuario de una sola sesión (SSU): Algo que el usuario dijo en una sesión. “¿Cuánto dura mi trayecto al trabajo?” -> “45 minutos.”
  • Asistente de sesión única (SSA): Algo que el asistente dijo en una sesión. “¿Puedes recordarme el restaurante de Roma que me gustó?” -> “Roscioli”. Esta categoría importa porque la respuesta se encuentra en la producción anterior del propio asistente, no en la del usuario.
  • Preferencia de sesión única (SSP): una preferencia que el usuario expresó. “Puedes sugerir accesorios que complementen mi equipo de fotografía” -> el sistema debe haber retenido la preferencia del usuario por equipo compatible con Sony.
  • Multi-Sesión (MS): La respuesta requiere sintetizar información de múltiples sesiones diferentes.
  • Actualización de conocimiento (KU): La información ha cambiado. “¿Cuántas bicicletas tengo actualmente?” -> “4.” Pero al principio del historial, la respuesta era 3. El sistema tiene que reconocer que la información ha sido sobrescrita.
  • Razonamiento temporal (TR): Preguntas que requieren aritmética de tiempo. “¿Cuántos meses han pasado desde mi última visita al museo?” -> el sistema tiene que identificar cuándo ocurrió la visita, cuándo se hace la pregunta y calcular la diferencia.

La categoría de actualización de conocimientos está particularmente bien diseñada porque la mayoría de los puntos de referencia no evalúan si un sistema maneja contradicciones en el historial de la conversación. Un sistema de memoria de agentes que no pueda manejar esta actualización devolverá con confianza información desactualizada, lo cual es uno de los modos de fallo más importantes en producción.

LoCoMo frente a LongMemEval: qué los hace genuinamente diferentes

Estas dos pruebas de rendimiento evalúan cosas distintas, and entender la diferencia importa antes de ver los resultados.

LoCoMo utiliza conversaciones reales y sin guion entre dos personas. El sistema de memoria debe manejar ambos lados, lo que dijo Caroline y lo que dijo Melanie. La canalización de ingesta refleja esto con una extracción de doble punto de vista: cada intercambio crea dos bloques de memoria, uno vinculado a cada hablante. Esto no es solo una convención de formato. Las preguntas de LoCoMo se pueden hacer desde cualquier perspectiva, y el sistema necesita la versión de los acontecimientos de cada hablante disponible en el momento de la recuperación.

LongMemEval utiliza conversaciones entre un usuario y un asistente de IA, con preguntas hechas por el usuario sobre su propia historia. En la configuración LME-M, también usamos doble punto de vista (un bloque desde la perspectiva del usuario y un bloque desde la perspectiva del asistente por cada intercambio), porque el tipo de pregunta SSA pregunta específicamente qué dijo el asistente. En LME-S, simplificamos a un único punto de vista secuencial y logramos puntuaciones idénticas con la mitad de la latencia. Ese compromiso se cubre en Parte 2.

La otra diferencia estructural es la escala. LoCoMo tiene 10 conversaciones. LongMemEval tiene 500 preguntas, cada una con su propio pajar. LoCoMo evalúa la profundidad de recuperación en una sola relación extendida. LongMemEval evalúa si el sistema de recuperación puede encontrar el recuerdo correcto a través de una colección grande y creciente de sesiones.

Las dos escalas de LongMemEval y por qué esto importa

LongMemEval se presenta en dos variantes: LME-S y LME-M. Las mismas 500 preguntas, la misma distribución de tipos de preguntas. La diferencia radica en qué tan difícil es para el sistema buscar.

LME-S coloca cada respuesta en un pajar de aproximadamente 46 sesiones (unos 115,000 tokens por problema). LME-M coloca la misma respuesta en unas 500 sesiones, aproximadamente 1.5 millones de tokens por problema. Esto representa una expansión de 20 veces en el espacio de búsqueda con la misma aguja por encontrar.

Esto resultó ser uno de los hallazgos más importantes del proyecto. La configuración que funciona bien en LME-S no se transfiere a LME-M. Si un sistema se ajusta en LME-S y se implementa a escala de producción, es probable que esté mal configurado de maneras que son difíciles de detectar sin evaluar en ambas escalas.

El ejemplo más claro es la profundidad de recuperación. El k óptimo en LME-S es 10. A escala LME-M, se necesita k=20. Con más sesiones en el pajar, la memoria relevante está más diluida y se requiere un conjunto de recuperación más profundo para mostrarla de manera confiable. El razonamiento temporal, que no muestra casi sensibilidad a k en LME-S, se beneficia significativamente de un k mayor en LME-M, porque el contexto de la fecha relevante se distribuye en más sesiones.

Las variantes de las indicaciones también presentan diferencias. La indicación de respuesta que ofrece el mejor desempeño en LME-S tiene un desempeño notablemente peor en LME-M. Observamos una diferencia de 11,8 puntos entre las variantes de las indicaciones en LME-M (72,41 TP3T frente a 60,61 TP3T).

LME-S es una útil pauta de desarrollo. LME-M se parece más a cómo es la producción en realidad. Evaluar en ambas, y prestar atención cuando los resultados divergen, vale la pena el esfuerzo.

Cómo medimos el desempeño

Rastreamos tres métricas en todos los experimentos.

La puntuación BLEU cuenta las superposiciones de n-gramas entre la respuesta generada y la respuesta de referencia. Como ejemplo simple: si la respuesta esperada es “bob likes pancakes” y el sistema devuelve “bob likes pancakes, cakes, and mustard”, la puntuación BLEU es 0.4 porque solo dos de los cinco pares de palabras en la salida coinciden con la respuesta esperada. BLEU es una útil verificación de cordura, pero penaliza el uso de paráfrasis y premia las coincidencias textuales de una manera que no siempre refleja si una respuesta es sustancialmente correcta.

La puntuación F1 mide la superposición a nivel de palabra sin requerir el orden de las palabras, calculando la precisión (qué fracción de las palabras generadas aparecen en la referencia) y la cobertura (qué fracción de las palabras de referencia aparecen en la salida). Para el mismo ejemplo, F1 obtiene una puntuación de 0.67. Mejor, pero sigue siendo puramente léxica.

El juez de LLM (puntuación J) es la métrica principal. Un LLM lee la respuesta esperada y la respuesta generada y juzga si la respuesta generada es semánticamente correcta. Para “a bob le gustan los panqueques” frente a “a bob le gustan los panqueques, los pasteles y la mostaza”, el juez otorga una puntuación de 1; la respuesta generada contiene la información correcta aun con contenido adicional. Esta es la métrica en la que más confiamos para evaluar si el sistema realmente está funcionando.

Una observación importante sobre el J-score: las instrucciones para los evaluadores son tan importantes como el sistema que se está evaluando. El evaluador de LoCoMo está configurado para ser generoso: “siempre que la respuesta se refiera al mismo tema, márcala como correcta”. LongMemEval utiliza variantes específicas por categoría: una para el razonamiento temporal (permite errores de “uno” en el conteo de días), otra para la actualización de conocimiento (califica como correcta la respuesta actualizada incluso si también se menciona información anterior), otra para las preferencias (basada en una rúbrica) y otra para la precisión directa. Al ejecutar nuestro sistema con un evaluador mucho más estricto, las puntuaciones bajan varios puntos, independientemente de cualquier cambio en el sistema. Las comparaciones entre evaluadores modifican las puntuaciones entre 5 y 10 puntos y no son interpretables. Cuando ejecutamos LoCoMo con las indicaciones para los evaluadores utilizadas por otras soluciones de memoria, obtuvimos una puntuación de 100% teóricamente imposible, lo que indicó de inmediato que la comparación estaba inflada por la indicación en lugar de reflejar la calidad de la recuperación. Reportar una puntuación J sin especificar la indicación del evaluador es como reportar la calificación de un examen sin especificar qué examen se aplicó.

Cómo funciona la tubería

Cuando un turno de conversación entra al sistema, pasa por una extracción de doble perspectiva antes de que se escriba cualquier cosa en la base de datos. El código de ingesta empareja cada mensaje del usuario con la siguiente respuesta del asistente y crea dos bloques de memoria, uno vinculado al usuario y otro vinculado al asistente. “El usuario dijo X, el asistente dijo Y” produce un bloque desde la perspectiva del usuario y un bloque separado desde la perspectiva del asistente.

Con context_required=True configurado en cada canalización, el sistema activa una llamada a LLM durante la ingesta para extraer un resumen en prosa y una lista de hechos discretos de cada intercambio. Lo que se escribe en Couchbase son tres cosas: el texto del mensaje sin procesar, el resumen y una lista de contextos de cadenas de hechos. Las marcas de tiempo se adjuntan como anotaciones en un formato legible por humanos (“1:10 pm on 27 March, 2023”) para que el modelo pueda razonar sobre ellas de forma natural en el momento de la recuperación.

Un bloque de memoria se ve más o menos así:

{
  "message": "User: When did I start the job? Assistant: You mentioned starting in March 2023.",
  "summary": "El usuario pregunta sobre su fecha de inicio en el trabajo; el asistente confirmó marzo de 2023.",
  "contexts": [
    "El usuario comenzó su trabajo en marzo de 2023",
    "El usuario expresó incertidumbre sobre la fecha exacta de inicio"
  ],
  "annotations": {
    "time": "1:10 pm on 27 March, 2023",
    "conversation_id": "abc123"
  }
}

La llamada de ingesta regresa en aproximadamente 251 ms en el percentil 50 (p50), cubriendo la validación, la generación de incrustaciones y la escritura en Couchbase. La extracción de contexto del LLM (resumen y lista de contextos) ocurre de manera asincrónica en segundo plano y toma aproximadamente 3.6 segundos en promedio. El llamador no espera por esto. Este desacoplamiento, mediante una cola de distribución que separa la latencia de ingesta de la latencia de extracción, es lo que hace que el sistema sea práctico a escala. Hay un modo sincrónico disponible cuando se requiere capacidad de búsqueda inmediata, a cambio de la espera de 3.6 segundos.

La búsqueda funciona de otra manera. La llamada a get_memory() incrusta la consulta (aproximadamente 305 ms en el p50) y ejecuta una búsqueda de similitud vectorial contra los bloques almacenados en Couchbase (aproximadamente 5 ms en el p50). La latencia total cara al cliente es de alrededor de 298 ms en el p50. El cuello de botella es el paso de incrustación, no la recuperación en sí. La búsqueda de texto completo (FTS) de Couchbase es rápida.

Específicamente para la canalización de evaluación: los recuerdos se ingieren una sola vez y persisten en Couchbase. Las etapas de búsqueda y evaluación se ejecutan en la base de datos activa con diferentes parámetros de configuración, sin necesidad de volver a ingerir datos entre los barridos de parámetros. 

El pipeline está construido. Los benchmarks están seleccionados. Las métricas están definidas. Todo eso es trabajo preparatorio. La verdadera pregunta es qué sucede realmente cuando ejecutas el sistema contra benchmarks reales a escala, a través de múltiples configuraciones experimentales diferentes. Eso es lo que Parte 2 Se trata de.

Compartir este artículo

Autor

Deja un comentario

¿Listo para comenzar con Couchbase Capella?

Comenzar a construir

Visita nuestro portal para desarrolladores para explorar NoSQL, consultar recursos y comenzar con los tutoriales.

Usa Capella gratis

Empieza a usar Couchbase en tan solo unos clics. Capella DBaaS es la forma más fácil y rápida de comenzar.

Ponte en contacto

¿Quieres saber más sobre las ofertas de Couchbase? Permítenos ayudarte.