
Розробка з використанням великих мовних моделей (LLM) зазвичай починається з простого циклу «запит-відповідь». Але щойно завдання виходить за межі простого чат-бота і вимагає від моделі виконання реальних дій — наприклад, інтеграції зовнішніх інструментів (tools), роботи з базами даних або доступу до файлової системи — ми стикаємося з фундаментальною проблемою. Стандартний API моделі за своєю природою є stateless (не зберігає стану) і не має вбудованих механізмів для керування складною логікою.
На перший погляд просте завдання, як-от «проаналізуй цей файл, знайди відповідні дані в інтернеті та створи звіт», перетворюється на складне завдання з оркестрації:
- Як керувати станом (state) і передавати контекст між численними викликами LLM?
- Як реалізувати циклічну логіку, де агент багаторазово взаємодіє з інструментами, доки не досягне мети?
- Як стандартизувати підключення до різних моделей (OpenAI, Gemini, локальних) та інструментів, не переписуючи код щоразу?
Щоб спростити розробку таких систем і надати розробникам стандартизований підхід до цього завдання з оркестрації, були створені фреймворки LangChain та LangGraph:
- LangChain надає уніфікований набір інструментів: стандартизовані інтерфейси до моделей, компоненти для промптів та інструментів.
- LangGraph — це фреймворк, побудований на основі LangChain, який дозволяє конструювати логіку прийняття рішень агента у вигляді графа станів, елегантно вирішуючи проблему циклів та розгалужень.
Щоб краще зрозуміти їхні ролі, скористаємося аналогією.
Уявіть, що ви будуєте щось із LEGO. У вас є окремі кубики (мотори, колеса, блоки), але самі по собі вони — лише деталі. Щоб зібрати з них робочу машину, вам потрібна інструкція та розуміння, як з’єднати ці деталі разом.
У світі ШІ-агентів:
- 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 — лінійні. Вони йдуть від точки А до точки Б. Але справжні завдання нелінійні. Вони вимагають циклів, розгалужень та прийняття рішень.
Наприклад, агент-дослідник повинен:
- Зрозуміти запит.
- Вирішити: чи потрібно шукати в інтернеті?
- Якщо так → використати інструмент пошуку.
- Проаналізувати результати.
- Вирішити: чи достатньо інформації?
- Якщо ні → повернутися до кроку 3 з уточненим запитом (це цикл).
- Якщо так → згенерувати фінальну відповідь.
Таку складну логіку неможливо описати простим ланцюжком.
Основна ідея 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) | LangGraph |
|---|---|---|
| Основне застосування | Прості, лінійні завдання | Складні, циклічні завдання (агенти) |
| Структура | Конвеєр (A → B → C) | Граф (блок-схема з розгалуженнями та циклами) |
| Керування потоком | Детермінований, заздалегідь визначений | Динамічний, визначається в реальному часі |
| Приклад завдання | 1. Взяти текст. 2. Підсумувати його. 3. Перекласти іншою мовою. | 1. Отримати питання. 2. Шукати в інтернеті, доки не знайдеться відповідь. 3. Узагальнити знайдене і відповісти. |
| Аналогія | Складальна лінія на заводі | Команда людей, що радиться і приймає рішення |
Збираємо все разом
- Введення користувача потрапляє в початковий Стан LangGraph.
- Вузол “Агент” отримує стан. Усередині цього вузла знаходиться ланцюжок LangChain (
промпт | модель | парсер). Модель, використовуючи Інструменти з LangChain, вирішує, що робити далі (наприклад, “викликати пошук”). Її рішення записується в Стан. - Умовне Ребро аналізує стан і направляє потік до Вузла “Виконавець Інструментів”.
- Цей вузол виконує реальний виклик інструменту (наприклад, робить веб-пошук) і записує результат назад у Стан.
- Потік повертається до Вузла “Агент” (це цикл). Тепер модель бачить результат пошуку і приймає нове рішення.
- Цикл повторюється, доки модель не вирішить, що завдання виконано. Тоді Умовне Ребро направить потік до завершення.