OpenAI’s GPT стал передовым инструментом искусственного интеллекта в мире и умеет решать запросы на основе своих обучающих данных. Однако он не может отвечать на вопросы по неизвестным темам:

  • Последние события после сентября 2021 г.
  • Ваши закрытые документы
  • Информация из прошлых разговоров

Эта задача становится еще более сложной, если вы имеете дело с данными в реальном времени, которые часто меняются. Более того, вы не можете передавать в GPT обширный контент и не может хранить ваши данные в течение длительных периодов времени. В этом случае вам необходимо эффективно создать собственное приложение LLM (модель изучения языка), чтобы обеспечить контекст процесса ответа. В этой статье вы узнаете, как разработать такое приложение с использованием библиотеки LLM App с открытым исходным кодом на Python. Исходный код находится на GitHub.

Цели обучения

Из статьи вы узнаете следующее:

  • Причина, по которой вам необходимо добавить собственные данные в ChatGPT.
  • Как использовать встраивания, быстрое проектирование и ChatGPT для лучшего ответа на вопросы.
  • Создайте свой собственный ChatGPT с пользовательскими данными с помощью приложения LLM.
  • Создайте API Python ChatGPT для поиска скидок или цен продажи в режиме реального времени.

Зачем предоставлять ChatGPT собственную базу знаний?

Прежде чем перейти к способам улучшения ChatGPT, давайте сначала изучим методы, которые можно сделать вручную, и определим их проблемы. Обычно ChatGPT расширяется посредством быстрого проектирования. Предположим, вы хотите находить скидки/предложения/купоны на различных онлайн-рынках в режиме реального времени.

Например, когда вы спрашиваете ChatGPT Можете ли вы найти мне скидки на мужскую обувь Adidas на этой неделе?, стандартный ответ, который вы можете получить из интерфейса ChatGPT UI, не обладая специальными знаниями:

Очевидно, что GPT дает общие рекомендации по поиску скидок, но не содержит подробностей относительно того, где и какой тип скидок, а также других деталей. Теперь, чтобы помочь модели, мы дополняем ее информацией о скидках из надежного источника данных. Вы должны взаимодействовать с ChatGPT, добавляя исходное содержимое документа перед публикацией реальных вопросов. Мы соберем этот образец данных из набора данных Сделка по продуктам Amazon и вставим в приглашение только один имеющийся у нас элемент JSON:

Как видите, вы получаете ожидаемый результат, и добиться этого довольно просто, поскольку ChatGPT теперь контекстно-зависим. Однако проблема этого метода заключается в том, что контекст модели ограничен(максимальная длина текста gpt-4 составляет 8192 токена). Эта стратегия быстро станет проблематичной, если входные данные огромны. Вы можете ожидать, что в продажах будут обнаружены тысячи товаров, и вы не сможете предоставить этот большой объем данных в качестве входного сообщения. Кроме того, после того как вы соберете свои данные, вы можете захотеть очистить, отформатировать и предварительно обработать данные, чтобы обеспечить качество и релевантность данных. Если вы используете конечную точку завершения чата OpenAI или создаете пользовательские плагины для ChatGPT, это создает следующие проблемы:

  • Стоимость. Если предоставить более подробную информацию и примеры, производительность модели может улучшиться, хотя и за более высокие затраты (для GPT-4 с входом 10 000 токенов и выходом 200 токенов стоимость составляет 0,624 доллара США). за прогноз). Повторная отправка одинаковых запросов может привести к увеличению затрат, если не используется локальная система кэширования.
  • Задержка. Проблема с использованием API ChatGPT для производства, например API OpenAI, заключается в их непредсказуемости. Нет никаких гарантий относительно предоставления стабильного обслуживания.
  • Безопасность. При интеграции пользовательских плагинов каждая конечная точка API должна быть указана в спецификации OpenAPI для обеспечения функциональности. Это означает, что вы раскрываете ChatGPT настройки своего внутреннего API — риск, к которому многие предприятия относятся скептически.
  • Офлайн-оценка. Проведение автономных тестов кода и вывода данных или локальная репликация потока данных является сложной задачей для разработчиков. Это связано с тем, что каждый запрос к системе может давать разные ответы.

