ЧТО ТАКОЕ AI-АГЕНТ НА САМОМ ДЕЛЕ
Отбросим маркетинг. AI-агент — это языковая модель, которой дали право вызывать функции и действовать в цикле, пока задача не решена. Всё. Чат-бот отвечает один раз. Агент отвечает, вызывает инструмент, смотрит на результат, решает что делать дальше — и повторяет.
Три обязательных компонента любого агента:
- Модель (LLM) — «мозг», принимает решения. GPT-класса, Claude, локальные Qwen/Llama — неважно, важна поддержка function calling.
- Инструменты (tools) — функции, которые агент может дёргать: поиск, калькулятор, HTTP-запрос, запись в БД, выполнение кода.
- Цикл управления (loop) — код, который гоняет модель и инструменты по кругу, хранит историю и решает, когда остановиться.
Ключевое слово 2026 года — tool calling (он же function calling). Модель не выполняет код сама. Она возвращает JSON вида «хочу вызвать функцию get_weather с аргументом city=Berlin», а ваш код это исполняет и возвращает результат обратно. Разберётесь с этим механизмом — поймёте 80% всех агентных фреймворков.
МИНИМАЛЬНЫЙ АГЕНТ БЕЗ ФРЕЙМВОРКОВ
Прежде чем тянуть LangGraph, соберите агента голыми руками. Это дисциплинирует: вы увидите, что фреймворк — просто удобная обёртка над этим циклом. Вот рабочий пример на Python с одним инструментом.
import json
from openai import OpenAI
client = OpenAI()
def get_weather(city: str) -> str:
# заглушка вместо реального API
return f"В городе {city} сейчас +7 и облачно"
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Вернуть текущую погоду в городе",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
},
}]
def run_agent(user_msg: str) -> str:
messages = [{"role": "user", "content": user_msg}]
while True:
resp = client.chat.completions.create(
model="gpt-4.1-mini",
messages=messages,
tools=tools,
)
msg = resp.choices[0].message
messages.append(msg)
if not msg.tool_calls:
return msg.content # модель закончила — выходим
for call in msg.tool_calls:
args = json.loads(call.function.arguments)
result = get_weather(**args)
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": result,
})
print(run_agent("Что надеть в Берлине сегодня?"))
Вот и весь агент. Цикл while True — это и есть «агентность». Модель либо вызывает инструмент (и мы возвращаем ей результат), либо отвечает финальным текстом (и мы выходим). Всё остальное — надстройки над этим паттерном.
ЗАЧЕМ ВООБЩЕ ФРЕЙМВОРКИ
Голый цикл ломается на реальных задачах. Как только вам нужны ветвления, повторные попытки, человек-в-цикле, параллельные инструменты, персистентная память между сессиями и наблюдаемость — вы начинаете переписывать половину фреймворка сами. Проще взять готовый.
Что дают фреймворки поверх ручного цикла:
- Управление состоянием — история, промежуточные результаты, контекст не разъезжаются.
- Контроль потока — условные переходы, циклы с лимитом, откаты.
- Персистентность — сохранение состояния в БД, чтобы агент пережил рестарт.
- Наблюдаемость — трейсинг каждого шага, что критично для дебага.
СРАВНЕНИЕ ФРЕЙМВОРКОВ 2026
Рынок устоялся. Есть три доминирующих подхода: графовый (LangGraph), декларативно-простой (мультиагентные SDK) и «магия под капотом». Ниже честное сравнение по практике, без вендорских лозунгов.
| Фреймворк | Модель управления | Кривая входа | Когда брать |
|---|---|---|---|
| LangGraph | Явный граф состояний (узлы + рёбра) | Средняя | Продакшн, сложная логика, нужен контроль |
| OpenAI Agents SDK | Хендоффы между агентами | Низкая | Быстрый старт, мультиагентные сценарии |
| CrewAI | Роли + задачи (команда агентов) | Низкая | Прототипы, «команда специалистов» |
| Голый Python + API | Ручной цикл | Высокая (сам всё пишешь) | Обучение, максимальный контроль, минимум зависимостей |
Мой практический вывод за 2026 год: LangGraph выиграл нишу серьёзного продакшена, потому что делает состояние и переходы явными — вы видите граф, а не гадаете, что происходит внутри «умной» абстракции. Для быстрого прототипа берите SDK попроще. Свежие релизы агентных инструментов и обёрток удобно отслеживать в каталоге REDDYX — там видно, что реально взлетает, а что хайп на неделю.
СОБИРАЕМ АГЕНТА НА LANGGRAPH
LangGraph моделирует агента как граф: узлы — это шаги (вызов модели, вызов инструментов), рёбра — переходы между ними. Тот же цикл, что мы писали руками, но декларативно и с персистентностью из коробки.
Базовый граф с одним инструментом
from langgraph.graph import StateGraph, END, MessagesState
from langgraph.prebuilt import ToolNode
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
@tool
def search_docs(query: str) -> str:
"""Найти информацию в базе знаний по запросу."""
return f"Найдено 3 документа по теме '{query}'"
llm = ChatOpenAI(model="gpt-4.1-mini").bind_tools([search_docs])
def call_model(state: MessagesState):
return {"messages": [llm.invoke(state["messages"])]}
def should_continue(state: MessagesState):
last = state["messages"][-1]
return "tools" if last.tool_calls else END
graph = StateGraph(MessagesState)
graph.add_node("agent", call_model)
graph.add_node("tools", ToolNode([search_docs]))
graph.set_entry_point("agent")
graph.add_conditional_edges("agent", should_continue)
graph.add_edge("tools", "agent") # после инструмента — снова к модели
app = graph.compile()
out = app.invoke({"messages": [("user", "Как настроить вебхуки?")]})
print(out["messages"][-1].content)
Обратите внимание на should_continue — это и есть условие выхода из цикла, вынесенное в отдельный узел. Ребро tools → agent замыкает петлю. Вы буквально видите архитектуру глазами, а не в голове.
Добавляем память между сессиями
Чтобы агент помнил разговор после рестарта, подключите чекпоинтер. Одна строка превращает stateless-агента в stateful:
from langgraph.checkpoint.memory import MemorySaver
# для продакшена: from langgraph.checkpoint.postgres import PostgresSaver
app = graph.compile(checkpointer=MemorySaver())
config = {"configurable": {"thread_id": "user-42"}}
app.invoke({"messages": [("user", "Меня зовут Влад")]}, config)
r = app.invoke({"messages": [("user", "Как меня зовут?")]}, config)
print(r["messages"][-1].content) # агент помнит: "Влад"
В проде замените MemorySaver на PostgresSaver — состояние ляжет в базу, и агент переживёт деплой. thread_id изолирует диалоги разных пользователей.
ЧТО ЛОМАЕТ АГЕНТОВ В ПРОДАКШЕНЕ
Демка на ноутбуке и агент на проде — две разные вселенные. По опыту сообщества и собственным набитым шишкам, вот главные грабли:
- Бесконечные циклы. Модель зацикливается на вызове инструмента. Всегда ставьте жёсткий лимит итераций (например,
recursion_limitв LangGraph). Без него агент сожжёт бюджет за минуты. - Раздувание контекста. История растёт, токены растут, стоимость растёт квадратично. Обрезайте старые сообщения или суммируйте их.
- Галлюцинации в аргументах. Модель выдумывает несуществующие параметры инструмента. Валидируйте вход через Pydantic до исполнения.
- Молчаливые падения инструментов. API упал — верните агенту текст ошибки, а не исключение. Он часто умеет пробовать другой путь.
- Отсутствие трейсинга. Без пошагового лога вы не поймёте, почему агент принял тупое решение. Ставьте наблюдаемость с первого дня.
По грубым замерам сообщества, наивный агент без контроля циклов и обрезки контекста легко тратит в 3–5 раз больше токенов, чем нужно. Дисциплина в управлении состоянием — это прямая экономия денег.
ПРОЕКТИРОВАНИЕ ИНСТРУМЕНТОВ — ГДЕ РЕШАЕТСЯ УСПЕХ
Секрет, о котором молчат туториалы: качество агента на 70% зависит не от модели, а от дизайна инструментов. Модель настолько же умна, насколько понятны ей описания функций.
- Описания пишите для модели, не для людей. Чёткое «Вернуть баланс счёта в USD по ID пользователя» бьёт сухое «get_balance».
- Один инструмент — одно действие. Не делайте «швейцарский нож» с десятью режимами. Модель путается.
- Возвращайте структурированный результат. JSON или чёткий текст, не сырой дамп на 5000 токенов.
- Делайте инструменты идемпотентными, где возможно. Агент может вызвать функцию дважды — это не должно ломать данные.
Практика: начните с 2–3 инструментов. Агент с пятью хорошо описанными функциями надёжнее, чем со тридцатью размытыми. Расширяйте, только когда узкое место реально в нехватке возможностей, а не в кривых описаниях.
Частые вопросы
Нужно ли знать LangChain, чтобы работать с LangGraph?
Нет, глубоко не нужно. LangGraph — самостоятельная библиотека для графов состояний. Достаточно понимать базовые объекты сообщений и как связываются инструменты. Начать можно прямо с примера графа выше, не изучая весь LangChain.
Какой язык лучше для AI-агента — Python или JavaScript?
Python — стандарт де-факто в 2026 году: максимум библиотек, примеров и поддержки фреймворков. JavaScript/TypeScript оправдан, если агент живёт внутри веб-приложения или вам критична единая кодовая база фронта и бэка. Для обучения и ML-задач берите Python.
Сколько стоит гонять AI-агента?
Зависит от модели и числа шагов. Мелкие модели уровня mini стоят копейки за запрос, но агент делает много вызовов в цикле, поэтому итоговая цена набегает. Главные рычаги экономии — лимит итераций, обрезка контекста и выбор дешёвой модели там, где не нужна максимальная точность.
Можно ли собрать агента на локальной модели без облака?
Да. Локальные модели с поддержкой tool calling (Qwen, Llama-класса) через Ollama или vLLM работают с теми же паттернами. Function calling у локальных моделей слабее облачных, поэтому упрощайте инструменты и тщательнее валидируйте их аргументы.
Если хотите видеть, какие агентные фреймворки, MCP-серверы и AI-тулзы реально выстреливают, а не тонут в хайпе — я публикую свежие находки с GitHub без воды. Telegram-канал REDDYX AI — новые репозитории каждые 30-60 минут.