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

Claude Agent SDK против OpenAI Agents SDK против Google ADK: один агент, три реализации

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

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

Источники: So Which Agent SDK Should You Build With?

Сейчас каждый крупный поставщик ИИ поставляет SDK для агентов, причем их предложения практически идентичны. Дайте нам ваши инструменты и инструкции, и мы запустим весь процесс: вызовы инструментов, структурированный вывод, ведение сессий и отслеживание. Если маркетинговые материалы настолько похожи, что же на самом деле отличает эти наборы, и на чем стоит сосредоточиться?

Чтобы выяснить это, я создал один и тот же агент три раза: с использованием Claude Agent SDK от Anthropic, SDK для агентов от OpenAI и Agent Development Kit (ADK) от Google. Этот агент — не игрушка. Это инструмент для анализа этикеток пищевых продуктов, который считывает фотографию, использует несколько инструментов для анализа, выдает вердикт и совершенствуется по мере изучения большего количества этикеток. При наличии одного агента и трех различных SDK любые различия в результатах связаны с SDK, а не с самой проблемой.

Кратко говоря: все три подхода практически полностью совпадают в том, что касается сложной части — цикла обработки данных, — но различаются во всем остальном. Они отличаются способом объявления инструмента, способом вставки изображения и наличием текстового вывода. Самое показательное — это различия в том, что ни один из них не делает за пользователя. В конце вы узнаете, какой набор подходит для какой задачи и сколько работы останется у вас после его выбора.

Ещё один механизм присутствует во всех трёх версиях. Агент был создан так, чтобы учиться на опыте. Он запоминает продукты, которые уже проверял, и названия добавок, которые смог распознать, причём сохраняет эту информацию на диске; благодаря этому при последующих запусках он в меньшей степени опирается на модель, работает быстрее и ведёт себя более предсказуемо. Веса модели никогда не меняются. Именно агент накапливает навыки. Ни один из SDK не предоставляет этой функции из коробки, поэтому он служит удобным инструментом для понимания того, где заканчивается готовое решение и начинается собственная разработка.

Во-первых, что считается агентом

Модель простого языка не является агентом. Можно рассматривать её как функцию, которая принимает текст и изображения и возвращает текст. Никакая информация не сохраняется между вызовами: она не может выполнять код или загружать страницы, а также не может снова вызвать себя. Если передать ей этикетку с информацией о питательной ценности, она расскажет, как бы провела исследование, но само исследование так и не происходит.

Агент — это модель, работающая в цикле с использованием инструментов. Паттерн её действий не меняется. Вы задаёте модели цель и список инструментов, которые она может использовать. Она отвечает либо окончательным результатом, либо запросом на использование инструмента, например «поищите E211». Если она запрашивает инструмент, что-то его выполняет и возвращает результат, после чего модель снова приступает к работе. Цикл повторяется до тех пор, пока не появится окончательный ответ.

Вся суть заключается именно в этом цикле: модель принимает решение, запускается инструмент, поступает результат, модель снова принимает решение. Наш исследователь проходит множество этапов — сначала для поиска продукта, затем для каждого добавки, после этого происходит проверка на соответствие критерию «Более здоровый выбор», определяется класс продукта и проводится окончательный анализ. На каждом этапе модель выбирает следующий шаг на основе только что полученной информации. Именно это делает систему агентной, и поэтому один вызов API внутри цикла for не подходит.

Обратите внимание на то, что на самом деле выводит модель: только «Я хотел бы вызвать check_sfa_additive с этими аргументами». Что-то ещё должно преобразовать это желание в реальный вызов функции и обеспечить продолжение работы. Этим «чем-то» является harness, который содержит гораздо больше непримечательных внутренних механизмов, чем ожидают большинство людей. Он делится на три уровня. Уровень разработки — это место, где создаётся агент. Уровень работы — это место, где агент используется в производственных условиях. Плоскость управления — это место, где контролируется вся группа агентов. Именно уровень разработки запускает весь цикл, и именно здесь находятся эти SDK.

Начните с слоя разработки, где создается отдельный агент. Он включает в себя сам цикл (запуск модели, обнаружение запросов к инструментам, повторение действий до завершения, безопасное прекращение работы при достижении лимита ходов или бюджета) и персону — системное указание, которое сообщает модели, кто она и как должна действовать. Вокруг них располагаются схемы инструментов, описывающие каждый инструмент для модели в ожидаемом ею формате, а также механизм выполнения инструментов, который фактически запускает вашу функцию, сервер MCP или встроенные компоненты, такие как чтение файлов, и фиксирует результаты. Клиент MCP позволяет агенту обращаться к серверам сторонних поставщиков. Механизм управления контекстом сохраняет текущий текст переписки, обрабатывает изображения и удаляет лишние данные, когда длина текста становится слишком большой. Настройки поставщика включают механизмы аутентификации, конечные точки и форматы запросов для конкретного поставщика. Кроме того, существует структурированный вывод, который принуждает и проверяет окончательный ответ с учётом фиксированной структуры, а также рабочие процессы с несколькими агентами, в которых агенты связаны друг с другом последовательно, параллельно или в циклах.

SDK упрощают всё это. При переходе от выполнения скриптов к управлению сервисом появляется слой Runtime, а вместе с ним и более длинный список требований. Агенту необходимо хостинговое выполнение, то есть конечная точка с изоляцией сессий, к которой могут обращаться другие системы. Ему нужен шлюз инструментов, механизмы повторных попыток, таймаутов и обработки учетных данных, обеспечивающие надежность вызовов инструментов в случае сбоев верхнего уровня API, а также управляемая память, позволяющая хранить сессии и долгосрочное состояние в хранилище, которое сохраняется после завершения процесса и может быть использовано между экземплярами. Также требуется идентификатор рабочей нагрузки для вызовов инструментов, чтобы эти вызовы осуществлялись не с личного ключа кого-либо, а также возможность отслеживания, включая трейсы и спаны, показывающие, какие инструменты были запущены, с какими данными и почему. Добавьте песочницу для собственного кода агента или инструментов браузера, надежные циклы, которые продолжают работу с последнего завершенного шага после сбоя, а также возможность масштабирования за счет конкурентности и автоматического масштабирования за пределами конечной точки.

Под ним находится плоскость управления, которая одновременно управляет множеством агентов. Реестр позволяет публиковать и находить агенты во время выполнения вместо их прямого связывания в коде. Каждому агенту необходимо иметь идентификатор в виде принадлежащей ему, отслеживаемой единицы в каталоге, а также четко определенные права доступа, которые обязательно соблюдаются, а не просто предполагаются. После завершения работы требуется журнал аудита и соответствия, показывающий, что делали агенты, механизмы управления данными относительно того, что может храниться и раскрываться в общей памяти, а также контроль затрат и квот с использованием бюджетов и лимитов скорости. Агенты могут взаимодействовать друг с другом по открытым протоколам, таким как A2A. Поскольку результаты работы инструментов сразу возвращаются в модель, важны механизмы контроля и защиты от внедрения вредоносного кода, а оценка позволяет определить, верны ли ответы, а не просто то, завершилась ли работа. Реестр инструментов и серверов MCP обеспечивает каталогизацию, версионирование, поиск, объединение ресурсов и аутентификацию для каждого сервера; возможность быстрого версионирования позволяет фиксировать, сравнивать и восстанавливать шаблоны запросов, что обеспечивает воспроизводимость результатов работы. Короче говоря, каждый из этих наборов представляет собой готовую систему. Наборы от Claude, OpenAI и Google включают всё необходимое — логику работы, инструменты, обработку контекста и подключение поставщиков услуг, — оставляя вам возможность написать самые важные части: ваши собственные инструменты, шаблоны запросов и формат вывода. ADK — это исключение с точки зрения названия, хотя он выполняет ту же функцию; поэтому термин «SDK» ниже охватывает все три набора в общем смысле.

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

