Histórico de bate-papo para Aplicativos de IA com Azure Cosmos DB Go SDK

Esta postagem no blog aborda como construir uma implementação de histórico de chat usando Azure Cosmos DB para NoSQL Go SDK e LangChainGo. Se você é novo no Go SDK, o aplicativo de chat de exemplo apresentado no blog serve como uma introdução prática, cobrindo operações básicas como leitura, upsert, etc. Ele também demonstra o uso do emulador baseado em Linux do Azure Cosmos DB (em prévia no momento da escrita) para testes de integração com Testcontainers para Go.

Desenvolvedores Go que desejam construir aplicativos de IA podem utilizar LangChainGo, que é um framework para aplicativos alimentados por LLM. Ele fornece APIs plugáveis para componentes como armazenamento de vetores, incorporação, carregamento de documentos, cadeias (para composição de múltiplas operações), histórico de chat e muito mais.


Antes de nos aprofundarmos, vamos dar um passo atrás para entender o básico.

O que é Histórico de Chat e por que é importante para Aplicações de IA Modernas?

Um requisito comum para aplicações de IA conversacional é ser capaz de armazenar e recuperar mensagens trocadas como parte das conversas. Isso é frequentemente referido como “histórico de chat”. Se você já utilizou aplicativos como ChatGPT (que também usa Azure Cosmos DB, a propósito!), você pode estar familiarizado com esse conceito.

Quando um usuário faz login, ele pode começar a conversar, e as mensagens trocadas como parte da conversa são salvas. Quando ele faz login novamente, pode ver suas conversas anteriores e continuar de onde parou.

O histórico de chat é obviamente importante para os usuários finais do aplicativo, mas não vamos esquecer dos LLMs! Por mais inteligentes que os LLMs possam parecer, eles não conseguem recordar interações passadas devido à falta de memória embutida (pelo menos por enquanto). Usar o histórico de chat preenche essa lacuna, fornecendo conversas anteriores como contexto adicional, permitindo que os LLMs gerem respostas mais relevantes e de alta qualidade. Isso melhora o fluxo natural das conversas e melhora significativamente a experiência do usuário.

Um exemplo simples ilustra isso: Suponha que você pergunte a um LLM via API, “Conte-me sobre o Azure Cosmos DB,” e ele responda com um parágrafo longo. Se você então fizer outra chamada de API dizendo, “Divida isso em tópicos para uma leitura mais fácil,” o LLM pode ficar confuso porque não tem contexto da interação anterior.

No entanto, se você incluir a mensagem anterior como parte do contexto na segunda chamada de API, é mais provável que o LLM forneça uma resposta precisa (embora não garantido, já que as saídas de LLM são inerentemente não determinísticas).

Como Executar o Chatbot

Como mencionei anteriormente, a aplicação de exemplo é uma maneira útil para você explorar o langchaingo, a implementação de histórico de chat do Azure Cosmos DB, bem como o Go SDK.

Antes de explorar os detalhes da implementação, é uma boa ideia ver a aplicação em ação. Consulte a seção README do repositório do GitHub, que fornece instruções sobre como configurar, executar e começar a conversar com o chatbot.

Visão geral da aplicação

A aplicação de chat segue um modelo de domínio direto: os usuários podem iniciar várias conversas, e cada conversa pode conter várias mensagens. Desenvolvido em Go, a aplicação inclui componentes de backend e frontend.

Backend

Ele tem várias subpartes:

  • A implementação de histórico de chat do Azure Cosmos DB.
  • Operações principais como iniciar um chat, enviar/receber mensagens e recuperar o histórico de conversas são expostas via uma API REST.
  • A API REST aproveita uma cadeia langchaingo para lidar com mensagens do usuário. A cadeia incorpora automaticamente o histórico de bate-papo para garantir que conversas passadas sejam enviadas para o LLM. langchaingo cuida de toda a orquestração – invocação LLM, inclusão de histórico de bate-papo e muito mais sem exigir implementação manual.

Frontend

Ele é construído usando JavaScript, HTML e CSS. É empacotado como parte do servidor web Go (usando o pacote embed) e invoca as APIs REST do backend em resposta às interações do usuário.

Implementação de Histórico de Bate-Papo Usando Azure Cosmos DB

