← Все статьи

Programmatic Tool Calling в GPT-5.6: руководство по миграции для маршрутизации и агентных workflow

GPT-5.6 вводит Programmatic Tool Calling — модель пишет JavaScript для оркестрации ваших инструментов внутри V8-песочницы, сокращая расход token на 24–63% и устраняя накладные расходы на round-trip. Условие: только Responses API. Разбираем миграцию с классического function calling, каждое breaking change и способ маршрутизации GPT-5.6 через OpenAI-совместимый gateway в переходный период.

· TheRouter

GPT-5.6 вышел 9 июля 2026 года. Его ключевая фича для разработчиков — не очередной benchmark, а Programmatic Tool Calling: механизм, позволяющий модели писать и выполнять JavaScript для координации ваших инструментов в изолированной V8-песочнице. Вместо того чтобы возвращать каждый результат инструмента обратно модели для повторного reasoning, GPT-5.6 может делать loop, branch, фильтрацию промежуточных данных и возвращать только финальный результат. OpenAI сообщает о сокращении output-token в среднем на 24%, а ранние клиенты видят до 63.5% сокращения на tool-heavy workflow.

Обязательное условие: Programmatic Tool Calling работает только с Responses API. Если ваши agent'ы всё ещё вызывают /v1/chat/completions, вы ничего из этого не получите. Это руководство проведёт вас через миграцию — что меняется, что ломается и как безопасно маршрутизировать трафик в переходный период.

  1. Меняйте три значения, а не три SDK. Замените api_key, base_url и model в существующем клиенте OpenAI. Код запроса и ответа оставьте неизменным.
  2. Сопоставьте model ID явно. ID модели у целевого провайдера почти никогда не совпадает с OpenAI ID. Держите словарь { openai_id: target_id } вне бизнес-логики.
  3. Проверьте формат streaming. SSE-чанки должны соответствовать контракту OpenAI: data: {...} + data: [DONE]. Прогоните один streaming вызов до продакшена.
  4. Проверьте rate-limit заголовки. Некоторые провайдеры не возвращают x-ratelimit-*. Добавьте обёртку с безопасным дефолтом.
  5. Оставьте путь отката. Раскатайте замену под feature flag, гоняйте оба endpoint в shadow-режиме 24 часа, затем переключайтесь.

Источники: Анонс OpenAI GPT-5.6, получено 2026-07-19; Документация Programmatic Tool Calling, получено 2026-07-19; Анализ миграции ByteIota, получено 2026-07-19; Цены OpenAI API, получено 2026-07-19.

TL;DR — до и после

ИзмерениеКлассический Function Calling (/v1/chat/completions)Programmatic Tool Calling (Responses API)
ОркестрацияРазработчик скриптует каждый шаг или модель выдаёт один tool call за ходМодель пишет JavaScript для координации инструментов
Round-trip'ыОдин API-вызов на tool → модель → следующий toolОдна программа обрабатывает N tool → единый результат
Расход tokenКаждый промежуточный результат входит в контекстТолько program_output входит в контекст
Параллельные вызовыУправляет разработчик или tool_choice: "auto"Нативный Promise.all() внутри V8-песочницы
Поддерживаемые моделиВсе GPT-4/5.xТолько GPT-5.6 Sol, Terra, Luna
API endpoint/v1/chat/completions/v1/responses

Что такое Programmatic Tool Calling?

При включении Programmatic Tool Calling GPT-5.6 может вернуть элемент типа program, содержащий JavaScript-код. OpenAI выполняет этот код в чистом изолированном V8-runtime. Программа может:

  • Вызывать ваши инструменты через await tools.your_function_name({ ... })
  • Запускать вызовы параллельно с Promise.all()
  • Использовать циклы, условия и промежуточные переменные
  • Фильтровать или агрегировать результаты перед возвратом

Ваше приложение по-прежнему выполняет фактические tool-функции — V8-песочница не имеет сетевого доступа, Node.js API или persistent state. Она оркестрирует; вы исполняете.

Результат: модель видит единственный program_output вместо 10 отдельных function_call_output. Для 10-шагового workflow это примерно 10× меньше накопления контекста.

Breaking Changes

Миграция с /v1/chat/completions на Responses API вносит несколько структурных изменений:

1. Структура ответа полностью меняется

До (Chat Completions):

{
  "choices": [{
    "message": {
      "role": "assistant",
      "tool_calls": [{
        "id": "call_abc123",
        "function": { "name": "get_weather", "arguments": "{\"city\":\"Shanghai\"}" }
      }]
    }
  }]
}

После (Responses API):

{
  "output": [
    {
      "type": "program",
      "call_id": "prog_abc123",
      "code": "const weather = await tools.get_weather({city: 'Shanghai'});\ntext(JSON.stringify(weather));",
      "fingerprint": "fp_xyz..."
    },
    {
      "type": "function_call",
      "call_id": "fc_001",
      "name": "get_weather",
      "arguments": "{\"city\":\"Shanghai\"}",
      "caller": { "caller_id": "prog_abc123" }
    }
  ]
}

