Перейти к содержимому
davidka.net > 💻 🧠 Код 1001 > 📑 Шпаргалки > 🧠 Шпаргалки по информатике > LangChain и LangGraph

LangChain и LangGraph

  • автор:

Разработка с использованием больших языковых моделей (LLM) начинается с простого цикла «запрос-ответ». Но как только задача выходит за рамки чат-бота и требует от модели реальных действий — интеграции внешних инструментов (tools), работы с базами данных или файловой системой — мы сталкиваемся с фундаментальной проблемой. Стандартный API модели по своей природе stateless и не имеет встроенных механизмов для управления сложной логикой.

Простая задача вроде «проанализируй этот файл, найди в интернете нужные данные и составь отчет» превращается в сложную задачу оркестрации:

  1. Как управлять состоянием и передавать контекст между множественными вызовами LLM?
  2. Как реализовать циклическую логику, где агент многократно обращается к инструментам, пока не достигнет цели?
  3. Как стандартизировать подключение разных моделей (OpenAI, Gemini, локальные) и инструментов, не переписывая код каждый раз?

Чтобы облегчить разработку таких систем и предоставить разработчикам стандартизированный подход к оркестрации, и были созданы фреймворки LangChain и LangGraph:

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

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

Представьте, что вы строите что-то из LEGO. У вас есть отдельные кубики (моторы, колёса, блоки), но сами по себе они — просто детали. Чтобы собрать из них рабочую машину, вам нужна инструкция и понимание, как соединить эти детали вместе.

LangChain предоставляет вам строительные блоки, а LangGraph — интеллектуальную систему для управления этими блоками, позволяя создавать по-настоящему автономных и полезных ИИ-агентов.

В мире ИИ-агентов:

  • LangChain — это ваш набор высокотехнологичных LEGO-кубиков.
  • LangGraph — это продвинутая инструкция, которая позволяет собирать из этих кубиков не просто статичные модели, а динамические, «умные» механизмы, способные принимать решения.

Давайте разберем каждый из этих инструментов по отдельности.

Часть 1: LangChain — Инструментарий для работы с LLM

Основная цель LangChain: упростить и стандартизировать взаимодействие между вашим кодом и большими языковыми моделями (LLM). Он предоставляет готовые компоненты («кубики») для решения типовых задач.

Ключевые компоненты LangChain (наши «кубики»):

1. Модели (Models)
Это обёртки для прямого взаимодействия с нейросетями. LangChain делит их на два типа:

  • LLMs: Старый интерфейс. Принимает на вход строку, возвращает строку.
    • Пример: llm.invoke("Какой цвет у неба?") → "Небо голубое."
  • ChatModels: Современный и более мощный интерфейс. Работает со списком сообщений (HumanMessage, AIMessage, SystemMessage). Это позволяет модели лучше понимать контекст диалога.
    • Пример: chat.invoke([HumanMessage(content="Какой цвет у неба?")]) → AIMessage(content="Небо обычно голубое...")

LangChain унифицирует API. Вам не нужно изучать, как работать с OpenAI, Gemini или локальной Ollama по-отдельности. Вы просто меняете один объект ChatOpenAI на ChatGoogleGenerativeAI или ChatOllama, а остальной код продолжает работать.

2. Промпты (Prompts)
Это шаблоны для ваших запросов к модели. Вместо того чтобы каждый раз вручную собирать текст запроса, вы создаете шаблон с переменными.

from langchain_core.prompts import ChatPromptTemplate

template = ChatPromptTemplate.from_messages([
    ("system", "Ты — полезный ассистент, который переводит текст на {output_language}."),
    ("human", "{text_to_translate}")
])

prompt_value = template.invoke({"output_language": "французский", "text_to_translate": "Я люблю программирование."})

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

3. Цепочки (Chains и язык LCEL)
Это сердце раннего LangChain. Цепочка — это последовательное соединение нескольких компонентов. Сегодня для этого используется LangChain Expression Language (LCEL), который выглядит как конвейер (|).

Простейшая цепочка: промпт | модель.

chain = template | get_gemini_llm()
response = chain.invoke({"output_language": "немецкий", "text_to_translate": "Привет, мир!"})
# response.content будет содержать "Hallo, Welt!"

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

4. Парсеры вывода (Output Parsers)
Модели возвращают текст, но в приложениях нам часто нужны структурированные данные (JSON, список, число). Парсеры преобразуют «сырой» текстовый ответ модели в нужный формат.

from langchain_core.output_parsers import JsonOutputParser