Использование встраивания, оперативного проектирования и ChatGPT для ответов на вопросы.

Многообещающий подход, который вы найдете в Интернете, — это использование LLM для создания вложений, а затем создание приложений с использованием этих вложений, например, для систем поиска и запросов. Другими словами, вместо запроса ChatGPT с использованием конечной точки завершения чата вы должны выполнить следующий запрос:

Учитывая следующие данные о скидках: {input_data} ответьте на этот запрос: {user_query}

Идея проста. Вместо того, чтобы публиковать вопрос напрямую, метод сначала создает векторные внедрения через API OpenAI для каждого входного документа (текст, изображение, CSV, PDF или другие типы данных), затем индексирует сгенерированные внедрения для быстрого поиска и сохраняет их в файле. база данных векторов и использует вопрос пользователя для поиска и получения соответствующих документов из базы данных векторов. Эти документы затем передаются в ChatGPT вместе с вопросом в качестве подсказки. Благодаря этому добавленному контексту ChatGPT может реагировать так, как если бы он был обучен на внутреннем наборе данных.

С другой стороны, если вы используете LLM App от Pathway, вам не нужны даже какие-либо векторные базы данных. Он реализует индексацию данных в памяти в реальном времени, напрямую считывая данные из любого совместимого хранилища, без необходимости запрашивать базу данных векторных документов, что требует таких затрат, как увеличение подготовительных работ, инфраструктура. и сложность. Синхронизировать исходный код и векторы болезненно. Кроме того, это еще сложнее, если подчеркнутые входные данные со временем меняются и требуют переиндексации.

ChatGPT с пользовательскими данными с помощью приложения LLM

Эти простые шаги, приведенные ниже, объясняют подход к конвейерной обработке данных для создания приложения ChatGPT для ваших данных с помощью приложения LLM.

  1. Собирать: ваше приложение считывает данные из различных источников данных (CSV, JsonLines, базы данных SQL, Kafka, Redpanda, Debezium и т. д.) в режиме реального времени, когда с помощью Pathway включен режим потоковой передачи ( Или вы также можете протестировать прием данных в статическом режиме). Он также отображает каждую строку данных в структурированную схему документа для лучшего управления большими наборами данных.
  2. Предварительная обработка. При желании вы можете легко очистить данные, удалив дубликаты, ненужную информацию и зашумленные данные, которые могут повлиять на качество ваших ответов, и извлекая поля данных, необходимые для дальнейшей обработки. Кроме того, на этом этапе вы можете замаскировать или скрыть данные конфиденциальности, чтобы избежать их отправки в ChatGPT.
  3. Встроить: каждый документ встраивается с помощью OpenAI API и извлекает встроенный результат.
  4. Индексирование: создает индекс по сгенерированным внедрениям в реальном времени.
  5. Поиск. Учитывая пользовательский вопрос, скажем, из API-интерфейса, создайте встраивание запроса из OpenAI API. Используя внедрения, на лету извлекайте векторный индекс по релевантности запросу.
  6. Спросить: вставьте вопрос и наиболее релевантные разделы в сообщение GPT. Вернуть ответ GPT (конечная точка завершения чата).

Создайте API ChatGPT Python для продаж.

Как только мы получим четкое представление о процессах работы приложения LLM в предыдущем разделе. Вы можете выполнить следующие действия, чтобы понять, как создать приложение для поиска скидок. Исходный код проекта можно найти на GitHub. Если вы хотите быстро начать использовать приложение, вы можете пропустить эту часть, клонировать репозиторий и запустить пример кода, следуя инструкциям в файле README.md.

Пример цели проекта

Вдохновленный этой статьей о корпоративном поиске, наш пример приложения должен предоставлять конечную точку HTTP REST API в Python, чтобы отвечать на запросы пользователей о текущих продажах, получая последние предложения из различных источников (CSV, Jsonlines, API, брокеров сообщений или баз данных). и использует конечные точки OpenAI API Встраивание и Завершение чата для генерации ответов помощника ИИ.

Шаг 1. Сбор данных (прием пользовательских данных)

