Historial del chat
Aprende cómo Neuron AI gestiona conversaciones de varios turnos.
Neuron AI te proporciona un sistema integrado para gestionar la memoria de una sesión de chat que realizas con el agente.
En muchas aplicaciones de preguntas y respuestas puedes mantener una conversación de ida y vuelta con el LLM, lo que significa que la aplicación necesita algún tipo de "memoria" de preguntas y respuestas anteriores, y alguna lógica para incorporarlas a su razonamiento actual.
Por ejemplo, si haces una pregunta de seguimiento como "¿Puedes ampliar el segundo punto?", esto no puede entenderse sin el contexto de los mensajes anteriores.
En el ejemplo siguiente puedes ver cómo el Agente no sabe mi nombre al principio:
use NeuronAI\Agent\Agent;
use NeuronAI\Chat\Messages\UserMessage;
$message = Agent::make()
->chat(new UserMessage("¿Cómo me llamo?"))
->getMessage();
echo $message->getContent();
// Lo siento, no conozco tu nombre. ¿Quieres contarme más sobre ti?Claramente el Agente no tiene ningún contexto sobre mí. Ahora pruebo a presentarme en el primer mensaje, y luego preguntar por mi nombre:
use NeuronAI\Agent\Agent;
use NeuronAI\Chat\Messages\UserMessage;
$agent = Agent::make()
$message = $agent->chat(new UserMessage("¡Hola, me llamo Valerio!"))->getMessage();
echo $message->getContent();
// Hola Valerio, encantado de conocerte, ¿en qué puedo ayudarte hoy?
$message = $agent->chat(new UserMessage("¿Recuerdas mi nombre?"))->getMessage();
echo $message->getContent();
// ¡Claro, tu nombre es Valerio!Cómo funciona el historial de chat
Neuron Agent toma la lista de mensajes intercambiados entre tu aplicación y el LLM y la convierte en un objeto llamado Historial de Chat. Es una parte crucial del framework porque el historial del chat debe gestionarse en función de la ventana de contexto del LLM subyacente.
Es importante enviar los mensajes anteriores de vuelta al LLM para mantener el contexto de la conversación, pero si la lista de mensajes crece lo suficiente como para superar la ventana de contexto del modelo, la solicitud será rechazada por el proveedor de IA, porque supera la capacidad máxima del LLM.
El historial del chat trunca automáticamente la lista de mensajes para no superar nunca la ventana de contexto, evitando errores inesperados. Quizá quieras considerar la implementación de estrategias más sofisticadas de gestión del contexto, como resumen.
Durante el recorte, el historial del chat intenta minimizar la pérdida de contexto. El recortador interno puede identificar un punto de corte ligeramente menos agresivo que el identificado inicialmente. Así que, para asegurarte de que la conversación del agente se mantiene dentro del límite, deberías configurar la ventana de contexto en el historial de chat del agente con un margen del 5%-10% respecto al límite real del modelo subyacente.
Si tu modelo trabaja con una ventana de contexto de 200K, deberías instanciar tu historial de chat con 190K, por ejemplo.
Cómo alimentar una conversación anterior
A veces ya tienes una representación de la conversación entre el usuario y el asistente y necesitas una forma de alimentar al agente con mensajes anteriores.
Puedes pasar simplemente un array de mensajes al chat() método. Esta conversación se cargará automáticamente en la memoria del agente y podrás seguir iterando sobre ella.
El último mensaje de la lista se considerará el más reciente.
Registrar el historial de chat
Por defecto, Neuron Agent utiliza un historial de chat "en memoria". Eso significa que solo conserva los mensajes durante el ciclo de ejecución actual. Pero, si quieres persistir los mensajes entre sesiones, puedes decirle al agente que use un componente diferente implementando el chatHistory método en la clase Agent.
InMemoryChatHistory
Simplemente almacena la lista de mensajes en un array. Se mantiene en memoria solo durante la ejecución actual. Se usa por defecto si no registras explícitamente otro componente.
FileChatHistory
Este componente te permite persistir la conversación en curso con el agente en un archivo y reanudarla más tarde. Para crear una instancia de FileChatHistory necesitas pasar la ruta absoluta del directorio donde quieras almacenar las conversaciones, y la clave única para la conversación actual.
El clave parámetro te permite almacenar distintos archivos para separar conversaciones. Puedes usar una clave única para cada usuario, o el ID de un hilo para permitir que los usuarios almacenen varias conversaciones.
SQLChatHistory
Este componente te permite almacenar la conversación en curso en una base de datos SQL. Antes de usar este componente debes crear la tabla en tu base de datos para almacenar mensajes. Aquí tienes el script SQL:
Puedes personalizar esta tabla añadiendo más columnas eventualmente para añadir una relación con tus usuarios o casos de uso similares. También puedes personalizar el nombre de la tabla pasando el tuyo propio al crear la instancia.
Para crear una instancia de SQLChatHistory necesitas pasar el thread_id para separar distintos hilos de conversación, y la PDO conexión a la base de datos.
Si tu aplicación está construida sobre un framework, puedes obtener fácilmente la conexión PDO desde el ORM. Aquí tienes un par de ejemplos en el contexto de aplicaciones Laravel o Symfony.
Laravel
Symfony
Puedes registrar tu agente como un servicio con una instancia de Doctrine\DBAL\Connection como dependencia del constructor:
EloquentChatHistory
Deberías crear tu propio modelo Eloquent y pasar la cadena de la clase como argumento del constructor. El modelo puede tener relaciones, ámbitos, atributos, etc. personalizados, pero la estructura básica debe basarse en este script de migración:
Ejemplo de modelo ChatMessage
Úsalo en tu agente:
Implementar historial de chat personalizado
Puedes crear una implementación personalizada del historial de chat para admitir una capa persistente diferente simplemente implementando AbstractChatHistory. Esto te permite heredar varios comportamientos para la gestión interna del historial, de modo que solo tienes que implementar un par de métodos para guardar mensajes en el sistema de almacenamiento que quieras usar.
La clase abstracta ya implementa algunos métodos de utilidad para calcular el uso de tokens basándose en las respuestas del proveedor de IA y recortar automáticamente la conversación en función del tamaño de la ventana de contexto. Solo tienes que centrarte en la interacción con el almacenamiento subyacente para añadir y eliminar mensajes, o borrar todo el historial.
Recomendamos encarecidamente revisar otras implementaciones como FileChatHistory para entender cómo crear la tuya propia.
Serializar/Deserializar mensajes
Cuando ChatHistory necesita almacenar un mensaje, este debe serializarse. Del mismo modo, cuando se instancia el componente ChatHistory, debería cargar todos los mensajes anteriores desde el almacenamiento subyacente (base de datos, caché, etc.) y deserializarlos al tipo de mensaje original.
Para serializar/deserializar mensajes de forma coherente, el AbstractChatHistory te proporciona serializeMessage() y deserializeMessage() métodos. Aquí tienes un ejemplo de cómo usarlos en una hipotética implementación de historial de chat en base de datos:
Última actualización