Обёртка choices[0].message исчезает. Вы получаете типизированный массив output с разными типами элементов (program, function_call, function_call_output, program_output, message).

2. Декларация tools получает allowed_callers

До:

tools = [
    {"type": "function", "function": {"name": "query_db", "parameters": {...}}}
]

После:

tools = [
    {"type": "programmatic_tool_calling"},  # Включаем фичу
    {
        "type": "function",
        "name": "query_db",
        "parameters": {...},
        "output_schema": {...},  # Помогает JS использовать типизированные результаты
        "allowed_callers": ["programmatic"]  # Или ["direct", "programmatic"]
    }
]

Три ключевых дополнения:

  • Добавить {"type": "programmatic_tool_calling"} в список tools
  • Установить allowed_callers на каждой функции ("direct", "programmatic" или оба)
  • Добавить output_schema для надёжного доступа к полям возврата из JavaScript

3. Параллельная отправка — теперь default

В Responses API GPT-5.6 по умолчанию выдаёт параллельные tool-вызовы. Если ваши handler'ы предполагают последовательное выполнение (например, tool B зависит от side effect tool A), они сломаются без предупреждения. Проведите аудит графа зависимостей инструментов.

4. Ответы по умолчанию хранятся на сервере

В отличие от Chat Completions (stateless), Responses API хранит ответы на стороне сервера по умолчанию. Для чувствительных к конфиденциальности workflow явно задайте store: false. Обратите внимание: store: false включает stateless continuation, но НЕ активирует Zero Data Retention (ZDR) — ZDR нужно включать на уровне организации или проекта.

5. code_interpreter → namespace tools.runtime

Старый тип code_interpreter заменён namespace'ом tools.runtime с per-call billing. Если вы полагаетесь на выполнение кода, учтите это в бюджете.

Пошаговый checklist миграции

Шаг 1: Аудит текущих паттернов tool calling

# Найти все вызовы chat/completions с tools в кодовой базе
grep -rn "chat.completions\|/v1/chat/completions" --include="*.py" --include="*.ts" .
grep -rn "tool_calls\|function_call" --include="*.py" --include="*.ts" .

Классифицировать каждую точку вызова:

  • Один tool call → один результат: Оставить как direct tool calling на Responses API
  • Многошаговые tool-цепочки: Кандидат для Programmatic Tool Calling
  • Semantic judgment между шагами: Оставить как direct (модель должна рассуждать между каждым результатом)

Шаг 2: Мигрировать на Responses API (без Programmatic Tool Calling)

Поменять endpoint и парсинг ответа:

# До
response = client.chat.completions.create(
    model="gpt-5.5",
    messages=[{"role": "user", "content": "..."}],
    tools=[{"type": "function", "function": {"name": "get_weather", ...}}]
)
tool_call = response.choices[0].message.tool_calls[0]

# После — Responses API, классический прямой вызов
response = client.responses.create(
    model="gpt-5.6-terra",
    input=[{"role": "user", "content": "..."}],
    tools=[{"type": "function", "name": "get_weather", "parameters": {...}}]
)
for item in response.output:
    if item.type == "function_call":
        result = execute_tool(item.name, item.arguments)

Шаг 3: Включить Programmatic Tool Calling для подходящих workflow

Для tool-heavy ограниченных workflow:

response = client.responses.create(
    model="gpt-5.6-terra",
    input=[{"role": "user", "content": "Сравни запасы по всем 5 складам"}],
    tools=[
        {"type": "programmatic_tool_calling"},
        {
            "type": "function",
            "name": "get_inventory",
            "parameters": {"type": "object", "properties": {"warehouse_id": {"type": "string"}}},
            "output_schema": {
                "type": "object",
                "properties": {"warehouse_id": {"type": "string"}, "units": {"type": "number"}},
                "required": ["warehouse_id", "units"]
            },
            "allowed_callers": ["programmatic"]
        }
    ]
)

# Обработать tool-вызовы программы
for item in response.output:
    if item.type == "function_call":
        result = execute_tool(item.name, item.arguments)
        # Вернуть результат, связав с программой через caller.caller_id

Шаг 4: Добавить guidance в system prompt

GPT-5.6 хорошо реагирует на явные инструкции по оркестрации:

Используй Programmatic Tool Calling для этапа сбора данных,
применяя только get_inventory и get_metrics.
Независимые вызовы запускай конкурентно.

Обработай промежуточные результаты и верни единый JSON-summary.
При transient failures повтори не более 2 раз.

Для операций записи, требующих одобрения, используй прямые tool-вызовы.

Rollback path

Если Programmatic Tool Calling даёт неожиданные результаты:

  1. Удалить {"type": "programmatic_tool_calling"} из tools — модель fallback'нется на direct tool calling на том же Responses API endpoint
  2. Переключить модель на gpt-5.5 — по-прежнему работает на Responses API с direct calling
  3. Полный откат на Chat Completions — сменить endpoint обратно на /v1/chat/completions и использовать любую модель GPT-5.x

