Главная / Статьи

LangGraph, OpenAI Agents SDK или Claude Agent SDK: соотнесите примитивы с типами работ.

Четыре примера рабочих нагрузок — голосовые функции, надежные процедуры возврата средств, миграция кода и операции MCP — показывают, какой фреймворк агентов подходит в том или ином случае, с комментариями по вопросам привязки к конкретной платформе, надежности и реального времени.

Издатель: REACTAPP.TOP11 мин чтения2534 слов

Источники: The Best Agent Framework in 2026: LangGraph vs OpenAI Agents SDK vs Claude Agent SDK

В сравнениях на 2026 год постоянно фигурируют три фреймворка агентов, каждый из которых основан на разной основной идее. LangGraph — это среда выполнения графов, в которой узлы представляют собой обычные функции, а рёбра определяют переходы между ними. SDK OpenAI Agents сосредоточен на передаче задач, при которой агент передаёт работу другому агенту через типизированные сессии с нативной поддержкой MCP. SDK Claude Agent — это неожиданный вариант: он предоставляет агенту компьютер, поскольку компания Anthropic построила его на выполнении команд в bash, записи файлах и хуках, будучи уверенной, что способный агент нуждается в настоящей оболочке.

Правильный выбор зависит от того, о чём редко спрашивают при сравнении архитектур: какую работу выполняет агент?

Три примитива

LangGraph предназначен для рабочих процессов с состоянием. Определяется схема состояния, и один типизированный объект перемещается по графу от первого узла к последнему. Поскольку механизмы сохранения состояния сохраняют его на каждом узле, выполнение может возобновиться после сбоя или ожидания одобрения человека с полностью сохраненным контекстом. Функция create_agent, появившаяся в LangChain 1.0, ставшей общедоступной 22 октября 2025 года, является лишь фасадом над этим движком выполнения, что положило конец дискуссиям о том, использовать LangChain или LangGraph.

SDK OpenAI Agents включает девять основных компонентов: Agents, Handoffs, Tools, Guardrails, Sessions и Realtime. Его атомарной единицей является агент, передающий задачу другому агенту. Независимость от поставщиков появилась в 2025 году благодаря поддержке более чем 100 моделей через LiteLLM. MCP считается инструментом первого класса, а голосовое взаимодействие встроено в семейство моделей gpt-realtime-2.

SDK Claude Agent основан на среде оболочки. Его набор инструментов включает Bash, Read, Write, Edit, Glob и Grep, а также хуки жизненного цикла с именами PreToolUse, PostToolUse и Stop; кроме того, существуют подагенты, работающие в отдельных изолированных окнах контекста. В конце 2025 года компания Anthropic изменила название с Claude Code SDK, поскольку этот инструментарий используется не только для программирования, но и для глубоких исследований, создания видео и ведения заметок. Разрешены только модели Claude, хотя их можно размещать на платформах Bedrock, Vertex и Azure Foundry.

Мнение, устаревшее к 2025 году

Распространённое в прошлом году мнение гласило, что SDK OpenAI Agents обязывает к использованию моделей OpenAI. Это утверждение устарело примерно на пятнадцать месяцев. Официальный репозиторий поддерживает API OpenAI Responses, а также примерно 100 других моделей благодаря интеграциям LiteLLM и Any-LLM.

# Install: pip install "openai-agents[litellm]"
# Env: export GEMINI_API_KEY=...
import os
from agents import Agent, Runner, function_tool
from agents.extensions.models.litellm_model import LitellmModel

@function_tool
def current_time_utc() -> str:
    """Return the current UTC time as an ISO-8601 string."""
    from datetime import datetime, timezone
    return datetime.now(timezone.utc).isoformat(timespec="seconds")

# OpenAI Agents SDK using Gemini via LiteLLM. No OpenAI key required.
gemini_model = LitellmModel(
    model="gemini/gemini-2.5-pro",
    api_key=os.environ["GEMINI_API_KEY"],
)

agent = Agent(
    name="time-agent",
    instructions="Answer time questions using the current_time_utc tool.",
    model=gemini_model,
    tools=[current_time_utc],
)

result = Runner.run_sync(agent, "What is the current UTC time?")
print(result.final_output)
# -> "The current UTC time is 2026-07-06T14:32:11+00:00."

