模擬 OpenAI API 的錯誤

一目了然
目標: 測試 OpenAI API 錯誤處理
時間: 10分鐘
插件:GenericRandomErrorPlugin、 RetryAfterPlugin
前置條件:設定開發代理

當您在應用程式中使用 OpenAI API 時,您應該測試應用程式如何處理 API 錯誤。 Dev Proxy 可讓您使用 GenericRandomErrorPlugin,模擬任何 OpenAI API 上的錯誤。 使用 RetryAfterPlugin,開發代理也會檢查你的應用程式是否在等待 Retry-After 標頭中指定的時間後,才再次呼叫 API。

提示

在命令提示字元中執行 devproxy config get openai-throttling以下載此預設。

在你的專案資料夾中,建立一個名為 devproxyrc.json. 的新檔案。 在程式代碼編輯器中開啟檔案。

在參考 plugins的 GenericRandomErrorPlugin 陣列中建立新的物件。 為 Dev Proxy 定義 OpenAI API URL,並在外掛程式設定中新增參考。

檔案: 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 在使要求失敗時會選擇的錯誤回應。 它們與 OpenAI API 回傳的錯誤相符:

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 追蹤你的應用程式必須等待多久。 credit_balance_exhausted回應沒有 Retry-After標頭,因為等待無法解決問題。

在你的專案資料夾中啟動開發代理:

devproxy

當你的應用程式呼叫 OpenAI API 時,Dev Proxy 會使 90% 的請求失敗,並顯示來自 openai-errors.json 檔案的隨機錯誤。 如果你的應用程式在 Retry-After 標頭中的時間之前再次呼叫 API,RetryAfterPlugin 會回報此情況並節流該要求。

請檢查你的應用程式:

  • 在發生slow_down或Retry-After錯誤後,等待rate_limit_exceeded時間。
  • 發生 credit_balance_exhausted 錯誤後停止呼叫 API,而不是重試。
  • server_is_overloaded 錯誤後會延遲重試,重試用盡時會顯示清晰訊息。

深入瞭解 GenericRandomErrorPlugin。

另請參閱