В уроке по поисковым приложениям мы кратко изучили, как интегрировать ваши собственные данные в большие языковые модели (LLM). В этом уроке мы углубимся в концепции привязки данных в вашем приложении LLM, механику процесса и методы хранения данных, включая встраивания и текст.
Видео скоро будет
В этом уроке мы рассмотрим следующее:
-
Введение в RAG, что это такое и почему это используется в ИИ (искусственном интеллекте).
-
Понимание того, что такое векторные базы данных, и создание одной для нашего приложения.
-
Практический пример интеграции RAG в приложение.
После завершения этого урока вы сможете:
-
Объяснить значение RAG в получении и обработке данных.
-
Настроить приложение RAG и привязать свои данные к LLM.
-
Эффективно интегрировать RAG и векторные базы данных в приложения LLM.
Для этого урока мы хотим добавить собственные заметки в образовательный стартап, что позволит чат-боту получать больше информации по разным предметам. Используя имеющиеся у нас заметки, учащиеся смогут лучше учиться и понимать различные темы, облегчая подготовку к экзаменам. Для создания нашего сценария мы будем использовать:
-
Azure OpenAI:LLM, который мы используем для создания нашего чат-бота -
Урок "ИИ для начинающих" по нейронным сетям: это данные, на которых мы будем основывать наш LLM -
Azure AI SearchиAzure Cosmos DB:векторная база данных для хранения наших данных и создания поискового индекса
Пользователи смогут создавать практические викторины на основе своих заметок, карточки для повторения и конспекты. Для начала давайте посмотрим, что такое RAG и как он работает:
Чат-бот на основе LLM обрабатывает запросы пользователей для генерации ответов. Он предназначен для интерактивного взаимодействия и общения с пользователями на широкий круг тем. Тем не менее, его ответы ограничены предоставленным контекстом и исходными обучающими данными. Например, GPT-4 имеет ограничение знаний до сентября 2021 года, что означает отсутствие информации о событиях после этой даты. Кроме того, данные, использованные для обучения LLM, не включают конфиденциальную информацию, такую как личные заметки или руководство по продукту компании.
Предположим, вы хотите развернуть чат-бота, который создаёт викторины из ваших заметок, вам потребуется соединение с базой знаний. Вот где RAG приходит на помощь. RAG работает следующим образом:
-
База знаний: Перед извлечением документы необходимо загрузить и предварительно обработать, обычно разбивая большие документы на меньшие части, преобразуя их в текстовые встраивания и сохраняя в базе данных.
-
Запрос пользователя: пользователь задаёт вопрос.
-
Извлечение: Когда пользователь задаёт вопрос, модель встраивания извлекает релевантную информацию из нашей базы знаний, чтобы предоставить более полный контекст, который будет включён в запрос.
-
Генерация с дополнением: LLM улучшает свой ответ на основе извлечённых данных. Это позволяет ответу основываться не только на предварительно обученных данных, но и на релевантной информации из добавленного контекста. Извлечённые данные используются для дополнения ответов LLM. Затем LLM возвращает ответ на вопрос пользователя.
Архитектура RAG реализована с использованием трансформеров, состоящих из двух частей: энкодера и декодера. Например, когда пользователь задаёт вопрос, входной текст «кодируется» в векторы, отражающие смысл слов, а векторы «декодируются» в наш индекс документов и генерируют новый текст на основе запроса пользователя. LLM использует модель энкодер-декодер для генерации результата.
Согласно предлагаемой статье Retrieval-Augmented Generation for Knowledge Intensive NLP Tasks существуют два подхода к реализации RAG:
-
RAG-Sequence — использует извлечённые документы для предсказания лучшего возможного ответа на запрос пользователя.
-
RAG-Token — использует документы для генерации следующего токена, затем извлекает их для ответа на запрос пользователя.
-
Богатство информации: обеспечивает актуальность и современность текстовых ответов. Таким образом, повышает эффективность выполнения задач в конкретной области за счёт доступа к внутренней базе знаний.
-
Снижает подделку ответов, используя проверяемые данные в базе знаний для контекста пользовательских запросов.
-
Является экономичным, поскольку дешевле, чем дообучение LLM.
Наше приложение основано на наших личных данных, а именно на уроке по нейронным сетям из курса «ИИ для начинающих».
Векторная база данных, в отличие от традиционных баз данных, представляет собой специализированную базу данных, предназначенную для хранения, управления и поиска векторных встраиваний. Она хранит числовые представления документов. Преобразование данных в числовые встраивания облегчает нашей системе ИИ понимание и обработку данных.
Мы сохраняем наши встраивания в векторных базах данных, поскольку LLM имеют ограничение на количество токенов, которые они могут принять на вход. Поскольку нельзя передать всю информацию о встраиваниях целиком, их нужно разбивать на части, и при запросе пользователя будут возвращены самые релевантные части вместе с запросом. Разбиение также снижает затраты на количество токенов, передаваемых через LLM.
Популярные векторные базы данных включают Azure Cosmos DB, Clarifyai, Pinecone, Chromadb, ScaNN, Qdrant и DeepLake. Вы можете создать модель Azure Cosmos DB с помощью Azure CLI следующей командой:
az login
az group create -n <resource-group-name> -l <location>
az cosmosdb create -n <cosmos-db-name> -r <resource-group-name>
az cosmosdb list-keys -n <cosmos-db-name> -g <resource-group-name>Прежде чем сохранить данные, необходимо преобразовать их в векторные встраивания. Если вы работаете с большими документами или длинными текстами, их можно разбивать на части в соответствии с ожидаемыми запросами. Разбиение может быть на уровне предложений или абзацев. Поскольку смыслы зависят от слов вокруг, можно добавить дополнительный контекст к части, например, заголовок документа или текст до или после части. Разбиение может быть выполнено следующим образом:
def split_text(text, max_length, min_length):
words = text.split()
chunks = []
current_chunk = []
for word in words:
current_chunk.append(word)
if len(' '.join(current_chunk)) < max_length and len(' '.join(current_chunk)) > min_length:
chunks.append(' '.join(current_chunk))
current_chunk = []
# Если последний фрагмент не достиг минимальной длины, добавьте его всё равно
if current_chunk:
chunks.append(' '.join(current_chunk))
return chunksПосле разбиения мы можем встроить текст с помощью различных моделей встраивания. Некоторые из моделей, которые можно использовать: word2vec, ada-002 от OpenAI, Azure Computer Vision и многие другие. Выбор модели зависит от используемых языков, типа кодируемого контента (текст/изображения/аудио), размера входных данных, а также длины выходных встраиваний.
Пример текстового встраивания с использованием модели OpenAI text-embedding-ada-002:

