Введение

Большие языковые модели (LLM) — это тип искусственного интеллекта (ИИ), который обучается на массивных наборах данных текста и кода. Они могут генерировать текст, переводить языки, писать различные виды творческого контента и информативно отвечать на ваши вопросы.

LangChain — это платформа с открытым исходным кодом, упрощающая создание приложений, использующих LLM. Он предоставляет набор инструментов и компонентов, которые упрощают разработку приложений, ориентированных на LLM.

Примечание: библиотека LangChain доступна как для Python, так и для JavaScript, но в этом руководстве мы будем использовать библиотеку Python.

Предпосылки

В этой статье предполагается, что у вас есть базовые знания следующих концепций LangChain:

  • Модели: компонент, представляющий LLM.
  • Подсказки: фрагмент текста, который используется для ввода данных в LLM. Они предоставляют LLM дополнительную информацию, необходимую для выполнения задачи.
  • Цепи: последовательность LLM, которые работают вместе для выполнения задачи.
  • Внедрение . Встраивание — это тип векторного представления текста, который можно использовать для представления значения слов и фраз.
  • Векторные хранилища: базы данных, в которых хранятся вложения, которые можно использовать для быстрого извлечения вложений для заданного слова или фразы.
  • Агенты: компонент, который позволяет LLM взаимодействовать со своей средой.

Что дальше?

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

Надеюсь, вам понравится статья!

Настраивать

Использование LangChain обычно требует интеграции с одним или несколькими поставщиками моделей, хранилищами данных, API-интерфейсами и т. д. В этом примере мы будем использовать API-интерфейсы моделей OpenAI.

Сначала нам нужно установить требования:

python-dotenv==1.0.0
langchain==0.0.137
openai==0.27.8

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

export OPENAI_API_KEY="..."

Если вы предпочитаете не устанавливать переменную среды, вы можете просто загрузить переменную среды с помощью файла .env.

import os
import openai
import sys
sys.path.append('../..')

from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv()) # read local .env file

openai.api_key  = os.environ['OPENAI_API_KEY']

Как обращаться к своим данным с помощью LangChain

Чтобы использовать LangChain, вам сначала нужно выбрать поставщика LLM. Доступен ряд различных поставщиков LLM, включая OpenAI, Cohere и Hugging Face.

from langchain.chat_models import ChatOpenAI
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature = 0.3)

Примечание: в дополнение к LLM, предоставляемым LangChain, вы можете использовать модели с открытым исходным кодом из открытой таблицы лидеров LLM от HuggingFace: https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard. Это возможно с помощью интеграции Huggingface с LangChain: https://python.langchain.com/docs/modules/model_io/models/llms/integrations/huggingface_hub.

Некоторые примеры LLM, которые вы можете использовать с интеграцией Huggingface, включают: Bard из Google AI, Llama из Cohere и Turing из Huggingface.

Мы можем использовать и другие модели LLM, такие как Llama 2:

Вам не нужен API_TOKEN!

pip install llama-cpp-python
from langchain.llms import LlamaCpp
from langchain.callbacks.manager import CallbackManager
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
# Callbacks support token-wise streaming
callback_manager = CallbackManager([StreamingStdOutCallbackHandler()])
# Verbose is required to pass to the callback manager

# Make sure the model path is correct for your system!
llm = LlamaCpp(
    model_path="/Users/rlm/Desktop/Code/llama/llama-2-7b-ggml/llama-2-7b-chat.ggmlv3.q4_0.bin",
    input={"temperature": 0.75, "max_length": 2000, "top_p": 1},
    callback_manager=callback_manager,
    verbose=True,
)

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

Загрузчики — это тип компонентов в LangChain, которые имеют дело со спецификой доступа и преобразования данных. Они возвращают список Document объектов.

В этой статье мы начнем с обсуждения загрузчиков — компонентов, которые можно использовать для загрузки данных из PDF, YouTube, URL и Notion. Другие источники также могут быть загружены, но эти являются наиболее распространенными.

PDF

Давайте загрузим пример PDF с вашего устройства!

from langchain.document_loaders import PyPDFLoader
loader = PyPDFLoader("docs/your_pdf_name.pdf")
pages = loader.load()

Каждая страница представляет собой Document.

Document содержит текст (page_content) и metadata.

len(pages)
page = pages[0]
print(page.page_content[0:500])
page.metadata

Ютуб

from langchain.document_loaders.generic import GenericLoader
from langchain.document_loaders.parsers import OpenAIWhisperParser
from langchain.document_loaders.blob_loaders.youtube_audio import YoutubeAudioLoader
url="https://www.youtube.com/watch?v=jGwO_UgTS7I"
save_dir="docs/youtube/"
loader = GenericLoader(
    YoutubeAudioLoader([url],save_dir),
    OpenAIWhisperParser()
)
docs = loader.load()
docs[0].page_content[0:500]

