Головна / Статті

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 — це середовище виконання графів, у якому вузли є звичайними функціями, а ребра визначають переходи. OpenAI Agents SDK орієнтований на передачу завдань, де агент передає роботу іншому через типовані сеанси, з нативною підтримкою MCP. Claude Agent SDK є несподіваним: він надає агенту комп’ютер, оскільки 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 контролює процес оркестрації.

    Завдання третє: робота з файлами та оболонкою

    Агент для міграції з команди з розробки досвіду користувача має пройтися по репозиторію на Java з 400 000 рядків коду, внести зміни до синтаксису, запустити тести на одиниці та створити запити на з’єднання коду. Це означає читання та редагування файлів, виконання команд оболонки та реагування на помилки компілятора. 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 виконується перед використанням інструменту, а рішення про відмову негайно зупиняє виклик. Підагент 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, а також способи вирішення питання про те, хто має керувати робочим процесом.