Когда пользователь задаёт вопрос, система извлечения преобразует его в вектор с помощью кодировщика запросов, затем выполняет поиск в нашем индексе документов для релевантных векторов, связанных с запросом. После этого она преобразует и входной вектор, и векторы документов в текст и передаёт их в LLM.
Извлечение происходит, когда система пытается быстро найти документы в индексе, соответствующие критериям поиска. Цель — получить документы, которые будут использованы для предоставления контекста и привязки LLM к вашим данным.
В нашей базе данных поиск можно выполнять несколькими способами:
-
Поиск по ключевым словам — используется для текстовых запросов.
-
Векторный поиск — преобразует документы из текста в векторные представления с помощью моделей встраивания, позволяя выполнять семантический поиск, основанный на значении слов. Извлечение происходит путём поиска документов, чьи векторные представления наиболее близки к запросу пользователя.
-
Гибридный — сочетание поиска по ключевым словам и векторного поиска.
Проблема извлечения возникает, когда в базе нет похожего ответа на запрос, тогда система предоставит лучший доступный ответ. Однако можно использовать такие методы, как установка максимального порога релевантности или гибридный поиск с комбинированием ключевых слов и векторов. В этом уроке мы используем гибридный поиск, сочетание векторного и ключевого слов.
Мы будем хранить данные в датафрейме с колонками, содержащими части текста и встраивания.
Система извлечения будет искать в базе знаний встраивания, максимально близкие друг к другу, — ближайших соседей, поскольку они отражают похожие тексты. Когда пользователь задаёт запрос, он сначала встраивается, а затем сопоставляется с похожими встраиваниями. Популярная метрика сходства — косинусное сходство, основанное на угле между двумя векторами.
Для измерения сходства можно также использовать Евклидово расстояние — прямое расстояние между концами векторов, или скалярное произведение, которое измеряет сумму произведений соответствующих элементов векторов.
Перед выполнением поиска необходимо создать поисковый индекс для базы знаний. Индекс хранит наши встраивания и может быстро возвращать наиболее похожие части даже в большой базе данных. Индекс можно создать локально с помощью:
from sklearn.neighbors import NearestNeighbors
embeddings = flattened_df['embeddings'].to_list()
# Создать индекс поиска
nbrs = NearestNeighbors(n_neighbors=5, algorithm='ball_tree').fit(embeddings)
# Для запроса к индексу можно использовать метод kneighbors
distances, indices = nbrs.kneighbors(embeddings)После запроса в базу может потребоваться сортировка результатов по релевантности. Повторная сортировка с помощью LLM использует машинное обучение для улучшения релевантности результатов поиска, упорядочивая их от наиболее релевантных. В Azure AI Search повторная сортировка выполняется автоматически с помощью семантического ранжировщика. Пример работы повторной сортировки с использованием ближайших соседей:
# Найти наиболее похожие документы
distances, indices = nbrs.kneighbors([query_vector])
index = []
# Вывести наиболее похожие документы
for i in range(3):
index = indices[0][i]
for index in indices[0]:
print(flattened_df['chunks'].iloc[index])
print(flattened_df['path'].iloc[index])
print(flattened_df['distances'].iloc[index])
else:
print(f"Index {index} not found in DataFrame")Последним шагом является добавление нашего LLM в систему, чтобы получать ответы, основанные на наших данных. Мы можем реализовать это следующим образом:
user_input = "what is a perceptron?"
def chatbot(user_input):
# Преобразовать вопрос в вектор запроса
query_vector = create_embeddings(user_input)
# Найти наиболее похожие документы
distances, indices = nbrs.kneighbors([query_vector])
# добавить документы к запросу для предоставления контекста
history = []
for index in indices[0]:
history.append(flattened_df['chunks'].iloc[index])
# объединить историю и ввод пользователя
history.append(user_input)
# создать объект сообщения
messages=[
{"role": "system", "content": "You are an AI assistant that helps with AI questions."},
{"role": "user", "content": "\n\n".join(history) }
]
# использовать чат-завершение для генерации ответа
response = openai.chat.completions.create(
model="gpt-4",
temperature=0.7,
max_tokens=800,
messages=messages
)
return response.choices[0].message
chatbot(user_input)-
Качество ответов — обеспечивать естественность, беглость и человекоподобность звучания.
-
Привязанность данных — оценка того, действительно ли ответ основан на предоставленных документах.
-
Релевантность — оценка соответствия и отношения ответа к заданному вопросу.
-
Беглость — проверка грамматической осмысленности ответа.
Существует множество сценариев, где вызовы функций могут улучшить ваше приложение, например:
-
Вопросы и ответы: привязка данных вашей компании к чату, который могут использовать сотрудники для заданий вопросов.
-
Системы рекомендаций: создание системы, которая находит наиболее похожие значения, такие как фильмы, рестораны и многое другое.
-
Чат-боты: хранение истории чатов и персонализация общения на основе данных пользователя.
-
Поиск изображений на основе векторных встраиваний, полезен при распознавании изображений и обнаружении аномалий.
Мы рассмотрели основные области RAG: добавление данных в приложение, запросы пользователей и вывод. Для упрощения создания RAG можно использовать такие фреймворки, как Semantic Kernel, Langchain или Autogen.
Для продолжения изучения генерации с дополнением извлечения (RAG) вы можете:
-
Создать фронтенд для приложения на выбранном вами фреймворке.
-
Использовать фреймворк, например LangChain или Semantic Kernel, и пересоздать ваше приложение.
Поздравляем с завершением урока 👏.
После завершения этого урока ознакомьтесь с нашей коллекцией по генеративному ИИ (Generative AI Learning collection), чтобы продолжить развивать свои знания в области генеративного ИИ!
Отказ от ответственности:
Этот документ был переведен с помощью автоматического сервиса перевода Co-op Translator. Несмотря на наши усилия обеспечивать точность, имейте в виду, что машинный перевод может содержать ошибки или неточности. Оригинальный документ на его исходном языке следует считать авторитетным источником. Для критически важной информации рекомендуется обратиться к профессиональному человеческому переводу. Мы не несем ответственности за любые недоразумения или неправильные толкования, возникшие в результате использования этого перевода.


