История чатов для AI приложений с использованием Azure Cosmos DB Go SDK

Этот пост в блоге рассматривает создание реализации истории чата с использованием Azure Cosmos DB для NoSQL Go SDK и LangChainGo. Если вы новичок в Go SDK, пример приложения чат-бота, представленный в блоге, служит практическим введением, охватывая базовые операции, такие как чтение, обновление и т. д. Кроме того, он демонстрирует использование эмулятора Azure Cosmos DB на основе Linux (на момент написания в стадии предварительного просмотра) для интеграционных тестов с Testcontainers для Go.

Разработчики Go, стремящиеся создавать приложения искусственного интеллекта, могут использовать LangChainGo, который является фреймворком для приложений на основе LLM. Он предоставляет подключаемые API для компонентов, таких как векторное хранилище, встраивание, загрузка документов, цепочки (для составления нескольких операций), история чата и многое другое.


Прежде чем приступить, давайте шагнем назад, чтобы понять основы.

Что такое история чата и почему она важна для современных приложений искусственного интеллекта?

Одним из общих требований для приложений искусственного интеллекта в области разговорного интерфейса является возможность сохранения и извлечения сообщений, обмениваемых в рамках разговоров. Это часто называется “историей чата”. Если вы использовали приложения, такие как ChatGPT (которое также использует Azure Cosmos DB, кстати!), вам может быть знаком этот концепт.

Когда пользователь входит в систему, он может начать чат, и сообщения, обменянные в рамках разговора, сохраняются. Когда они входят в систему снова, они могут увидеть свои предыдущие разговоры и продолжить с того места, где остановились.

История чата очевидно важна для конечных пользователей приложения, но давайте не забудем про LLM! Несмотря на то, насколько умными могут показаться LLM, они не могут вспомнить прошлые взаимодействия из-за отсутствия встроенной памяти (по крайней мере, на данный момент). Использование истории чата заполняет этот разрыв, предоставляя предыдущие разговоры в качестве дополнительного контекста, что позволяет LLM генерировать более релевантные и качественные ответы. Это улучшает естественный ход разговоров и значительно повышает пользовательский опыт.

Простой пример иллюстрирует это: Предположим, вы спрашиваете LLM через API: “Расскажите мне о Azure Cosmos DB”, и он отвечает длинным абзацем. Если затем вы делаете еще один вызов API, говоря: “Разбейте это на маркированные пункты для более легкого чтения”, LLM может запутаться, потому что ему не хватает контекста из предыдущего взаимодействия.

Однако, если вы включите предыдущее сообщение в контекст второго вызова API, LLM скорее всего предоставит точный ответ (хотя это не гарантировано, поскольку выводы LLM по своей природе недетерминированны).

Как запустить чатбот

Как я уже упоминал ранее, образец приложения – это полезный способ изучить langchaingo, реализацию истории чата в Azure Cosmos DB, а также Go SDK.

Прежде чем изучать детали реализации, полезно увидеть приложение в действии. Обратитесь к разделу README репозитория GitHub, где содержатся инструкции по настройке, запуску и началу общения с чат-ботом.

Обзор приложения

Чат-приложение следует простой модели домена: пользователи могут начинать несколько разговоров, и каждый разговор может содержать несколько сообщений. Приложение, созданное на Go, включает как бэкенд, так и фронтенд.

Бэкенд

Он имеет несколько подчастей:

  • Реализация истории чата в Azure Cosmos DB.
  • Основные операции, такие как начало чата, отправка/получение сообщений и получение истории разговоров, доступны через REST API.
  • REST API использует цепочку langchaingo для обработки сообщений пользователей. Цепочка автоматически включает историю чата, чтобы гарантировать, что прошлые разговоры отправляются в LLM. langchaingo обрабатывает всю оркестрацию – вызов LLM, включение истории чата и многое другое без необходимости ручной реализации.

Фронтенд

Он создан с использованием JavaScript, HTML и CSS. Он упакован как часть веб-сервера Go (с использованием пакета embed) и вызывает REST API бэкенда в ответ на взаимодействие пользователя.

Реализация истории чата с использованием Azure Cosmos DB

