Simulare gli errori dalle API OpenAI

A colpo d'occhio
Obiettivo: Testare la gestione degli errori dell'API OpenAI
Tempo: 10 minuti
Plugins:GenericRandomErrorPlugin, RetryAfterPlugin
Prerequisiti:Configurare il proxy di sviluppo

Quando usi le API OpenAI nella tua app, devi testare il modo in cui l'app gestisce gli errori api. Dev Proxy consente di simulare gli errori in qualsiasi API OpenAI usando il GenericRandomErrorPlugin. Con RetryAfterPlugin, Dev Proxy verifica anche che l'app attenda il tempo indicato nell'intestazione Retry-After prima di chiamare nuovamente l'API.

Suggerimento

Scarica questo preset eseguendo il comando nel prompt dei comandi devproxy config get openai-throttling.

Nella cartella del progetto creare un nuovo file denominato devproxyrc.json. Aprire il file in un editor di codice.

Creare un nuovo oggetto nella matrice di plugins che fa riferimento all'GenericRandomErrorPlugin. Definire l'URL dell'API OpenAI per Dev Proxy da monitorare e aggiungere un riferimento alla configurazione del plug-in.

File: 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/*"
  ]
}

Aggiungere RetryAfterPlugin e creare l'oggetto di configurazione del plug-in per fornire a GenericRandomErrorPlugin il percorso delle risposte di errore e la percentuale di richieste che hanno esito negativo.

File: devproxyrc.json (configurazione completa)

{
  "$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

Aggiungi RetryAfterPlugin prima di GenericRandomErrorPlugin nel file di configurazione. Se lo si aggiunge dopo, GenericRandomErrorPlugin fa sì che la richiesta non vada a buon fine prima che RetryAfterPlugin possa controllarla.

Nella stessa cartella creare il file openai-errors.json. Questo file contiene le risposte di errore scelte da Dev Proxy quando Dev Proxy non riesce a gestire una richiesta. Corrispondono agli errori restituiti dall'API OpenAI:

Status error.code Cosa simula
429 rate_limit_exceeded L'app ha raggiunto il limite di token al minuto (TPM) o di richieste al minuto (RPM).
429 slow_down La frequenza delle richieste dell'app è aumentata troppo rapidamente.
429 credit_balance_exhausted L'organizzazione non ha più crediti prepagati. Riprovare non aiuta.
503 server_is_overloaded Il modello è temporaneamente sottoposto a overload.

Per altre informazioni su questi errori, vedere Codici di errore nella documentazione di OpenAI.

Nome file: 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"
            }
          }
        }
      ]
    }
  ]
}

Il valore @dynamic imposta l'intestazione Retry-After e indica a RetryAfterPlugin di tenere traccia della durata dell'attesa dell'app. La credit_balance_exhausted risposta non ha l'intestazione Retry-After, perché aspettare non risolve il problema.

Avviare Dev Proxy nella cartella del progetto:

devproxy

Quando l'app chiama le API OpenAI, Dev Proxy fa fallire il 90% delle richieste con un errore casuale dal file openai-errors.json. Se l'app chiama nuovamente l'API prima dell'ora nell'intestazione Retry-After, RetryAfterPlugin lo segnala e limita la richiesta.

Verifica che la tua app:

  • Attende per il tempo Retry-After dopo un errore rate_limit_exceeded o slow_down.
  • Arresta la chiamata all'API dopo un credit_balance_exhausted errore, invece di riprovare.
  • Riprova con un ritardo dopo un server_is_overloaded errore e mostra un messaggio chiaro quando si esauriscono i tentativi.

Altre informazioni su GenericRandomErrorPlugin.

Vedere anche