Создание модели LitellmModel с использованием названия модели Gemini демонстрирует возможность использования этой платформы вне экосистемы OpenAI; декоратор @function_tool ведет себя одинаково независимо от того, какая модель используется в основе. Пути, не связанные с OpenAI, описываются как реализуемые с максимальными усилиями, причем уровень совместимости функций варьируется в зависимости от поставщика. Поскольку строгие ограничения на количество моделей исключены, платформы соревнуются между собой по своим архитектурным основам.

Тестовая компания с четырьмя агентами

Возьмем среднюю по размеру финтех-компанию под названием Meridian, у которой в разных командах разрабатываются четыре агента.

  • Агент голосовой поддержки, который отвечает на вопросы, связанные с оплатой, по телефону.
  • Многоагентная система возврата средств, которая проверяет правила борьбы с мошенничеством перед передачей заявки в финансовый отдел.
  • Внутренний агент для миграции кода, который анализирует большой репозиторий на Java, применяет синтаксические преобразования и создает запросы на слияние кода.
  • Панель управления операциями, которая запрашивает данные из Sentry, Linear, PagerDuty и Postgres через серверы MCP.
  • Ниже приведены четыре варианта реализации с указанием того, какой фреймворк подходит для каждого случая.

    Задача номер один: голосовой и реальнозначительный стриминг

    Команда, занимающаяся обработкой голосовых данных, работает в рамках строгих ограничений по задержке — менее 500 мс для стриминга, — при этом необходимо обеспечивать возможность вмешательства пользователя. Процесс преобразования речи в текст, последующая обработка текста моделью и затем преобразование текста обратно в речь слишком медленный, поскольку каждый сетевой прыжок увеличивает задержку.

    Для этой задачи подходит SDK OpenAI Agents. Модель gpt-realtime-2 нативно обрабатывает аудиотокены, а RealtimeAgent обеспечивает интеграцию этой функциональности. Ни LangGraph, ни Claude Agent SDK в середине 2026 года не предлагали нативных инструментов для реальнозначительной обработки на таком уровне.

    # Install: pip install openai-agents
    # Env: export OPENAI_API_KEY=...
    import asyncio
    from agents import function_tool
    from agents.realtime import RealtimeAgent, RealtimeRunner
    
    @function_tool
    def lookup_billing_balance(account_id: str) -> str:
        """Return the current outstanding balance for an account."""
        # In production, this hits the billing service. Here it is a stub.
        return "42.17 USD outstanding as of 2026-07-06."
    
    voice_agent = RealtimeAgent(
        name="meridian-billing-voice",
        instructions=(
            "You are Meridian's billing voice assistant. Answer politely, briefly. "
            "Confirm the account_id before disclosing any balance."
        ),
        tools=[lookup_billing_balance],
    )
    
    async def main():
        runner = RealtimeRunner(
            starting_agent=voice_agent,
            config={"model_settings": {"model_name": "gpt-realtime-2.1"}},
        )
    
        # session handles the audio stream and tool calls
        session = await runner.run()
    
        async with session:
            # Wire the audio input source here via sounddevice or pyaudio
            async for event in session:
                if event.type == "history_updated":
                    # The item contains the finalized transcript once the turn ends
                    print(f"History updated with item: {event.item}")
                elif event.type == "error":
                    print(f"Error: {event.error}")
                    break
    
    asyncio.run(main())
    

    RealtimeAgent и RealtimeSession обрабатывают входящие и исходящие аудиопотоки, а также цикл вызовов инструментов; инструменты, объявленные с помощью @function_tool, выполняются в реальном времени в рамках сессии так же, как и в текстовом агенте. Фреймворк отображает цикл событий, в то время как состояние WebSocket остается невидимым.

    Если пытаться реализовать это в LangGraph или Claude Agent SDK, потребуется написать собственный код для WebSocket, реализовать обнаружение активности голоса и учитывать сложную семантику прерываний, что превращает проект агента в проект медиапайплайна. Если политика компании требует использования моделей голоса Claude или Gemini, ситуация меняется. Anthropic позже добавил поддержку реального времени, поэтому тем, кто читает этот текст после середины 2026 года, следует проверить совместимость функций.

    Задача два: надежная оркестрация с утверждением человека

    Процесс возврата средств требует проверки на мошенничество, последующей передачи заявки на финансовое одобрение, ожидания ручной проверки для возвратов свыше 500 долларов и окончательного решения, записываемого обратно в Postgres. Он должен функционировать при сбоях сервера и обрабатывать асинхронные задержки в ручной обработке без потери контекста.

    LangGraph идеально подходит. Пункты контроля в сочетании с примитивом прерывания обеспечивают именно тот контрольный поток, который необходим длительно выполняющимся бизнес-процессам. Команды, работающие в промышленных условиях, поддерживают эту архитектуру: Uber сообщает о сокращении времени работы разработчиков примерно на 21 000 часов благодаря использованию LangGraph в системах AutoCover и Validator, а LinkedIn опубликовала статью о иерархической семантической памяти для своего инструмента Hiring Assistant; детали конструкции его надзорных механизмов и подагентов рассматриваются отдельно в технических докладах LangChain.

    from typing import TypedDict, Literal
    from langgraph.graph import StateGraph, START, END
    from langgraph.checkpoint.memory import MemorySaver
    from langgraph.types import interrupt, Command
    from langchain_google_genai import ChatGoogleGenerativeAI
    
    # LangGraph is provider-agnostic. Here it uses Gemini.
    llm = ChatGoogleGenerativeAI(model="gemini-2.5-pro", temperature=0)
    
    class RefundState(TypedDict):
        order_id: str
        amount_usd: float
        customer_reason: str
        fraud_risk: Literal["low", "medium", "high"] | None
        finance_decision: Literal["approved", "denied"] | None
        human_review_needed: bool
    
    def fraud_check(state: RefundState) -> RefundState:
        """Run the LLM-backed fraud check against the customer's stated reason."""
        prompt = (
            f"Assess fraud risk for refund of ${state['amount_usd']:.2f}. "
            f"Customer reason: {state['customer_reason']!r}. "
            "Respond with one word: low, medium, or high."
        )
        verdict = llm.invoke(prompt).content.strip().lower()
        if verdict not in {"low", "medium", "high"}:
            verdict = "high"  # fail-closed on ambiguous LLM output
        return {**state, "fraud_risk": verdict}
    
    def finance_approval(state: RefundState) -> RefundState:
        """Above $500 or medium risk, pause for a human. Otherwise auto-approve."""
        needs_human = state["amount_usd"] > 500 or state["fraud_risk"] in {"medium", "high"}
        if needs_human:
            # Pause the graph. On resume, interrupt returns the human's decision.
            human_decision = interrupt({
                "order_id": state["order_id"],
                "amount_usd": state["amount_usd"],
                "fraud_risk": state["fraud_risk"],
                "prompt": "Approve (yes/no)?",
            })
            return {**state, "human_review_needed": True, "finance_decision": human_decision}
        return {**state, "human_review_needed": False, "finance_decision": "approved"}
    
    # Build the graph
    graph = StateGraph(RefundState)
    graph.add_node("fraud_check", fraud_check)
    graph.add_node("finance_approval", finance_approval)
    graph.add_edge(START, "fraud_check")
    graph.add_conditional_edges(
        "fraud_check",
        lambda s: "finance_approval" if s["fraud_risk"] != "high" else END,
    )
    graph.add_edge("finance_approval", END)
    
    # Checkpointer. For production, swap MemorySaver for PostgresSaver.
    compiled = graph.compile(checkpointer=MemorySaver())
    
    # Run it. Interrupt fires on the $850 refund and the graph pauses.
    config = {"configurable": {"thread_id": "order-4291"}}
    result = compiled.invoke(
        {
            "order_id": "4291",
            "amount_usd": 850.00,
            "customer_reason": "arrived damaged, no photo",
            "fraud_risk": None,
            "finance_decision": None,
            "human_review_needed": False,
        },
        config=config,
    )
    
    # Later, a human reviewer says yes. Resume with Command.
    final = compiled.invoke(Command(resume="approved"), config=config)
    

    Паттерн паузы и возобновления обеспечивает надежную работу кода. Вызов функции interrupt() внутри узла одобрения финансовых операций записывает текущее состояние в checkpointer, после чего система может быть выключена. Через несколько часов команда с параметром resume, установленным в значение approved, продолжает работу с того же места, где была остановлена, под тем же идентификатором потока, без повторной проверки на мошенничество.

    Существует одно ограничение, связанное с надежностью. Система с открытым исходным кодом сохраняет состояние в MemorySaver, который находится в оперативной памяти процесса. Для реального восстановления после сбоя при высокой нагрузке требуется LangGraph Platform с поддержкой Postgres или пользовательский модуль PostgresSaver.

    SDK OpenAI Agents предоставляет механизмы Sessions для сохранения состояния разговора и Sandbox Agents для работы с долгосрочными задачами, но не имеет аналогов для сохранения состояния на уровне узлов в произвольной структуре графа. SDK Claude Agent хранит состояние сессий в формате JSONL локально или использует Managed Agents для обеспечения долговечности хранения, при этом возникает необходимость использования моделей, доступных только в рамках Claude. На данный момент функции надежной оркестрации задач находятся в распоряжении LangGraph.

    Задача номер три: работа с файлами и оболочкой

    Агент для миграции от команды по разработке пользовательского интерфейса должен просмотреть репозиторий на 400 000 строк на языке Java, внести изменения в синтаксис, запустить тесты на единицы и создать запросы на слияние кода. Это подразумевает чтение и редактирование файлов, выполнение команд оболочки и реагирование на ошибки компилятора. Bash и Edit составляют практически всю объем работу.

    SDK Claude Agent напрямую соответствует этой модели, поскольку основная идея Anthropic заключается в предоставлении агентам компьютера. В нём имеются встроенные инструменты для Bash, Read, Write, Edit, Glob и Grep, а хуки служат средством управления. Хук PreToolUse позволяет ввести ограничения против разрушительных команд, а хук PostToolUse может запускать форматтеры или инструменты проверки кода. Подагенты распределяют работу по преобразованию между изолированными контекстами, так что длинный журнал ошибок компилятора, переданный подагенту, не загрязняет окно основного агента.

    # Install: pip install claude-agent-sdk
    # Env: export ANTHROPIC_API_KEY=...
    import anyio
    from claude_agent_sdk import (
        ClaudeSDKClient,
        ClaudeAgentOptions,
        AgentDefinition,
        HookMatcher,
    )
    
    # PreToolUse hook: block Bash calls that look like rm -rf
    async def block_dangerous_bash(input_data, tool_use_id, context):
        if input_data.get("tool_name") == "Bash":
            cmd = input_data.get("tool_input", {}).get("command", "")
            if "rm -rf" in cmd or "rm  -rf" in cmd:
                return {
                    "hookSpecificOutput": {
                        "hookEventName": "PreToolUse",
                        "permissionDecision": "deny",
                        "permissionDecisionReason": "rm -rf blocked by policy",
                    }
                }
        return {}
    
    # Subagent: runs in isolated context to lint one file
    lint_agent = AgentDefinition(
        description="Run linters on a single file and return a concise report.",
        prompt=(
            "You are the lint subagent. Given a file path, run the project's linter "
            "on it and return a one-paragraph summary of failures. Do not fix anything."
        ),
        tools=["Bash", "Read"], # Note: tools is deprecated in favor of skills in recent SDKs
    )
    
    options = ClaudeAgentOptions(
        system_prompt=(
            "You are Meridian's code migration agent. Walk the target directory, "
            "apply the migration, run tests, and open a PR. Prefer small commits."
        ),
        allowed_tools=["Bash", "Read", "Write", "Edit", "Glob", "Grep"],
        hooks={"PreToolUse": [HookMatcher(hooks=[block_dangerous_bash])]},
        agents={"lint": lint_agent},
        # resume="mig-run-2026-07-06-01",  # uncomment to resume a prior session
    )
    
    async def main():
        async with ClaudeSDKClient(options=options) as client:
            await client.query(
                "Migrate services/payments/ from Java 17 to Java 21. "
                "For every file you touch, delegate to the `lint` subagent afterward. "
                "Do NOT commit or open PRs yet. Stop after changes are on disk."
            )
            async for message in client.receive_response():
                print(message)
    
    anyio.run(main)
    

    Список allowed_tools определяет среду агента. Хуки служат своего рода ограничительным механизмом, расположенным внутри цикла агента, а не вокруг него: хук PreToolUse выполняется перед использованием инструмента, а решение deny немедленно прерывает его вызов. Подагент lint имеет собственные инструменты и окно контекста. В новых версиях SDK поле tools в объекте AgentDefinition постепенно заменяется на поле skills, хотя старый формат по-прежнему работает. Приведенная ниже строка с комментарием иллюстрирует восстановление состояния сессии из файлов JSONL на локальном диске.

    В LangGraph эти примитивы оболочки придётся реализовывать в виде пользовательских функций на Python. Агенты Sandbox SDK от OpenAI работают в контейнерах, что по архитектуре схоже, но набор примитивов не называется и не предоставляется в том же файлоцентричном формате. Проблема заключается в «закрытости» моделей: команда, строго следующая правилу избегания такой закрытости на уровне моделей, не может использовать SDK Claude Agent и вынуждена обращаться к LangGraph, самостоятельно разрабатывая примитивы для bash и редактирования.

    Задача четвёртая: оркестрация с акцентом на MCP

    Панель управления команды платформы отвечает на один вопрос, введённый инженером. За её спиной агент собирает ошибки из Sentry, заявки из Linear, инциденты из PagerDuty и данные пользователей из Postgres. Почти весь его ресурс тратится на координацию серверов MCP от сторонних поставщиков, а на формирование ответа — совсем немного.

    Здесь SDK OpenAI Agents и SDK Claude Agent находятся на одном уровне. В обоих случаях MCP является основным строительным блоком, а серверы ведут себя как локальные функции. LangGraph также может использовать MCP, но в середине 2026 года это требует большего количества шаблонного кода, и команды обычно сами оборачивают серверы в инструменты. Решающим фактором между этими двумя лидерами является второстепенное ограничение.

    • Выбирайте SDK OpenAI Agents для первичного отслеживания, строгих ограничений и передачи задач специализированным подагентам, или когда привлекательно направлять простые задачи синтеза к более дешевым поставщикам через LiteLLM.
    • Выбирайте SDK Claude Agent для управления жизненным циклом интеграций, строгой изоляции подагентов и надежности использования инструментов от Claude.

    Специальные обертки API для распространённых инструментов SaaS отнимают время инженеров. Стандарт MCP унифицирует контекст и процесс поиска инструментов, поэтому фреймворку достаточно просто не мешать, причём оба SDK поддерживают этот подход из коробки.

    Краткое резюме по типам задач

    • Реальное время общения с возможностью вмешательства: OpenAI Agents SDK.
    • Многокомпонентные процессы с участием нескольких агентов и проверкой человеком: LangGraph.
    • Работа с файлами, оболочкой и миграцией кода: Claude Agent SDK.
    • Сложная оркестрация с использованием MCP: OpenAI Agents SDK или Claude Agent SDK.

    Примечание о CrewAI

    Многие читатели ожидают упоминания CrewAI в подобном сравнении. Однако при проверке стало ясно, что данные о текущей версии, использовании Flows и примерах применения в корпорациях не были настолько надёжными, как у остальных трёх решений, поэтому от него решили воздержаться, вместо того чтобы дополнять текст менее достоверными источниками.

    Настоящий выбор

    Четыре агента оказались в трех фреймворках: агенты для обработки голоса и платформы — в OpenAI SDK, агент для обработки возвратов средств — в LangGraph, а агент для миграции — в Claude Agent SDK. Споры о том, какой фреймворк лучше, — неверный подход. Задача заключается в том, чтобы привести основные примитивы фреймворка в соответствие с характером выполняемой работы.

    В следующем раунде, вероятно, снова возникнут споры относительно надежности, поскольку LangGraph Platform будет конкурировать с Managed Agents от Anthropic. LangGraph может получить примитивы реального времени первого класса, или же Anthropic может открыть свой SDK для других поставщиков моделей. До тех пор примитивы определяют архитектуру.

    Связанные материалы

  • Отслеживание агентов LangGraph в Vertex AI Agent Engine с использованием OpenTelemetry — Agent Engine по умолчанию не отслеживает агентов LangGraph. Необходимо добавить OpenTelemetry при запуске, скрыть учетные данные, обработать ключевые функции и отправлять данные в Cloud Trace.
  • LangGraph против Google ADK в 2026 году: явная оркестрация или композиция агентов — Сравнение двух способов создания агентов: управление состоянием и графом в LangGraph против композиции агентов в ADK, а также способы определения того, кто должен контролировать рабочий процесс.