LangChainGo является расширяемым фреймворком, включая свой компонент истории чата (или памяти). Чтобы интегрировать Azure Cosmos DB, вам необходимо реализовать интерфейс schema.ChatMessageHistory, который предоставляет методы для управления историей чата:

  • AddMessage для добавления сообщений в разговор (или начала нового).
  • Messages для извлечения всех сообщений для разговора.
  • Clear для удаления всех сообщений в разговоре.

Хотя вы можете напрямую создать экземпляр CosmosDBChatMessageHistory и использовать эти методы, рекомендуемый подход заключается в его интеграции в приложение langchaingo. Ниже приведен пример использования истории чата Azure Cosmos DB с LLMChain:

Go

 

// Создание экземпляра истории чата
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
}

// Создание памяти с историей чата
chatMemory := memory.NewConversationBuffer(
    memory.WithMemoryKey("chat_history"),
    memory.WithChatHistory(cosmosChatHistory),
)

// Создание цепочки LLM
chain := chains.LLMChain{
    Prompt:       promptsTemplate,
    LLM:          llm,
    Memory:       chatMemory,
    OutputParser: outputparser.NewSimple(),
    OutputKey:    "text",
}

С точки зрения Azure Cosmos DB, отметим, что реализация в этом примере лишь один из множества возможных вариантов. Показанный здесь основан на комбинации идентификатора пользователя в качестве ключа раздела и идентификатора беседы (иногда называемого идентификатором сеанса) в качестве уникального ключа (id элемента Azure Cosmos DB).

Это позволяет приложению:

  • Получить все сообщения для беседы. Это точечное чтение с использованием уникального идентификатора (идентификатора беседы) и ключа раздела (идентификатора пользователя).
  • Добавьте новое сообщение в беседу. Вместо операции create используйте операцию upsert, чтобы избежать необходимости выполнения операции read перед записью.
  • Удалите определенную беседу. Используйте операцию delete, чтобы удалить беседу (и все ее сообщения).

Хотя интерфейс langchaingo не предоставляет этой функции, при интеграции в приложение вы также можете выполнить отдельный запрос для получения всех бесед пользователя. Это также эффективно, поскольку запрос ограничен одним разделом.

Упростите тестирование с помощью эмулятора Azure Cosmos DB и Testcontainers

Образец приложения включает базовые тестовые случаи как для истории чата в Azure Cosmos DB, так и для основного приложения. Следует отметить использование testcontainers-go для интеграции с эмулятором Azure Cosmos DB на основе Linux в контейнере Docker.

Это отлично подходит для интеграционных тестов, поскольку база данных доступна локально, и тесты выполняются намного быстрее (не забывайте также о экономии затрат!). Приятным бонусом является то, что вам не нужно управлять жизненным циклом контейнера Docker вручную. Об этом заботится часть набора тестов, благодаря API testcontainers-go, что удобно позволяет запускать контейнер перед запуском тестов и завершать его после их завершения.

Вы можете обратиться к тестовым случаям в образце приложения для получения дополнительной информации. Вот фрагмент того, как используется 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)
    }

    // Дайте эмулятору немного больше времени на полную инициализацию
    time.Sleep(5 * time.Second)

    return container, nil
}

Если вас интересует использование эмулятора Azure Cosmos DB в CI-конвейерах, ознакомьтесь с статьей в блоге.

Завершение

Возможность хранения истории чата является важной частью приложений искусственного интеллекта для общения. Они могут служить отличным дополнением к существующим техникам, таким как RAG (извлекающая генерация). Попробуйте приложение чатбота и дайте нам знать, что вы думаете!

Хотя реализация в примерном приложении довольно проста, способ моделирования данных истории чата зависит от требований. Одним из таких сценариев, который был представлен, является этот отличный пост блога о том, как Microsoft Copilot масштабируется до миллионов пользователей с помощью Azure Cosmos DB.

Некоторые из ваших требований могут включать в себя:

  • Хранение метаданных, таких как реакции (помимо сообщений)
  • Показ топ N последних сообщений
  • Учет периода хранения данных истории чата (использование TTL)
  • Внедрение дополнительной аналитики (на основе взаимодействий пользователя) на основе данных истории чата и многое другое.

Независимо от реализации, всегда убедитесь, что вы используете лучшие практики для моделирования данных. Ссылка на рекомендации здесь: здесь.

Вы уже используете или планируете использовать Azure Cosmos DB для ваших приложений на Go? Мы будем рады услышать вас! Отправьте нам ваши вопросы и отзывы.

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