Responses API поддерживает оба режима одновременно. Можно включить Programmatic Tool Calling для одних tool (allowed_callers: ["programmatic"]) и оставить другие только для прямого вызова (allowed_callers: ["direct"]).

Влияние на стоимость

МодельInput / 1M tokensOutput / 1M tokensПримечания
gpt-5.5$5.00$25.00Текущий baseline
gpt-5.6-sol$5.00$30.00Frontier; output +20% vs 5.5
gpt-5.6-terra$2.50$15.00Рекомендуется; input –50%, output –40% vs 5.5
gpt-5.6-luna$1.00$6.00Массовые задачи; input –80%, output –76% vs 5.5

Цены из OpenAI, получено 19 июля 2026.

С Programmatic Tool Calling на Terra комбинированный эффект впечатляющий:

  • Стоимость модели: input –50% / output –40% (Terra vs GPT-5.5)
  • Сокращение token: –24% до –63.5% (меньше round-trip, меньше накопления контекста)
  • Итоговая экономия: обычно 60–80% дешевле за завершённый workflow vs GPT-5.5 с классическим tool calling

Когда НЕ использовать Programmatic Tool Calling

Оставить direct tool calling когда:

  • Каждый результат меняет план — semantic judgment между шагами требует reasoning модели
  • Write-операции требуют approval — сохранить чёткие authorization boundaries
  • Инструменты имеют order-зависимые side effects — V8-песочница может распараллелить вызовы
  • Нужна полная provenance цитирования — program_output сворачивает промежуточные шаги
  • Workflow из одного шага — overhead генерации программы не оправдан для одного вызова

Ограничения V8-песочницы

V8-runtime имеет жёсткие лимиты:

  • Нет сетевого доступа (инструменты — единственный внешний интерфейс)
  • Нет Node.js API, нет require(), нет import пакетов
  • Нет persistent state между выполнениями
  • Нет console.log (используйте text() или image() для вывода)
  • Нет subprocess execution или доступа к файловой системе
  • Можно вызывать только tool с allowed_callers: ["programmatic"]

Это security-фичи. Программа может взаимодействовать с внешними системами только через явно opted-in инструменты.

Маршрутизация через OpenAI-совместимый gateway

Если вы маршрутизируете API-трафик через TheRouter или другой OpenAI-совместимый gateway, путь миграции тот же — укажите base_url на ваш gateway и используйте gpt-5.6-terra как model ID. Формат Responses API проходит транспарентно, когда ваш gateway его поддерживает.

Для команд в процессе миграции типичный паттерн:

  1. Маршрутизировать трафик gpt-5.6-terra через gateway для новых workflow с Programmatic Tool Calling
  2. Оставить gpt-5.5 на fallback-маршруте для существующего Chat Completions кода
  3. Мигрировать call site'ы инкрементально; мониторить расход token по маршрутам

Это избегает big-bang cutover и позволяет сравнивать расходы side-by-side.

Timeline и рекомендации

Временные рамкиДействие
СейчасАудит tool-calling паттернов; классификация на programmatic-eligible или direct-only
Неделя 1–2Миграция на Responses API с direct tool calling (без Programmatic Tool Calling)
Неделя 2–3Включение Programmatic Tool Calling на ограниченных tool-heavy workflow
Неделя 3–4Benchmark экономии token; подбор tier модели (Sol → Terra → Luna) по качеству
Q1 2027response_format: {"type": "json_object"} теряет guaranteed-shape — миграция на JSON Schema 2025-12

FAQ

Q: Обязательно ли использовать Programmatic Tool Calling для работы с GPT-5.6? Нет. GPT-5.6 работает со стандартным direct tool calling на Responses API. Programmatic Tool Calling — opt-in через тип programmatic_tool_calling.

Q: Можно ли использовать Programmatic Tool Calling с Chat Completions API? Нет. Требуется Responses API (/v1/responses).

Q: Как со streaming? Responses API поддерживает streaming. События выполнения программы стримятся по мере их возникновения — вы увидите program, function_call и program_output элементы инкрементально.

Q: GPT-5.6 есть в models-data.ts TheRouter? На момент написания ещё нет. Model ID GPT-5.6 (gpt-5.6-sol, gpt-5.6-terra, gpt-5.6-luna) подтверждены через API OpenAI, но могут быть не отражены во всех routing-конфигурациях. Проверьте live endpoint /models/ вашего gateway.


GPT-5.6 вышел 9 июля 2026. Документация Programmatic Tool Calling актуальна на момент написания (19 июля 2026). Цены, доступность моделей и ограничения песочницы могут измениться — перед production-deployment проверяйте официальную документацию OpenAI.

Внутренние ссылки

Модели, упомянутые в статье

Помощь и контакты