ym88659208ym87991671
Компоненты | Документация для разработчиков

Компоненты

Обновлено 6 августа 2024

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

Чат-модели

Языковые модели, которые используют последовательность сообщений в качестве входных данных и возвращают чат-сообщения в качестве выходных данных (в отличие от использования обычного текста). Такой подход характерен для более новых моделей. Более старые модели это, как правило, LLM. Чат-модели поддерживают назначение различных ролей для сообщений, что помогает различать сообщения от ИИ, пользователей и инструкции, такие как системные сообщения.

Хотя базовые модели работают по принципу «сообщение на входе, сообщение на выходе», обертки GigaChain также позволяют этим моделям принимать строку в качестве входных данных. Это позволяет использовать чат-модели вместо LLM.

Когда строка передается в качестве входных данных, она преобразуется в HumanMessage, который затем передается базовой модели.

GigaChain не предоставляет ChatModel, а использует интеграции со сторонними сервисами.

При создании экземпляра ChatModel используется стандартный параметр:

  • model — имя модели.

Объекты ChatModel также принимают другие параметры, специфичные для выбранной интеграции. Так, при работе с GigaChat, вы можете передать параметры credentials и scope, которые содержат авторизационные данные и версию API, к которой нужно обратиться.

Некоторые чат-модели подготовлены для вызова инструментов и предоставляют для этого специальный API. Такие модели рекомендуется использовать, если ваши задачи требуют вызова инструментов. Подробности — в разделе Вызов инструментов.

LLM

Те языковые модели, которые в качестве входных данных принимают строку, на выходе также возвращают строку.

Хотя базовые модели работают по принципу «строка на входе, строка на выходе», обертки GigaChain также позволяют этим моделям принимать сообщения в качестве входных данных. Это делает их взаимозаменяемыми с ChatModels. Когда сообщения передаются в качестве входных данных, они форматируются в строку перед передачей базовой модели.

Для работы с LLM GigaChain использует интеграции со сторонними сервисами.

Сообщения

Некоторые языковые модели принимают список сообщений в качестве входных данных и на выходе возвращают сообщение. Существует несколько различных типов сообщений. Все сообщения имеют свойства role, content и response_metadata.

Свойство role описывает автора сообщения. GigaChain предоставляет разные классы сообщений для различных ролей.

Свойство content описывает содержание сообщения. Содержание может быть представлено:

  • строковыми данными — большинство моделей работает именно с такими данными;
  • списком словарей — используется для мультимодального ввода, где словарь содержит данные о типе ввода и месте, из которого он был получен.

HumanMessage

Сообщение от пользователя.

AIMessage

Сообщение от модели. Кроме content, сообщения модели имеют свойства:

  • response_metadata — дополнительные метаданные ответа. Эти данные, как правило, зависят от модели, которую вы используете. Например, данные могут содержать логарифм вероятности и информацию об использовании токенов.

  • tool_calls — данные о решении языковой модели вызвать инструмент. Они являются частью вывода AIMessage и доступны с помощью свойства .tool_calls.

    Это свойство возвращает список словарей. Каждый словарь содержит ключи:

    • name — имя инструмента, который нужно вызвать;
    • args — аргументы вызываемого инструмента;
    • id — идентификатор вызова инструмента.

SystemMessage

Системное сообщение, которое сообщает модели, как себя вести. Некоторые модели могут не поддерживать системное сообщение.

FunctionMessage

Результат вызова функции. Кроме role и content, FunctionMessage содержит свойство name. Оно указывает имя функции, вызов которой привел к данному результату.

ToolMessage

Данное сообщение представляет результат вызова инструмента. Оно отличается от FunctionMessage тем, что соответствует типам сообщений OpenAI function и tool. Кроме role и content, это сообщение содержит свойство tool_call_id, которое передает идентификатор вызова инструмента,

Шаблоны промптов

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

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

Шаблоны промптов возвращают значение промпта (PromptValue). Это значение можно передать в LLM или чат-модель, а также можно преобразовать в строку или список сообщений. PromptValue упрощает переключение между строковыми данными и сообщениями.

Существует несколько различных типов шаблонов промптов.

String PromptTemplates

