Logo Craft Homelab Docs Контакты Telegram
LangGraph: агенты с состоянием — Graphs, nodes
Mon Jan 05 2026

LangGraph: агенты с состоянием

Разработка надежных AI-агентов часто сводится к управлению состоянием. Традиционные подходы, опирающиеся на простые переменные или сессии, быстро накапливают сложность и становятся не масштабируемыми для задач, требующих запоминания долгосрочной информации и контекста. LangGraph предлагает решение – Graph-based framework для представления состояния агента как графа, где узлы (nodes) представляют собой элементы состояния, а ребра (edges) – связи между ними. Это позволяет создавать более выразительные, гибкие и масштабируемые агенты. В этой статье мы погрузимся в LangGraph, рассмотрим его архитектуру, пример использования и обсудим потенциальные узкие места.

Переплетение сущностей: Внутри LangGraph

LangGraph использует Graph Neural Networks (GNNs) для управления состоянием агента. Вместо отдельных переменных, состояние представляется в виде графа. Каждый node в графе представляет собой сущность (например, переменную, факт, предыдущее действие), а edge – связь между ними. Эта связь позволяет агенту не просто хранить информацию, но и делать выводы на основе взаимосвязей между различными частями состояния.

Как это работает?

  1. Nodes: Представляют собой сущности, которые могут быть как простыми (числа, строки), так и сложными (объекты, результат работы других компонентов). Каждый узел имеет свойство graph_id, которое идентифицирует его в графе.
  2. Edges: Определяют связи между узлами. Они могут иметь метки, описывающие тип связи (например, “cause”, “effect”, “depends_on”).
  3. Graph Neural Network (GNN): GNN обрабатывает граф, распространяя информацию между узлами через ребра. Это позволяет учитывать контекст и зависимости при принятии решений. В LangGraph используются упрощенные GNN для эффективной обработки графов состояния в реальном времени.
  4. Persistence: LangGraph предоставляет встроенные механизмы для сохранения и загрузки графа состояния, что делает агентов stateful.

Пример:

Представим себе агента, которому нужно спланировать путешествие. Состояние агента может представлять собой граф с узлами, такими как:

  • destination: Место назначения (например, “Париж”).
  • budget: Бюджет поездки (например, 2000$).
  • flights: Информация о доступных рейсах.
  • hotels: Информация о доступных отелях.

Ребра могут представлять связи, такие как:

  • destination —(depends_on)—> flights (Поиск рейсов зависит от места назначения)
  • budget —(constraint)—> flights (Рейсы должны соответствовать бюджету)

Использование GNN позволяет агенту эффективно обновлять состояние, добавляя новую информацию и корректируя существующие связи.

from langgraph.core import Graph, Node, Edge
import uuid

# Создаем граф
graph = Graph()

# Создаем узлы
destination_node = Node(graph_id=str(uuid.uuid4()), label="destination", value="Paris")
budget_node = Node(graph_id=str(uuid.uuid4()), label="budget", value=2000)
flights_node = Node(graph_id=str(uuid.uuid4()), label="flights", value="[]") #пустой список на старте
hotels_node = Node(graph_id=str(uuid.uuid4()), label="hotels", value="[]")
graph.add_node(destination_node)
graph.add_node(budget_node)
graph.add_node(flights_node)
graph.add_node(hotels_node)

# Создаем ребра
destination_to_flights = Edge(graph_id=str(uuid.uuid4()), source=destination_node.graph_id, target=flights_node.graph_id, label="depends_on")
destination_to_budget = Edge(graph_id=str(uuid.uuid4()), source=destination_node.graph_id, target=budget_node.graph_id, label="depends_on")
flights_to_budget_cost = Edge(graph_id=str(uuid.uuid4()), source=flights_node.graph_id, target=budget_node.graph_id, label="cost")

graph.add_edge(destination_to_flights)
graph.add_edge(destination_to_budget)
graph.add_edge(flights_to_budget_cost)

# Печатаем граф (упрощенная версия для демонстрации)
print(f"Nodes: {graph.nodes}")
print(f"Edges: {graph.edges}")

Узкие места: Что нужно учитывать в продакшене?

  • Размер графа: Чем больше граф, тем выше вычислительные затраты на обработку. Используйте стратегии графовой оптимизации, такие как pruning (удаление неактуальных узлов/ребер) и aggregation (объединение близких узлов).
  • Сложность GNN: Упрощенные GNN, используемые в LangGraph, жертвуют некоторой выразительностью ради производительности. Если требуется более точная обработка, может потребоваться использование более сложных GNN, но это увеличит вычислительные затраты.
  • Persistence overhead: Сохранение и загрузка графа может быть затратной операцией, особенно при больших графах. Оптимизируйте формат хранения (например, сериализация в бинарный формат) и используйте кэширование.
  • Проблемы с памятью: Графы могут потреблять значительный объем памяти, особенно если узлы содержат большие объемы данных. Внимательно следите за использованием памяти и используйте эффективные структуры данных.
  • Scalability: Horizontal scaling LangGraph может потребовать архитектурных изменений в компонентах, которые взаимодействуют с графом. Нужно планировать это заранее.

Verdict: Когда использовать LangGraph?

LangGraph – отличный выбор для:

  • Stateful AI-агентов: Когда агенту необходимо запоминать контекст и учитывать историю действий.
  • Задач, требующих долгосрочного планирования: Например, планирование маршрутов, управление ресурсами, решение сложных задач.
  • Систем, требующих гибкости и расширяемости: Благодаря графовой структуре, LangGraph легко адаптируется к новым задачам и требованиям.

LangGraph не является оптимальным решением для:

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