URL-адреса

from langchain.document_loaders import WebBaseLoader

loader = WebBaseLoader("https://github.com/basecamp/handbook/blob/master/37signals-is-you.md")

docs = loader.load()
print(docs[0].page_content[:500])

Понятие

Выполните шаги здесь для примера сайта Notion:

  • Дублируйте страницу в свое собственное пространство Notion и экспортируйте как Markdown / CSV.
  • Разархивируйте его и сохраните как папку, содержащую файл уценки для страницы Notion.

from langchain.document_loaders import NotionDirectoryLoader
loader = NotionDirectoryLoader("docs/Notion_DB")
docs = loader.load()

print(docs[0].page_content[0:200])
docs[0].metadata

Ответ на вопрос по документам

В этом разделе мы узнаем, как использовать LangChain для создания системы контроля качества, которая может отвечать на вопросы о наборе документов. Начнем с импорта необходимых компонентов.

from langchain.chains import RetrievalQA
from langchain.chat_models import ChatOpenAI
from langchain.document_loaders import CSVLoader
from langchain.vectorstores import DocArrayInMemorySearch
from IPython.display import display, Markdown
from langchain.indexes import VectorstoreIndexCreator

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

Мы загружаем пример данных CSV:

file = 'your_csv_data.csv'
loader = CSVLoader(file_path=file)

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

index = VectorstoreIndexCreator(
    vectorstore_cls=DocArrayInMemorySearch
).from_loaders([loader])

query ="Please list all your shirts with sun protection \
in a table in markdown and summarize each one."

response = index.query(query)
display(Markdown(response))

В коде не используется модель LLM, поскольку на запрос можно ответить без использования модели LLM. Индекс хранилища векторов может ответить на запрос, просто сравнивая вектор запроса с векторами документов в индексе.

Если вы хотите использовать модель LLM в коде, вы можете сделать это, заменив класс VectorstoreIndexCreator на класс RetrievalQA. Класс RetrievalQA использует модель LLM для ответа на запросы. Мы углубимся в это позже.

Давайте теперь сделаем шаг за шагом процесс:

loader = CSVLoader(file_path=file)
docs = loader.load()
docs[0]

from langchain.embeddings import OpenAIEmbeddings
embeddings = OpenAIEmbeddings()
embed = embeddings.embed_query("Hi my name is Harrison")
db = DocArrayInMemorySearch.from_documents(
    docs, 
    embeddings
)
query = "Please suggest a shirt with sunblocking"
docs = db.similarity_search(query)

retriever = db.as_retriever()
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature = 0.3)
qdocs = "".join([docs[i].page_content for i in range(len(docs))])
response = llm.call_as_llm(f"{qdocs} Question: Please list all your \
shirts with sun protection in a table in markdown and summarize each one.")
display(Markdown(response))

Код загружает файл CSV. Затем он использует данные для создания списка документов. Затем встраивает запрос в вектор и создает индекс хранилища векторов из документов и вложений. После этого он использует индекс хранилища векторов для поиска документов, похожих на вектор запроса. Наконец, он извлекает первые k документов из результатов поиска и использует модель LLM для генерации ответа.

Все эти шаги можно инкапсулировать в цепочку Лангчейна. Итак, здесь мы можем создать цепочку RetrievalQA. Это выполняет поиск, а затем отвечает на вопросы по извлеченным документам.

qa_stuff = RetrievalQA.from_chain_type(
    llm=llm, 
    chain_type="stuff", 
    retriever=retriever, 
    verbose=True
)
query =  "Please list all your shirts with sun protection in a table \
in markdown and summarize each one."
response = qa_stuff.run(query)
display(Markdown(response))

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

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

qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type="stuff", retriever=docsearch.as_retriever(), return_source_documents=True)

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

  • Сокращение карты: данные обрабатываются последовательно.
  • Уточнить: данные обрабатываются параллельно и улучшается качество вывода.
  • Map Rerank: данные обрабатываются параллельно и ранжируются выходные данные.

Сокращение карты происходит медленнее, но более эффективно с точки зрения использования памяти. Уточнение выполняется быстрее и обеспечивает более высокое качество вывода. Реранжирование карты является самым быстрым и может ранжировать выходные данные.

qa_chain_mr = RetrievalQA.from_chain_type(
    llm,
    retriever=vectordb.as_retriever(),
    chain_type="map_reduce"
)
result = qa_chain_mr({"query": question})
result["result"]

qa_chain_mr = RetrievalQA.from_chain_type(
    llm,
    retriever=vectordb.as_retriever(),
    chain_type="refine"
)
result = qa_chain_mr({"query": question})
result["result"]

Ограничения RetrievalQA

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

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

Оценка вашего приложения LLM

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