Шаблоны промптов, которые используются для форматирования одной строки и, как правило, применяются для более простых входных данных. Пример распространенного способа создания и использования PromptTemplate:

from langchain_core.prompts import PromptTemplate

prompt_template = PromptTemplate.from_template("Расскажи мне шутку про {topic}")

prompt_template.invoke({"topic": "коты"})

ChatPromptTemplates

Шаблоны промптов, которые используются для форматирования списка сообщений. Эти «шаблоны» сами по себе состоят из списка шаблонов. Пример распространенного способа создания и использования ChatPromptTemplate:

from langchain_core.prompts import ChatPromptTemplate

prompt_template = ChatPromptTemplate.from_messages([
("system", "Ты полезный ассистент"),
("user", "Расскажи мне шутку про {topic}")
])

prompt_template.invoke({"topic": "коты"})

В примере ChatPromptTemplate создаст два сообщения при вызове:

  • первое — системное сообщение, которое не содержит переменных для форматирования;
  • второе — сообщение от пользователя (HumanMessage). Оно может изменяться с помощью переменной topic, которую задает пользователь.

MessagesPlaceholder

Шаблон промптов, который отвечает за добавление списка сообщений в определенное место. Так, пример работы с ChatPromptTemplate показывает, как можно форматировать два сообщения, каждое из которых представляет собой строку. В свою очередь MessagesPlaceholder используется если нужно, чтобы пользователь передал список сообщений, которые требуется поместить в определенное место.

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.messages import HumanMessage

prompt_template = ChatPromptTemplate.from_messages([
("system", "Ты полезный ассистент"),
MessagesPlaceholder("msgs")
])

prompt_template.invoke({"msgs": [HumanMessage(content="привет!")]})

При выполнении примера создается список из двух сообщений:

  • первое — системное сообщение;
  • второе — сообщение HumanMessage, которое передал пользователь.

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

Того же результата можно достигнуть без MessagesPlaceholder следующим образом:

prompt_template = ChatPromptTemplate.from_messages([
("system", "Вы полезный ассистент"),
("placeholder", "{msgs}") # <-- Измененный код
])

Селекторы образцов

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

Парсеры вывода

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

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

GigaChain поддерживает парсеры вывода различных типов. Список поддерживаемых парсеров представлен в таблице, которая содержит поля:

  • Название — название парсера вывода.
  • Поддержка потоковой передачи — поддерживает ли парсер потоковую передачу токенов.
  • Инструкции по формату — есть ли у парсера инструкции по формату данных. Как правило, это доступно для всех парсеров, кроме случаев, когда требуемая схема не указана в промпте, а задается другими параметрами (например, при вызове функций OpenAI), или когда OutputParser оборачивает другой OutputParser.
  • Вызов LLM — может ли парсер вывода самостоятельно вызывать LLM. Как правило, к вызову LLM обращаются только те парсеры, которые хотят исправить формат выходных данных.
  • Тип выходных данных — ожидаемый тип входных данных. Большинство парсеров вывода работают как со строками, так и с сообщениями. Но некоторые, например, функции OpenAI, требуют сообщения с конкретными kwargs.
  • Тип выходных данных — тип выходных данных объекта, возвращаемого парсером.
  • Описание — комментарий, описывающий парсер и ситуации, когда он может быть полезен.
