Historial de Chat para Aplicaciones de IA con Azure Cosmos DB Go SDK

Esta publicación de blog cubre cómo construir una implementación de historial de chat utilizando Azure Cosmos DB para el SDK de NoSQL de Go y LangChainGo. Si eres nuevo en el SDK de Go, la aplicación de chat de muestra presentada en el blog sirve como una introducción práctica, cubriendo operaciones básicas como leer, upsert, etc. También demuestra el uso del emulador de Azure Cosmos DB basado en Linux (en vista previa en el momento de la escritura) para pruebas de integración con Testcontainers para Go.

Los desarrolladores de Go que buscan construir aplicaciones de IA pueden usar LangChainGo, que es un marco para aplicaciones impulsadas por LLM. Proporciona APIs conectables para componentes como almacenamiento de vectores, incrustación, carga de documentos, cadenas (para componer múltiples operaciones), historial de chat y más.


Antes de sumergirnos, demos un paso atrás para entender lo básico.

¿Qué es el historial de chat y por qué es importante para las aplicaciones de IA modernas?

Un requisito común para aplicaciones de IA conversacional es poder almacenar y recuperar mensajes intercambiados como parte de las conversaciones. Esto se conoce comúnmente como “historial de chat”. Si has utilizado aplicaciones como ChatGPT (¡que también utiliza Azure Cosmos DB, por cierto!), es posible que estés familiarizado con este concepto.

Cuando un usuario inicia sesión, puede comenzar a chatear, y los mensajes intercambiados como parte de la conversación se guardan. Cuando inicia sesión nuevamente, puede ver sus conversaciones anteriores y continuar desde donde lo dejó.

El historial de chat es, obviamente, importante para los usuarios finales de la aplicación, pero ¡no olvidemos a los LLMs! Por inteligentes que parezcan los LLMs, no pueden recordar interacciones pasadas debido a la falta de memoria incorporada (al menos por ahora). Usar el historial de chat cierra esta brecha al proporcionar conversaciones anteriores como contexto adicional, permitiendo que los LLMs generen respuestas más relevantes y de alta calidad. Esto mejora el flujo natural de las conversaciones y mejora significativamente la experiencia del usuario.

Un ejemplo simple ilustra esto: Supongamos que le preguntas a un LLM a través de una API, “Háblame sobre Azure Cosmos DB,” y responde con un extenso párrafo. Si luego haces otra llamada a la API diciendo, “Desglosa esto en viñetas para una lectura más fácil,” el LLM podría confundirse porque carece de contexto de la interacción anterior.

Sin embargo, si incluyes el mensaje anterior como parte del contexto en la segunda llamada a la API, es más probable que el LLM proporcione una respuesta precisa (aunque no está garantizado, ya que las salidas de los LLM son inherentemente no determinísticas).

Cómo ejecutar el chatbot

Como mencioné anteriormente, la aplicación de muestra es una forma útil para que explores langchaingo, la implementación del historial de chat de Azure Cosmos DB, así como el Go SDK.

Antes de explorar los detalles de la implementación, es una buena idea ver la aplicación en acción. Consulta la sección README del repositorio de GitHub, que proporciona instrucciones sobre cómo configurar, ejecutar y comenzar a conversar con el chatbot.

Resumen de la aplicación

La aplicación de chat sigue un modelo de dominio sencillo: los usuarios pueden iniciar múltiples conversaciones, y cada conversación puede contener varios mensajes. Desarrollada en Go, la aplicación incluye componentes tanto de backend como de frontend.

Backend

Consta de varias partes:

  • La implementación del historial de chat de Azure Cosmos DB.
  • Las operaciones principales como iniciar un chat, enviar/recibir mensajes y recuperar el historial de conversaciones se exponen a través de una API REST.
  • La API REST aprovecha una cadena langchaingo para manejar los mensajes de usuario. La cadena incorpora automáticamente el historial de chat para asegurar que las conversaciones pasadas se envíen al LLM. langchaingo maneja toda la orquestación – invocación de LLM, inclusión de historial de chat, y más sin necesidad de implementación manual.

Frontend

Está construido utilizando JavaScript, HTML y CSS. Se empaqueta como parte del servidor web Go (usando el paquete embed) e invoca las APIs REST de backend en respuesta a las interacciones del usuario.

Implementación de Historial de Chat Utilizando Azure Cosmos DB

LangChainGo es un marco enchufable, que incluye su componente de historial de chat (o memoria). Para integrar Azure Cosmos DB, necesitas implementar la interfaz schema.ChatMessageHistory, la cual provee métodos para manejar el historial de chat:

  • AddMessage para añadir mensajes a una conversación (o iniciar una nueva).
  • Messages para recuperar todos los mensajes de una conversación.
  • Clear para borrar todos los mensajes en una conversación.

Si bien puedes instanciar directamente un objeto CosmosDBChatMessageHistory y utilizar estos métodos, el enfoque recomendado es integrarlo en la aplicación langchaingo. A continuación se muestra un ejemplo de cómo utilizar el historial de chat de Azure Cosmos DB con un LLMChain:

Go

 

// Crear una instancia de historial de chat
cosmosChatHistory, err := cosmosdb.NewCosmosDBChatMessageHistory(cosmosClient, databaseName, containerName, req.SessionID, req.UserID)
if err != nil {
    log.Printf("Error creating chat history: %v", err)
    sendErrorResponse(w, "Failed to create chat session", http.StatusInternalServerError)
    return
}

// Crear una memoria con el historial de chat
chatMemory := memory.NewConversationBuffer(
    memory.WithMemoryKey("chat_history"),
    memory.WithChatHistory(cosmosChatHistory),
)

// Crear una cadena LLM
chain := chains.LLMChain{
    Prompt:       promptsTemplate,
    LLM:          llm,
    Memory:       chatMemory,
    OutputParser: outputparser.NewSimple(),
    OutputKey:    "text",
}

Desde el punto de vista de Azure Cosmos DB, cabe destacar que la implementación en este ejemplo es solo una de las muchas opciones posibles. La que se muestra aquí se basa en una combinación del ID de usuario como la clave de partición y el ID de conversación (también conocido como ID de sesión a veces) como la clave única (id de un elemento de Azure Cosmos DB).

Esto permite a una aplicación:

  • Obtener todos los mensajes de una conversación. Se trata de una lectura puntual utilizando el ID único (ID de conversación) y la clave de partición (ID de usuario).
  • Agregar un nuevo mensaje a una conversación. Utiliza una operación upsert (en lugar de crear) para evitar la necesidad de una lectura antes de escribir.
  • Eliminar una conversación específica. Utiliza la operación eliminar para eliminar una conversación (y todos sus mensajes).

Aunque la interfaz langchaingo no lo expone, al integrarlo como parte de una aplicación, también puedes emitir una consulta separada para obtener todas las conversaciones de un usuario. Esto también es eficiente ya que está enfocado en una sola partición.

Simplifica las pruebas con Azure Cosmos DB Emulator y Testcontainers

La aplicación de ejemplo incluye casos de prueba básicos tanto para el historial de chat de Azure Cosmos DB como para la aplicación principal. Vale la pena destacar el uso de testcontainers-go para integrar el contenedor docker del emulador de Azure Cosmos DB basado en Linux.

Esto es excelente para pruebas de integración, ya que la base de datos está disponible localmente y las pruebas se ejecutan mucho más rápido (¡sin olvidar el ahorro de costos también!). Lo mejor es que no es necesario gestionar manualmente el ciclo de vida del contenedor Docker. Esto se encarga como parte del conjunto de pruebas, gracias a la API testcontainers-go que facilita iniciar el contenedor antes de que se ejecuten las pruebas y terminarlo una vez que estén completas.

Puedes consultar los casos de prueba en la aplicación de ejemplo para más detalles. Aquí tienes un fragmento de cómo se utiliza testcontainers-go:

Go

 

func setupCosmosEmulator(ctx context.Context) (testcontainers.Container, error) {
    req := testcontainers.ContainerRequest{
        Image:        emulatorImage,
        ExposedPorts: []string{emulatorPort + ":8081", "1234:1234"},
        WaitingFor:   wait.ForListeningPort(nat.Port(emulatorPort)),
    }

    container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
        ContainerRequest: req,
        Started:         true,
    })
    if err != nil {
        return nil, fmt.Errorf("failed to start container: %w", err)
    }

    // Darle al emulador un poco más de tiempo para inicializarse por completo
    time.Sleep(5 * time.Second)

    return container, nil
}

Si estás interesado en usar el Emulador de Azure Cosmos DB en pipelines de CI, echa un vistazo al post del blog.

Conclusión

Almacenar el historial de chat es una parte importante de las aplicaciones de inteligencia artificial conversacional. Pueden ser un gran complemento para técnicas existentes como RAG (generación aumentada por recuperación). ¡Prueba la aplicación de chatbot y cuéntanos qué piensas!

Mientras que la implementación en la aplicación de muestra es relativamente simple, cómo modelas los datos del historial de chat depende de los requisitos. Un escenario que se ha presentado es este excelente artículo de blog sobre cómo Microsoft Copilot se escala a millones de usuarios con Azure Cosmos DB.

Algunos de tus requisitos podrían incluir:

  • Almacenar metadatos, como reacciones (además de mensajes)
  • Mostrar los N mensajes recientes más importantes
  • Considerar el período de retención de datos del historial de chat (usando TTL)
  • Incorporar análisis adicionales (sobre interacciones de usuarios) basados en los datos del historial de chat y más.

Independientemente de la implementación, asegúrate siempre de incorporar las mejores prácticas para el modelado de datos. Consulta aquí para obtener pautas.

¿Ya estás utilizando o planeas aprovechar Azure Cosmos DB para tus aplicaciones en Go? ¡Nos encantaría saber de ti! Envíanos tus preguntas y comentarios.

Source:
https://dzone.com/articles/chat-history-ai-applications-azure-cosmos-db-go-sdk