Имитация ошибок из API OpenAI

На первый взгляд
Цель: Проверка обработки ошибок API OpenAI
Время: 10 минут
Подключаемые модули:GenericRandomErrorPlugin, RetryAfterPlugin
Предварительные требования:настройка прокси-сервера разработки

При использовании API OpenAI в приложении необходимо проверить, как приложение обрабатывает ошибки API. Прокси Dev позволяет имитировать ошибки в любом API OpenAI с помощью GenericRandomErrorPlugin. При использовании RetryAfterPlugin прокси-сервер разработки также проверяет, ждет ли приложение столько времени, сколько указано в заголовке Retry-After, перед тем как снова вызвать API.

Кончик

Скачайте эту предустановку, выполнив команду в командной строке devproxy config get openai-throttling.

В папке проекта создайте новый файл с именем devproxyrc.json. Откройте файл в редакторе кода.

Создайте новый объект в массиве plugins, ссылающегося на GenericRandomErrorPlugin. Определите URL-адрес API OpenAI для прокси-сервера разработки для отслеживания и добавьте ссылку на конфигурацию плагина.

Файл: devproxyrc.json

{
  "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/rc.schema.json",
  "plugins": [
    {
      "name": "GenericRandomErrorPlugin",
      "enabled": true,
      "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
      "configSection": "openAIAPI"
    }
  ],
  "urlsToWatch": [
    "https://api.openai.com/*"
  ]
}

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

Файл: devproxyrc.json (полная конфигурация)

{
  "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/rc.schema.json",
  "plugins": [
    {
      "name": "RetryAfterPlugin",
      "enabled": true,
      "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll"
    },
    {
      "name": "GenericRandomErrorPlugin",
      "enabled": true,
      "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
      "configSection": "openAIAPI"
    }
  ],
  "urlsToWatch": [
    "https://api.openai.com/*"
  ],
  "openAIAPI": {
    "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/genericrandomerrorplugin.schema.json",
    "errorsFile": "openai-errors.json",
    "rate": 90
  }
}

Caution

Добавьте RetryAfterPlugin перед GenericRandomErrorPlugin в вашем файле конфигурации. Если вы добавите его после, GenericRandomErrorPlugin отклоняет запрос, прежде чем RetryAfterPlugin сможет его проверить.

В той же папке создайте файл openai-errors.json. Этот файл содержит ответы об ошибках, из которых Dev Proxy выбирает, когда не удается выполнить запрос. Они соответствуют ошибкам, возвращающим API OpenAI:

Status error.code Что это имитирует
429 rate_limit_exceeded Ваше приложение достигло лимита токенов в минуту (TPM) или запросов в минуту (RPM).
429 slow_down Частота запросов вашего приложения увеличилась слишком быстро.
429 credit_balance_exhausted У вашей организации нет предоплаченных кредитов. Повторные попытки не помогают.
503 server_is_overloaded Модель временно перегружена.

Дополнительные сведения об этих ошибках см. в разделе коды ошибок в документации OpenAI.

Файл: openai-errors.json

{
  "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/genericrandomerrorplugin.errorsfile.schema.json",
  "errors": [
    {
      "request": {
        "url": "https://api.openai.com/*"
      },
      "responses": [
        {
          "statusCode": 429,
          "headers": [
            {
              "name": "content-type",
              "value": "application/json; charset=utf-8"
            },
            {
              "name": "Retry-After",
              "value": "@dynamic"
            }
          ],
          "body": {
            "error": {
              "message": "Rate limit reached for gpt-4.1 in organization org-K7hT684bLccDbBRnySOoK9f2 on tokens per min (TPM): Limit 30000, Used 30000, Requested 1200. Please try again in 2.4s. Visit https://platform.openai.com/settings/organization/limits to learn more.",
              "type": "tokens",
              "param": null,
              "code": "rate_limit_exceeded"
            }
          }
        },
        {
          "statusCode": 429,
          "headers": [
            {
              "name": "content-type",
              "value": "application/json; charset=utf-8"
            },
            {
              "name": "Retry-After",
              "value": "@dynamic"
            }
          ],
          "body": {
            "error": {
              "message": "Rate limit reached for gpt-4.1 in organization org-K7hT684bLccDbBRnySOoK9f2 on requests per min (RPM): Limit 500, Used 500, Requested 1. Please try again in 120ms. Visit https://platform.openai.com/settings/organization/limits to learn more.",
              "type": "requests",
              "param": null,
              "code": "rate_limit_exceeded"
            }
          }
        },
        {
          "statusCode": 429,
          "headers": [
            {
              "name": "content-type",
              "value": "application/json; charset=utf-8"
            },
            {
              "name": "Retry-After",
              "value": "@dynamic"
            }
          ],
          "body": {
            "error": {
              "message": "Your request rate increased too quickly. Reduce your request rate and increase it gradually.",
              "type": "rate_limit_error",
              "param": null,
              "code": "slow_down"
            }
          }
        },
        {
          "statusCode": 429,
          "headers": [
            {
              "name": "content-type",
              "value": "application/json; charset=utf-8"
            }
          ],
          "body": {
            "error": {
              "message": "Your organization has no prepaid credits remaining. Add credits to continue using the API. For more information on this error, read the docs: https://developers.openai.com/api/docs/guides/error-codes.",
              "type": "insufficient_quota",
              "param": null,
              "code": "credit_balance_exhausted"
            }
          }
        },
        {
          "statusCode": 503,
          "headers": [
            {
              "name": "content-type",
              "value": "application/json; charset=utf-8"
            }
          ],
          "body": {
            "error": {
              "message": "The requested model is temporarily overloaded. Please try again later.",
              "type": "service_unavailable_error",
              "param": null,
              "code": "server_is_overloaded"
            }
          }
        }
      ]
    }
  ]
}

Значение @dynamic задает заголовок Retry-After и указывает RetryAfterPlugin отслеживать, как долго приложение должно ждать. У Retry-After ответа нет credit_balance_exhausted заголовка, так как ожидание не исправляет это.

Запустите прокси-сервер разработки в папке проекта:

devproxy

Когда приложение вызывает API OpenAI, прокси-сервер разработки вызывает ошибку в 90% запросов со случайной ошибкой из файла openai-errors.json. Если приложение снова вызывает API до времени, указанного в заголовке Retry-After, RetryAfterPlugin сообщает об этом и ограничивает частоту запросов.

Убедитесь, что ваше приложение:

  • Retry-After Ожидает в течение времени после ошибки rate_limit_exceeded или slow_down.
  • Перестает вызывать API после ошибки credit_balance_exhausted, вместо повторной попытки.
  • Повторяет попытки с задержкой после ошибки server_is_overloaded и отображает четкое сообщение, когда попытки заканчиваются.

Дополнительные сведения о genericRandomErrorPlugin.

См. также