НазваниеПоддержка потоковой передачуИнструкции по форматуВызов LLMТип входных данныхТип выходных данныхОписание
JSONstr | MessageОбъект JSONВозвращает JSON-объект. Можно указать модель Pydantic, в соответствии с которой парсер вернет JSON. Наиболее надежный парсер для получения структурированных данных, который не использует вызов функций
XMLstr | MessagedictВозвращает словарь тегов. Используйте, когда нужен XML-вывод. Используйте с моделями, которые хорошо работают с XML (например, Anthropic)
CSVstr | MessageList[str]Возвращает список значений, разделенных запятыми
OutputFixingstr | MessageОборачивает другой парсер вывода. Если обернутый парсер вывода выдаст ошибку, то OutputFixing передаст сообщение об ошибке и неправильный вывод в LLM и попросит модель исправить вывод
RetryWithErrorstr | MessageОборачивает другой парсер вывода. Если обернутый парсер вывода выдаст ошибку, то RetryWithError передаст оригинальные входные данные, неправильный вывод и сообщение об ошибке в LLM и попросит модель внести исправления. В отличие от OutputFixingParser, также передает исходные инструкции
Pydanticstr | Messagepydantic.BaseModelПринимает пользовательскую модель Pydantic и возвращает данные, оформленные соответствующим образом
YAMLstr | Messagepydantic.BaseModelПринимает пользовательскую модель Pydantic и возвращает данные, оформленные соответствующим образом. Для кодирования использует YAML
PandasDataFramestr | MessagedictПолезен для выполнения операций с DataFrame библиотеки pandas
Enumstr | MessageEnumПреобразует ответ в одно из заданных значений перечисления (enum)
Datetimestr | Messagedatetime.datetimeПреобразует ответ в строку даты и времени (datetime)
Structuredstr | MessageDict[str, str]Возвращает структурированную информацию. Менее развитый, чем другие парсеры вывода, так как позволяет полям быть только строками. Это может быть полезно при работе с небольшими LLM

История чата

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

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

Документы

Объект Document в GigaChain содержит информацию о некоторых данных. Он имеет два атрибута:

  • page_content: str — содержимое документа, представленное в виде строки;
  • metadata: dict — связанные с документом произвольные метаданные. Могут содержать идентификатор документа, имя файла и другие данные.

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

Классы, которые загружают объекты Document. GigaChain поддерживает интеграции с теми же сервисами, что и LangChain, например, Slack, Notion, Google Drive и другие. Подробнее об интеграциях с источниками данных — в официальной документации LangChain.

Каждый DocumentLoader имеет свои специфические параметры, но любой из них можно вызвать одинаково с помощью метода .load. Пример использования:

from langchain_community.document_loaders.csv_loader import CSVLoader

loader = CSVLoader(
... # <-- Специфические параметры интеграции
)
data = loader.load()

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

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

Общее описание работы разделителей текста:

  1. Разделение текста на небольшие, семантически значимые части. Как правило, на предложения.
  2. Объединение этих небольших частей в более крупные до достижения определенного размера. Требуемый размер определяется собственной функцией.
  3. Чтобы сохранить контекст между разными фрагментам, после достижения нужного размера, создается отдельный фрагмент текста. Затем начинается создание нового фрагмента текста с некоторым перекрытием.

Таким образом, при настройке разделителя текста следует учитывать:

  • Как текст делится.
  • Как измеряется размер фрагмента.

Модели эмбеддингов

Класс Embeddings предназначен для взаимодействия с моделями, которые создают векторное представление текста (эмбеддинги). При работе с GigaChat для эмбеддингов используется модель Embeddings. Вы также можете использовать подходящие модели других сервисов. Класс Embeddings предоставляет стандартный интерфейс для работы с моделями разных сервисов.

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

Базовый класс Embeddings в GigaChain предоставляет два метода: один для эмбеддинга документов и один для эмбеддинга запроса. Первый принимает на вход несколько текстов, тогда как второй — один текст. Разделение на два метода обусловлено тем, что некоторые модели эмбеддингов имеют разные методы для эмбеддинга документов (для поиска) и запросов (сам поисковый запрос).

Векторные хранилища

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

Векторные хранилища можно преобразовать в интерфейс ретривера следующим образом:

vectorstore = MyVectorStore()
retriever = vectorstore.as_retriever()

Ретриверы

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

Ретриверы принимают строковый запрос на вход и возвращают список объектов Document на выходе.

Инструменты

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

Инструмент состоит из:

  • названия;
  • описания того, что делает инструмент;
  • JSON-схемы входных данных инструмента;
  • функции, которую вызывает инструмент;
  • указания на то следует ли возвращать результат работы инструмента непосредственно пользователю. Это актуально только для агентов.

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

tools = [...] # Определение списка инструментов
llm_with_tools = llm.bind_tools(tools)
ai_msg = llm_with_tools.invoke("Сделай 1, 2, 3...") # AIMessage(tool_calls=[ToolCall(...), ...], ...)

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

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

Наборы инструментов

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

Все наборы инструментов реализуют метод get_tools, который возвращает список инструментов:

# Инициализация набора инструментов
toolkit = ExampleToolkit(...)

