Создание пользовательских приложений вопрос-ответ с использованием LangChain и векторной базы данных Pinecone

Создание приложений QA с помощью LangChain и базы данных Pinecone

Введение

Появление больших языковых моделей является одним из самых захватывающих технологических достижений нашего времени. Они открывают бесконечные возможности в области искусственного интеллекта, предлагая решения реальных проблем в различных отраслях. Одним из увлекательных применений этих моделей является разработка пользовательских систем вопрос-ответ или чат-ботов, которые основываются на персональных или организационных источниках данных. Однако, поскольку LLM обучаются на общедоступных данных, полученные ими ответы не всегда будут конкретными или полезными для конечного пользователя. Для решения этой проблемы мы можем использовать такие фреймворки, как LangChain, чтобы разработать пользовательские чат-боты, которые предоставляют конкретные ответы на основе наших данных. В этой статье мы узнаем, как создавать пользовательские приложения вопрос-ответ с использованием Streamlit Cloud.

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

Прежде чем мы углубимся в статью, давайте определим основные цели обучения:

  • Изучить полный рабочий процесс пользовательского вопрос-ответа и роль каждого компонента в этом процессе
  • Понять преимущества приложения вопрос-ответа по сравнению с настройкой пользовательской LLM
  • Изучить основы векторной базы данных Pinecone для хранения и извлечения векторов
  • Создать семантическую поисковую систему с использованием LLM от OpenAI, LangChain и векторной базы данных Pinecone для разработки приложения на Streamlit.

Эта статья была опубликована в рамках Data Science Blogathon.

Обзор приложений вопрос-ответ

Источник: ScienceSoft

Ответы на вопросы или “обсуждение ваших данных” являются широко распространенным случаем использования LLM и LangChain. LangChain предоставляет ряд компонентов для загрузки любых источников данных для вашего случая использования. Он поддерживает множество источников данных и трансформаторов для преобразования их в набор строк для хранения в векторных базах данных. После того, как данные хранятся в базе данных, можно выполнять запросы к базе данных с использованием компонентов, называемых извлекателями. Кроме того, с использованием LLM мы можем получать точные ответы, подобные чат-ботам, без необходимости перебирать огромное количество документов.

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

Источник: Документация LangChain

Рабочий процесс приложений вопрос-ответ

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

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

Это общий рабочий процесс системы вопрос-ответа, который может решать множество реальных проблем. Я не углублялся в каждый компонент LangChain, но если вы хотите узнать больше об этом, то ознакомьтесь с моей предыдущей статьей, опубликованной на Analytics Vidhya (Ссылка: Нажмите здесь)

Диаграмма рабочего процесса приложения вопрос-ответ (изображение автора)

Преимущества индивидуальных приложений вопрос-ответ по сравнению с тонкой настройкой модели

  1. Контекстно-специфичные ответы
  2. Адаптируемость к новым входным документам
  3. Необходимость проведения тонкой настройки модели, что позволяет сэкономить затраты на обучение модели
  4. Более точные и конкретные ответы, а не общие ответы

Что такое база векторов Pinecone?

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

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

Pinecone идеально подходит для таких приложений и оптимизирована для хранения и запроса множества векторов с низкой задержкой для создания приложений с удобным интерфейсом. Давайте узнаем, как создать базу векторов Pinecone для нашего приложения вопрос-ответ.

# установка pinecone-client
pip install pinecone-client

# импорт pinecone и инициализация с вашим API-ключом и именем среды
import pinecone
pinecone.init(api_key="ВАШ_API_КЛЮЧ", environment="ВАША_СРЕДА")

# создание первого индекса для начала работы с хранением векторов 
pinecone.create_index("first_index", dimension=8, metric="cosine")

# Upsert пример данных (5 8-мерных векторов)
index.upsert([
    ("A", [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]),
    ("B", [0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2]),
    ("C", [0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3]),
    ("D", [0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4]),
    ("E", [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5])
])

# Используйте метод list_indexes() для получения списка доступных индексов в базе данных
pinecone.list_indexes()

[Output]>>> ['first_index']

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

Создание пайплайна семантического поиска с использованием OpenAI и Pinecone

Мы узнали, что в рабочем процессе приложения вопрос-ответ есть 5 шагов. В этом разделе мы выполним первые 4 шага: загрузчики документов, разделители текста, хранение векторов и извлечение документов.

Для выполнения этих шагов в вашей локальной среде или в облачной среде ноутбука, такой как Google Colab, вам необходимо установить некоторые библиотеки и создать учетную запись в OpenAI и Pinecone для получения соответствующих API-ключей. Давайте начнем с настройки среды:

Установка необходимых библиотек

# установка langchain и openai с другими зависимостями
!pip install --upgrade langchain openai -q
!pip install pillow==6.2.2
!pip install unstructured -q
!pip install unstructured[local-inference] -q
!pip install detectron2@git+https://github.com/facebookresearch/[email protected] /
                                            #egg=detectron2 -q