LangChainGo é um framework plugável, incluindo seu componente de histórico de bate-papo (ou memória). Para integrar o Azure Cosmos DB, é necessário implementar a interface schema.ChatMessageHistory, que fornece métodos para gerenciar o histórico de bate-papo:

  • AddMessage para adicionar mensagens a uma conversa (ou iniciar uma nova).
  • Messages para recuperar todas as mensagens de uma conversa.
  • Clear para excluir todas as mensagens em uma conversa.

Embora você possa instanciar diretamente um objeto CosmosDBChatMessageHistory e usar esses métodos, a abordagem recomendada é integrá-lo ao aplicativo langchaingo. Abaixo está um exemplo de uso do histórico de chat do Azure Cosmos DB com um LLMChain:

Go

 

// Criar uma instância de histórico 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
}

// Criar uma memória com o histórico de chat
chatMemory := memory.NewConversationBuffer(
    memory.WithMemoryKey("chat_history"),
    memory.WithChatHistory(cosmosChatHistory),
)

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

Do ponto de vista do Azure Cosmos DB, observe que a implementação neste exemplo é apenas uma das muitas opções possíveis. O mostrado aqui é baseado em uma combinação do ID do usuário como a chave de partição e o ID da conversa (também chamado às vezes de ID de sessão) sendo a chave única (id de um item do Azure Cosmos DB).

Isto permite que um aplicativo:

  • Obtenha todas as mensagens de uma conversa. Este é uma leitura de ponto usando o ID único (ID da conversa) e a chave de partição (ID do usuário).
  • Adicione uma nova mensagem a uma conversa. Ele utiliza uma operação upsert (em vez de create) para evitar a necessidade de uma read antes da escrita.
  • Exclua uma conversa específica. Ele utiliza a operação delete para remover uma conversa (e todas as suas mensagens).

Embora a interface langchaingo não a exponha, ao integrar isso como parte de um aplicativo, você também pode emitir uma consulta separada para obter todas as conversas de um usuário. Isso também é eficiente, pois está limitado a uma única partição.

Simplifique os testes com o Emulador Azure Cosmos DB e Testcontainers

A aplicação de exemplo inclui casos de teste básicos tanto para o histórico de chat do Azure Cosmos DB quanto para a aplicação principal. Vale ressaltar o uso do testcontainers-go para integrar o contêiner Docker emulador do Azure Cosmos DB baseado em Linux.

Isso é ótimo para testes de integração, pois o banco de dados está disponível localmente e os testes são executados muito mais rapidamente (sem esquecer a economia de custos também!). O diferencial é que você não precisa gerenciar manualmente o ciclo de vida do contêiner Docker. Isso é cuidado como parte do conjunto de testes, graças à API testcontainers-go, que torna conveniente iniciar o contêiner antes da execução dos testes e encerrá-lo uma vez que estiverem concluídos.

Você pode consultar os casos de teste na aplicação de exemplo para mais detalhes. Aqui está um trecho de como o testcontainers-go é utilizado:

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)
    }

    // Dê um pouco mais de tempo para o emulador inicializar completamente
    time.Sleep(5 * time.Second)

    return container, nil
}

Se você está interessado em utilizar o Emulador do Azure Cosmos DB em pipelines de CI, confira o post do blog.

Finalizando

Ser capaz de armazenar o histórico de conversas é uma parte importante dos aplicativos de IA conversacional. Eles podem servir como um ótimo complemento às técnicas existentes, como RAG (geração aumentada por recuperação). Experimente o aplicativo de chatbot e nos diga o que você acha!

Embora a implementação no aplicativo de exemplo seja relativamente simples, como você modela os dados do histórico de conversas depende dos requisitos. Um cenário apresentado é este excelente post de blog sobre como o Microsoft Copilot escala para milhões de usuários com o Azure Cosmos DB.

Alguns dos seus requisitos podem incluir:

  • Armazenar metadados, como reações (além de mensagens)
  • Mostrar as principais N mensagens recentes
  • Considerar o período de retenção dos dados do histórico de conversas (usando TTL)
  • Incorporar análises adicionais (sobre interações do usuário) com base nos dados do histórico de conversas e muito mais.

Independentemente da implementação, sempre certifique-se de incorporar as melhores práticas para modelagem de dados. Consulte aqui para diretrizes.

Você já está utilizando ou planeja aproveitar o Azure Cosmos DB para suas aplicações em Go? Adoraríamos ouvir você! Envie-nos suas perguntas e feedback.

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