Всем привет! На связи лид разработки SDK GigaChat’a — Константин Крестников. В этой статье я расскажу о том, что такое GigaChain и как в целом SDK позволяет упростить жизнь разработчика LLM, например, научить LLM давать ответы на вопросы по вашим документам или работать в режиме автономного агента. Также поговорим про решения, которые практически невозможно сделать без использования SDK.
GigaСhain — это ответвление (fork) открытой библиотеки LangСhain на Python. Её главная цель — облегчить жизнь разработчику. Библиотека состоит из большого количества различных компонентов, которые позволяют работать с промптами, объединять вызовы к большим языковым моделям в цепочки, загружать данные из разных источников и сохранять обработанные ответы языковой модели.
SDK GigaChain отличается от LangChain тем, что он переведен на русский язык, адаптирован к экосистеме русскоязычных языковых моделей и, конечно же, к GigaChat. В нем есть большое количество различных утилит:
Библиотека на Python содержит интерфейсы и интеграции для множества компонентов, базовую среду выполнения для объединения этих компонентов в цепочки и агенты, а также примеры их реализаций.
Хаб промптов — набор типовых отлаженных промптов для решения различных задач.
GigaServe — библиотека для публикации цепочек GigaChain как REST API.
Кроме этого, фреймворк совместим со сторонним сервисом LangSmith — платформой для разработчиков, которая позволяет отлаживать, тестировать, оценивать и отслеживать цепочки, построенные на любой платформе LLM, и легко интегрируется с LangChain и GigaChain.
Почему мы приняли решение делать свой форк, а не добавлять поддержку Gigachat в LangChain? Всё дело в том, что в проекте, который построен вокруг NLP, содержится огромное количество английского текста, который ровным слоем распределен по всей библиотеке, а PR с неплохим решением для мультиязычности авторы LangChain не принимают. Штош.
Как начать использовать GigaChain
GigaChain как открытая библиотека опубликована в различных репозиториях, в том числе и в pypi, поэтому вам достаточно написать:
pip install gigachain_community
И SDK появится в вашем окружении. Дальше мы импортируем объект gigachat и начинаем им пользоваться.
Для авторизации запросов к GigaChat вам нужно получить авторизационные данные для работы с GigaChat API.
Передайте полученные авторизационные данные в параметре credentials объекта GigaChat. Также потребуется установить сертификаты МинЦифры или же отключить проверку ssl с помощью флага verify_ssl_certs=False. Подробнее про настройку авторизации.
User: Привет
Bot: Здравствуйте!
User: Ты кто?
Bot: Я -- виртуальный помощник.
User: Как тебя зовут?
Bot: Меня зовут GigaChat.
Библиотека GigaChain обратно совместима с LangChain, что позволяет использовать ее не только для работы с GigaChat, но и для работы с другими LLM в различных комбинациях.
Подробная документация для GigaChain доступна в репозитории.
Что можно сделать с помощью GigaChain
GigaChain содержит большое количество инструментов и примеров, которые можно использовать в качестве основы своего проекта или просто изучать для расширения кругозора в области возможных кейсов применений LLM.
При решении задач с помощью языковых моделей, часто необходимо учитывать различные дополнительные факты и данные при формировании ответа, например:
LLM-система для помощи сотрудникам компании: брать во внимание внутреннюю документацию компании при формировании ответа;
Юридический консультант для застройщика: проверять генерируемые рекомендации и заключения на соответствие специализированным нормам законодательства.
В ходе обучения большие языковые модели запоминают достаточно много информации из самых разных источников, что формирует их common knowledge. Лидирующие модели демонстрируют хорошее качество работы и на более узких доменах, например в медицине или экономике. Однако не всегда этого бывает достаточно для решения поставленных задач.
LLM хорошо отвечает на вопросы по тем знаниям, на которых она училась. Но что делать в случае, когда ответ нужно дать по данным пользователя?
Самое простое — положить все данные в промпт и спросить. А если не влезут?
В таких случаях одним из подходов является RAG (Retrieval Augmented Generation), про который я расскажу далее.
Ответы на вопросы по документам (RAG)
Идея RAG — обогатить вопрос пользователя дополнительными данными, которые помогут сети дать правильный ответ. Главное, выбрать из множества данных те, которые окажутся действительно полезными.
RAG включает в себя хранение, поиск дополнительной релевантной информации и ее интеграцию в контекст модели. Таким образом, документы, содержащие актуальную для запроса информацию, будут вставлены в контекст модели перед началом генерации ответа, что позволит учесть специфику доменной области в работе LLM без дообучения.
Работает это следующим образом: специальный алгоритм «режет» документы пользователя на небольшие фрагменты, после чего выполняет поиск, чтобы найти те части, которые с наибольшей вероятностью могут содержать ответ на поставленный вопрос. Про реализацию данного решения расскажу далее.
Для начала, с помощью различных адаптеров, мы загружаем документы пользователя в память. В рамках GigaChain таких адаптеров-загрузчиков достаточное количество. Вы можете загружать PDF, текстовые файлы, можно загружать данные из интернета, из википедии, из каких-то других источников, например, патентной базы данных.
После этого каждый документ «разрезается» на некоторое количество частей и для каждой части считается эмбеддинг.
Эмбеддинг — это числовой вектор, внутреннее представление текста моделью. Было замечено, что у текстов со сходными смыслами — сходные эмбеддинги. Затем такие векторы смыслов складываются в специальную векторную базу данных. В рамках GigaChain поддерживаются самые популярные базы, например, Chroma и FAISS.
Далее переходим к вопросу пользователя. После того, как пользователь его задал, для вопроса также считается эмбеддинг и выполняется поиск наиболее релевантных частей в базе данных. Затем из этих частей склеивается новый мета-документ, такой, чтобы он мог поместиться в запрос к языковой модели, и после этого она, ориентируясь на данный документ, может ответить на вопрос пользователя.
Как реализовать RAG? Пользователь, который хочет его реализовать, сталкивается с большим количеством вопросов:
На какие части нужно порезать документ?
Какую векторную базу данных использовать?
Какой использовать алгоритм сравнения эмбеддингов?
Какие применить ухищрения? Например, можно сгенерировать синонимы вопроса или возможные варианты ответа и после этого выполнять поиск. Или можно каждый фрагмент документа обогатить дополнительной метаинформацией, например к какой главе он относится, какой был порядковый номер страницы и т. д.
Ответить на эти вопросы довольно сложно, на сегодня нет методики, которая позволяет выбрать оптимальные алгоритмы. И чаще всего лучшим решением является эмпирический подход — пробуем различные варианты реализации RAG, пока не найдем оптимальный. Делать это вручную достаточно трудоемко, и тут снова нам на помощь приходит GigaChain. Библиотека содержит большое количество загрузчиков документов, адаптеров к разным базам данных, коннекторов к различным алгоритмам поиска и т. п.
Например, на сегодняшний день в GigaChain доступны унаследованные из LangChain 161 загрузчик документов, 63 векторных хранилища, 48 способов эмбеддинга и практически каждый день появляются новые интеграции. Также есть множество готовых пайплайнов для ответов на вопросы по документам. Большая часть промптов в них переведены и адаптированы для работы с русским языком и GigaChat.
Но они также отлично работают с OpenAI и другими вендорами.
В GigaChain есть множество готовых пайплайнов с различными реализациями RAG. Вы можете быстро проверить различные комбинации, посмотреть на готовые примеры и собрать ту реализацию RAG, которая лучше всего будет работать с вашими документами и с вашим типом бизнес-задач.
Ниже я покажу возможности GigaChain на примере практической реализации RAG.
RAG с использованием GigaChat на примере задачи «разговор с книгой»
Пользователь может обсудить свою любимую книгу с LLM. Сама книга добавляется в GigaChat с помощью RAG, так что он отлично в ней ориентируется.
При этом первый прототип решения занимал 50 строк кода на python вместе с UI.
Мы уже знаем, что подход RAG позволяет большим языковым моделям (LLM) отвечать на вопросы по документам, которые не помещаются в промпт. Ниже приведен пример того, как можно научить модель отвечать на вопросы, используя текст из книги.
В качестве примера рассмотрим текст романа Булгакова «Мастер и Маргарита» (главы 1 и 2).
Мы хотим получить ответ на вопрос:
Какой плащ был у Понтия Пилата?
Ответ содержится во второй главе книги и выглядит так:
В белом плаще с кровавым подбоем, шаркающей кавалерийской походкой, ранним утром четырнадцатого числа весеннего месяца нисана в крытую колоннаду между двумя крыльями дворца ирода великого вышел прокуратор Иудеи Понтий Пилат.
Перейдем к практике.
Установка
Для работы нам понадобится векторная база данных. Будем использовать Chroma.
%pip install chromadb
Инициализация модели
Теперь инициализируем модель GigaChat.
from langchain.chat_models.gigachat import GigaChat
llm = GigaChat(credentials=...)
Для проверки зададим модели вопрос про цвет плаща без какого-либо контекста. Возможно, она и так будет давать ожидаемый ответ...
from langchain.schema import HumanMessage
question = "Какой плащ был у Понтия Пилата?"
llm([HumanMessage(content=question)]).content[0:200]
'Понтий Пилат, римский прокуратор Иудеи, известен своим красно-белым плащом.
Этот плащ был характерной чертой его должности и символизировал его власть и
статус. \n\nВ исторических источниках описывается'
Видим, что модель не отвечает так, как нам хотелось бы, поэтому применим RAG-подход.
Подготовка документа
Для работы с документом нам нужно разделить его на части. Будем использовать TextLoader
для загрузки книги и RecursiveCharacterTextSplitter
, чтобы разделить текст на приблизительно равные куски в ≈1000 символов с перекрытием в ≈200 символов. Этот тип сплиттера сам выбирает каким способом следует оптимально разделять документ (по абзацам, по предложениям и т. д.):
from langchain.document_loaders import TextLoader
from langchain.text_splitter import (
RecursiveCharacterTextSplitter,
)
loader = TextLoader("../мастер_и_маргарита.txt")
documents = loader.load()
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200,
)
documents = text_splitter.split_documents(documents)
print(f"Total documents: {len(documents)}")
Total documents: 91
После нарезки мы получили 91 документ с частями книги.
Создание базы данных эмбеддингов
Ранее я рассказывал, что эмбеддинг — это векторное представление текста, которое может быть использовано для определения смысловой близости текстов. Векторная база данных хранит тексты и соответствующие им эмбеддинги, а также умеет выполнять поиск по ним. Для работы с базой данных мы создаем объект GigaChatEmbeddings
и передаем его в базу данных Chroma.
from chromadb.config import Settings
from langchain.vectorstores import Chroma
from langchain_community.embeddings import GigaChatEmbeddings
embeddings = GigaChatEmbeddings(
credentials="..."
)
db = Chroma.from_documents(
documents,
embeddings,
client_settings=Settings(anonymized_telemetry=False),
)
Поиск по базе данных
Теперь можно обратиться к базе данных и попросить найти документы, которые с наибольшей вероятностью содержат ответ на наш вопрос.
По-умолчанию база данных возвращает четыре наиболее релевантных документа. Этот параметр можно изменить в зависимости от решаемой задачи и типа документов.
docs = db.similarity_search(question, k=4)
len(docs)
4
print(f"... {str(docs[0])[620:800]} ...")
Видно, что первый же документ содержит внутри себя часть книги с ответом на наш вопрос.
... акцент почему-то пропал: - Все просто: в белом плаще...\n\n\n\n
Глава 2\n\nПонтий Пилат\n\nВ белом плаще с кровавым подбоем,
шаркающей кавалерийской походкой, ранним утром четырнадц ...
QnA цепочка
Теперь мы создадим цепочку QnA, которая специально предназначена для ответов на вопросы по документам. В качестве аргументов передается языковая модель и ретривер (на основе БД).
from langchain.chains import RetrievalQA
qa_chain = RetrievalQA.from_chain_type(llm, retriever=db.as_retriever())
Наконец можно задать вопрос нашей цепочке и получить правильный ответ!
qa_chain({"query": question})
{'query': 'Какой плащ носил Понтий Пилат?',
'result': 'Понтий Пилат носил белый плащ с кровавым подбоем.'}
Несколько дополнительных вопросов для проверки работоспособности:
qa_chain({"query": "Какая трость была у Воланда?"})
{'query': 'Какая трость была у Воланда?',
'result': 'Трость, которую держал Воланд,
имела черный набалдашник в виде головы пуделя.'}
qa_chain({"query": "В чем главная проблема человека?"})
{'query': 'В чем главная проблема человека?',
'result': 'Главная проблема человека, согласно данному контексту,
заключается в том, что он не может управлять своей жизнью
и всем распорядком на земле без точного плана на некоторый срок.'}
AI-агенты
В завершение хотелось бы немного рассказать про агентов. Все о них говорят, но однозначного понимания того, что такое агент, пока нет. Например, вот так выглядят определения от OpenAI:
Системы, которые адаптивно преследуют сложные составные цели, используя рассуждения, и при этом не каждый их шаг контролируется человеком (то есть им предоставляется автономия), а поведение не заложено заранее.
или так:
Системы, способные на широкий спектр действий и достаточно надежны, чтобы в определенных обстоятельствах пользователь мог доверить им эффективно и автономно выполнять задачи для достижения сложных целей ВМЕСТО пользователя.
А Билл Гейтс говорит, что агенты — это тип программного обеспечения, который реагирует на естественный язык и может выполнять множество различных задач на основе знаний пользователя.
Я бы дополнил определение агентов следующим тезисом:
«Агент – это программа, которая способна взаимодействовать с внешней средой с помощью инструментов и корректировать своё поведение в зависимости от результатов взаимодействия (рефлексия).
Без рефлексии агент превращается в цепочку вызовов модели».
И да, GigaChain со своими возможностями является ничем иным, как инструментом для создания агентов.
В качестве примера хочу поделиться примером мультиагентной системы ChatDev. Это среда, в которой агенты на основе нейросетевых моделей совместно и совершенно автономно разрабатывают софт по ТЗ от пользователя.
И пусть сегодня способности этой платформы находятся на уровне старшеклассника, уверен, что через год подобные мультиагентные платформы будут писать код на уровне студента, а через два — не хуже джуна.
Мне удалось завести этот dream team из агентов на GigaChat Pro. Снял небольшое, но занимательное видео о том, как команда агентов творит магию и создает софт. На видео агенты на основе GigaChat’a совместно разрабатывают софт, а именно создают квиз по кибербезопасности на тему «безопасность мобильного устройства». При этом они не только пишут техническую реализацию, но и придумывают вопросы с правильными и неправильными вариантами ответов.
Форк проекта, адаптированого для работы с GigaChat и GigaChain: https://github.com/Rai220/GigaChatDev .
Напомню, что пока это учебный пример и не стоит ждать, что агенты будут справляться с реальными задачами. Часто, у них не получается написать рабочую программу, также они не могут оценить интерфейс, поэтому бывает так, что программа может и рабочая, но из-за отображения пользоваться ей невозможно.
Что думаете? Кажется за агентами будущее. Пора пристегнуться.
Также напомню о том, что в Telegram-канале Salute AI мы с коллегами начали делиться наработками в области машинного обучения и другими рабочими моментами. А в соответствующем чатике Salute AI Community можно пообщаться с нами лично.