Усильте свои исследования с помощью индивидуального AI-ассистента с поддержкой LLM.

Усовершенствуйте свои исследования с индивидуальным AI-ассистентом, поддерживающим LLM.

Введение

В мире, затопленном информацией, эффективный доступ и извлечение актуальных данных имеют огромную ценность. ResearchBot – это передовой проект приложения, использующий возможности LLM (Large Language Models) от OpenAI с использованием Langchain для информационного поиска. Эта статья подобна пошаговому руководству по созданию собственного ResearchBot и тому, как он может быть полезен в реальной жизни. Это похоже на наличие интеллектуального помощника, который находит нужную информацию среди массы данных. Независимо от того, любите ли вы программирование или интересуетесь искусственным интеллектом, этот руководство здесь, чтобы помочь вам усилить ваше исследование с помощью настроенного LLM ассистента. Это ваш путь к разблокировке потенциала LLM и революционированию способа доступа к информации.

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

  • Понять более глубокие концепции LLM (Large Language Models), Langchain, Vector Database и Embeddings.
  • Исследовать применение LLM и ResearchBot в реальных сферах, таких как исследования, поддержка клиентов и генерация контента.
  • Открыть для себя лучшие практики интеграции ResearchBot в существующие проекты или рабочие процессы, улучшая производительность и принятие решений.
  • Построить ResearchBot для оптимизации процессов извлечения данных и ответа на вопросы.
  • Оставаться в курсе тенденций в области технологии LLM и ее потенциала для революционизации способа доступа и использования информации.

Эта статья была опубликована в рамках блог-марафона по науке о данных.

Что такое ResearchBot?

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

Представьте себе, что у вас есть персональный помощник, который может читать и понимать несколько статей, документов, веб-страниц и предоставлять вам соответствующие и краткие резюме. Наша цель с ResearchBot – сократить время и усилия, необходимые для ваших исследовательских целей.

Практические примеры использования

  • Финансовый анализ: Будьте в курсе последних новостей рынка и получайте быстрые ответы на финансовые вопросы.
  • Журналистика: Эффективно собирайте фоновую информацию, источники и ссылки для статей.
  • Здравоохранение: Получайте доступ к актуальным медицинским исследованиям и кратким изложениям для научных целей.
  • Академия: Находите актуальные академические статьи, исследовательские материалы и ответы на исследовательские вопросы.
  • Правовое исследование: Поиск юридических документов, решений и анализа юридических вопросов с минимальными затратами времени.

Техническая терминология

Векторная база данных

Контейнер для хранения векторных вложений текстовых данных, который является важным для эффективного поиска на основе сходства.

Понимание намерений и контекста запроса пользователя для выполнения поиска без полной зависимости от точного совпадения ключевых слов.

Вложение

Числовое представление текстовых данных, позволяющее эффективное сравнение и поиск.

Техническая архитектура проекта

Техническая архитектура
  • Мы используем модель вложений для создания векторных вложений для информации или контента, который необходимо индексировать.
  • Векторное вложение вставляется в векторную базу данных с некоторым ссылочным указателем на исходный контент, из которого было создано вложение.
  • Когда приложение выдает запрос, мы используем ту же модель вложений для создания вложений для запроса и используем эти вложения для запроса в базу данных на сходные векторные вложения.
  • Эти сходные вложения связаны с исходным контентом, на основе которого они были созданы.

Как работает ResearchBot?

Работа

Эта архитектура облегчает хранение, извлечение и взаимодействие с контентом, делая нашего ResearchBot мощным инструментом для извлечения информации и анализа. Он использует векторные вложения и векторную базу данных для облегчения быстрого и точного поиска контента.

Компоненты

  1. Документы: Это статьи или контент, которые вы хотите индексировать для последующего обращения и извлечения.
  2. Слитки: Этот процесс разбивает документы на меньшие, управляемые части. Это важно для работы с большими документами или статьями, обеспечивая их идеальную соответствуют ограничениям языковой модели и эффективному индексированию.
  3. Векторная база данных: Векторная база данных является важной частью архитектуры. В ней хранятся векторные вложения, сгенерированные из контента. Каждый вектор связан с исходным контентом, из которого он был получен, создавая связь между численным представлением и исходным материалом.
  4. Извлечение: Когда пользователь обращается к системе, та же модель вложения используется для создания вложений для запроса. Затем эти вложения запроса используются для поиска векторной базы данных похожих векторных вложений. Результатом является большая группа похожих векторов, каждый из которых связан с исходным источником контента.
  5. Подсказка: Здесь пользователь взаимодействует с системой. Пользователи вводят запросы, и система обрабатывает эти запросы для извлечения соответствующей информации из векторной базы данных, предоставляя ответы и ссылки на исходный контент.

