LangGraph агент собирается за один вечер: установка занимает пять минут, минимальный рабочий граф с циклом и инструментом умещается в сорок строк кода. Ниже разберём это по шагам на Python, покажем полный код агента-исследователя и отдельно дадим бло…
10+ лет в маркетинге, 300+ клиентских проектов: сайты, реклама, боты. Создатель GoBanana (228K+ пользователей, 11.6 млн ₽ выручки) и VibeCoderz. Делаю AI-продукты сам через Claude Code, Cursor, Windsurf и консультирую тех, кто хочет так же.
Об авторе →Claude Code: новый CLI-агент от Anthropic
Anthropic выпустила Claude Code — терминальный AI-агент для разработчиков. Инструмент работает прямо в командной строке и умеет писать, редактировать и запускать код.
Zcode AI: Полный гид по визуальному интерфейсу для Claude Code и AI-агентов
Узнайте, как использовать Zcode для управления Claude Code, Gemini и Codex в едином GUI. Настройка провайдеров, MCP-серверов и визуальный вайбкодинг.
YouTube-канал с монетизацией из любой точки мира: Пошаговый гайд 2026
Инструкция по созданию YouTube-канала: обход блокировок SMS, настройка расширенных функций через виртуальные номера и правила безопасности для монетизации.
Windsurf Code Maps: Как глубоко понимать архитектуру проекта перед написанием кода
Полный гайд по Windsurf Code Maps, модели Sway 1.5 и Sway Grep. Узнайте, как визуализировать архитектуру кода и ускорить разработку в 13 раз.
Vk Fast Cash Strategy
Аудитория ВКонтакте — это те же люди, что и в Instagram, но 'социальный контракт' площадки другой. Если Instagram — это 'дорогой ресторан' с демонстрацией успеха, то VK — это 'душевная шашлычная'. Здесь не работает глянцевый 'успешный успех
LangGraph агент собирается за один вечер: установка занимает пять минут, минимальный рабочий граф с циклом и инструментом умещается в сорок строк кода. Ниже разберём это по шагам на Python, покажем полный код агента-исследователя и отдельно дадим блок для тех, кто работает на JavaScript.
LangGraph 1.2, вышедший в мае 2026, превращает запуск агента в устойчивый граф с чекпоинтами на каждом шаге.LangChain team на 11 мая 2026 фиксирует каждый переход через подключаемый saver — Memory, SQLite или Postgres. В статье: установка, минимальный StateGraph, полный код агента с циклом поиска, частые ошибки новичков и блок про LangGraph.js.
Если вы ещё не разобрались, что вообще такое LangGraph и зачем нужен граф вместо обычной цепочки, лучше сначала прочитать вводную статью про концепцию LangGraph. Здесь фокус на код, архитектуру объяснять с нуля не будем.
Установка сводится к одной команде pip и настройке ключа через переменную окружения. Частая ошибка новичков — забытый ключ, из-за которого первый запуск падает с authorization error, а не с ошибкой в графе.
Актуальная версия LangGraph держит паритет по фичам с прошлым годом, но добавила стабильный checkpointing из коробки.На апрель 2026 фреймворк собрал более 126 000 звёзд на GitHub и остаётся самым распространённым open-source инструментом для production-агентов. Для старта этого достаточно, версии в отдельные числа гнаться не стоит.

Ставим сам фреймворк и провайдера модели:
pip install -U langgraph langchain-anthropicКлюч задаём через переменную окружения, не хардкодим в коде:
export ANTHROPIC_API_KEY="sk-ant-..."Здесь и спотыкается процентов тридцать новичков. Ключ выставлен в терминале, но скрипт запущен из другого окружения (IDE, venv, Docker), и переменная туда не долетела. Проверка простая: echo $ANTHROPIC_API_KEY прямо перед запуском скрипта, в том же терминале, где будете его гонять.

Состояние графа это словарь с типами, который передаётся между узлами и накапливает историю. Для агента с сообщениями достаточно поля messages и счётчика попыток, который защищает от бесконечного цикла.
Разберём состояние из двух полей, этого хватает для первого рабочего агента:
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph.message import add_messages
class AgentState(TypedDict):
messages: Annotated[list, add_messages]
search_attempts: intАннотация add_messages делает поле "добавляемым": новое сообщение дописывается в список, а не перезаписывает историю целиком. Про типизацию в Python подробнее можно посмотреть в отдельной статье про типы данных, если TypedDict видите впервые.
Счётчик search_attempts не обязателен по документации, но именно он спасает от зацикленного графа, когда модель раз за разом решает "нужно ещё поискать".