!apt-get install poppler-utils
!pip install pinecone-client -q
!pip install tiktoken -q

# настройка среды openai
import os
os.environ["OPENAI_API_KEY"] = "ВАШ_API_КЛЮЧ"

# импорт библиотек
import os
import openai
import pinecone
from langchain.document_loaders import DirectoryLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Pinecone
from langchain.llms import OpenAI
from langchain.chains.question_answering import load_qa_chain

После установки настройки импортируйте все библиотеки, упомянутые в приведенном выше кодовом фрагменте. Затем следуйте следующим шагам:

Загрузите документы

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

# загрузка документов из каталога content/data
каталог = '/content/data'

# функция load_docs для загрузки документов с использованием функции langchain
def load_docs(директория):
  loader = DirectoryLoader(директория)
  documents = loader.load()
  return documents

documents = load_docs(каталог)
len(documents)
[Output]>>> 5

Разделите текстовые данные

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

# разделение документов с использованием рекурсивного текстового разделителя
def split_docs(документы, размер_части=200, перекрытие_части=20):
  text_splitter = RecursiveCharacterTextSplitter(размер_части=размер_части, перекрытие_части=перекрытие_части)
  docs = text_splitter.split_documents(документы)
  return docs

# разделить документы
docs = split_docs(documents)
print(len(docs))
[Output]>>>12

Храните данные в векторном хранилище

После разделения документов мы сохраним их векторные представления в базе данных векторов с использованием OpenAI embeddings.

# пример встраивания на случайном слове
embeddings = OpenAIEmbeddings()

# инициировать pinecondb
pinecone.init(
    api_key="ВАШ-КЛЮЧ-API",
    environment="ВАШ-ENV"
)

# определить имя индекса
index_name = "langchain-project"

# сохранить данные и встраивания в индекс pinecone
index = Pinecone.from_documents(docs, embeddings, index_name=index_name)

Извлечение данных из векторной базы данных

На этом этапе мы извлечем документы из векторной базы данных, используя семантический поиск. У нас есть векторы, сохраненные в индексе с именем “langchain-project”, и после выполнения запроса мы получим наиболее похожие документы из базы данных.

# Пример запроса к нашей базе данных
запрос = "Какие есть различные типы домашних животных?"

# выполнить поиск похожести и сохранить документы в переменной result
result = index.similarity_search(
    запрос,  # наш поисковый запрос
    k=3  # вернуть 3 наиболее релевантных документа
)
-
--------------------------------[Output]--------------------------------------
result
[Document(page_content='Маленькие млекопитающие, такие как хомячки, морские свинки и 
кролики, часто выбираются из-за
низких затрат на уход. Птицы прекрасны и поют,
а рептилии, такие как черепахи и ящерицы, могут стать интересными домашними животными.', 
metadata={'source': '/content/data/Different Types of Pet Animals.txt'}),
 Document(page_content='Домашние животные разных форм и размеров, каждое из которых подходит 
для разных образов жизни и домашних условий. Собаки и кошки являются самыми 
распространенными и известными своим спутничеством и уникальной индивидуальностью. Маленькие', 
metadata={'source': '/content/data/Different Types of Pet Animals.txt'}),
 Document(page_content='интересными домашними животными. Даже рыбки, с их успокаивающим присутствием, 
могут быть замечательными домашними животными.', 
metadata={'source': '/content/data/Different Types of Pet Animals.txt'})]

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

Приложение для пользовательского вопросно-ответного приложения с использованием Streamlit

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

Структура репозитория

Добавьте эти файлы проекта

  1. main.py — Файл на языке Python, содержащий код front-end для streamlit
  2. qanda.py — Дизайн запроса и функция модели для возврата ответа на запросы пользователей
  3. utils.py — Вспомогательные функции для загрузки и разделения входных документов
  4. vector_search.py — Функция для работы с текстовыми векторами и хранения векторов
  5. requirements.txt — Зависимости проекта для запуска приложения в общедоступном облаке streamlit

В этом проекте демонстрируются два типа источников данных:

  1. Текстовые данные на основе веб-URL
  2. Онлайн-файлы в формате PDF

Эти два типа содержат широкий спектр текстовых данных и являются наиболее частыми для многих случаев использования. Ниже приведен основной код на языке Python (main.py), чтобы понять пользовательский интерфейс приложения.

# импорт необходимых библиотек
import streamlit as st
import openai
import qanda
from vector_search import *
from utils import *
from io  import StringIO

# ввод ключа OpenAI API
api_key = st.sidebar.text_input("Введите ключ OpenAI API:", type='password')
# ключ OpenAI
openai.api_key = str(api_key)