Загрузчики документов в LangChain

Используйте загрузчики документов для загрузки данных из источника в виде документа. Документ представляет собой текст и связанную с ним метаданные. Например, существуют загрузчики документов для загрузки простого текстового файла .txt, для загрузки текстового содержимого статей или блогов, а также для загрузки транскрипта видео с YouTube.

Существует множество типов загрузчиков документов:

Пример – TextLoader

Этот код демонстрирует функциональность TextLoader из Langchain. Он загружает текстовые данные из существующего файла “Langchain.txt” в класс TextLoader, готовя его для дальнейшей обработки. Переменная ‘file_path’ хранит путь к загружаемому файлу для будущих целей.

# Импортировать класс TextLoader из модуля langchain.document_loadersfrom langchain.document_loaders import TextLoader# Рассматриваем класс TextLoader, указывая файл для загрузки, например "Langchain.txt"loader = TextLoader("Langchain.txt")# Загрузить содержимое из указанного файла ("Langchain.txt") в класс TextLoaderloader.load()# Проверить тип экземпляра "loader", который должен быть "TextLoader"type(loader)# Путь к файлу, связанному с TextLoader, содержится в переменной "file_path"loader.file_path
TextLoaders

Разделители текста в LangChain

Разделители текста отвечают за разбиение документа на более мелкие документы. Эти меньшие единицы упрощают работу с контентом и его обработку. В контексте нашего проекта ResearchBot мы используем разделители текста для подготовки данных к дальнейшему анализу и извлечению.

Зачем нам нужны разделители текста?

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

Ручной подход к разделению текста на части

# Пример случайного текста из Википедииtext# Предположим, что ограничение на количество токенов LLM составляет 100, в нашем коде мы можем сделать простую вещь, например,текст[:100]
текст
кусок

Ну, но мы хотим получить полные слова и сделать это для всего текста, мы можем использовать функцию split в Python

words = text.split(" ")len(words)chunks = []s = ""for word in words:    s += word + " "    if len(s)>200:        chunks.append(s)        s = ""        chunks.append(s)chunks[:2]
Блоки

Разделение данных на блоки можно выполнить в нативном Python, но это утомительный процесс. Кроме того, при необходимости, вам может потребоваться экспериментировать с использованием нескольких разделителей последовательно, чтобы убедиться, что каждый блок не превышает предельное ограничение по длине токена соответствующего МЛЯ.

Langchain предлагает лучший способ с использованием классов разделителя текста. В Langchain есть несколько классов разделителей текста, позволяющих нам это сделать.

1. Разделитель текста по символам

Этот класс предназначен для разделения текста на более мелкие блоки на основе определенных разделителей. Например, абзацы, точки, запятые и переносы строк (\n). Он более полезен для разбиения текста на смешанные блоки для дальнейшей обработки.

from langchain.text_splitter import CharacterTextSplittersplitter = CharacterTextSplitter(    separator = "\n",    chunk_size=200,    chunk_overlap=0)chunks = splitter.split_text(text)len(chunks)for chunk in chunks:    print(len(chunk))
Разделитель текста по символам

Как видно, хотя мы указали размер блока 200, так как разделение произошло на основе \n, оно создало блоки, которые больше 200.

Другой класс из Langchain может быть использован для рекурсивного разделения текста на основе списка разделителей. Этот класс называется RecursiveTextSplitter. Посмотрим, как он работает.

2. Рекурсивный разделитель текста

Это разновидность разделителя текста, который работает, рекурсивно анализируя символы в тексте. Он пытается разделить текст на разные части, итеративно находя разные комбинации символов, пока не определит подходящий способ разделения на части текста и различного типа объемы.