Для простоты мы можем использовать в качестве источника данных любой Jsonlines. Приложение принимает файлы Jsonlines типа discounts.jsonl и использует эти данные при обработке запросов пользователей. Источник данных предполагает наличие объекта doc для каждой строки. Обязательно сначала преобразуйте входные данные в Jsonlines. Вот пример файла Jsonline с одним необработанным файлом:

{"doc": "{'position': 1, 'link': 'https://www.amazon.com/deal/6123cc9f', 'asin': 'B00QVKOT0U', 'is_lightning_deal': False, 'deal_type': 'DEAL_OF_THE_DAY', 'is_prime_exclusive': False, 'starts_at': '2023-08-15T00:00:01.665Z', 'ends_at': '2023-08-17T14:55:01.665Z', 'type': 'multi_item', 'title': 'Deal on Crocs, DUNLOP REFINED(\u30c0\u30f3\u30ed\u30c3\u30d7\u30ea\u30d5\u30a1\u30a4\u30f3\u30c9)', 'image': 'https://m.media-amazon.com/images/I/41yFkNSlMcL.jpg', 'deal_price_lower': {'value': 35.48, 'currency': 'USD', 'symbol': '$', 'raw': '35.48'}, 'deal_price_upper': {'value': 52.14, 'currency': 'USD', 'symbol': '$', 'raw': '52.14'}, 'deal_price': 35.48, 'list_price_lower': {'value': 49.99, 'currency': 'USD', 'symbol': '$', 'raw': '49.99'}, 'list_price_upper': {'value': 59.99, 'currency': 'USD', 'symbol': '$', 'raw': '59.99'}, 'list_price': {'value': 49.99, 'currency': 'USD', 'symbol': '$', 'raw': '49.99 - 59.99', 'name': 'List Price'}, 'current_price_lower': {'value': 35.48, 'currency': 'USD', 'symbol': '$', 'raw': '35.48'}, 'current_price_upper': {'value': 52.14, 'currency': 'USD', 'symbol': '$', 'raw': '52.14'}, 'current_price': {'value': 35.48, 'currency': 'USD', 'symbol': '$', 'raw': '35.48 - 52.14', 'name': 'Current Price'}, 'merchant_name': 'Amazon Japan', 'free_shipping': False, 'is_prime': False, 'is_map': False, 'deal_id': '6123cc9f', 'seller_id': 'A3GZEOQINOCL0Y', 'description': 'Deal on Crocs, DUNLOP REFINED(\u30c0\u30f3\u30ed\u30c3\u30d7\u30ea\u30d5\u30a1\u30a4\u30f3\u30c9)', 'rating': 4.72, 'ratings_total': 6766, 'page': 1, 'old_price': 49.99, 'currency': 'USD'}"}

Самое приятное то, что приложение всегда знает об изменениях в папке данные. Если вы добавите еще один файл JSONlines, приложение LLM творит чудеса и автоматически обновляет ответ модели ИИ.

Шаг 2. Загрузка и сопоставление данных

С помощью входного соединителя JSONlines Pathway мы прочитаем локальный файл JSONlines, сопоставим записи данных в схему и создадим таблицу Pathway. Полный исходный код смотрите в app.py:

...
sales_data = pw.io.jsonlines.read(
    "./examples/data",
    schema=DataInputSchema,
    mode="streaming"
)

Сопоставьте каждую строку данных со структурированной схемой документа. Полный исходный код смотрите в app.py:

class DataInputSchema(pw.Schema):
    doc: str

Шаг 3. Внедрение данных

Каждый документ встроен в API OpenAI и извлекает встроенный результат. Полный исходный код смотрите в embedder.py:

...
embedded_data = embeddings(context=sales_data, data_to_embed=sales_data.doc)

Шаг 4. Индексирование данных

Затем мы строим мгновенный индекс по сгенерированным вложениям:

index = index_embeddings(embedded_data)

Шаг 5. Обработка и индексирование пользовательских запросов

Мы создаем конечную точку REST, берем пользовательский запрос из полезных данных запроса API и встраиваем пользовательский запрос в API OpenAI.

...
query, response_writer = pw.io.http.rest_connector(
    host=host,
    port=port,
    schema=QueryInputSchema,
    autocommit_duration_ms=50,
)

embedded_query = embeddings(context=query, data_to_embed=pw.this.query)

