Histórico de Bate-papo para Aplicações de IA com Azure Cosmos DB Go SDK

Este post no blog aborda como construir uma implementação de histórico de chat usando o Azure Cosmos DB para o SDK Go NoSQL e LangChainGo. Se você é novo no SDK Go, o aplicativo de chatbot 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é-visualização na época da escrita) para testes de integração com Testcontainers para Go.

Desenvolvedores Go que desejam construir aplicações de IA podem usar LangChainGo, que é um framework para aplicações impulsionadas por LLM. Ele fornece APIs plugáveis para componentes como armazenamento vetorial, incorporação, carregamento de documentos, cadeias (para compor várias operações), histórico de chat e muito mais.


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

O Que É Histórico de Chat e Por Que É Importante para Aplicações Modernas de IA?

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ê usou aplicações como ChatGPT (que também usa o Azure Cosmos DB, a propósito!), 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 da aplicação, 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 ao fornecer 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: “Fale-me sobre o Azure Cosmos DB”, e ele responda com um longo parágrafo. Se você então fizer outra chamada de API dizendo: “Divida isso em pontos para facilitar a leitura”, o LLM pode ficar confuso porque lhe falta contexto da interação anterior.

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

Como Executar o Chatbot

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

Antes de explorar os detalhes da implementação, é uma boa ideia ver o aplicativo 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 do Aplicativo

O aplicativo de chat segue um modelo de domínio simples: os usuários podem iniciar várias conversas, e cada conversa pode conter várias mensagens. Construído em Go, o aplicativo inclui componentes tanto de backend quanto de frontend.

Backend

Possui várias subpartes:

  • A implementação do 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 por meio de uma API REST.
  • A API REST utiliza uma cadeia langchaingo para gerenciar mensagens de usuários. A cadeia incorpora automaticamente o histórico de chat para garantir que conversas passadas sejam enviadas ao LLM. O langchaingo lida com toda a orquestração – invocação do LLM, inclusão do histórico de chat e mais, sem exigir implementação manual.

Frontend

É construída usando JavaScript, HTML e CSS. Está empacotada como parte do servidor web Go (usando o pacote embed) e invoca as APIs REST de backend em resposta às interações dos usuários.

Implementação do Histórico de Chat Usando Azure Cosmos DB

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

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

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

Go

 

// Crie uma instância do 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
}

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

// Crie 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. A mostrada aqui é baseada em uma combinação do ID do usuário como a chave de partição e o ID da conversa (também referido como ID da sessão às vezes) sendo a chave única (id de um item do Azure Cosmos DB).

Isso permite que um aplicativo:

  • Obtenha todas as mensagens de uma conversa. Esta é uma leitura pontual 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 gravação.
  • 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 do Azure Cosmos DB e Testcontainers

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

Isso é ótimo para testes de integração, já que o banco de dados está disponível localmente e os testes são executados muito mais rapidamente (não vamos esquecer também da economia de custos!). A cereja do bolo é 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 de os testes serem executados e encerrá-lo uma vez que estejam completos.

Você pode consultar os casos de teste no aplicativo de exemplo para mais detalhes. Aqui está um trecho de como testcontainers-go é usado:

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ê ao emulador um pouco mais de tempo para inicializar completamente
    time.Sleep(5 * time.Second)

    return container, nil
}

Se você estiver interessado em usar o Emulador do Azure Cosmos DB em pipelines de CI, confira o post no blog.

Encerrando

Armazenar o histórico de chat é 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 chat depende dos requisitos. Um desses cenários que foi apresentado é este excelente post de blog sobre como o Microsoft Copilot escala para milhões de usuários com Azure Cosmos DB.

Alguns dos seus requisitos podem incluir:

  • Armazenar metadados, como reações (além das mensagens)
  • Mostrar as N mensagens mais recentes
  • Considerar o período de retenção de dados do histórico de chat (usando TTL)
  • Incorporar análises adicionais (sobre interações do usuário) com base nos dados do histórico de chat e 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á usando ou planeja aproveitar o Azure Cosmos DB para suas aplicações Go? Adoraríamos ouvir de você! Envie-nos suas perguntas e feedback.

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