Минимальный рабочий паттерн: один узел-reasoner решает вызывать ли инструмент, узел tools выполняет вызов, условное ребро замыкает цикл обратно на reasoner. Prebuilt-компоненты LangGraph убирают половину ручного кода.
Частая ошибка при проектировании графа агента, это создание отдельного узла под каждый возможный вызов инструмента. Получается граф на пятнадцать узлов там, где хватило бы двух. Рабочий паттерн проще: один reasoner, один tools node, и условное ребро между ними.
Сначала объявляем инструмент. Возьмём поиск и простую математику, этого достаточно для демонстрации:
from langchain_core.tools import tool
from duckduckgo_search import DDGS
@tool
def web_search(query: str) -> str:
"""Ищет актуальную информацию в интернете по запросу."""
with DDGS() as ddgs:
results = list(ddgs.text(query, max_results=3))
return str(results)
@tool
def multiply(a: float, b: float) -> float:
"""Перемножает два числа."""
return a * b
tools = [web_search, multiply]Дальше связываем инструменты с моделью через bind_tools. Без этого шага модель просто не узнает, что функции существуют, даже если они объявлены рядом:
from langchain_anthropic import ChatAnthropic
from langgraph.prebuilt import ToolNode, tools_condition
from langgraph.graph import StateGraph, START, END
llm = ChatAnthropic(model="claude-sonnet-4-6", temperature=0)
llm_with_tools = llm.bind_tools(tools)
def reasoner(state: AgentState):
response = llm_with_tools.invoke(state["messages"])
return {"messages": [response], "search_attempts": state.get("search_attempts", 0) + 1}Температуру ставим в ноль, для агента с инструментами это почти всегда правильный выбор. Креативность здесь не нужна, нужна предсказуемость вызовов.
Собираем сам граф. tools_condition уже встроен в LangGraph, он смотрит на последнее сообщение и сам решает, был ли вызван инструмент:
graph_builder = StateGraph(AgentState)
graph_builder.add_node("reasoner", reasoner)
graph_builder.add_node("tools", ToolNode(tools))
graph_builder.add_edge(START, "reasoner")
graph_builder.add_conditional_edges("reasoner", tools_condition)
graph_builder.add_edge("tools", "reasoner")
graph = graph_builder.compile()Ребро tools -> reasoner и есть тот самый цикл. Модель вызывает инструмент, результат возвращается reasoner-у, тот решает, хватает ли данных для ответа или нужен ещё один вызов.

Запускаем и смотрим на результат:
result = graph.invoke({
"messages": [("user", "Сколько будет 234 умножить на 18, и кто сейчас CEO LangChain?")],
"search_attempts": 0
})
print(result["messages"][-1].content)Такой агент справляется с двумя разными задачами подряд: сначала считает, потом ищет, комбинируя оба инструмента без дополнительной логики с вашей стороны. Это и есть смысл паттерна ReAct через function calling, а не через ручной парсинг текстового ответа модели.
Если нужна память между запросами, добавляем checkpointer при компиляции:
from langgraph.checkpoint.memory import MemorySaver
memory = MemorySaver()
graph = graph_builder.compile(checkpointer=memory)
config = {"configurable": {"thread_id": "user-42"}}
graph.invoke({"messages": [("user", "Запомни, меня зовут Игорь")]}, config)thread_id тут ключевой параметр. Один и тот же thread_id, и агент продолжает разговор с того же места. Для прода вместо MemorySaver ставят Postgres-checkpointer, чтобы состояние переживало перезапуск сервера.
Максим: «Мог просто засесть до пяти ночи и просто там править одну какую-то функцию, которая не работала. Если бы не терпение, в моменте я уже испотел, и мне хотелось просто всё это закрыть. Но я понимал, что это можно решить и нужно решить, чтобы идти дальше.»
С условными рёбрами в графе бывает похожая история: цикл не останавливается, и не сразу понятно почему. В девяти случаях из десяти дело в отсутствии проверки счётчика попыток в условии, а не в самой модели.