from langchain.text_splitter import RecursiveCharacterTextSplitterr_splitter = RecursiveCharacterTextSplitter(    separators = ["\n\n", "\n", " "],  # Список разделителей     chunk_size = 200,  # Размер каждого созданного блока    chunk_overlap  = 0,  # Размер перекрытия между блоками     length_function = len  # Функция для вычисления размера,)chunks = r_splitter.split_text(text)for chunk in chunks:    print(len(chunk))    first_split = text.split("\n\n")[0]first_splitlen(first_split)  second_split = first_split.split("\n")second_splitfor split in second_split:    print(len(split))    second_split[2]second_split[2].split(" ")
разделитель

Давайте разберем, как мы сформировали эти блоки:

первое разделение

Рекурсивный разделитель текста использует список разделителей: separators = [“\n\n”, “\n”, “.”]

Теперь он будет сначала разбиваться по \n\n, а затем, если размер получившегося отрезка превышает параметр chunk_size, который в данном случае равен 200, он будет использовать следующий разделитель – \n.

second_split

Третий отрезок превышает размер 200. Теперь он попытается разделить его с использованием третьего разделителя – пробела.

final_split

Когда вы разделяете это по пробелу (то есть second_split[2].split(“ “)), он отделяет каждое слово, а затем объединяет эти отрезки так, чтобы их размер был близок к 200.

Векторная база данных

Теперь представим себе сценарий, когда вам нужно хранить миллионы или даже миллиарды векторных эмбеддингов слов, это может быть важной сценой в приложении реального мира. Реляционные базы данных, способные хранить структурированные данные, могут оказаться не подходящими из-за своих ограничений в работе с такими большими объемами данных.

Вот где вступают в игру векторные базы данных. Векторная база данных разработана для эффективного хранения и получения векторных данных, что делает ее подходящей для хранения векторных эмбеддингов слов.

Векторные базы данных революционизируют поиск информации с помощью семантического поиска. Они используют мощность векторных эмбеддингов и умные техники индексации для более быстрого и точного поиска.

Чем отличается векторный индекс от векторной базы данных?

Отдельные векторные индексы, такие как FAISS (Facebook AI Similarity Search), могут улучшить поиск и получение векторных эмбеддингов, но они не обладают возможностями, которые есть в одной из баз данных. Векторные базы данных, с другой стороны, специально разработаны для управления векторными эмбеддингами, обладая множеством преимуществ по сравнению с использованием отдельных векторных индексов.

FAISS

Шаги:

1: Создайте векторы исходного текстового столбца

2: Создайте индекс FAISS для векторов

3: Нормализуйте исходные векторы и добавьте их в индекс

4: Закодируйте поисковый текст с использованием того же кодировщика и нормализуйте выходной вектор

5: Ищите похожий вектор в созданном индексе FAISS

df = pd.read_csv("sample_text.csv")df# Шаг 1: Создайте векторы исходного текстового столбцаfrom sentence_transformers import SentenceTransformerencoder = SentenceTransformer("all-mpnet-base-v2")vectors = encoder.encode(df.text)vectors# Шаг 2: Создайте индекс FAISS для векторовimport faissindex = faiss.IndexFlatL2(dim)# Шаг 3: Нормализуйте исходные векторы и добавьте их в индексindex.add(vectors)index# Шаг 4: Закодируйте поисковый текст с использованием того же кодировщикаsearch_query = "ищу места для посещения во время отпуска"vec = encoder.encode(search_query)vec.shapesvec = np.array(vec).reshape(1,-1)svec.shape# Шаг 5: Ищите похожий вектор в индексе FAISSdistances, I = index.search(svec, k=2)distancesrow_indices = I.tolist()[0]row_indicesdf.loc[row_indices]

Если мы проверим этот набор данных,

data

мы преобразуем этот текст в векторы с использованием векторных эмбеддингов слов

vectors

Учитывая мой search_query = “ищу места для посещения во время каникул”

Результаты

Данный поиск предоставляет наиболее похожие 2 результата, связанные с моим запросом, с использованием семантического поиска в категории “Путешествия”.

При выполнении поискового запроса база данных использует такие техники, как Locality-Sensitive Hashing (LSH), чтобы ускорить процесс. LSH группирует похожие векторы в корзины, обеспечивая более быстрый и направленный поиск. Это означает, что вам не нужно сравнивать ваш вектор запроса со всеми сохраненными векторами.

Извлечение

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

Проблемы извлечения

Извлечение в семантическом поиске представляет несколько проблем, таких как ограничение токенов, налагаемое языковыми моделями, такими как GPT-3. При работе с несколькими соответствующими фрагментами данных происходит превышение лимита ответов.

Метод Stuff

В этой модели происходит сбор всех соответствующих фрагментов данных из векторной базы данных и их объединение в запрос (отдельный). Главным недостатком этого процесса является превышение лимита токенов, что приводит к неполным ответам.

Stuff

Метод Map Reduce

Чтобы преодолеть ограничение токенов и упростить процесс извлечения вопрос-ответ, этот процесс предоставляет решение, которое вместо объединения соответствующих фрагментов в запрос (отдельный), если есть 4 фрагмента. Пропустить все через отдельные изолированные LLM. Эти вопросы предоставляют контекстную информацию, которая позволяет модели языка сосредоточиться на содержании каждого фрагмента независимо. В результате получается набор одиночных ответов для каждого фрагмента. Наконец, делается окончательный вызов LLM, чтобы объединить все эти отдельные ответы и найти лучший ответ на основе полученных из каждого фрагмента идей.

Map Reduce

Рабочий процесс ResearchBot

(1) Загрузка данных

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

# Укажите URL для сбора данных loaders = UnstructuredURLLoader(urls=[    "",    ""])data = loaders.load() len(data)

(2) Разделение данных на фрагменты

Данные разделяются на более мелкие, управляемые секции или фрагменты, упрощая эффективную обработку и обработку больших текстовых документов.

text_splitter = RecursiveCharacterTextSplitter(    chunk_size=1000,    chunk_overlap=200)# Используйте split_documents вместо split_text, чтобы получить фрагменты.docs = text_splitter.split_documents(data)len(docs)docs[0]

(3) Создание векторных представлений для этих фрагментов и сохранение их в индекс FAISS

Фрагменты текста преобразуются в числовые векторные представления (встраивания) и сохраняются в индексе Faiss, оптимизируя извлечение похожих векторов.

# Создание встраиваний для фрагментов с использованием openAIEmbeddingsembeddings = OpenAIEmbeddings()# Передайте документы и встраивания для создания векторного индекса FAISSvectorindex_openai = FAISS.from_documents(docs, embeddings)# Сохранение созданного векторного индекса в локальном файлеfile_path="vector_index.pkl"with open(file_path, "wb") as f:    pickle.dump(vectorindex_openai, f)        if os.path.exists(file_path):    with open(file_path, "rb") as f:        vectorIndex = pickle.load(f)

(4) Получение похожих векторных представлений для заданного вопроса и вызов LLM для получения окончательного ответа

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

# Инициализация LLM соответствующими параметрамиllm = OpenAI(temperature=0.9, max_tokens=500) chain = RetrievalQAWithSourcesChain.from_llm(  llm=llm,   retriever=vectorIndex.as_retriever())chainquery = "" #задайте ваш запрос langchain.debug=Truechain({"question": query}, return_only_outputs=True)

Окончательное применение

После использования всех этих этапов (загрузчик документов, разбивка текста, векторная база данных, поиск, предложение) и создания приложения с помощью Streamlit, мы закончили создание нашего ResearchBot.

URL

Это раздел на странице, где вставляются ссылки на блоги или статьи. Я указал ссылки на последние выпущенные модели iPhone в 2023 году. Перед началом разработки этого приложения ResearchBot у всех будет вопрос, почему мы создаем этот ResearchBot, если у нас уже есть ChatGPT. Вот ответ:

Ответ ChatGPT:

ChatGPT

Ответ ResearchBot:

Research Bot

Здесь мой запрос – “Какова цена Apple iPhone 15?”

Эти данные из 2023 года и они не доступны в ChatGPT 3.5, но мы обучили наш ResearchBot с последней информацией о iPhone. Итак, мы получили нужный ответ от нашего ResearchBot.

Вот три проблемы использования ChatGPT:

  1. Копирование содержимого статьи – это трудоемкая работа.
  2. Нам нужна агрегированная база знаний.
  3. Ограничение на количество слов – 3000 слов.

Заключение

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

Часто задаваемые вопросы

Показанные в этой статье материалы не принадлежат Analytics Vidhya и используются по усмотрению автора.