Introducción
Cuando se diseña un agente de IA, es habitual empezar por el modelo, las herramientas disponibles, los prompts o la integración con los sistemas corporativos. Sin embargo, una de las decisiones arquitectónicas más importantes es más básica: dónde vive el historial de conversación.
Esa decisión condiciona si el usuario puede retomar una conversación al día siguiente, si puede pedir una regeneración de respuesta, si la aplicación puede comparar ramas alternativas de una conversación o si cada llamada al modelo debe reconstruir todo el contexto desde cero.
En el contexto de Microsoft Agent Framework, el historial de chat no debe verse solo como una lista de mensajes. Puede representarse como:
- una secuencia lineal de turnos;
- un estado gestionado por la aplicación;
- una conversación gestionada por un servicio;
- una estructura con ramas, útil para reintentos, comparaciones o exploración de alternativas.
La elección afecta a coste, privacidad, portabilidad, latencia, cumplimiento normativo y experiencia de usuario.
Qué entendemos por historial de chat
En una aplicación con agentes, el historial suele incluir más que mensajes de usuario y respuestas del asistente. Según el caso, puede contener:
- mensajes del usuario;
- respuestas del agente;
- instrucciones del sistema o del desarrollador;
- llamadas a herramientas;
- resultados devueltos por herramientas;
- metadatos de sesión;
- identificadores de usuario o tenant;
- marcas temporales;
- estado de ejecución;
- referencias a documentos o fuentes utilizadas;
- información de auditoría.
No todo ese contenido debe enviarse siempre al modelo. Parte puede mantenerse como histórico completo, parte puede resumirse y parte puede excluirse por motivos de privacidad, coste o relevancia.
Patrones principales de almacenamiento
1. Historial gestionado por la aplicación
En este patrón, la aplicación es responsable de almacenar los mensajes y decidir qué parte del historial se envía en cada interacción con el modelo o el agente.
La aplicación puede guardar la conversación en memoria, en una base de datos relacional, en una base documental o en otro sistema persistente. En cada turno, reconstruye el contexto necesario y lo pasa al agente.
Ventajas
- Mayor control sobre los datos.
- Mejor portabilidad entre proveedores o servicios.
- Posibilidad de aplicar políticas propias de retención, cifrado y anonimización.
- Facilidad para auditar qué contexto se envió en cada llamada.
- Independencia respecto al almacenamiento interno de un servicio concreto.
Limitaciones
- La aplicación debe implementar la lógica de persistencia.
- Es necesario gestionar límites de contexto y coste de tokens.
- Puede requerir estrategias de resumen o recorte del historial.
- La concurrencia y los reintentos deben diseñarse explícitamente.
Este patrón encaja bien cuando la organización necesita control estricto del dato o cuando quiere evitar acoplarse al mecanismo de conversación de un servicio específico.
2. Historial gestionado por el servicio
En otros diseños, el servicio de IA mantiene la conversación y la aplicación conserva principalmente un identificador de hilo, sesión o conversación.
La aplicación no reconstruye todo el historial en cada llamada, sino que delega parte del estado conversacional en el servicio subyacente.
Ventajas
- Menos lógica de persistencia en la aplicación.
- Reanudación de conversaciones más sencilla.
- Modelo de desarrollo más directo para experiencias de chat lineales.
- Menor necesidad de reenviar todo el historial en cada petición.
Limitaciones
- Mayor dependencia del servicio que almacena el estado.
- Menor portabilidad si se cambia de proveedor o de arquitectura.
- Las políticas de retención, exportación y borrado deben revisarse con atención.
- Puede ser más difícil reproducir exactamente una conversación si no se guardan metadatos suficientes en la aplicación.
Este patrón puede ser adecuado para prototipos, asistentes internos o aplicaciones en las que la simplicidad operativa pesa más que la portabilidad completa del historial.
3. Historial como árbol o grafo de conversación
No todas las conversaciones son lineales. Un usuario puede pedir “inténtalo de nuevo”, comparar varias respuestas, explorar alternativas o volver a un punto anterior de la conversación.
En esos casos, representar el historial como una lista puede ser insuficiente. Una alternativa es modelarlo como un árbol o grafo, donde cada mensaje o estado conserva una relación con su nodo anterior.
Ejemplo conceptual
{
"conversation_id": "conv-001",
"nodes": [
{
"id": "n1",
"parent_id": null,
"role": "user",
"content": "Diseña una arquitectura para un agente de soporte."
},
{
"id": "n2",
"parent_id": "n1",
"role": "assistant",
"content": "Primera propuesta de arquitectura."
},
{
"id": "n3",
"parent_id": "n1",
"role": "assistant",
"content": "Propuesta alternativa con mayor énfasis en cumplimiento."
}
]
}
Ventajas
- Permite ramificar conversaciones.
- Facilita comparar respuestas alternativas.
- Mejora la trazabilidad de reintentos.
- Puede representar mejor experiencias avanzadas de agentes.
Limitaciones
- El modelo de datos es más complejo.
- Requiere decidir qué rama está activa.
- La recuperación de contexto debe tener en cuenta el camino elegido.
- La interfaz de usuario debe reflejar la estructura de ramas si se expone al usuario.
Este patrón es especialmente relevante cuando la experiencia no se limita a un chat secuencial, sino que incluye exploración, edición, comparación o flujos de trabajo iterativos.
Opciones de almacenamiento
La elección del patrón lógico no obliga a usar una tecnología concreta. El historial puede almacenarse en distintos sistemas según requisitos de escala, consulta y gobierno del dato.
Almacenamiento en memoria
El almacenamiento en memoria es útil para pruebas, demos o sesiones efímeras. Mantiene el historial mientras vive el proceso o la sesión.
Ventajas
- Implementación simple.
- Baja latencia.
- Adecuado para prototipos.
Limitaciones
- No ofrece persistencia fiable.
- No es adecuado para escalado horizontal sin mecanismos adicionales.
- Se pierde el historial si el proceso se reinicia.
- No es suficiente para auditoría o cumplimiento.
No debería ser la opción principal para aplicaciones de producción que necesiten recuperar conversaciones pasadas.
Bases de datos relacionales
Una base de datos relacional puede ser adecuada cuando se necesitan consultas estructuradas, integridad transaccional, auditoría o integración con sistemas corporativos existentes.
Un modelo básico puede separar conversaciones, mensajes y eventos:
CREATE TABLE Conversations (
conversation_id NVARCHAR(100) PRIMARY KEY,
user_id NVARCHAR(100) NOT NULL,
created_at DATETIME2 NOT NULL,
status NVARCHAR(50) NOT NULL
);
CREATE TABLE ConversationMessages (
message_id NVARCHAR(100) PRIMARY KEY,
conversation_id NVARCHAR(100) NOT NULL,
parent_message_id NVARCHAR(100) NULL,
role NVARCHAR(50) NOT NULL,
content NVARCHAR(MAX) NOT NULL,
created_at DATETIME2 NOT NULL,
FOREIGN KEY (conversation_id) REFERENCES Conversations(conversation_id)
);
Este esquema es solo ilustrativo. En un sistema real habría que añadir controles de acceso, cifrado, clasificación de datos, retención y trazabilidad de cambios.
Bases de datos documentales o NoSQL
Las bases de datos documentales pueden resultar prácticas cuando cada conversación se almacena como documento o cuando la estructura de los mensajes varía con frecuencia.
Un documento conceptual podría tener esta forma:
{
"id": "conv-001",
"tenant_id": "tenant-01",
"user_id": "user-123",
"messages": [
{
"id": "msg-001",
"role": "user",
"content": "Necesito ayuda con una incidencia.",
"created_at": "2026-04-25T10:00:00Z"
},
{
"id": "msg-002",
"role": "assistant",
"content": "Puedo ayudarte. ¿Cuál es el código de error?",
"created_at": "2026-04-25T10:00:05Z"
}
]
}
Este enfoque simplifica la lectura de una conversación completa, pero requiere cuidar el tamaño de los documentos, la estrategia de particionado y las consultas necesarias para auditoría o analítica.
Almacenamiento de archivo
En aplicaciones con requisitos de cumplimiento o conservación a largo plazo, puede ser útil separar el almacenamiento operativo del almacenamiento histórico.
Por ejemplo:
- base de datos principal para conversaciones activas;
- almacenamiento de archivo para transcripciones cerradas;
- políticas de retención y borrado según normativa;
- exportaciones controladas para auditoría.
Este patrón evita que el almacenamiento operativo crezca indefinidamente y permite aplicar reglas distintas al dato activo y al dato histórico.
Índices semánticos y memoria derivada
Un índice vectorial o semántico no debería confundirse con el historial completo de chat. Puede ser útil para recuperar fragmentos relevantes de conversaciones anteriores, pero normalmente representa una memoria derivada, no la fuente de verdad.
Si se usa este enfoque, conviene guardar también:
- el origen del fragmento indexado;
- la conversación o mensaje del que procede;
- la fecha de generación del embedding;
- la política de eliminación asociada;
- el vínculo con los permisos originales del dato.
Esto es importante porque borrar un mensaje del historial debería implicar revisar también cualquier representación derivada de ese mensaje.
Criterios para elegir un patrón
Persistencia
La primera pregunta es si la conversación debe sobrevivir al cierre de sesión, al reinicio del servicio o al cambio de dispositivo.
Si la respuesta es sí, el almacenamiento en memoria no basta. Será necesario un repositorio persistente y una estrategia clara de recuperación.
Portabilidad
Cuando el historial está controlado por la aplicación, suele ser más sencillo migrar entre modelos, servicios o proveedores. Cuando el historial está gestionado por un servicio, la aplicación puede ser más simple, pero también más dependiente de ese servicio.
Privacidad y cumplimiento
El historial de chat puede contener datos personales, secretos, información contractual, datos médicos, información financiera o material regulado.
Por tanto, el diseño debe contemplar:
- minimización de datos;
- cifrado en tránsito y en reposo;
- control de acceso por usuario, rol o tenant;
- retención limitada;
- borrado verificable;
- auditoría de accesos;
- separación entre datos operativos y datos analíticos.
Coste
Guardar todo el historial y reenviarlo completo en cada turno puede elevar el coste, especialmente en conversaciones largas.
Algunas estrategias habituales son:
- conservar el histórico completo en almacenamiento barato;
- enviar solo los últimos turnos al modelo;
- resumir partes antiguas de la conversación;
- recuperar solo mensajes relevantes;
- separar historial completo de contexto activo.
Latencia
Reconstruir el contexto de una conversación puede implicar lecturas de base de datos, llamadas a servicios externos, recuperación semántica o generación de resúmenes.
La arquitectura debe equilibrar precisión y velocidad. En algunos casos, conviene mantener una vista materializada del contexto activo para evitar recalcularlo en cada turno.
Experiencia de usuario
La experiencia esperada condiciona el modelo de historial:
- Para un chat simple, una secuencia lineal puede ser suficiente.
- Para “regenerar respuesta”, conviene conservar alternativas.
- Para comparar opciones, puede hacer falta un árbol de conversación.
- Para colaboración entre usuarios, se necesita control de versiones y concurrencia.
- Para continuidad entre sesiones, la persistencia es obligatoria.
Recomendaciones prácticas
1. Separar historial completo y contexto enviado al modelo
No todo lo almacenado debe enviarse en cada llamada. Una buena práctica es distinguir entre:
- historial completo, usado para auditoría y continuidad;
- contexto activo, usado para construir la siguiente respuesta;
- memoria derivada, usada para recuperación semántica o personalización.
Esta separación ayuda a controlar coste, privacidad y relevancia.
2. Diseñar el modelo de datos desde el principio
Aunque se empiece con un prototipo, conviene prever campos básicos:
- identificador de conversación;
- identificador de mensaje;
- rol del emisor;
- contenido;
- marca temporal;
- relación con mensaje padre, si se permiten ramas;
- identificador de usuario o tenant;
- versión del esquema;
- metadatos de herramientas o acciones.
Añadir estos elementos más tarde puede ser costoso si ya existen conversaciones persistidas.
3. Registrar llamadas a herramientas de forma explícita
En agentes que usan herramientas, el historial no debería limitarse al texto visible para el usuario. También puede ser necesario registrar:
- qué herramienta se invocó;
- con qué argumentos;
- qué resultado devolvió;
- si hubo error;
- qué parte del resultado se mostró al usuario;
- qué datos se omitieron por seguridad.
Esto facilita depuración, auditoría y análisis de comportamiento.
4. Aplicar políticas de retención
No todas las conversaciones deben conservarse indefinidamente. La política de retención debe definirse según el tipo de dato, la finalidad y los requisitos legales o corporativos.
También hay que considerar los datos derivados: resúmenes, embeddings, trazas y registros de observabilidad.
5. Evitar acoplar la interfaz al almacenamiento interno
La interfaz puede mostrar una conversación lineal aunque internamente exista un árbol de estados. Del mismo modo, una conversación puede estar archivada en frío aunque se muestre como si siguiera disponible.
Separar la experiencia de usuario del modelo físico de almacenamiento permite evolucionar la arquitectura sin rediseñar toda la aplicación.
Papel de Microsoft Agent Framework
Según la publicación oficial de Microsoft sobre patrones de almacenamiento de historial de chat en Microsoft Agent Framework, el framework aborda un problema práctico: distintos servicios de IA modelan el historial de conversación de formas diferentes. Algunos flujos tratan la conversación como una lista de mensajes que la aplicación reenvía; otros se apoyan en hilos o estado gestionado por el servicio; y otros escenarios requieren estructuras más ricas, como ramas.
La aportación de un framework de agentes en este punto no debe interpretarse como que todas las decisiones de almacenamiento desaparecen. La aplicación sigue teniendo que decidir:
- qué datos conserva;
- dónde los conserva;
- durante cuánto tiempo;
- qué parte se envía al modelo;
- cómo se audita;
- cómo se elimina;
- cómo se protege frente a accesos indebidos.
El valor está en disponer de abstracciones que ayuden a trabajar con diferentes patrones sin rediseñar por completo la aplicación cada vez que cambia el servicio subyacente o el modelo de conversación.
Errores comunes
Guardar solo el texto visible
En agentes con herramientas, workflows o llamadas externas, el texto visible no siempre explica por qué se produjo una respuesta. Sin eventos internos, depurar errores puede ser difícil.
Enviar siempre todo el historial
Enviar toda la conversación en cada turno puede ser innecesario, caro y, en algunos casos, contraproducente. Es preferible construir un contexto relevante y controlado.
No diseñar borrado y retención
Si no se define desde el principio cómo se elimina una conversación, después puede ser difícil borrar también copias, resúmenes, embeddings o registros asociados.
Mezclar memoria de usuario con transcripción
La memoria persistente de preferencias de usuario no es lo mismo que el historial completo de conversación. Conviene separarlas, aplicar permisos distintos y permitir su revisión o eliminación.
No contemplar ramas
Si la aplicación permite reintentos, edición o comparación de respuestas, una lista lineal puede quedarse corta. En esos casos, conviene modelar relaciones entre mensajes o estados.
Conclusión
El almacenamiento del historial de chat es una decisión central en la arquitectura de agentes. No afecta solo a la persistencia: determina la experiencia de usuario, el coste, la privacidad, la capacidad de auditoría y la portabilidad de la solución.
Para escenarios simples, un historial lineal gestionado por la aplicación o por el servicio puede ser suficiente. Para experiencias más avanzadas, como reintentos, comparación de respuestas o continuidad entre sesiones, conviene considerar modelos con ramas, separación entre historial completo y contexto activo, y políticas claras de retención.
La recomendación práctica es empezar por las preguntas arquitectónicas antes de elegir la tecnología:
- ¿Quién es responsable del historial: la aplicación o el servicio?
- ¿La conversación debe ser lineal o ramificable?
- ¿Qué parte del historial se envía al modelo?
- ¿Qué datos deben conservarse por auditoría?
- ¿Cómo se aplican retención, borrado y control de acceso?
- ¿Qué coste y latencia son aceptables?
Responder bien a estas preguntas suele ser más importante que elegir una base de datos concreta. En agentes de producción, el historial de chat no es un detalle de implementación: es parte del contrato de experiencia, seguridad y gobierno del sistema.