# заголовок приложения
_ , col2,_ = st.columns([1,7,1])
with col2:
    col2 = st.header("Simplchat: Чат с вашими данными")
    url = False
    query = False
    pdf = False
    data = False
    # выбор опции на основе потребностей пользователя
    options = st.selectbox("Выберите тип источника данных",
                            options=['Веб-URL','PDF','Существующий источник данных'])
    # задание запроса на основе опций источников данных
    if options == 'Веб-URL':
        url = st.text_input("Введите URL источника данных")
        query = st.text_input("Введите ваш запрос")
        button = st.button("Отправить")
    elif options == 'PDF':
        pdf = st.text_input("Введите ссылку на PDF-файл") 
        query = st.text_input("Введите ваш запрос")
        button = st.button("Отправить")
    elif options == 'Существующий источник данных':
        data= True
        query = st.text_input("Введите ваш запрос")
        button = st.button("Отправить") 

# написать код для получения результата на основе заданного запроса и источников данных   
if button and url:
    with st.spinner("Обновление базы данных..."):
        corpusData = scrape_text(url)
        encodeaddData(corpusData,url=url,pdf=False)
        st.success("База данных обновлена")
    with st.spinner("Поиск ответа..."):
        title, res = find_k_best_match(query,2)
        context = "\n\n".join(res)
        st.expander("Контекст").write(context)
        prompt = qanda.prompt(context,query)
        answer = qanda.get_answer(prompt)
        st.success("Ответ: "+ answer)

# написать код для получения результата на основе заданного запроса и источников данных
if button and pdf:
    with st.spinner("Обновление базы данных..."):
        corpusData = pdf_text(pdf=pdf)
        encodeaddData(corpusData,pdf=pdf,url=False)
        st.success("База данных обновлена")
    with st.spinner("Поиск ответа..."):
        title, res = find_k_best_match(query,2)
        context = "\n\n".join(res)
        st.expander("Контекст").write(context)
        prompt = qanda.prompt(context,query)
        answer = qanda.get_answer(prompt)
        st.success("Ответ: "+ answer)
        
if button and data:
    with st.spinner("Поиск ответа..."):
        title, res = find_k_best_match(query,2)
        context = "\n\n".join(res)
        st.expander("Контекст").write(context)
        prompt = qanda.prompt(context,query)
        answer = qanda.get_answer(prompt)
        st.success("Ответ: "+ answer)
        
        
# удаление векторов из базы данных
st.expander("Удаление индексов из базы данных")
button1 = st.button("Удалить текущие векторы")
if button1 == True:
    index.delete(deleteAll='true')

Чтобы ознакомиться с другими файлами кода, пожалуйста, посетите репозиторий проекта на GitHub. (Ссылка: Нажмите здесь)

Развертывание приложения Q&A на Streamlit Cloud

Интерфейс приложения

Streamlit предоставляет общедоступное облачное хранилище для размещения приложений бесплатно. Кроме того, streamlit легко использовать благодаря своим функциям автоматизированной конвейера непрерывной интеграции и доставки. Чтобы узнать больше о streamlit для создания приложений – пожалуйста, посетите мою предыдущую статью, написанную на Analytics Vidya (ссылка: Нажмите здесь)

Отраслевые сценарии использования пользовательских приложений для вопросов и ответов

Внедряйте пользовательские приложения для вопросов и ответов во многих отраслях, так как в этой области возникают новые и инновационные сценарии использования. Давайте рассмотрим такие сценарии использования:

Поддержка клиентов

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

Здравоохранение

Информация критична для того, чтобы пациенты получали своевременное лечение от определенных заболеваний. Здравоохранение может разработать интерактивного чат-бота, предоставляющего медицинскую информацию, информацию о препаратах, объяснения симптомов и рекомендации по лечению на естественном языке без необходимости общения с реальным человеком.

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

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

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

Правительство и государственные услуги

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

Вывод

В заключение, мы исследовали захватывающие возможности создания пользовательского приложения для вопросов и ответов с использованием LangChain и базы данных векторов Pinecone. Этот блог познакомил нас с основными концепциями, начиная с обзора приложения для вопросов и ответов до понимания возможностей базы данных векторов Pinecone. Комбинируя мощь семантического поискового конвейера OpenAI с эффективной системой индексации и извлечения Pinecone, мы смогли использовать потенциал для создания надежного и точного решения для вопросов и ответов с помощью streamlit. Давайте рассмотрим основные выводы из статьи:

Основные выводы

  • Большие языковые модели (LLM) перевернули представление об искусственном интеллекте, позволяя создавать разнообразные приложения. Пользовательская настройка чат-ботов с персональными или организационными данными является мощным подходом.
  • В то время, как общие LLM обладают широким пониманием языка, настраиваемые приложения для вопросов и ответов имеют преимущество перед тонко настроенными персонализированными LLM благодаря их гибкости и экономичности.
  • Интегрируя базу данных векторов Pinecone, LLM OpenAI и LangChain, мы узнали, как разработать семантический поисковый конвейер и развернуть его на облачной платформе, такой как streamlit.

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

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