Почему вызов LLM — это не приложение: какое место занимает LangChain в пайплайне RAG
Узнайте, что на самом деле делает LangChain, проследив работу приложения для ответов на вопросы к документам от загрузки PDF до получения обоснованного ответа, и определите, когда альтернативная платформа будет более подходящей.
Позвонить большой языковой модели легко: отправляете запрос, получаете текст в ответ. Но создать что-то полезное на основе этого вызова — совсем не просто. Настоящее приложение должно обрабатывать документы, находить важные фрагменты, вести учет разговора, составлять запросы и отображать всё это через интерфейс, причем модель — лишь одна из составляющих этой системы. В этой статье объясняется, что такое LangChain, путем подробного рассмотрения именно всех этих вспомогательных компонентов, причем в качестве примера используется помощник для чтения документов. После прочтения вы сможете описать каждый этап процесса поиска информации, указать, какие задачи берет на себя фреймворк вроде LangChain, и определить, подходит ли он или один из его аналогов вашему проекту.
Что такое LangChain, в одном абзаце
LangChain — это фреймворк с открытым исходным кодом для создания приложений на основе больших языковых моделей. Вместо предоставления готовой модели он дает модульные строительные блоки и полный набор инструментов для всех компонентов, связанных с моделью: шаблоны запросов, парсеры результатов, загрузчики документов, механизмы поиска информации, системы памяти, инструменты и элементы, соединяющие их между собой. Он работает с крупнейшими поставщиками моделей, интегрируется с большим количеством сторонних инструментов, бесплатен в использовании и находится в активной разработке. К типичным примерам приложений, создаваемых с его помощью, относятся чат-боты, системы ответов на вопросы, технологии генерации с усиленным поиском информации (RAG) и автономные агенты.
Ключевое изменение в подходе заключается в том, что LangChain — это не сама большая языковая модель. Это слой, который позволяет большой языковой модели работать с вашими данными, запросами и пользователями. Если вы всегда отправляете только один запрос и выводите ответ, он вам не нужен. Как только у вашего приложения появляется несколько шагов, вам приходится писать ту самую инфраструктуру, которую уже предоставляет LangChain.
Обзор основ
Полезно сначала увидеть всю картину в целом, прежде чем углубляться в детали. Изучение LangChain обычно делится на три этапа, каждый из которых основан на предыдущем.
Основы
Это элементы, с которыми сталкивается каждое приложение на базе LangChain:
- общая модель компонентов
- модели, то есть обёртки вокруг API чатов и генерации текста
- запросы и шаблоны запросов
- парсинг вывода, позволяющий преобразовывать свободный текст в структурированные данные
Генерация с усилением на основе поиска
RAG — это способ, с помощью которого модель может отвечать на вопросы на основе собственных документов. Ключевые компоненты включают:
- загрузчики документов
- разделители текста
- эмбеддинги
- хранилища векторов
- механизмы поиска
- сбор всего вышеупомянутого в рабочее приложение RAG
Агенты
Агенты позволяют модели самостоятельно решать, какие действия выполнить. Основные темы здесь —:
- инструменты и наборы инструментов
- запуск инструментов
- создание агента, использующего эти инструменты
Остальная часть статьи посвящена первым двум областям, поскольку именно они объясняют, зачем вообще существует данная платформа.
Проблема, которую решает LangChain
Система производственного LLM редко обрабатывает всего один запрос. Посмотрите, с чем приходится сталкиваться даже небольшому ассистенту:
- принятие документов
- проведение семантического поиска
- генерация и хранение эмбеддингов
- использование метода генерации с усилением на основе поиска
- управление контекстом и состоянием разговора
- координация одного или нескольких вызовов LLM
- обслуживание интерфейса чата
Каждый из этих элементов можно обрабатывать отдельно. Однако при ручном объединении они превращаются в запутанную сеть пользовательского кода, где изменение модели, хранилища векторов или формата запроса требует редактирования нескольких файлов. Ценность LangChain заключается в том, что она предоставляет для каждой задачи стандартный интерфейс и набор повторно используемых абстракций, благодаря чему компоненты легко соединяются в единую цепочку обработки и могут заменяться независимо друг от друга.
Пример реализации: читалка книг с ИИ
Рассмотрим приложение, в котором пользователи загружают книги или PDF-файлы, читают их в встроенном просмотрщике и задают ассистенту вопросы о прочитанном. Представьте учебник по машинному обучению: студент может спросить о компромиссе между смещением и дисперсией, о структуре определенной архитектуры CNN, о том, что делает обратное распространение ошибок, как работают механизмы внимания или какой алгоритм оптимизации подходит для решения той или иной задачи.
Ассистент сможет дать правильный ответ только в том случае, если увидит нужные страницы. Это единственное требование влечет за собой целую цепочку действий: загрузка загруженного файла, поиск фрагментов, связанных с вопросом, поддержание целостности истории чата, составление запроса, объединяющего вопрос с этими фрагментами, и его отправка в модель.
В этом приложении LangChain будет заниматься следующим:
- загрузкой и парсингом загруженных документов
- подключением интерфейса чата к LLM
Это наиболее наглядное иллюстрирование того, почему один только ЯЗЫКОВОЙ МОДЕЛЬ НЕ ДАЕТ ГОТОВОГ ПРИМЕНЕНИЯ. Модель обеспечивает языковые способности; всё, что делает ответ актуальным для конкретной книги, поступает из сопутствующих компонентов.
Семантический поиск: нахождение текста по смыслу
Суть читалки заключается в способности извлекать нужные отрывки из большого объема информации. Поиск по ключевым словам здесь неэффективен, поскольку вопросы учащихся редко содержат те же слова, что и учебник. Семантический поиск решает эту проблему с помощью эмбеддингов — числовых векторов, которые располагают тексты с похожим смыслом рядом друг относительно в высокомерноменной пространстве. Поиск тогда означает нахождение сохраненных векторов, наиболее близких к вектору вопроса.
Простой пример
Предположим, запрос звучит так: «Какая столица Франции?» Система семантического поиска не ищет документы, которые просто содержат схожие слова с вопросом. Она ищет отрывок, значение которого наиболее близко к значению вопроса, а именно параграф о Париже, а не отрывки о Берлине или Мадриде, хотя те также касаются европейских столиц и могут получить высокий балл за совпадающие слова.
В этом и заключается практическая разница. Системы на основе ключевых слов ранжируют документы по совпадающим терминам; системы семантического поиска ранжируют их по степени близости значений. На практике многие производственные системы сочетают оба подхода, поскольку точные термины, такие как коды продуктов или сообщения об ошибках, по-прежнему выигрывают от сопоставления ключевых слов.
Почему это важно для приложений с большими языковыми моделями
Модели отвечают гораздо лучше, когда им предоставляется релевантный контекст. Следовательно, качественный поиск напрямую влияет на:
- лучший поиск документов
LangChain сам по себе не реализует векторный поиск. Он интегрируется с необходимыми для этого компонентами: моделями эмбеддингов, векторными базами данных, инструментами поиска и алгоритмами определения сходства, все они предоставляются через единообразные интерфейсы.
Как только документы становятся доступными для поиска, ответ на вопрос следует предсказуемой последовательности:
- Пользователь задает вопрос. Вопрос поступает на языке естественного общения.
- Вопрос преобразуется в эмбеддинг. Он конвертируется в вектор, что позволяет сравнивать его по смыслу, а не по точным словам.
- Получаются соответствующие тексты. Система извлекает те фрагменты или страницы, векторы которых наиболее близки.
- Вводные данные собираются воедино. Полученные отрывки и первоначальный вопрос объединяются в промпт для модели.
- Модель обрабатывает его. Полный промпт, включающий контекст и вопрос, передается в ЯИМ.
- Возвращается обоснованный ответ. Поскольку модель рассуждает на основе предоставленного текста, а не только благодаря памяти, ответ более точен и его происхождение легче отследить.
Каждая стрелка в этом списке обозначает передачу данных между компонентами, и именно это и предназначено управлять LangChain. Он упрощает процесс поиска информации, связывает вместе этапы формирования запросов, обрабатывает информацию из памяти, вставляет контекст в запросы и координирует вызовы модели. Этот шестиступенчатый процесс является основой любой системы RAG. Если вы хотите более подробно узнать о самом процессе поиска, наша статья объясняет, как системы RAG получают свежие знания по запросу.
Полная архитектура RAG
Вышеописанные шесть шагов предполагают, что документы уже индексированы. Полная система включает два потока обработки: один предназначен для подготовки документов заранее, а другой — для ответа на запросы по мере их поступления.
Подготовка документов к поиску
Прежде чем кто-либо сможет задать вопрос, каждый документ должен быть преобразован в формат, доступный для поиска:
- Загрузка. PDF-файл сохраняется в хранилище, например, в контейнер AWS S3.
- Загрузка в систему. Специальный модуль загружает файл и извлекает его текст для дальнейшей обработки.
- Разделение на части. Модуль разделения текста расщепляет его на более мелкие фрагменты или страницы. Это важно, поскольку сохранение всей книги как одного вектора приведет к смешиванию всех её тем, а у моделей ограниченные окна контекста.
- Генерация векторов. Каждый фрагмент проходит через модель генерации векторов и преобразуется в вектор.
- Хранение. Векторы вместе с текстом, который они представляют, сохраняются в базе данных векторов.
По окончании этого этапа документ готов к поиску. Обычно эта процедура выполняется один раз при загрузке документа, а не при каждом вопросе.
Ответ на запрос
Когда поступает вопрос, запускается второй процесс:
- Встраивание запроса. Вопрос преобразуется в вектор с помощью того же модели встраивания, так что он оказывается в одном пространстве с сохраненными фрагментами.
- Поиск. Поиск по сходству находит фрагменты, наиболее близкие к вопросу.
- Загрузка контекста. Эти фрагменты извлекаются из векторной базы данных.
- Создание промпта. Полученный текст и вопрос пользователя объединяются в системный промпт.
- Запуск модели. Готовый промпт отправляется в API большой языковой модели.
- Ответ. Модель возвращает ответ, основанный на полученном материале.
Один из моментов, которые сбивают с толку начинающих: запрос и документы должны быть эмбеддированы с помощью одной и той же модели. Векторы, полученные с двух разных моделей эмбеддинга, несопоставимы, и их случайное использование снижает качество поиска.
Что вы бы написали сами
Без фреймворка команда, разрабатывающая такую систему, должна была бы самостоятельно реализовать управление запросами, логику поиска, вставку контекста, многократные операции, работу с памятью, интеграцию инструментов и механизмы их согласования. Ни один из этих аспектов по сути не является сложным, но их суммарное воздействие приводит к тому, что код тесно связывается с одной моделью и одной базой данных. Реусаблируемые абстракции LangChain для каждого из этих элементов позволяют разрабатывать быстрее и изменять компоненты позже с меньшим количеством переписывания кода.
Что предлагает фреймворк
Четыре преимущества постоянно упоминаются.
Цепочки как модель композиции
Цепочка элементов, таких как шаблон запроса, вызов модели и парсер результата, объединяет их в единый рабочий процесс, который можно запустить, протестировать и повторно использовать. В текущих версиях это реализуется с помощью Runnables и LCEL, которые позволяют соединять компоненты между собой.
Код, независимый от модели
Поскольку LangChain поддерживает основных поставщиков больших языковых моделей через общий интерфейс, ваше приложение не привязано к одному поставщику. Замена модели становится просто изменением настроек, а не переписыванием кода, что полезно как для контроля затрат, так и для тестирования новых моделей.
Широкая экосистема
Фреймворк поставляется вместе с большим набором компонентов и интеграций или позволяет подключиться к ним: загрузчики для многих типов файлов, хранилища векторов, поставщики эмбеддингов и соответствующие инструменты. Вероятно, большинство необходимых вам компонентов уже существует в виде готовых интеграций.
Память и состояние
Приложения для диалогов должны помнить то, что было сказано ранее. LangChain предоставляет способы управления контекстом диалога, памятью и состоянием в ходе взаимодействий. Рекомендуемый подход менялся с выходом новых версий: в более новых руководствах акцент делается на использовании LangGraph для рабочих процессов с сохранением состояния, поэтому обязательно ознакомьтесь с актуальной документацией для вашей версии.
Что можно создать с его помощью
К типичным примерам приложений относятся:
- Чат-боты для диалогов, в которых пользователи общаются с ИИ на естественном языке.
- Помощники с знаниями, помогающие людям находить и понимать информацию в собственных документах или базах знаний.
- Агенты ИИ, выполняющие многоэтапные задачи и принимающие решения о том, какие инструменты использовать на каждом этапе.
- Автоматизация рабочих процессов, где LLM является одним из этапов более крупного автоматизированного процесса.
Когда стоит рассмотреть альтернативу
LangChain — это лишь один из нескольких вариантов, причем у каждой альтернативы свои особенности:
- LlamaIndex сосредотачивается на подключении больших языковых моделей к внешним данным и создании приложений на основе данных и технологии RAG.
- Haystack предназначен для поиска, ответов на вопросы, работы с технологией RAG и агентных приложений.
- Semantic Kernel — это open-source SDK от Microsoft, позволяющий встраивать ИИ-модели в существующее программное обеспечение и координировать многоэтапные ИИ-работы.
- DSPy рассматривает системы больших языковых моделей как программы, которые необходимо оптимизировать, вместо того чтобы заставлять пользователя самостоятельно формулировать каждый запрос.
- AutoGen разработан для приложений, в которых несколько агентов сотрудничают друг с другом.
- CrewAI предназначен для координации команд агентов, работающих вместе над задачами.
- PydanticAI — это фреймворк на Python для производственных приложений и агентов, обеспечивающий структурированные и типобезопасные результаты.
Ориентировочное правило: если ваше приложение в основном занимается поиском данных из собственных источников, стоит рассмотреть LlamaIndex или Haystack. Если для вас важны типизированные результаты, обратите внимание на PydanticAI. Если ключевой идеей является совместная работа нескольких агентов, подойдут AutoGen или CrewAI. Преимущество LangChain заключается в широте функционала, что делает его разумным стандартом, когда вы еще не уверены в формате вашего приложения. Чтобы ознакомиться с прямым сравнением двух наиболее популярных вариантов, посмотрите наше сравнение LangChain и LlamaIndex.
Также стоит знать, когда не следует использовать какие-либо фреймворки. Функция, работающая с одним запросом, или небольшой скрипт с одним вызовом модели и вручную написанным запросом часто бывают понятнее без слоя абстракции. Фреймворки оправдывают себя по мере увеличения количества шагов и количество заменяемых компонентов.
Элементы, которые стоит изучить дальше
После того как мы поняли общую картину, следующим логичным шагом являются отдельные компоненты, из которых состоит каждое приложение LangChain:
- Модели — интерфейсы для взаимодействия с различными ИИ-моделями.
- Запросы — элементы, определяющие способ реакции модели на входные данные.
- Цепочки — элементы, соединяющие компоненты в рабочие процессы.
- Индексы — элементы, связывающие приложения с внешними источниками знаний. В более новой документации этот аспект обычно описывается с использованием терминов загрузчики, хранилища векторов и механизмы поиска.
Понимание того, за что отвечает каждый из этих компонентов, значительно упрощает чтение кода LangChain и помогает определить, какие элементы действительно необходимы вашему приложению.
Основные выводы
- ГЛМ — это лишь один из компонентов приложения; загрузка данных, поиск информации, формирование запросов, память и интерфейс — это всё остальное, и именно создание этого «остального» помогает LangChain.
- Семантический поиск сортирует текст по значению с использованием эмбеддингов, именно поэтому он находит абзац о Париже при запросе об столице Франции.
- Система RAG состоит из двух потоков обработки: офлайн-потока, который загружает, разделяет, встраивает и хранит документы, и онлайн-потока, который встраивает запрос, получает контекст, формирует промпт и вызывает модель.
- Всегда встраивайте запросы и документы с помощью одной и той же модели, иначе качество поиска снизится.
- Основные преимущества LangChain — это композиция на основе цепочек, независимость от поставщиков, широкая экосистема интеграций и инструменты для управления состоянием и памятью.
- Альтернативы вроде LlamaIndex, Haystack, Semantic Kernel, DSPy, AutoGen, CrewAI и PydanticAI акцентируют внимание на разных аспектах, и для очень простых задач может вообще не понадобиться какая-либо фреймворк-среда.
Связанные материалы
- Как устроен RAG: этапы работы пайплайна, основные компоненты и различные варианты реализации — Понять, как работает технология Retrieval-Augmented Generation от начала до конца, какие компоненты необходимы системе RAG и как многочисленные варианты этой технологии связаны между собой.
- Разбор RAG: как системы искусственного интеллекта получают свежие знания по запросу — Узнать, как функционирует Retrieval-Augmented Generation, начиная с разбиения данных на части и создания векторных представлений и заканчивая поиском в векторном пространстве, что позволяет моделям ИИ отвечать на вопросы без повторной обучения.