Есть несколько способов оценить приложение LLM. Одним из распространенных подходов является использование метрики оценки BLEU, которая измеряет сходство между сгенерированным текстом и эталонным текстом. Другой подход заключается в использовании человеческой оценки, когда человек оценивает качество сгенерированного текста. Последний подход — это оценка с помощью LLM. Это гибридный подход, который сочетает в себе преимущества оценки BLEU и оценки человека.

В этой статье мы обсудим два метода оценки производительности приложений на основе LLM: оценка человеком (вручную) и оценка с помощью LLM.

examples = [
    {
        "query": "Do the Cozy Comfort Pullover Set\
        have side pockets?",
        "answer": "Yes"
    },
    {
        "query": "What collection is the Ultra-Lofty \
        850 Stretch Down Hooded Jacket from?",
        "answer": "The DownTek collection"
    }
]

Оценка вручную

Ручную оценку LLM можно выполнить путем пошаговой проверки построения ответа.

from langchain.chains import RetrievalQA
from langchain.chat_models import ChatOpenAI
from langchain.document_loaders import CSVLoader
from langchain.indexes import VectorstoreIndexCreator
from langchain.vectorstores import DocArrayInMemorySearch

file = 'you_csv_file.csv'
loader = CSVLoader(file_path=file)
data = loader.load()

index = VectorstoreIndexCreator(
    vectorstore_cls=DocArrayInMemorySearch
).from_loaders([loader])

llm = ChatOpenAI(temperature = 0.0)
qa = RetrievalQA.from_chain_type(
    llm=llm, 
    chain_type="stuff", 
    retriever=index.vectorstore.as_retriever(), 
    verbose=True,
    chain_type_kwargs = {
        "document_separator": "<<<<>>>>>"
    }
)

import langchain
langchain.debug = True
qa.run(examples[0]["query"])

# ==> Manual evaluation of the LLM by checking step by step the construction of the response

Цель «langchain.debug=True» — пошаговая проверка построения ответа. Например, вы можете проверить следующее:

  • Релевантность извлеченных документов. Соответствуют ли извлеченные документы запросу?
  • Качество сводки LLM: точно ли резюмирует LLM информацию, содержащуюся в извлеченных документах?
  • Общая согласованность ответа: легко ли понять ответ и следовать ему?

Оценка с помощью LLM

Оценка с помощью LLM — это метод оценки производительности приложения на основе LLM с использованием LLM для создания удобочитаемой сводки выходных данных приложения. Затем сводка оценивается человеком-оценщиком, который может дать отзыв о точности, полноте и ясности сводки.

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

# Turn off the debug mode
langchain.debug = False

predictions = qa.apply(examples)

from langchain.evaluation.qa import QAEvalChain
llm = ChatOpenAI(temperature=0)
eval_chain = QAEvalChain.from_llm(llm)
graded_outputs = eval_chain.evaluate(examples, predictions)

for i, eg in enumerate(examples):
    print(f"Example {i}:")
    print("Question: " + predictions[i]['query'])
    print("Real Answer: " + predictions[i]['answer'])
    print("Predicted Answer: " + predictions[i]['result'])
    print("Predicted Grade: " + graded_outputs[i]['text'])
    print()

# Truncated output 
"""
Example 0:
Question: Do the Cozy Comfort Pullover Set have side pockets?
Real Answer: Yes
Predicted Answer: The Cozy Comfort Pullover Set, Stripe does have side pockets.
Predicted Grade: CORRECT

Example 1:
Question: What collection is the Ultra-Lofty 850 Stretch Down Hooded Jacket from?
Real Answer: The DownTek collection
Predicted Answer: The Ultra-Lofty 850 Stretch Down Hooded Jacket is from the DownTek collection.
Predicted Grade: CORRECT
"""

Внедрение LLM в производство с LangSmith

LangChain был создан, чтобы уменьшить входной барьер для создания прототипов LLM. Эта цель в значительной степени достигнута, но следующая задача — запустить эти прототипы в производство.

LangSmith — это единая платформа для отладки, тестирования, оценки и мониторинга ваших приложений LLM. Он предоставляет ряд функций, которые могут помочь вам улучшить качество ваших приложений, в том числе:

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

Ленгчейн = прототипирование

ЛэнгСмит = производство

Последние мысли

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

LangSmith — это новая платформа, которая поможет вам вывести ваши LLM-приложения на новый уровень. Он предоставляет ряд функций, которые могут помочь вам в отладке, тестировании, оценке и мониторинге ваших приложений.

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

Будьте в курсе последних новостей и обновлений в сфере творческого ИИ — подписывайтесь на меня в Medium и LinkedIn

На Medium я пишу о GenAI, MultiModal, NLP и оптимизации маркетинга. Вы также можете найти меня в LinkedIn, где я общаюсь с другими творческими энтузиастами и профессионалами в области ИИ.

Хорошего дня!