Шаг 6: Поиск сходства и оперативное проектирование

Мы выполняем поиск по сходству, используя индекс для определения наиболее релевантных совпадений для внедрения запроса. Затем мы создаем приглашение, которое объединяет запрос пользователя с полученными соответствующими результатами данных и отправляет сообщение в конечную точку завершения ChatGPT для получения правильного и подробного ответа.

responses = prompt(index, embedded_query, pw.this.query)

Мы использовали тот же подход к контекстному обучению, когда создавали приглашение и добавляли внутренние знания в ChatGPT в prompt.py.

prompt = f"Given the following discounts data: \\n {docs_str} \\nanswer this query: {query}"

Шаг 7: Верните ответ

Последний шаг — просто вернуть пользователю ответ API.

# Build prompt using indexed data
responses = prompt(index, embedded_query, pw.this.query)

Шаг 9: Соберите все вместе

Теперь, если мы объединим все вышеперечисленные шаги, у вас есть API Python с поддержкой LLM для пользовательских данных о скидках, готовый к использованию, как вы видите реализацию в скрипте Python app.py.

import pathway as pw

from common.embedder import embeddings, index_embeddings
from common.prompt import prompt


def run(host, port):
    # Given a user question as a query from your API
    query, response_writer = pw.io.http.rest_connector(
        host=host,
        port=port,
        schema=QueryInputSchema,
        autocommit_duration_ms=50,
    )

    # Real-time data coming from external data sources such as jsonlines file
    sales_data = pw.io.jsonlines.read(
        "./examples/data",
        schema=DataInputSchema,
        mode="streaming"
    )

    # Compute embeddings for each document using the OpenAI Embeddings API
    embedded_data = embeddings(context=sales_data, data_to_embed=sales_data.doc)

    # Construct an index on the generated embeddings in real-time
    index = index_embeddings(embedded_data)

    # Generate embeddings for the query from the OpenAI Embeddings API
    embedded_query = embeddings(context=query, data_to_embed=pw.this.query)

    # Build prompt using indexed data
    responses = prompt(index, embedded_query, pw.this.query)

    # Feed the prompt to ChatGPT and obtain the generated answer.
    response_writer(responses)

    # Run the pipeline
    pw.run()


class DataInputSchema(pw.Schema):
    doc: str


class QueryInputSchema(pw.Schema):
    query: str

Шаг 10. Добавьте интерактивный интерфейс (необязательно)

Чтобы сделать ваше приложение более интерактивным и удобным для пользователя, вы можете использовать Streamlit для создания внешнего приложения. См. реализацию в этом файле app.py.

Запуск приложения

Следуйте инструкциям в разделе Как запустить проект файла README.md, и вы сможете начать задавать вопросы о скидках, а API будет отвечать в соответствии с добавленным вами источником данных о скидках.

После того, как мы передаем эти знания GPT с помощью пользовательского интерфейса (применив источник данных), посмотрите, что он ответит:

Приложение учитывает как Rainforest API, так и файловые документы discounts.csv (мгновенно объединяет данные из этих источников), индексирует их в режиме реального времени и использует эти данные при обработке запросов.

Дальнейшие улучшения

Мы обнаружили лишь некоторые возможности приложения LLM, добавив в ChatGPT информацию о конкретной предметной области, например скидки. Вы можете достичь большего:

  • Включайте дополнительные данные из внешних API, а также различные файлы (например, Jsonlines, PDF, Doc, HTML или текстовый формат), базы данных, такие как PostgreSQL или MySQL, и потоковую передачу данных с таких платформ, как Kafka, Redpanda или Debedizum.
  • Сохраняйте моментальный снимок данных, чтобы наблюдать за изменениями продажных цен с течением времени, поскольку Pathway предоставляет встроенную функцию для расчета различий между двумя изменениями.
  • Помимо обеспечения доступа к данным через API, приложение LLM позволяет передавать обработанные данные другим последующим соединителям, таким как инструменты бизнес-аналитики и аналитики. Например, настройте его на получение оповещений при обнаружении изменений цен.

Связанные ресурсы

Сообщество

Присоединяйтесь к каналу Discord, чтобы узнать, как работает помощник AI ChatBot, который мы создали с помощью приложения LLM.