# ... создаем промпт, который просит модель ответить в формате JSON
parser = JsonOutputParser()
chain = template | get_openai_llm() | parser

# Теперь chain.invoke(...) вернет не текстовый объект, а Python-словарь (dict)

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

5. Инструменты (Tools)
Это то, что даёт модели «руки». Инструмент — это любая функция, которую может вызвать агент. Это может быть:

  • Поиск в интернете (TavilySearch, BraveSearch).
  • Калькулятор.
  • Функция для чтения файла с диска.
  • Обращение к вашему внутреннему API.

Модель сама по себе не знает, какая сегодня погода или что написано в вашем файле report.docx. Инструменты — это единственный способ для неё получить доступ к внешней информации и выполнять действия в реальном мире.


Часть 2: LangGraph — Оркестратор для создания агентов

Если LangChain — это набор деталей, то LangGraph — это система управления, которая решает, какую деталь и в какой момент использовать.

Проблема, которую решает LangGraph: Классические цепочки (chains) в LangChain — линейные. Они идут от точки А к точке Б. Но настоящие задачи нелинейны. Они требуют циклов, ветвлений и принятия решений.

Например, агент-исследователь должен:

  1. Понять запрос.
  2. Решить: нужно ли искать в интернете?
  3. Если да → использовать инструмент поиска.
  4. Проанализировать результаты.
  5. Решить: достаточно ли информации?
  6. Если нет → вернуться к шагу 3 с уточненным запросом (это цикл).
  7. Если да → сгенерировать финальный ответ.

Такую сложную логику невозможно описать простой цепочкой.

Основная идея LangGraph: представить работу агента как граф состояний (или блок-схему).

Ключевые компоненты LangGraph (элементы блок-схемы):

1. Состояние (State)
Это центральная память всего процесса. Обычно это Python-словарь (TypedDict), который передается от одного шага к другому. Каждый шаг может читать из него данные и записывать в него новые.

Пример состояния: {"user_request": "...", "search_results": [], "final_answer": None}.

2. Узлы (Nodes)
Это блоки действий на вашей блок-схеме. Каждый узел — это Python-функция, которая:

  • Принимает на вход текущее состояние.
  • Выполняет какое-то действие (вызывает LLM, использует инструмент).
  • Возвращает обновленное состояние.

Примеры узлов: call_model_node, execute_tool_node, analyze_results_node.

3. Рёбра (Edges)
Это стрелки, которые соединяют узлы. Они определяют, какой узел будет выполняться следующим. Рёбра бывают двух видов:

  • Обычные рёбра: Просто соединяют узел А с узлом Б. После завершения А всегда будет запущен Б.
  • Условные рёбра (Conditional Edges): Это самая важная часть. После узла А запускается специальная функция-«маршрутизатор», которая смотрит на текущее состояние и решает, куда идти дальше: к узлу Б, В или Г.

Пример условного ребра:

  • После вызова модели (узел agent_node) мы проверяем состояние.
  • Если в ответе модели есть вызов инструмента → идём к узлу execute_tool_node.
  • Если вызова инструмента нет → идём к конечному узлу END.

LangChain vs. LangGraph: Когда что использовать?

КритерийLangChain (LCEL Chains)LangGraph
Основное применениеПростые, линейные задачиСложные, циклические задачи (агенты)
СтруктураКонвейер (A → B → C)Граф (блок-схема с ветвлениями и циклами)
Поток управленияДетерминированный, заранее заданныйДинамический, определяется в реальном времени
Пример задачи1. Взять текст.
2. Суммаризировать его.
3. Перевести на другой язык.
1. Получить вопрос.
2. Искать в интернете, пока не найдется ответ.
3. Обобщить найденное и ответить.
АналогияСборочная линия на заводеКоманда людей, совещающаяся и принимающая решения

Собираем всё вместе

  1. Пользовательский ввод попадает в начальное Состояние LangGraph.
  2. Узел «Агент» получает состояние. Внутри этого узла находится цепочка LangChain (промпт | модель | парсер). Модель, используя Инструменты из LangChain, решает, что делать дальше (например, «вызвать поиск»). Её решение записывается в Состояние.
  3. Условное Ребро анализирует состояние и направляет поток к Узлу «Исполнитель Инструментов».
  4. Этот узел выполняет реальный вызов инструмента (например, делает веб-поиск) и записывает результат обратно в Состояние.
  5. Поток возвращается к Узлу «Агент» (это цикл). Теперь модель видит результат поиска и принимает новое решение.
  6. Цикл повторяется, пока модель не решит, что задача выполнена. Тогда Условное Ребро направит поток к завершению.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *