Как OpenAI Agents API ведёт долгоживущего AI-агента? Context, Tools, Subagents и JSON-состояние (2026)
Публичная бета 10 сентября — не «ещё один чат». OpenAI отдал harness, на котором Codex уже шёл сутками: Session продолжается, контекст уплотняется, у каждого субагента своё окно. Здесь только о том, как длинная задача выживает: какой JSON хранить, что сжимает OpenAI, какие items читать после обрыва.
Перед чтением
| Объект | Что делает | Что хранить |
|---|---|---|
| Session | Устойчивый экземпляр на часы и окна | session_id |
| Turn | Асинхронная работа от одного ввода | turn_id / финальные события |
| Items | Сохранённые сообщения и вызовы инструментов | Повтор после обрыва |
| Compact | Автосжатие у предела окна | Ключевые поля — у вас |
| Subagent | Свой контекст, параллельная работа | Потолок параллелизма |
Простаивающая session — не успех. Смотрите события turn и items, не последнее предложение.
Длинная задача живёт в Session, не в более длинном prompt
Ответ Agents API конкретен: создать устойчивую session и слать дальнейший ввод на тот же session_id. Близко к пределу контекста harness сам уплотняет раннюю работу. Независимые подзадачи можно отдать субагенту. Полный чат заново не собираете.
- Продолжить: привязать
session_idк вашему разговору. Не открывать вторую session на тот же случай. - Обрыв: поток не переигрывается. Забрать session и items. Не считать, что клиент помнит прошлый прыжок.
- Деньги и номера: compact роняет детали. Номера заказов, суммы, согласования — в вашем JSON.
Как Session стыкуется с JSON инструментов: Разбор OpenAI Agents API. Кому держать цикл: Agents API vs Responses API. Если Agent и Function Calling ещё одно слово — сначала Полный гид по AI-агенту.
Session продолжается; Turn идёт асинхронно
Создать один раз: модель, инструменты, среду, multi_agent. Официально: POST /v1/agents/sessions с OpenAI-Beta: agents=v1. Хостинг-песочница: openai_hosted:
{
"agent": {
"model": "gpt-6-astra",
"instructions": "Look up orders. Confirm before any refund. Delegate independent lookups to subagents.",
"tools": [
{
"type": "function",
"name": "lookup_order",
"parameters": {
"type": "object",
"properties": {
"order_id": { "type": "string", "pattern": "^[A-Z]-\\d{4}$" }
},
"required": ["order_id"],
"additionalProperties": false
}
},
{ "type": "web_search" }
],
"multi_agent": { "enabled": true, "max_concurrent_subagents": 3 }
},
"environment": { "type": "openai_hosted", "workspace_directory": "/workspace" },
"input": [
{
"role": "user",
"content": [{ "type": "input_text", "text": "Look up A-1042 and keep the case open." }]
}
]
}
Ещё одно agent.session.input.message в ту же session. Простой открывает новый turn; активный направляет текущий. Отмена — agent.session.input.cancel: session и сохранённая работа остаются:
{
"events": [
{
"type": "agent.session.input.message",
"input": [
{
"role": "user",
"content": [
{ "type": "input_text", "text": "Warehouse marked A-1042 packed. Continue." }
]
}
]
}
]
}
Смотреть исход, не «простоит ли». Официальные события: agent.session.turn.completed, failed, cancelled. Завершённый turn не значит, что каждый инструмент успешен. Нужен результат функции — читать required_actions.
Цепочка инструментов тянется часами; запись назад — всё ещё JSON
На длинной задаче модель по-прежнему только заполняет аргументы. Когда ваша функция настала, harness останавливается; вы возвращаете результат по turn_id / call_id. Через четыре часа форма та же:
{
"type": "tool_result",
"turn_id": "turn_4",
"call_id": "call_3c91",
"success": true,
"output": "{\"order_id\":\"A-1042\",\"status\":\"packed\"}"
}
Функции нужны вы. MCP и web_search может выполнить harness. Субагенты наследуют MCP и веб-поиск; function-инструменты не наследуют. Побочные эффекты по вашим заказам остаются у главного агента.
Дверь по-прежнему Schema. Широкий object на длинном прогоне опаснее: после compact модель чаще выдумает номер. MCP — ещё одна таблица инструментов; граница в MCP Tool Schema vs Function Calling.
Compact сжимает окно, не вашу книгу учёта
Официально: когда session подходит к пределу, Agents API сам уплотняет ранний контекст, чтобы работа перешла через окна. Этот компрессор писать не нужно. Это не слой context_management / /responses/compact у Responses.
- Agents API: session сжимает себя. Забрать items и проверить, что номер заказа ещё там.
- Responses: включить compact или вызвать endpoint compact. Зашифрованный compaction item передать дальше, не обрезать руками.
- Оба: сжатие роняет детали. Суммы, подтверждения, выпуски пишет хозяин.
Если order_id живёт только в чате, книгу учёта отдали сводке. Schema как дверь: Зачем ИИ нужен JSON Schema.
Субагенты: параллельно, но контекст раздельный
С multi_agent.enabled harness даёт create, message, wait и interrupt. Эти инструменты не объявляете. Координация видна как items:
{
"data": [
{
"type": "function_call",
"turn_id": "turn_4",
"call_id": "call_3c91",
"name": "lookup_order",
"arguments": "{\"order_id\":\"A-1042\"}"
},
{
"type": "create_subagent_call",
"agent_id": "agent_main",
"task": "Compare A-1042 packing notes with the invoice."
}
]
}
- Свой контекст: у каждого субагента один. Главный агент закрывает create / message / wait / interrupt.
- Ограничить параллелизм: по умолчанию 6, без координатора. В проде закрепить меньшее число.
- Готовый item ≠ готовая подзадача: завершённый
create_subagent_callзначит только «отправлено». Смотретьagent.session.subagent.createdи items этого субагента.
Handoff должен быть проверяемым JSON, не «передайте в биллинг». Как уложить в Schema: JSON Schema и рабочие процессы агента.
Держите своё состояние; не просите compact его помнить
OpenAI хранит конфигурацию session, разговор и сохранённую работу. Вам всё равно нужен деловой объект, который соберётся после обрыва:
{
"session_id": "sess_8f21",
"order_id": "A-1042",
"last_turn_id": "turn_4",
"last_call_id": "call_3c91",
"awaiting": "tool_result",
"compact_checkpoint": "after_turn_3"
}
Этот объект — не Session, не SDK session, не Responses conversation и не sandbox. Удаление одного не чистит остальные. Резидентность данных пока только США; своя песочница не делает API ZDR.
Пять шагов, чтобы закрыть задачу через окна
Не восстанавливать демо задом наперёд. Идти по объектам:
- Создать одну session и записать
session_idв разговор. Таблицу инструментов и Schema затянуть один раз. - Подписаться, потом слать дальше. Открыть поток до
agent.session.input.message, иначе ранние события пропадут. - На required_actions писать назад. Тот же
turn_id/call_id. Не повторять на новой session. - После обрыва — список items. Поток не переигрывается.
order=ascи сверить номер заказа и открытые вызовы. - После compact снова сверить книгу. Если сводка потеряла
A-1042, следующий прыжок выдумает номер.
Все пять стоят на объектах. Пропустить шаг — поставить на то, что окно ещё не полное.
Разбирать длинную задачу — разложить два JSON-следа
Большинство сбоев — несовпадение объектов, не более глупая модель.
- формат items session рядом с локальным состоянием. Проверить, что
session_id/call_idсходятся. - извлечь JSONPath вытащить
order_id,turn_idиagent_idсубагента. - JSON Diff items до и после compact. Номер поплыл — сначала сжатие, потом модель.
- Items главного агента и субагента — отдельными списками. В одной странице координация прилипнет не к тому.
- Не вставлять заказы, session и внутренний MCP в публичный форматтер. JSONSort работает в браузере локально.
Если оба следа собираются заново, задачу продолжили. Иначе снова угадали.
Частые ловушки
- Считать простой успехом. Сначала
turn.completed/failed/cancelled, потом результаты инструментов. - Ждать переигрывания потока после обрыва. Официально: нет. Забрать session и items.
- Оставить номер заказа только в чате. После compact сводка может потерять
A-1042. - Включить multi_agent без потолка. Умолчание 6 всё равно разворачивает токены и побочные эффекты.
- Отдать function субагенту. Субагенты не поддерживают function-инструменты. Поиск заказа — у главного агента.
- Считать Session и Conversation одним ресурсом. Удаление одного не чистит другое.
FAQ
Долгий прогон — это просто более длинный prompt?
Нет. Это устойчивая session, автоматический compact и деловой JSON, который держите вы. Более длинный системный prompt не поднимает предел окна.
Можно смешивать compact Agents и compact Responses?
Нельзя. Session Agents сжимает себя. Responses использует context_management или /responses/compact. Два ресурса, два следующих входа окна.
Как восстановиться после обрыва?
Загрузить session и items по сохранённому session_id. Поток не переигрывает пропущенные события. Выровнять last_turn_id и открытый call_id, затем записать назад или послать следующее сообщение.
Может ли субагент вызвать мой lookup_order?
Нет. Официально: function-инструменты не поддерживаются. Наследуют MCP, веб-поиск и файлы / команды среды. Поиск своих заказов остаётся у главного агента.
Своя песочница даёт Zero Data Retention?
Нет. Официально: Agents API сейчас только с резидентностью в США и без ZDR. Self-hosted песочница этого не меняет.
Вывод
Долгий прогон — не более умная модель. Это устойчивая Session, автоматический compact и JSON-состояние, которое держите вы. Аргументы инструментов, события turn, items субагента — объекты на этой цепи.
Сначала запишите, соберёте ли A-1042 после обрыва. Если да, задача жива. Модели сменятся; session_id и Schema должны устояться раньше.
Дальше
- OpenAI Agents API, полный разбор Как стыкуются Session, tool calling и Schema
- Agents API vs Responses API Кто должен крутить цикл
- Что такое AI-агент? Полный гид Среда выполнения и JSON-контракт
- Зачем ИИ нужен JSON Schema Schema / Function Calling / Structured Output
- JSON Schema и рабочие процессы агента Уложить инструменты и состояние в Schema
- Локальный ящик JSONSort Формат, проверка, Diff
- Все статьи Ещё заметки про JSON и ИИ
Журнал изменений: Первая публикация