Для фуллстек-проектов на Next.js необязательно поднимать отдельный Python-бэкенд ради одного агента. LangGraph.js повторяет концепцию графов Python-версии и достиг паритета по ключевым возможностям.
К середине 2026 года разрыв между Python и JS версиями практически закрылся.LangGraph TypeScript достиг production-стабильности ещё в середине 2025 года, с полным паритетом по функциям с Python-версией, включая StateGraph, условные рёбра, checkpointing и human-in-the-loop. Пакет активно используется в проде, не только в пет-проектах.Пакет @langchain/langgraph фиксирует более 42 000 еженедельных загрузок на апрель 2026 года.
Установка:
npm install @langchain/langgraph @langchain/core @langchain/anthropicМинимальный граф на TypeScript выглядит почти зеркально Python-версии:
import { StateGraph, START, END, Annotation } from "@langchain/langgraph";
import { ChatAnthropic } from "@langchain/anthropic";
const State = Annotation.Root({
messages: Annotation<string[]>({
reducer: (curr, next) => curr.concat(next),
default: () => [],
}),
});
const llm = new ChatAnthropic({ model: "claude-sonnet-4-6", temperature: 0 });
async function reasoner(state: typeof State.State) {
const response = await llm.invoke(state.messages.join("\n"));
return { messages: [response.content as string] };
}
const graph = new StateGraph(State)
.addNode("reasoner", reasoner)
.addEdge(START, "reasoner")
.addEdge("reasoner", END)
.compile();Логика та же самая: типизированное состояние, узлы как функции, рёбра как переходы. Разница в основном в синтаксисе Annotation вместо TypedDict и в том, что у Python версии заметно больше готовых примеров и community-интеграций под редкие сценарии.

Три ошибки повторяются почти в каждом первом проекте: забытый API-ключ, граф с избыточным числом узлов и отсутствие ограничения на циклы. Все три решаются на этапе проектирования, а не отладки.
| Ошибка | Почему возникает | Как избежать |
|---|---|---|
| Забытый ключ API | Переменная окружения задана не в том терминале или сессии | Проверять echo $KEY_NAME прямо перед запуском |
| Слишком много узлов | Разработчик создаёт узел под каждый вызов инструмента отдельно | Использовать один reasoner и prebuilt ToolNode вместо ручного дробления |
| Бесконечный цикл | Условное ребро не проверяет число итераций | Добавить счётчик в состояние и лимит попыток в условии |
| Инструмент "невидим" для модели | Инструмент объявлен, но не передан через bind_tools | Всегда явно вызывать llm.bind_tools(tools) |
Нужно ли знать LangChain, чтобы начать с LangGraph?
Нет, но понимание того, как модель вызывает инструменты, ускорит старт. LangGraph работает поверх LangChain как отдельный слой оркестрации, глубоко в LangChain погружаться необязательно.
Чем StateGraph отличается от обычной цепочки?
Цепочка идёт строго вперёд. StateGraph умеет циклы, ветвление по условию и паузу на человеке, это нужно там, где агент сам решает, вызывать инструмент ещё раз или закончить.
Можно ли использовать LangGraph без OpenAI?
Да, привязки к одному провайдеру нет. Работает с Anthropic, Google, DeepSeek и локальными моделями через соответствующие интеграции LangChain.
Почему граф зацикливается бесконечно?
Чаще всего из-за отсутствия лимита итераций. Добавьте счётчик в состояние и проверяйте его в условном ребре.
Стоит ли сразу ставить Postgres для checkpointer?
Для обучения и прототипа хватает MemorySaver. Postgres нужен, когда состояние должно переживать перезапуск сервера или когда несколько инстансов работают с одним графом параллельно.
Есть ли разница между LangGraph и LangGraph.js по возможностям?
По ключевым фичам паритет достигнут. Разница в основном в объёме готовых примеров, у Python-версии их накопилось больше за счёт более раннего старта.
Что делать, если агент не видит инструменты?
Проверьте вызов bind_tools с передачей списка инструментов. Без явного bind_tools модель не узнает о существовании функций, даже если они объявлены рядом в коде.
Обновлено: август 2026. Разбирали свежую версию LangGraph и текущий синтаксис StateGraph. Если пишете агента на связке с Claude Code, паттерн reasoner + tools node переносится туда почти без изменений.
Источники: официальная документация LangGraph, репозиторий LangGraph.js.
Полный каталог AI-инструментов и IDE для вайбкодинга — на странице каталога VibeCoderz. Если застряли на конкретном шаге или собираете что-то сложнее демо-агента, можно записаться на консультацию к Максиму.