Агент, находящийся на тестировании: исследователь этикеток с пищевой информацией

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

  1. Он считывает этикетку с помощью собственной системы видения модели, извлекая название продукта, полный список ингредиентов и добавок, количество сахара и насыщенных жиров на 100 мл, а также информацию о том, является ли продукт напитком. Фотография является единственным источником информации, поскольку нет базы данных продуктов, на которую можно было бы опираться.
  2. Для каждого обнаруженного добавка, независимо от того, указано на этикетке E471 или «Соевый лецитин», он проверяет список разрешенных добавок, утвержденный SFA Сингапура, и сообщает о статусе добавка и любых предупреждениях для потребителей.
  3. Он запрашивает данные из набора HPB на сайте data.gov.sg, чтобы выяснить, имеет ли продукт символ Healthier Choice.
  4. Для напитков он определяет ожидаемый уровень питательной ценности A/B/C/D на основе содержания сахара и насыщенных жиров.
  5. Все полученные данные он обрабатывает, формируя итоговую оценку — ЗЕЛЕНЫЙ, ЯНТАРНЫЙ или КРАСНЫЙ — с указанием источника информации (инструмента или этикетки), а также излагая логику принятия решения модели в начале отчета.

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

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

Обеспечение справедливости сравнения

Всё, что не является частью SDK, должно было оставаться идентичным. Все три демо-программы обращаются к одному прокси LiteLLM — шлюзу, совместимому с OpenAI, который также обслуживает конечную точку /v1/messages от Anthropic для SDK Claude. Один корневой файл .env содержит ключи, базовые URL и названия моделей для каждого из них; моделями являются Claude Sonnet 4.6, GPT-5.4 и Gemini 3.5 Flash. Способ, которым каждое SDK подключается к этому прокси, многое раскрывает о его настройках.

Каждая демо-версия находится в своем собственном проекте uv, поэтому ее можно запустить без установки зависимостей других проектов. Таблица добавок SFA была сгенерирована один раз на основе PDF с перечнем разрешенных добавок, опубликованного сингапурским агентством по продовольствию; в результате был создан файл sfa_additives.json (примерно 540 записей, из которых около 270 содержат номера E), который затем без изменений копировался в каждый проект. Изображения для тестирования также были идентичны: два реальных сингапурских продукта — пакетик Milo 3in1 и упаковка молока Marigold HL.

Таким образом, остается лишь то, что действительно является решением SDK: как определяется инструмент, как добавляются изображения, как настраивается модель, существует ли текстовый вывод и как отображается результат работы.

Небольшое предупреждение перед приведением кода. Приведённые ниже фрагменты содержат инструмент recall_product и аргумент e_number_hint. Они обеспечивают функции памяти и самосовершенствования, о которых пойдёт речь далее, поэтому пока можно их проигнорировать.

SDK Claude Agent от Anthropic

SDK Claude Agent разработан непосредственно для Claude Code — инструмента, который многие уже используют в терминале, и именно это решение определяет всю архитектуру. Вы не собираете циклы из примитивов; вы управляете полноценным, проверенным в боевых условиях агентом, предоставляя ему свои инструменты и команды. Встроенные инструменты (Read, Write, Edit, Bash, WebFetch) уже доступны, модель разрешений и управление контекстом реализованы, а ваши собственные инструменты подключаются через сервер MCP, работающий внутри вашего процесса. Всё выполняется асинхронно с использованием anyio.

Вы покупаете настоящего агента для работы с компьютером, готового к использованию. Любой инструмент, требующий чтения файлов, выполнения команд оболочки, редактирования исходного кода или просмотра контента, поставляется в производственной версии с первого дня, поскольку используется та же самая технология, что и в Claude Code. MCP считается инструментом первого класса, поэтому пользовательский инструмент, который вы напишете, будет работать без изменений как в Claude Code, так и в Claude Desktop, а также в вашем собственном приложении. Из этих трех вариантов этот использует наиболее совершенную среду выполнения агентов.

Стоимость определяется инструментами, для которых вы вручную вводите название, описание и схему:

@tool(
    "check_sfa_additive",
    "Check whether a food additive is permitted by the Singapore Food Agency, "
    "using the full SFA permitted-additives list parsed from the official PDF. "
    "Accepts an E-number ('E211') OR a name ('Sodium Benzoate', 'Soy Lecithin'). "
    "If you pass a name and also know its E/INS number, set e_number_hint — an "
    "unrecognised name that the hint resolves is REMEMBERED for next time.",
    {"additive": str, "e_number_hint": str},
)
async def check_sfa_additive(args: dict) -> dict:
    raw = args["additive"].strip()
    hint = args.get("e_number_hint", "").strip()
    entry = _resolve_additive(raw)
    if not entry and hint:
        entry = _resolve_additive(hint)
        if entry:  # learn: this label name -> this number, persisted to disk
            num = entry["e_number"] or entry.get("ins") or ""
            _MEMORY["learned_aliases"][_norm(raw)] = re.sub(r"\(.*\)", "", num).lower()
            _save_memory(_MEMORY)
    return _ok(_format_entry(entry, raw))

Для ввода данных в словарь {arg: type} требуется больше усилий, чем для двух других наборов, однако он не допускает никакой двусмысленности. Инструменты затем предоставляются через внутренний сервер MCP, и модель обращается к ним с префиксом mcp__<server>__<tool>; об этом необходимо помнить при указании значений в параметре allowed_tools:

server = create_sdk_mcp_server(
    name="sg-nutrition-tools",
    version="1.0.0",
    tools=[recall_product, check_sfa_additive, check_hcs, calculate_nutri_grade],
)

options = ClaudeAgentOptions(
    system_prompt=SYSTEM_PROMPT,
    mcp_servers={"sg": server},
    allowed_tools=[
        "mcp__sg__recall_product",
        "mcp__sg__check_sfa_additive",
        "mcp__sg__check_hcs",
        "mcp__sg__calculate_nutri_grade",
    ],
    model=CLAUDE_MODEL,
    permission_mode="bypassPermissions",
    max_turns=20,
    # Point the bundled CLI at the LiteLLM proxy's Anthropic endpoint.
    env={
        **os.environ,
        "ANTHROPIC_BASE_URL": BASE_URL,
        "ANTHROPIC_AUTH_TOKEN": API_KEY,
    },
)

Изображения добавляются аналогичным способом «самостоятельной обработки». Аргумента image= не существует. Функция query() принимает асинхронный итерируемый набор словарей с сообщениями, поэтому вы сами формируете необработанные блоки контента, характерные для Claude — блок текста вместе с блоком изображения:

async def message_stream():
    yield {
        "type": "user",
        "message": {"role": "user", "content": [
            {"type": "text", "text": "Investigate this nutrition label."},
            {"type": "image", "source": {"type": "base64", "media_type": mime, "data": b64}},
        ]},
    }

async with ClaudeSDKClient(options=options) as client:
    await client.query(message_stream())
    async for message in client.receive_response():
        ...  # stream ToolUseBlock / TextBlock as they arrive

Острый край — это модельная схема подключения. SDK запускает встроенную CLI Claude Code, которая использует формат сообщений от Anthropic, поэтому её можно перенаправить к прокси с помощью переменных окружения (ANTHROPIC_BASE_URL и ANTHROPIC_AUTH_TOKEN). Передавать объект клиента не требуется. Преимущество заключается в полной прозрачности процесса: вы можете выводить каждый ToolUseBlock по мере его поступления и наблюдать за развитием цикла добавления элементов в реальном времени. Вот пример работы с пакетом Milo:

sausheong claude-demo % uv run python main.py ../milo.jpeg

Investigating image: ../milo.jpeg
────────────────────────────────────────────────────────────
I'll start by reading the label carefully, then run all checks in parallel.

**Reading from the label:**
- **Product:** Nestlé MILO 3in1
- **Net weight:** 27g powder sachet (add hot water to prepare — this is a **powder, not a ready-to-drink beverage**)
- **Ingredients:** Sugar, PROTOMAL® Malt Extract (Contains Barley), Skimmed Milk (Cow's Milk), Cocoa, Palm Oil, Minerals (Dicalcium Phosphate, Disodium Phosphate, Ferric Pyrophosphate), Resistant Dextrin, Flavourings, Vitamins (C, B3, D, B6, B2, B12)
- **Identifiable additives:** Dicalcium Phosphate (E341), Disodium Phosphate (E339), Ferric Pyrophosphate; Flavourings (generic — cannot identify specific ones)

Kicking off recall + HCS check + all additive checks simultaneously:
  → tool: recall_product({'product_name': 'Nestlé MILO 3in1'})
  → tool: check_hcs({'product_name': 'MILO 3in1'})
  → tool: check_sfa_additive({'additive': 'Dicalcium Phosphate', 'e_number_hint': 'E341'})
  → tool: check_sfa_additive({'additive': 'Disodium Phosphate', 'e_number_hint': 'E339'})
  → tool: check_sfa_additive({'additive': 'Ferric Pyrophosphate', 'e_number_hint': 'E450'})
All checks returned. Note: this is a **powder**, not a ready-to-drink beverage, so Nutri-Grade (which requires per-100ml liquid values) does **not apply** — I will skip `calculate_nutri_grade`.

---

## Reasoning

**Step 1 — Product recall.** This product has been seen before. The prior verdict is consistent with what I read now — I'll treat this fresh investigation as the authoritative one and use the prior as a cross-check.

**Step 2 — Label reading.**
- MILO 3in1 is a **27g powder sachet** — you add hot water to make a drink. It is classified as a "Tonic Food Drink" on the label. Because it is sold as a dry powder (not a pre-packaged ready-to-drink liquid), Nutri-Grade per-100ml calculation does not apply.
- Nutritional values per serving (27g): Energy 110 kcal, Total Fat ~2.4g, Saturated Fat ~1.2g, Total Sugars ~13.8g (of which Added Sugars ~10g), Sodium ~38mg.
- **Sugar is the #1 ingredient** — it appears first in the ingredient list, before the malt extract.

**Step 3 — Additives.**
- **Dicalcium Phosphate (E341):** SFA-permitted ✅ — used as a mineral/calcium source.
- **Disodium Phosphate (E339):** SFA-permitted ✅ — used as an acidity regulator/mineral.
- **Ferric Pyrophosphate:** SFA-permitted ✅ — used as an iron supplement/mineral source.
- **Resistant Dextrin:** A dietary fibre ingredient (prebiotic fibre), not a regulated additive — no E number, no SFA check needed.
- **Flavourings:** Generic label — cannot identify specific flavouring compounds; SFA check not possible.
- **Vitamins (C, B3, D, B6, B2, B12):** Added as nutritional fortification, not food additives in the regulatory sense. Riboflavin (B2) carries E101 when used as a colourant, but here it's explicitly declared as a vitamin supplement — standard and expected.

**Step 4 — Healthier Choice Symbol.** HCS certified ✅ (MILO 3in1 Activ-Go appears multiple times in the HPB dataset — `check_hcs`).

**Step 5 — Sugar content reality check.** Each 27g sachet contains ~13.8g total sugars (~10g added sugars). That's more than **half the sachet's weight is sugar**, and exceeds the WHO daily added-sugar guideline of 25g in less than one cup. This is label-read, not a tool finding.

---

## Verdict

### 🟢 GREEN — No Concern
- **All three declared additives are SFA-permitted** (Dicalcium Phosphate E341, Disodium Phosphate E339, Ferric Pyrophosphate) — `check_sfa_additive` ×3.
- **Carries the Healthier Choice Symbol** — HPB has certified MILO 3in1 Activ-Go — `check_hcs`.
- **Vitamins and minerals fortified** — B2, B3, B6, B12, C, D, plus calcium and iron — label.
- **Contains barley malt extract** — a whole-grain source of energy — label.
- **Resistant Dextrin** (prebiotic dietary fibre) is a functional ingredient, not a concern — label.

### 🟡 AMBER — Worth Knowing
- **Palm Oil present** — a saturated fat source. Saturated fat is 1.2g per sachet (~4.4g per 100g of powder). Not alarming at one serving, but worth knowing if you have multiple cups a day — label.
- **"Flavourings" are not specified** — cannot determine whether natural or artificial. No SFA check was possible — label.
- **Nutri-Grade does not apply here** — this is sold as a powder. If you reconstitute it and compare the drink to ready-to-drink alternatives, it would likely land in Grade C or D territory based on sugar content, but no regulatory grade is required on the packet.

### 🔴 RED — Genuinely Concerning
- **Sugar is the #1 ingredient** — it appears first in the list, meaning it is the dominant ingredient by weight. Each sachet delivers **~13.8g total sugars / ~10g added sugars** — label. That's 40% of the WHO's recommended 25g/day added-sugar limit in a single cup. If you're drinking 2–3 sachets a day (as Nestlé's own label suggests for daily energy), you are consuming **20–30g of added sugar from MILO alone**, likely exceeding the daily limit.
- **Marketing framing vs. nutritional reality:** The packet prominently says "Nourishing Energy" and shows vitamins, but the sugar load is the dominant nutritional feature. The fortification (vitamins, minerals) does not offset this — label.

**Bottom line for a Singapore shopper:** MILO 3in1 is safe from an additives and regulatory standpoint — everything checks out with SFA and HPB. But it is a **sugar-heavy product** dressed up in health language. Treat it as an occasional treat rather than a daily nutritious breakfast drink, especially for children.

Где возникают проблемы. Не существует встроенного структурированного формата вывода, поэтому приходится работать с текстом, либо самостоятельно его анализировать, либо активно задавать вопросы относительно его формы, что является самой значительной разницей по сравнению с SDK OpenAI. Схемы форматирования создаются вручную, поэтому необходимо писать больше кода и постоянно синхронизировать его с каждой функцией. Подключение моделей осуществляется через среду выполнения, причем прокси, к которому вы обращаетесь, должен предоставлять конечную точку формата Anthropic /v1/messages, поскольку одной только конечной точки, совместимой с OpenAI, недостаточно. Список allowed_tools следует рассматривать как предварительное одобрение, а не как среду изоляции: это означает «пропустить запрос на подтверждение для этих инструментов», а не «агент может использовать только эти инструменты», и те, кто воспринимает его как список разрешенных инструментов, могут столкнуться с неожиданностями. Игнорируйте префикс mcp__sg__ — в таком случае инструмент просто останется неподтвержденным без какой-либо ошибки. Этот вариант также имеет более высокую нагрузку, поскольку в фоновом режиме запускается среда выполнения Claude Code, а не осуществляется простой вызов API.

Выбирайте его тогда, когда агенту необходимо управлять устройством. Это означает чтение и запись файлов, выполнение команд в оболочке, редактирование кодовой базы или просмотр контента — любую задачу, при которой встроенные инструменты Claude Code позволяют избежать необходимости создания сандбокса. Это также естественный выбор, если вы уже используете MCP или создаёте что-то, что должно вести себя как Claude Code. Цикл потоковой обработки легко отслеживать, что удобно для агентов, работающих длительное время.

Используйте его тогда, когда вам нужен компактный цикл вызова функций с вводом данных, возвращающий структурированный объект — именно для этого и создан SDK OpenAI. Используйте другой вариант, если вы не можете предоставить конечную точку в формате Anthropic или если важна небольшая размерность зависимостей. Простая задача вроде «позвонить трем инструментам и вернуть объект Pydantic» требует гораздо меньше ресурсов.

SDK OpenAI Agents

SDK OpenAI — это лёгкий, специально разработанный в духе Python обёрток вокруг цикла, полностью ориентированный на сам язык. Подсказки типов превращаются в схемы инструментов, документация — в описания инструментов, а модели Pydantic — в контракт вывода. Ничто не предписывает определённой структуры проекта, нет отдельной среды выполнения и не требуется использование MCP. Вы пишете функции и модели, создаёте Agent и передаёте его в Runner.run. Цель — минимизировать расстояние между функцией на Python и рабочим агентом.

Самый сильный аспект этого инструмента — возможность ввода и обработки данных в формате типизированных объектов. Укажите параметр output_type=YourModel, и в качестве результата будет возвращен проверенный Python-объект, а не набор байтов, который вы ошибочно считаете JSON; SDK формирует запрос, парсит ответ, проверяет его корректность и, при несоответствии формата, возвращает запрос модели. Схемы, генерируемые автоматически из типовых указаний, плюс бесплатная панель управления трейсингом на собственном сервере OpenAI, делают этот инструмент самым быстрым способом создания структурированного, наблюдаемого агента. Когда задача заключается в «принять входные данные и вернуть типизированный результат», ни один другой инструмент не является настолько прямолинейным.

Для работы с этими инструментами совершенно не требуется создание схем:

@function_tool
async def check_sfa_additive(additive: str, e_number_hint: str = "") -> str:
    """Check whether a food additive is permitted by the Singapore Food Agency.

    Looks the additive up in the full SFA permitted-additives list (parsed from
    the official SFA PDF). Accepts either an E-number or a plain-English name as
    printed on a Singapore label.

    Args:
        additive: An E-number ('E211', 'e211', 'en:e211') OR an additive name
            ('Sodium Benzoate', 'Soy Lecithin', 'MSG').
        e_number_hint: Optional. If you pass a name and also know its E/INS
            number, supply it here. If the name isn't recognised but the number
            is, the mapping is REMEMBERED so the name resolves directly next time.    """
    ...

Декоратор считывает указания типов и раздел Args документации, а затем формирует схему JSON, поэтому нет необходимости вручную вести какие-либо записи.

Наибольшая польза проявляется в результатах работы. Вердикт представляется в виде модели Pydantic:

class NutritionVerdict(BaseModel):
    reasoning: str          # declared first: the model works out loud before committing
    product_name: str
    summary: str
    green: list[Finding]
    amber: list[Finding]
    red: list[Finding]
    recommendation: str

При использовании output_type=NutritionVerdict модель возвращает проверенный объект без необходимости в парсинге и без рисков. Хорошим приемом является размещение поля reasoning в начале: структурированный вывод одновременно служит рабочей доской, позволяя модели обдумать выводы перед их фиксацией, а вы сохраняете организованный объект вместе с обоснованием.

Подключение модели и ввод изображений — самые упорядоченные из трех вариантов:

client = AsyncOpenAI(base_url=BASE_URL, api_key=API_KEY)
model = OpenAIChatCompletionsModel(model=OPENAI_MODEL, openai_client=client)
agent = Agent(name="SG Nutrition Investigator", model=model,
              instructions=INSTRUCTIONS, output_type=NutritionVerdict,
              tools=[recall_product, check_sfa_additive, check_hcs, calculate_nutri_grade])

user_input = [{"role": "user", "content": [
    {"type": "input_text", "text": "Investigate this nutrition label."},
    {"type": "input_image", "image_url": _data_url(image_path)},  # base64 data URL
]}]
result = await Runner.run(agent, input=user_input)
verdict: NutritionVerdict = result.final_output

Это клиент AsyncOpenAI, предназначенный для работы с прокси, обернутый в OpenAIChatCompletionsModel; элемент input_image содержит фотографию. Никаких сложностей.

Важные моменты. По умолчанию вызовы инструментов выполняются параллельно, поэтому модель может одновременно запустить несколько вызовов check_sfa_additive. Наши инструменты асинхронные и не имеют побочных эффектов, что является преимуществом. Инструменты, изменяющие общее состояние, использующие нереентрентные соединения или зависящие от определённого порядка действий, будут вести себя некорректно; сбои в таких случаях возникают прерывисто и зависят от времени, что является худшим вариантом. Необходимо либо сделать инструменты безопасными для параллельной работы, либо ограничить действия модели.

У трекинга есть свои недостатки. Панель управления отличная, но данные трекинга отправляются на собственный точку входа OpenAI, и за прокси третьей стороны ключ, выданный прокси, не может авторизоваться там. Поэтому при вызове set_tracing_disabled(True) ваш лучший инструмент для отслеживания исчезает всего за одну строку кода. Вне домена api.openai.com придется полагаться на OpenTelemetry или собственные механизмы логирования. Существуют и другие проблемы: за прокси требуется использовать OpenAIChatCompletionsModel, поскольку стандартный путь API Responses направлен на точки входа OpenAI, и неправильный выбор приводит к непонятным ошибкам. Схема output_type должна соответствовать правилам строгого режима, поэтому модели с глубокой вложенностью или множеством объединений могут вызвать повторные попытки валидации; по этой причине типы Finding и NutritionVerdict остаются простыми. В коробке не поставляются никакие инструменты для работы с компьютером, поэтому нет файловой системы, оболочки или возможности просмотра контента, если только вы сами их не добавите.

Вот результаты анализа пакетика Milo:

sausheong openai-demo % uv run python main.py ../milo.jpeg

Investigating image: ../milo.jpeg
────────────────────────────────────────────────────────────
Product: Nestlé MILO 3 in 1 Activ-Go

Reasoning: I read the sachet as **Nestlé MILO 3 in 1 Activ-Go**. The front says “goodness of malt, milk & cocoa” and the back says “MILO Ionic Food Drink,” so this is a **powdered drink mix**, not a ready-to-drink beverage. Because it is not sold as a beverage with per-100ml nutrition for the prepared drink as consumed, I did **not** calculate Nutri-Grade; that tool is only for beverages.

I first checked whether this product had been investigated before. A prior record existed, and it broadly matched what I can read here: a sweetened powdered malt-cocoa-milk drink sachet with permitted phosphate additives, relatively high in sugar for a single sachet, and not found in the HCS database. I used that only as background and then re-read this label fresh.

From the nutrition panel, I can read:
- Serving size: **1 sachet (27g)**
- Servings per package: **1**
- Per 100g / per serving shown side by side
- **Total sugars: 50.1g per 100g; 13.8g per serving**
- **Saturated fat: 0.5g per 100g; 1.2g per serving**
This is a powder, so the relevant direct reading is per 100g, not per 100ml.

I can read the ingredient list as:
**Sugar, Protomalt™ Malt Extract (contains barley), skimmed milk/cow’s milk, cocoa, palm oil, minerals (dicalcium phosphate, disodium phosphate), fibre (pyrophosphate), resistant dextrin, flavourings, vitamins (C, B3, D, B6, B2, B12).**

For additives, I checked each identifiable additive individually where possible:
- **Dicalcium phosphate**: checked and found **permitted by SFA**. That lands in GREEN.
- **Disodium phosphate**: checked and found **permitted by SFA**. That also lands in GREEN.
- The label also contains the broader terms **“phosphates”** and **“pyrophosphate”/“fibre (pyrophosphate)”** in wording around ingredients, but the image does not clearly identify a specific additive code for the pyrophosphate entry, and the generic umbrella term “phosphates” is not reliable enough on its own. I therefore do not treat the generic term as confirmed permitted just from the broad word alone. I only rely on the specifically named phosphates I could check.
- **Flavourings** is too generic to identify a specific additive, so I could not check it individually.
- The vitamins and minerals are nutrients rather than red-flag food additives in the SFA additive sense.

I also checked for the **Healthier Choice Symbol** using the product name. It was **not found** in the HCS database.

Main nutritional takeaways from the label:
- Sugar is the **first ingredient**, which usually means it is the largest ingredient by weight.
- The product contains **50.1g sugar per 100g** powder, and **13.8g sugar per 27g sachet**. That is quite a lot for one small sachet drink.
- Saturated fat is **1.2g per sachet**, which is not extreme, but the bigger concern here is sugar.

So the overall picture is: the identifiable phosphate additives appear permitted, but nutritionally this is still a **sweetened convenience drink mix** rather than a lower-sugar everyday option.

Summary: This is a powdered MILO drink sachet, not a ready-to-drink beverage. The clearly identifiable phosphate additives on the label are permitted by SFA, but sugar is the first ingredient and the product contains 50.1g sugar per 100g, or 13.8g per 27g sachet. It was not found in the Healthier Choice Symbol database.

🟢 Dicalcium phosphate is permitted by SFA.  [check_sfa_additive]
🟢 Disodium phosphate is permitted by SFA.  [check_sfa_additive]
🟢 This is a powdered drink mix rather than a ready-to-drink beverage, so Nutri-Grade was not applicable here.  [label]
🟡 Generic terms such as “flavourings” and the unclear “fibre (pyrophosphate)” wording are not specific enough to confirm exact additive identities from the image alone.  [label]
🟡 The product was not found in the Healthier Choice Symbol database.  [check_hcs]
🟡 Saturated fat is 1.2g per 27g sachet (0.5g per 100g listed on the label panel image).  [label]
🔴 Sugar is the first ingredient on the label.  [label]
🔴 Total sugars are 50.1g per 100g and 13.8g per 27g sachet, which is high for a small single-serve drink mix.  [label]

Recommendation: Fine as an occasional sachet drink if convenience matters, but not the best everyday choice if you are trying to reduce sugar. If you drink MILO often, consider using plain MILO powder with your own milk and less sugar, or choose a lower-sugar version.

Используйте его тогда, когда задача структурирована, например, для классификации, извлечения информации, оценки или выдачи вердиктов, где текстовые форматы превосходят простой прозаический текст, и когда требуется минимум кода на Python. Командам, которые ценят типовые указания, он понравится, а благодаря бэкенду OpenAI бесплатная отладка упрощает работу с многоэтапными агентами.

Пропустите его тогда, когда ваши инструменты нельзя сделать безопасными для одновременной работы, и вы не хотите иметь дело с параллельной работой по умолчанию, когда вам нужна возможность отслеживания действий, но вы работаете через не OpenAI-интерфейс (в этом случае отладка отсутствует), или когда агент должен использовать инструменты файловой системы и оболочки сразу после запуска — это сфера применения Claude. Для нескольких взаимодействующих агентов с четким потоком управления более подходит ADK, и это третий инструментарий.

Google's Agent Development Kit (ADK)

Из этих трех ADK — единственный, который действительно является фреймворком с четко определенной архитектурой, в отличие от остальных более легковесных решений. Он включает в себя агентов, сессии, компонент Runner, SessionService, а также явные многопроцессные рабочие процессы с использованием SequentialAgent, ParallelAgent и агентов с циклами. Заданная структура проекта позволяет инструментам находить нужных агентов, а adk web открывает локальный интерфейс чата с инспектором событий. Инструменты представляют собой обычные функции на Python с документацией в стиле Google docstrings; в них отсутствуют декораторы и словари схем. Благодаря обертке LiteLlm ADK остается опцией, наименее зависящей от конкретных поставщиков.

ADK — это архитектура для систем, а не для скриптов. Когда под «агентом» на самом деле подразумевается несколько агентов, таких как планировщик, передающий задачи рабочим, последовательная или параллельная структура обработки, ADK предоставляет их в качестве составных элементов первого класса, избавляя вас от необходимости реализовывать логику управления вручную. Встроены механизмы работы с сессиями, интерфейс отладки является лучшим среди аналогов, а модель, независимая от поставщика, не принуждает вас зависеть от одного конкретного поставщика. Эта архитектура предназначена для развития в сложное, имеющее состояние приложение с несколькими агентами.

Здесь определения инструментов наиболее просты:

async def check_sfa_additive(additive: str, e_number_hint: str = "") -> dict:
    """Check whether a food additive is permitted under Singapore Food Agency rules.

    Looks the additive up in the full SFA permitted-additives list (parsed from
    the official SFA PDF). Accepts either an E-number or a plain-English name as
    printed on a Singapore label.

    Args:
        additive: An E-number ('E211', 'e211', 'en:e211') OR an additive name
            ('Sodium Benzoate', 'Soy Lecithin', 'MSG').
        e_number_hint: Optional E/INS number for when you pass a name. If the
            name isn't recognised but the number is, the mapping is REMEMBERED
            so the name resolves directly next time.

    Returns:
        dict with the input, resolved e_number/name, permitted status, schedule
        and any consumer note. found=False if it is not in the SFA list.
    """
    ...

Схема формируется на основе документации в стиле Google с элементами Args и Returns, поэтому качество этой документации имеет огромное значение. Нечеткая документация негативно сказывается на выборе инструментов моделью, так что она фактически является контрактом.

Чтобы adk web мог найти ваш root_agent, проект должен иметь определенную структуру пакетов:

adk-demo/
  sg_nutrition_investigator/
    __init__.py      # from . import agent
    agent.py         # tools + root_agent
  main.py            # standalone Runner + InMemorySessionService
root_agent = LlmAgent(
    name="sg_nutrition_investigator",
    model=LiteLlm(model="openai/" + GEMINI_MODEL, api_base=BASE_URL, api_key=API_KEY),
    instruction=INSTRUCTION,
    tools=[FunctionTool(recall_product), FunctionTool(check_sfa_additive),
           FunctionTool(check_hcs), FunctionTool(calculate_nutri_grade)],
)
# image input — the cleanest of the three:
message = types.Content(role="user", parts=[
    types.Part(text="Investigate this nutrition label."),
    types.Part.from_bytes(data=Path(image_path).read_bytes(), mime_type=mime),
])

Модель обрабатывается через обертку ADK LiteLlm, при этом префикс openai/ заставляет LiteLlm использовать протокол, совместимый с OpenAI, для взаимодействия с прокси. Передача изображений с помощью types.Part.from_bytes является наиболее удобным из трех способов, а adk web предлагает лучший встроенный опыт разработки среди рассматриваемых решений.

Проблемы. Большинство из них связано с весом. Вне adk web необходимо подключить Runner, SessionService, а также явно указать идентификаторы приложения, пользователя и сессии ещё до отправки первого сообщения — это много лишних действий по сравнению с несколькими строками кода, требуемыми в других решениях. Структура кода также играет важную роль. Строка from . import agent в файле __init__.py позволяет adk web находить объект root_agent, и любое отклонение от этой структуры мешает его обнаружению. litellm генерирует предупреждения о неиспользуемых бэкендах (безвредные уведомления о Bedrock и SageMaker вида «no module named botocore»), а ADK добавляет предупреждение о схеме [EXPERIMENTAL], в результате чего оба механизма отключаются при импорте. Структурированный вывод также требует больше усилий, поскольку параметр response_schema в Gemini более чувствителен к воздействию прокси по сравнению с параметром output_type у OpenAI, поэтому в этом примере используется оценка на основе введённого текста. Справедливости ради стоит отметить, что прокси оказывает не меньшее влияние, чем ADK. Ещё один момент: при использовании пути LiteLlm в сочетании с Gemini-flash агент описывал свои действия менее подробно, чем другие при одинаковом вводе, что показывает, что поведение зависит от модели и способа её подключения, а не только от SDK.

Результат работы с Milo sachet:

sausheong adk-demo % uv run python main.py ../milo.jpeg

Investigating image: ../milo.jpeg
────────────────────────────────────────────────────────────
  → tool: recall_product({'product_name': 'Nestle MILO 3 in 1'})
  → tool: check_sfa_additive({'e_number_hint': 'E341', 'additive': 'Dicalcium Phosphate'})
  → tool: check_sfa_additive({'additive': 'Disodium Phosphate', 'e_number_hint': 'E339'})
  → tool: check_sfa_additive({'additive': 'Ferric Pyrophosphate'})
  → tool: check_hcs({'product_name': 'Nestle MILO 3 in 1'})
  → tool: calculate_nutri_grade({'saturated_fat_per_100ml': 0.5, 'sugar_per_100ml': 6.1})
## Reasoning

We investigated the label of **Nestle MILO 3 in 1 (with Activ-Go)**. Here is our step-by-step analysis:

1. **Product Categorisation & Reconstitution**:
   * This is a dry beverage powder sold in single-serving 27g sachets.
   * The nutritional information panel provides two columns: "Per Serving 27g" (the dry sachet) and "Per 100ml*" (as reconstituted by adding 200ml of hot water).
   * For the **Singapore Nutri-Grade** system, the grading is calculated based on the beverage *as reconstituted* according to the directions.

2. **Sugar & Saturated Fat Analysis (Per 100ml prepared)**:
   * **Total Sugars**: **6.1g per 100ml** (of which 4.8g is Added Sugar).
   * **Saturated Fat**: **0.5g per 100ml**.
   * Feeding these values into the Nutri-Grade calculator yields **Nutri-Grade C** (due to the sugar content being > 5g/100ml). Grade C beverages are classified as "less healthy" and must display the Nutri-Grade label at retail.

3. **Ingredients & Additives Analysis**:
   * **Sugar is the #1 Ingredient**: Refined sugar is listed first on the ingredients list, meaning it is the largest ingredient by weight in this packet—even ahead of malt extract and milk powder.
   * **Additives**:
     * **Dicalcium Phosphate** (E341(ii)) and **Disodium Phosphate** (E339(ii)) are SFA-approved food additives used as stabilizers and emulsifiers.
     * **Ferric Pyrophosphate** is an SFA-approved mineral nutrient used to fortify the drink with Iron.
   * **Healthier Choice Symbol (HCS)**: The packet displays the red HCS logo. This is because it is formulated to be "25% lower in sugar" *compared to regular malted beverages*. However, in absolute terms, it still carries enough sugar to land in Nutri-Grade C.

---

## Verdict

### 🟢 Green Findings
* **Fortified with Vitamins & Minerals** `[label]`: Contains B-vitamins (B2, B3, B6, B12), Vitamin C, Vitamin D, Calcium, and Iron (via *Ferric Pyrophosphate* `[check_sfa_additive]`).
* **Contains Soluble Fibre** `[label]`: Features *Resistant Dextrin*, a prebiotic soluble dietary fibre (1.1g per serving) that supports gut health.
* **SFA-Approved Additives** `[check_sfa_additive]`: Phosphates used for stabilizing and emulsifying (*Dicalcium Phosphate* and *Disodium Phosphate*) are fully permitted.
* **Healthier Choice Certified** `[check_hcs]`: Carries Singapore's HCS logo for having at least 25% less sugar than standard malted chocolate drinks.

### 🟡 Amber Findings
* **Nutri-Grade C** `[calculate_nutri_grade]`: When prepared as instructed, it gets a **Grade C** because of its **6.1g of sugar per 100ml**. Grade C drinks are in the "less healthy" bracket.
* **Contains Palm Oil** `[label]`: Palm oil is added to give a rich mouthfeel, contributing **1.2g of saturated fat per serving** (0.5g/100ml).

### 🔴 Red Findings
* **Sugar is the Main Ingredient** `[label]`: Sugar is listed as the very first ingredient on the label, which means there is more plain sugar by weight than malt extract (*PROTOMALT*) or milk powder.
* **High Sugar Load per Cup** `[label]`: A single small 27g sachet contains **13.8g of total sugar** (equivalent to about **3 teaspoons of sugar**), of which **10.8g** (approx. 2.5 teaspoons) is added refined sugar. Drinking multiple cups a day can quickly max out your recommended daily limit for added sugars.

Выбирайте ADK тогда, когда вы создаёте систему, в которой участвует несколько взаимодействующих агентов, предусмотрены явные последовательные, параллельные или циклические рабочие процессы, существует реальное состояние сессии, а также возможность замены моделей между разными поставщиками. Инструмент adk web окупает себя уже на этапе разработки, а архитектура возвращает первоначальные затраты по мере расширения проекта.

Обходитесь без него тогда, когда используется единственный простой агент. Шаблоны для запуска и управления сессией, а также предустановленная структура представляют собой дополнительные расходы, которые невозможно компенсировать. Для максимально быстрого результата используйте SDK OpenAI, а для агента, работающего на компьютере с встроенными инструментами, — библиотеку Claude. ADK оправдывает свою сложность при масштабировании, но в меньших масштабах это скорее чрезмерная архитектура, чем необходимость.

Запуск демонстраций

После создания всех трех агентов вот как их запустить. Каждый из них представляет собой проект uv, и каждый из них читает корневой файл .env, содержащий ключ прокси, базовый URL и названия трех моделей:

cd openai-demo        # or claude-demo, or adk-demo
uv run python main.py ../milo.jpeg
uv run python main.py ../hl.jpeg

Чтобы воссоздать таблицу SFA из PDF, выполните команду uv run --with pdfplumber python build_additives.py. Передайте путь к собственной фотографии этикетки. Две включённые в набор этикетки являются настоящими продуктами из Сингапура, и их оценки соответствуют ожидаемым: молоко получает класс Nutri-Grade B, а порошок Milo после приготовления оценивается как C.

Что делать за пределами одной обработки

Демонстрация, выполняющая одну простую обработку, скрывает наиболее интересные аспекты. Три дополнения, идентичные по форме во всех SDK, делают агентов более реалистичными, причём каждое из них говорит что-то о используемом SDK.

Реальные данные. Проверка на наличие добавок — это не какой-то детский словарь из семи статей. Файл build_additives.py парсит официальный PDF SFA, в котором три таблицы имеют разные форматы столбцов (само по себе сложная задача), и выделяет примерно 540 добавок. Во время загрузки каждая демонстрационная версия создаёт нормализованный индекс названий, благодаря чему обозначение «мононатрий глутамат» совпадает с официальным названием из PDF — «Monosodium L-glutamate». Индекс номеров E/INS, основанный на базовом номере, позволяет номеру «500» находить запись «500(ii)». Краткая таблица соответствий используется для обозначения настоящего сленга, отсутствующего в PDF, такого как «MSG» и «витамин C». Все элементы, которых действительно нет в списке, отображаются как простое «отсутствует в списке», и никогда не указывается ложное значение «разрешено».

Память и обучение. Эти два аспекта лучше рассматривать вместе:

  • Объяснение. Каждый агент показывает свои рассуждения: в случае OpenAI это поле с текстом рассуждений, а в случае Claude и ADK — раздел, начинающийся с ## Reasoning.
  • Воспоминание. Сначала запускается инструмент recall_product, который выводит любые предыдущие вердикты по тому же продукту, причем каждый запуск сохраняет свой результат. Если одну метку проверяют дважды, во второй раз результат сравнивается с первым выводом.
  • Обучение. Если метка выводит название, которое таблица не распознаёт, а модель предоставляет правильное число через e_number_hint, соответствие между названием и числом сохраняется в файле agent_memory.json. При следующем запуске это название будет распознаваться без обращения к модели.

Это и есть обучение на уровне системы. Веса никогда не меняются, однако агент совершенствует свои собственные данные и инструменты на основе опыта. Это практический и доступный вид обучения, в отличие от тонкой настройки, которую ни один из этих инструментов не выполняет во время работы. Каждый из них включает встроенный слой сессий, который можно использовать для хранения данных в производственных условиях (OpenAI’s SQLiteSession, хранилище сессий Claude, SessionService ADK), а файл JSON просто делает демо-версию портативной и удобной для анализа.

Чем больше меток оно считывает, тем лучше становится. Фотография, в которой названия ингредиентов модель преобразует в числа, обучает систему поиска новому псевдониму, и каждый исследованный продукт становится чем-то, что может быть воспроизведено в следующей обработке. Когда впервые появляется «дифосфат натрия», система опирается на модель для его преобразования в E339; после этого детерминистическая таблица уже знает этот результат, поэтому процесс становится быстрее, дешевле и может быть повторен без вызова модели. По мере обработки различных продуктов файл agent_memory.json превращается в словарь псевдонимов и историю выводов, собранную самим агентом. Если направить группу агентов на один общий файл памяти, название, выученное одним из агентов, становится известным всем. Модель остается неизменной, в то время как агенты развиваются.

Последний момент, связанный с реальными тестами: при запросе на передачу номера E вместе с его названием все три модели надежно справились с задачей, преобразуя «Дифосфат дисодный» в E339 без какой-либо помощи. Это пример работы цикла: общие знания моделей позволяют компенсировать недостатки детерминистического поиска, а система запоминает результат.

Кто что предоставляет

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

Если посмотреть на слой разработки, почти всё имеет зелёный цвет; инструментальные пакеты практически полностью согласны относительно создания одного агента. Однако если взглянуть на два нижних слоя, ситуация меняется: несколько зелёных или янтарных элементов по краям (рабочие процессы и оценка ADK, отслеживание в OpenAI) расположены среди моря красного цвета, характерного для всех трёх подходов. Именно этот контраст является ключевым выводом. В вопросе создания агента они согласны, но управление его работой и эксплуатацией остаётся на вашей ответственности.

Пробелы в SDK

Слой разработки — это то, что SDK делают простым в использовании. Слои выполнения и управления в них в основном отсутствуют, и, честно говоря, именно это SDK и не предназначены обеспечивать.

Начните с проблем, которые возникли только во время демонстрационной сборки. Одной из них является инструментальный шлюз, который слой выполнения отличает от обычного вызова инструмента. Фреймворк верно вызывает ваш инструмент, но ничего не делает для обеспечения его надежности. Например, API HCS от data.gov.sg иногда возвращает код 503 вместе с телом в формате HTML, и простой вызов response.json() приводил к сбою всей сессии (это был болезненный урок). Помощник _safe_json, таймауты в десять секунд и механизмы обработки случаев «не в списке» решили эту проблему, благодаря чему нестабильность исходного сервиса превратилась в просто отметку, а не в причину сбоя агента. Повторные попытки, стратегии откладывания запросов и обработка ошибок внутри инструментов — всё это на вашей ответственности, ведь именно для этого и предназначен шлюз.

Вторая проблема — это управляемая память. Все три подхода включают слой сессий, представляющий состояние общения на одном узле, но он не является тем же, что приложение, хранящее данные в памяти, к которым может обращаться вся сеть узлов. Файл agent_memory.json, создаваемый здесь (список выученных алиасов, история операций recall_product, данные, обновляющие модель агента с каждой меткой), представляет собой логику доменной обработки, расположенную сверху, и фраза «чем больше вы его используете, тем лучше» не является функцией специальных инструментов. Аналогичная ситуация с использованием реальных данных: парсинг PDF-файлов SFA в более чем 540 структурированных элементов, создание нормализованного индекса и поиск по базовым номерам — ничто из этого не входит в компетенцию SDK, а подача реальных данных агенту — это процесс, который необходимо настроить самостоятельно, а не просто включить какой-то функционал.

Безопасность параллельной работы инструментов хуже, чем просто отсутствие обработки ошибок, поскольку сама среда создаёт угрозу. По умолчанию SDK OpenAI выполняет независимые вызовы инструментов параллельно, и обеспечение их безопасности — ваша ответственность. Ещё один обычный момент: отображение результата и его сохранение в любом месте — это стандартный код приложения, к которому SDK не имеет доступа.

Если смотреть на слой выполнения, агенту сначала необходима хостинговая среда выполнения — способ запуска из источников, отличных от терминальной сессии, с возможностью одновременного выполнения множества задач и автоматическим масштабированием. Ему также требуется идентификатор нагрузки — учетные данные, предоставляемые инструментам, чтобы вызовы осуществлялись через именованную нагрузку, а не с использованием API-ключа, скрытого в переменной окружения. Кроме того, необходимы надежные циклы с возможностью возобновления, чтобы при сбое на середине процесса выполнение продолжалось, а не начиналось заново. Ничего из этого отсутствует в скриптах, находящихся на ноутбуке, и SDK также не обещает предоставлять подобные функции. Слой выполнения должен также обеспечивать масштабирование агентов по мере роста нагрузки.

В плоскости управления все три инструмента практически бесполезны. Оценка — это первый случай: фраза «всё запустилось без ошибок» не означает, что результат верен, а правильная оценка качества агента во многом зависит от вас. ADK является частичным исключением благодаря своей системе оценки, тогда как два остальных оставляют этот вопрос открытым.

Далее — ограничения и защита от внедрения команд. Результат каждого инструмента представляет собой ненадёжный ввод, возвращаемый в модель, и фото метки или ответ API могут содержать инструкцию вроде «игнорируйте свои правила». Уровень покрытия неравномерен, и ничего не происходит автоматически, поэтому модель угроз определяете вы сами.

Затем следует идентичность агента с определением диапазона разрешений. Эти наборы позволяют задать персонажа, но не уточняют статус агента как основного элемента каталога и то, до чего ему разрешено доступать, поэтому связывание его с реальным владельцем и ограничение его диапазона действий остаются на вашей ответственности.

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

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

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

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

Такой SDK, который следует использовать?

Что касается самих наборов, вот краткое описание каждого в одном предложении. Выбирайте Claude Agent SDK, когда агент должен управлять компьютером, работать с файлами, оболочкой, кодом и осуществлять поиск в интернете; это самая зрелая среда выполнения, требующая ручного определения схем, не предусматривающая типизированного вывода и настройки средовых переменных. Выбирайте OpenAI Agents SDK для структурированного ввода и вывода с минимальным использованием Python; он обеспечивает наиболее быстрый типизированный обмен данными, при условии согласия на использование стандартных параллельных инструментов и отсутствие возможности отслеживания действий через прокси. Выбирайте Google ADK, когда несколько агентов должны сотрудничать в рамках четко определенных рабочих процессов с использованием реальных сессий; его интерфейс для разработчиков является самым мощным, а выбор моделей — самым широким, хотя простой одиночный агент может посчитать его слишком тяжелым.

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

Что показало создание трех версий

Создание агента тремя способами привело к однозначному выводу: цикл работы агента — это уже решенная, стандартизированная проблема, и все три набора инструментов эффективно её решают. Настоящие различия кроются в дополнительных компонентах: в ручно написанных или автоматически генерируемых схемах, в выводе в виде свободного текста или в формате с форматированием, а также в наличии полноценной среды выполнения, легкого клиента или полноценной фреймворковой структуры. Это вопросы соответствия задаче, а не качества. Подберите SDK, соответствующий вашей задаче — будь то Claude для управления компьютером, OpenAI для получения форматированного результата или ADK для многоагентных систем — и любой из этих вариантов хорошо вам послужит.

Основной урок заключается в понимании границ, причем три уровня показывают, где они проходят. Сами наборы включают уровень разработки и предоставляют его вам уже к концу дня. Уровни выполнения и управления, то есть реальное управление агентами и координация всей группы, принадлежат вам, и именно здесь сосредоточены основные усилия инженеров. Инструмент для расследований стал полезным только после добавления того, чего не предоставляет ни один SDK: проработанной таблицы SFA для ориентира, механизма обработки сбоев, который обычно находится в инструменте-шлюзе, а также функций, улучшающих его работу с каждой добавленной меткой. Поэтому сначала выберите SDK в зависимости от его соответствия уровню разработки, а затем рассчитайте бюджет на два нижних уровня.

За этой историей скрывается более обширная, находящаяся в более низких уровнях архитектуры. Поскольку создание агентов с использованием одного агента стало обыденностью, конкуренция сместилась на уровень управления этими агентами и определения того, кто ими управляет. Там формируются новые продукты: среды выполнения вроде AWS Bedrock AgentCore и Google’s Gemini Enterprise Agent Runtime, способные запускать любые компоненты, созданные с помощью трех существующих наборов инструментов, а также системы управления, такие как Microsoft’s Agent 365 и Google Enterprise, которые отвечают за регистрацию, идентификацию и контроль всего флота агентов. Они практически полностью предлагают элементы этой архитектуры. Проблема в том, что каждая облачная платформа хочет иметь все три уровня, поэтому SDK, который вы выберете сегодня, завтра может склонить вас к использованию среды выполнения и систем управления конкретного поставщика.

Связанные статьи

  • Память ИИ-агента в 2026 году: сравнение Mem0, Letta, Zep и облачных платформ — Обзор памяти агентов в 2026 году: типы памяти CoALA, Mem0, Letta, Zep, облачные решения, критерии оценки, риски «отравления» данных и выбор оптимальной конфигурации для конкретной задачи.
  • Использование инструментов в производственной среде для агентов: происхождение данных, повторные попытки и возможности мониторинга — Агент банка чрезмерно использовал платную API и сгенерировал вымышленный номер телефона. Рассматриваются минимальные наборы инструментов, происхождение параметров, трехуровневая система повторных попыток и показатели эффективности каждого инструмента.
  • Снимки памяти агента, навыки, затухание данных и ограничение действия памяти по веткам — Четыре дополнения к встроенному слою памяти векторной базы данных для программных агентов: переносимые снимки с возможностью слияния, активация навыков, затухание данных с проверкой конфликтов и память, ограниченная по веткам.
  • Пятиагентская служба поддержки на Gemini 3.1 и ADK: сортировка запросов, исследование, принятие действий, контроль качества и координация — Создание многогранной системы поддержки клиентов с использованием Google ADK и Gemini 3.1: передача задач с указанием формата, циклы коррекции качества, движок агентов или Cloud Run, управление сессиями и расчет затрат.
  • Агенты, совершенствующиеся благодаря навыкам: повторное использование, отбор, исправление и проверка — четырехэтапный подход к созданию агентов, способных улучшать собственные навыки: сохранение рабочего кода, усовершенствование описаний, предложение проверенных исправлений и проверка результата перед передачей.
  • Сокращение расходов на токены RAG на 67% с помощью Qdrant Multivectors и Sentence Isolation — пайплайн для обработки данных в сфере юридического анализа, который переранжирует результаты с использованием ColBERT внутри Qdrant, изолирует соответствующее предложение и позволяет сократить расходы на токены на 67,1% за счет небольшого увеличения задержек.
  • Повторно используемые промпты для ИИ-агентов, которые должен сохранять каждый разработчик — категоризированная библиотека промптов для ревью кода, тестирования, отладки, дизайна, создания документации, работы с Git и обучения, плюс пять привычек, которые помогают сделать любой промпт для агента более эффективным.