LangGraph українською: коли він кращий за OpenAI SDK
LangGraph українською майже ніхто не пояснює нормально, тому почну з чесного визначення. LangGraph — це бібліотека-оркестратор від команди LangChain, яка дозволяє описати агента як граф станів: вузли роблять роботу, ребра вирішують, куди йти далі, а стан тече між ними. Потрібна вона тоді, коли вашому агенту мало одного проходу «питання → відповідь» і починаються цикли, розгалуження та памʼять.
Що таке LangGraph насправді
Під капотом LangGraph — це звичайний орієнтований граф поверх будь-якого LLM. Ви не пишете нескінченний while-цикл із купоюif-ів. Ви описуєте три речі:
- State — обʼєкт, що тече крізь увесь процес. Зазвичай це повідомлення, проміжні результати, лічильники, прапорці.
- Nodes (вузли) — функції, що приймають стан і повертають його оновлення. Виклик моделі, виклик інструмента, парсинг відповіді — кожен крок це вузол.
- Edges (ребра) — переходи. Бувають прямі (A завжди в B) і умовні (з A в B або C залежно від стану). Умовні ребра і дають вам гілки та цикли.
Головна цінність: граф детермінований і прозорий. Ви бачите всі можливі шляхи на діаграмі, можете зробити checkpoint у будь-якій точці, відмотати назад і повторити прогін. Для дебагу агента в продакшні це різниця між «розберуся за годину» і «розберуся за три дні».
Коли чистого OpenAI SDK достатньо
Чесно і відразу: більшості агентів LangGraph не потрібен. Якщо у вас один прохід, кілька інструментів і лінійна логіка — голий OpenAI SDK (або Anthropic SDK) із tool-calling у простому циклі робить свою справу і не тягне зайву залежність.
Лишайтеся на чистому SDK, коли:
- Сценарій лінійний: запит → виклик 1-2 інструментів → відповідь. Без гілок, що повертаються назад.
- Стан вміщується в історію повідомлень і вам не треба його зберігати між сесіями днями.
- Немає human-in-the-loop: агент не зупиняється посеред процесу, щоб дочекатися підтвердження людини.
- Один агент, один домен, до 8 інструментів. Тут граф — це церемонія заради церемонії.
Я кажу це прямо клієнтам: якщо ваш кейс закривається 80 рядками на голому SDK, додавати LangGraph — це наростити складність без вигоди. Фреймворк має зʼявлятися тоді, коли біль уже є, а не «на виріст».
Коли LangGraph виграє
А ось де голий SDK перетворюється на павутину if-ів, і LangGraph реально окупається:
- Цикли. Агент намагається, перевіряє результат, переробляє, поки не пройде валідацію. На SDK це ручний цикл із лічильниками; у LangGraph це ребро, що веде вузол сам у себе.
- Розгалуження. «Якщо запит про оплату — у billing-гілку, якщо технічний — у support-гілку». Умовне ребро замість стіни вкладених
if/else. - Human-in-the-loop. Граф зупиняється на вузлі, чекає підтвердження людини, потім продовжує з того ж стану. Це вбудована можливість, а не милиця.
- Persistence (збереження стану). Checkpointer пише стан у Postgres або Redis. Процес може жити годинами чи днями, переживати рестарт сервера і продовжувати з місця зупинки.
- Multi-agent handoff. Кілька агентів передають роботу один одному через спільний стан. Оркестратор як окремий вузол вирішує, хто наступний. Деталі — у статті про multi-agent системи →
LangGraph приклад: мінімальний StateGraph
Найкоротший туторіал, який щось пояснює. Граф із двох вузлів: один викликає модель, інший вирішує, чи треба ще один прохід. Псевдо-Python, близький до реального API LangGraph:
from langgraph.graph import StateGraph, START, END
from typing import TypedDict
class State(TypedDict):
question: str
answer: str
tries: int
def call_model(state: State) -> dict:
# тут реальний виклик LLM; спрощено
reply = llm.invoke(state["question"])
return {"answer": reply, "tries": state["tries"] + 1}
def is_good(state: State) -> str:
# умовне ребро: повторити чи завершити
if "не знаю" in state["answer"] and state["tries"] < 3:
return "retry"
return "done"
graph = StateGraph(State)
graph.add_node("call_model", call_model)
graph.add_edge(START, "call_model")
graph.add_conditional_edges(
"call_model", is_good, {"retry": "call_model", "done": END}
)
app = graph.compile()
result = app.invoke({"question": "Що таке LangGraph?", "tries": 0})Сорок рядків, а ви вже маєте цикл із повторними спробами та умовою виходу. На голому SDK це те саме, але логіка переходів розмазана по тілу циклу. Тут вона винесена в граф: retry веде вузол сам у себе, done веде в END. Додати checkpointer — і цей самий граф переживе рестарт.
LangGraph vs OpenAI SDK: коротка таблиця
Чистий OpenAI SDK виграє
- Один прохід, лінійна логіка
- До 8 інструментів, один домен
- Стан живе в історії повідомлень
- Прототип, MVP, швидка перевірка ідеї
- Команда не хоче нову залежність
LangGraph виграє
- Цикли, гілки, повторні спроби
- Human-in-the-loop із паузами
- Стан зберігається днями (persistence)
- Multi-agent передача роботи
- Потрібен replay і прозорий дебаг
Зверніть увагу: LangGraph не замінює SDK, він над ним. Усередині вузлів ви все одно кличете ту саму модель тим самим клієнтом. LangGraph лише забирає на себе оркестрацію переходів і стану.
LangGraph vs n8n: це не конкуренти
Питання, яке ставлять майже всі: «навіщо LangGraph, якщо є n8n?». Це різні рівні. n8n — це no-code оркестрація інтеграцій: перетягнув ноди, зʼєднав вебхук з API, відправив дані з точки A в точку B. LangGraph — це код-рівень міркування агента: цикли, стан, рішення моделі всередині процесу.
На практиці вони чудово композуються. Типова звʼязка: n8n ловить подію (новий лід, лист, повідомлення), кидає її у HTTP-ендпоінт, за яким стоїть LangGraph-агент, агент думає і повертає результат, n8n розкидає його по CRM, Slack і пошті. n8n — це «де і коли», LangGraph — це «як думати». Не вибір між ними, а правильне місце для кожного.
Як це виглядає в реальному продакшні
Класичний кейс із моєї практики: support-агент для e-commerce, що обробляє звернення в Telegram. Спочатку був один прохід на голому SDK — і працював. Біль почався, коли додали повернення товарів: агент мав зібрати дані замовлення, перевірити політику повернень, дочекатися підтвердження менеджера на суми понад поріг, і лише потім оформити.
Це класичний human-in-the-loop із паузою на годину-дві. На циклі з if-ами це перетворювалося на кошмар зі станом у глобальних змінних. Переписали на LangGraph: вузол «зібрати дані», вузол «перевірити політику», пауза на approval через checkpointer у Postgres, вузол «оформити». Стан переживає рестарт, кожен прогін видно в трейсі, регресій більше немає.
Стек під такі задачі я будую так: LangGraph для оркестрації, Claude або GPT як reasoning-шар, Postgres як checkpointer і памʼять, Telegram Bot API як фронтенд. Якщо вам цікаво, яку модель брати під який вузол — розклав це у матриці вибору моделі →
Повну розробку таких агентів під ключ — від ТЗ до деплою і моніторингу — роблю в рамках розробки AI-агентів →
Поширені помилки з LangGraph
- Беруть LangGraph на лінійний кейс. Якщо немає циклів, гілок чи пауз — це зайва складність. Спочатку голий SDK, граф — коли біль зʼявиться.
- Запихають усе в один гігантський стан. Стан має бути мінімальним і явним. Роздутий стан робить граф нечитабельним так само, як роздутий промпт.
- Забувають про checkpointer. Без нього ви втрачаєте головну перевагу — persistence і replay. Тоді справді простіше було б на SDK.
- Плутають LangGraph і LangChain. Це різні речі. LangChain — це абстракції над промптами і ланцюжками. LangGraph — це граф станів. Можна брати LangGraph і не торкатися решти LangChain.
Чи брати LangGraph вам?
Чесний тест на одну хвилину. Якщо ваш агент: робить один прохід, не зупиняється на людину, не зберігає стан днями і має до 8 інструментів — беріть голий OpenAI SDK і не ускладнюйте. Якщо ж у вас зʼявилися цикли, гілки, паузи на approval або кілька агентів, що передають роботу — LangGraph окупиться вже на першому серйозному дебагу.
Я будую і так, і так, і швидко раджу простіший варіант. Якщо не впевнені, з якого боку межі ви — напишіть, за 30 хвилин дзвінка скажу чесно, чи треба вам граф взагалі.