Создайте уровень совместимости API ответов в шлюзе AI API
Шлюз API ответов — это не просто прокси-сервер Chat Completions с новым маршрутом. Сохраняйте элементы ответа, состояние, вызовы инструментов, потоки, непрерывность рассуждений, атрибуцию использования и поведение при переходе на более раннюю версию с помощью первоклассного уровня совместимости.
Не реализуйте /v1/responses, переводя каждый запрос в /v1/chat/completions и надеясь, что форма будет достаточно близкой. Этот адаптер может возвращать текст, но он может незаметно потерять те части, которые важны для разработчиков: элементы ответа, состояние на стороне сервера, вызовы инструментов, непрерывность рассуждений, события жизненного цикла потока, семантику отмены и атрибуцию использования на уровне элементов.
Практическая цель — уровень совместимости, который рассматривает API ответов как более функциональный протокол. Сохраните поддержку завершения чата для существующих клиентов, но создайте ответы как отдельную поверхность шлюза со своей собственной моделью состояния, нормализатором потока, реестром вызовов инструментов, матрицей возможностей и резервными правилами.
Что такое факт, что такое политика и что такое прогноз?
Факты. OpenAI описывает API ответов как объединяющий возможности, которые ранее были разделены на функции завершения чата и помощников, включая поддержку таких инструментов, как веб-поиск, поиск файлов и использование компьютера. API предоставляет такие поля, как previous_response_id, потоковую передачу, выбор инструментов и встроенные инструменты. Документация SDK показывает, что previous_response_id может обеспечить непрерывность диалога, в то время как предыдущие инструкции не переносятся автоматически и должны быть отправлены повторно, когда они все еще должны применяться. Справочник по потоковой передаче OpenAI включает в себя отдельные жизненный цикл ответа и выходные события, а не только дельты токенов.
Рекомендации. Шлюз должен сохранять эту семантику, а не сглаживать ее по умолчанию. Он должен отклонять или явно понижать запросы, если целевой поставщик не может поддерживать требуемое поведение.
Прогноз. Дополнительные рабочие нагрузки агента будут зависеть от структуры элементов ответа, трассировок выполнения инструментов и контекста рассуждений с отслеживанием состояния. Шлюзы, которые моделируют эти концепции, теперь будет легче расширять, чем шлюзы, которые рассматривают ответы как косметическую конечную точку.
Определить отдельный контракт совместимости для ответов
Первая ошибка реализации заключается в предположении, что совместимость с OpenAI означает одну универсальную схему запроса и ответа. На практике /v1/chat/completions и /v1/responses должны быть отдельными контрактами совместимости.
Сохраните общий уровень аутентификации, выставления счетов, квот и маршрутизации, но отделите уровень протокола:
<ул>Это разделение имеет значение для тестов на соответствие. Адаптер поставщика, который проходит тесты чата, по-прежнему может не пройти тесты ответов, поскольку он не может сохранить previous_response_id, порядок элементов, структуру отказа, метаданные размещенного инструмента или названия событий потоковой передачи.
Минимальный контракт совместимости должен отвечать:
<ул>store=false?Если у вас уже есть шлюз AI API, рассматривайте поддержку ответов как расширение протокола, а не псевдоним маршрута.
Используйте каноническую модель ответа
API Responses возвращает более одного сообщения помощника. Он может представлять различные выходные элементы и события. Вашему шлюзу необходима внутренняя каноническая модель, прежде чем он будет сопоставлен с каким-либо поставщиком.
Практическая схема внутреннего элемента может начинаться так:
{
"gateway_response_id": "gw_resp_...",
"provider_response_id": "resp_...",
"tenant_id": "ten_123",
"key_id": "key_456",
"model_alias": "агент-по умолчанию",
"провайдер": "openai",
"предметы": [
{
"item_id": "item_1",
"тип": "текст",
"роль": "помощник",
"content": [{ "type": "output_text", "text": "..." }],
"статус": "завершено"
},
{
"item_id": "item_2",
"type": "function_call",
"call_id": "call_abc",
"name": "lookup_order",
"arguments_json": "{\"order_id\":\"123\"}",
"статус": "завершено"
}
],
"использование": {
«входные_токены»: 0,
«выходные_токены»: 0,
"reasoning_tokens": ноль,
"tool_units": []
},
"статус": "завершено"
Включайте типы товаров еще до того, как каждый поставщик сможет их произвести. Полезные категории включают в себя:
<ул>Смысл в том, чтобы не предоставлять пользователям закрытую схему. Цель состоит в том, чтобы шлюз не выбрасывал информацию до того, как он сможет ее проверить, выставить счет, транслировать, воспроизвести или преобразовать.
Создайте государственную книгу, принадлежащую шлюзу
previous_response_id — это поле, которое наиболее наглядно демонстрирует разницу между проксированием чата без сохранения состояния и совместимостью ответов. Если клиент ссылается на предыдущий ответ, шлюз должен знать, что означает этот идентификатор, разрешено ли арендатору использовать его и может ли поставщик продолжить работу с ним.
Создайте реестр штата с указанием арендатора и идентификатора ответа:
{
"gateway_response_id": "gw_resp_789",
"provider_response_id": "resp_provider_789",
"previous_gateway_response_id": "gw_resp_456",
"tenant_id": "ten_123",
"user_id": "user_999",
"key_id": "key_456",
"модель": "gpt-...",
"провайдер": "openai",
"store_mode": "провайдер|шлюз|нет",
"retention_policy": "standard|zero_retention|custom_30d",
"instructions_hash": "sha256:...",
"tool_policy_id": "tools_readonly_v3",
"create_at": "...",
"expires_at": "...",
«deleted_at»: ноль
Важное правило: не эмулируйте автоматически previous_response_id путем воспроизведения полной истории чата, если клиент явно не разрешил такое поведение по удержанию и затратам. Воспроизведение может увеличить стоимость токена, изменить положение конфиденциальности и изменить поведение модели. Безопаснее вернуть явную ошибку возможности, чем молча отправлять сохраненный контент разговора, который приложение не ожидало сохранить или повторно использовать.
Режимы обработки состояний
<ул>store=false или политика клиента запрещает сохранение. previous_response_id следует отклонять, если поставщик не может обработать запрос без сохранения шлюза и это разрешено политикой.Также помните, что клиенту может потребоваться повторно отправить предыдущие инструкции, когда они продолжат действовать. Шлюзу не следует изобретать скрытые инструкции для компенсации, если такое поведение не является частью явной политики клиента.
Проверка инструментов перед отправкой
Отклики делают использование инструмента более централизованным. Уровень совместимости должен обрабатывать две широкие категории:
<ул>При входе проверьте схемы инструментов перед маршрутизацией:
<ул>Для вызова функций приложения требуется стабильный идентификатор вызова. Модель генерирует вызов функции с call_id; приложение отправляет выходные данные инструмента со ссылкой на этот идентификатор; шлюз записывает оба в одну и ту же трассировку. Без этого ключа объединения журналы аудита и повторные попытки становятся неоднозначными.
Для размещенных инструментов зарезервируйте бюджет перед отправкой и оплатите стоимость позднее. Размещенные инструменты могут добавлять расходы, выходящие за рамки обычного учета токенов, поэтому подключите реестр инструментов к унифицированному выставлению счетов AI API, а не скрывайте эти затраты внутри общей суммы вызовов модели.
Нормализация потоковой передачи как событий, а не текста токена
Прокси-серверу чата часто удается избежать пересылки дельт токенов. Шлюз ответов не может. Поток имеет смысл жизненного цикла: ответ может начинаться, элементы вывода могут начинаться и завершаться, текст может поступать в дельтах, вызовы инструментов могут собираться постепенно, использование может поступать в конце или во время потока, а ответ может завершиться с ошибкой или быть отменен.
Определите схему событий шлюза, а затем сопоставьте с ней каждый поток поставщика:
событие: response_started
данные: { "response_id": "gw_resp_123", "status": "in_progress" }
событие: выход_item_startedданные: { "item_id": "item_1", "type": "text" }
событие: text_delta
данные: { "item_id": "item_1", "delta": "Привет" }
событие:tool_call_delta
data: { "item_id": "item_2", "call_id": "call_abc", "arguments_delta": "{\"order" }
событие: use_delta
данные: { "output_tokens": 12 }
событие: завершено
данные: { "response_id": "gw_resp_123", "usage": { ... }
Рекомендуемые нормализованные события:
<ул>response_startedoutput_item_startedoutput_item_completedtext_deltarefusal_deltatool_call_deltatool_result_receivedusage_deltaзавершеноотмененоне удалосьКогда клиент отключается, распространите отмену вверх по течению, если провайдер поддерживает это. Запишите состояние частичного ответа в любом случае. Если позже поставщик возвращает окончательное использование через отложенный обратный вызов или финальный фрагмент, согласуйте реестр. Совместимость потоковой передачи зависит не только от задержки, но и от учета и жизненного цикла.
Создайте матрицу возможностей поставщика
Мультимодельная маршрутизация полезна только тогда, когда шлюз понимает, что можно безопасно маршрутизировать. Добавьте возможности, специфичные для ответов, в каталог моделей:
{
"model_alias": "агент-по умолчанию",
"маршруты": [
{
"провайдер": "openai",
"модель": "...",
«supports_responses»: правда,
«supports_previous_response_id»: правда,
«supports_store_false»: правда,
«supports_builtin_web_search»: правда,
«supports_function_calling»: правда,
«supports_stream_lifecycle_events»: правда,
«supports_reasoning_context_continuity»: правда,
"max_tool_schema_bytes": 65536
},
{
"провайдер": "provider_b",
"модель": "...",
"supports_responses": ложь,
«chat_adapter_available»: правда,
"loss_profile": ["no_previous_response_id", "no_hosted_tools", " Flattened_stream"]
}
]
Резервный вариант должен учитывать потери. Если для запроса требуется встроенный веб-поиск, а резервный поставщик не может его выполнить, не отвечайте молча без поиска. Если запрос зависит от сохраненного контекста обоснования и резервный маршрут не может его сохранить, верните ошибку возможности или ответ на понижение версии, на который клиент явно согласился.
Полезный вариант запроса:
{
"модель": "агент-по умолчанию",
"вход": "...",
"fallback_policy": {
«allow_lossy»: ложь,
"allow_losses": []
}
Для менее деликатных случаев использования арендаторы могут разрешить понижение версии с потерями:
{
"fallback_policy": {
«allow_lossy»: правда,
"allowed_losses": [" Flattened_stream", "no_reasoning_summary"]
}
Шлюз в любом случае должен регистрировать резервное решение. Это делает возможной последующую отладку, когда агент ведет себя по-другому после сбоя провайдера или перенаправления модели.
Использование атрибутов на уровне ответа и элемента
Вызовы ответов могут стоить дороже, чем эквивалентное завершение чата, поскольку они могут включать в себя выполнение инструмента, более длинный контекст, токены рассуждения, поиск файлов, поиск в Интернете или повторяющиеся инструкции. Одного совокупного количества токенов недостаточно для панели анализа использования AI API.
Запись использования на двух уровнях:
<ул>Это позволит разработчикам ответить на конкретные вопросы:
<ул>Относиться к нулевому хранению и удалению как к первоклассному поведению
Состояние на стороне сервера полезно, но оно меняет обязательства шлюза по хранению. Встройте политику на уровне протокола, а не рассматривайте ее как настройку журнала.
Для каждого запроса ответов выполните следующее:
<ул>магазина на уровне запросаЕсли хранение отключено, шлюз по-прежнему может хранить минимальные рабочие метаданные: метки времени, идентификаторы, статус, количество токенов, стоимость и решения политики. Не храните необработанные запросы, полные выходные данные инструмента или восстановленную историю, если это не разрешено политикой.
Добавление соответствия перед запуском
Не полагайтесь на ручные тесты «счастливого пути». Добавьте приспособления, которые проверяют поведение протокола на прямых маршрутах OpenAI, маршрутах, адаптированных поставщиком, и резервных сценариях.
Минимальный набор тестов
<ул>previous_response_id; шлюз проверяет право собственности арендатора и режим состояния.Рекомендуемая последовательность развертывания
<ол>/v1/responses, не меняя существующее поведение чата.Практическое заключение
Уровень совместимости API ответов должен сохранять значение протокола, а не просто возвращать правдоподобный текст. Создайте его на основе пяти надежных объектов: канонической модели элементов ответа, реестра состояний диалога, журнала вызовов инструментов, нормализатора потоковой передачи событий и матрицы возможностей поставщика.
Самым безопасным значением по умолчанию является строгая совместимость: если маршрут не может сохранить требуемое состояние, инструменты, контекст обоснования, потоковые события или поведение хранения, возвращайте явную ошибку возможности. Добавляйте резервный вариант с возможностью потери данных только тогда, когда разработчики поймут, что будет удалено. Этот подход может показаться менее удобным, чем автоматическое выравнивание, но он предотвращает худший вариант отказа: приложение, которое выглядит совместимым, молча теряя семантику, которая заставила его в первую очередь использовать API Responses.