# Получение списка инструментов
tools = toolkit.get_tools()

Агенты

Языковые модели не совершают действия сами — они просто генерируют текст. Одним из основных случаев использования GigaChain является создание агентов.

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

GigaGraph — это расширение GigaChain, которое предназначено для создания управляемых и настраиваемых агентов. Подробнее о концепции агентов — в документации GigaGraph.

Для работы с агентами в GigaChain также существует класс AgentExecutor — среда выполнения для агентов. В документации вы найдете раздел посвященный работе с AgentExecutor, но для создания агентов рекомендуется использовать GigaGraph.

Колбэки

GigaChain предоставляет систему колбэков, которая позволяет вам подключаться к различным этапам работы вашего LLM-приложения. Это полезно для логирования, мониторинга, потоковой передачи и других задач. На эти события можно подписаться с помощью аргумента callbacks, доступного в API. Этот аргумент представляет список объектов-обработчиков, которые должны реализовать один или несколько методов, описанных ниже.

Обработчики колбэков

CallbackHandlers — это объекты, которые реализуют интерфейс CallbackHandler. Интерфейс содержит метод для каждого события, на которое можно подписаться. При получении события объект CallbackManager вызывает соответствующий метод каждого обработчика.

class BaseCallbackHandler:
"""Базовый обработчик колбэков, который можно использовать для обработки колбэков в gigachain."""

def on_llm_start(
self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any
) -> Any:
"""Выполняется при запуске LLM."""

def on_chat_model_start(
self, serialized: Dict[str, Any], messages: List[List[BaseMessage]], **kwargs: Any
) -> Any:
"""Выполняется при запуске чат-модели."""

def on_llm_new_token(self, token: str, **kwargs: Any) -> Any:
"""Выполняется при получении нового токена LLM. Доступно только при включенной потоковой передаче."""

def on_llm_end(self, response: LLMResult, **kwargs: Any) -> Any:
"""Выполняется при завершении работы LLM."""

def on_llm_error(
self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any
) -> Any:
"""Выполняется при ошибке LLM."""

def on_chain_start(
self, serialized: Dict[str, Any], inputs: Dict[str, Any], **kwargs: Any
) -> Any:
"""Выполняется при запуске цепочки."""

def on_chain_end(self, outputs: Dict[str, Any], **kwargs: Any) -> Any:
"""Выполняется при завершении работы цепочки."""

def on_chain_error(
self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any
) -> Any:
"""Выполняется при ошибке цепочки."""

def on_tool_start(
self, serialized: Dict[str, Any], input_str: str, **kwargs: Any
) -> Any:
"""Выполняется при запуске инструмента."""

def on_tool_end(self, output: Any, **kwargs: Any) -> Any:
"""Выполняется при завершении работы инструмента."""

def on_tool_error(
self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any
) -> Any:
"""Выполняется при ошибке инструмента."""

def on_text(self, text: str, **kwargs: Any) -> Any:
"""Выполняется при обработке произвольного текста."""

def on_agent_action(self, action: AgentAction, **kwargs: Any) -> Any:
"""Выполняется при действии агента."""

def on_agent_finish(self, finish: AgentFinish, **kwargs: Any) -> Any:
"""Выполняется при завершении работы агента."""

Передача колбэков

Свойство callbacks доступно на большинстве объектов в API (моделях, инструментах, агентах и т.д.) в двух разных местах:

  • Колбэки конструктора определяются в конструкторе, например, ChatAnthropic(callbacks=[handler], tags=['a-tag']). В этом случае колбэки используются для всех вызовов, сделанных с этим объектом, и будут применяться только к этому объекту. Например, если вы инициализируете чат-модель с колбэками конструктора, а затем используете ее в цепочке, колбэки будут вызываться только при обращении к этой модели.
  • Колбэки запроса передаются в метод invoke, который используется для выполнения запроса. В этом случае колбэки используются только для этого конкретного запроса и всех подзапросов, которые он содержит. Например, вызов последовательности, которая вызывает модель, используя тот же обработчик, переданный в методе invoke(). В методе invoke() колбэки передаются в параметре config.
ПАО Сбербанк использует cookie для персонализации сервисов и удобства пользователей.
Вы можете запретить сохранение cookie в настройках своего браузера.