AIコーディング 2026.05.14

OpenAI APIエラーの解決方法:429・トークン超過・ChatCompletionエラーの対処法と実装例

タグ:OpenAI / API / エラー対処

OpenAI APIで頻発するエラーの全体像

OpenAI APIを使って開発を進めていると、予期しないエラーに遭遇することは多いです。特に本番環境に移行する段階で、429エラー(レート制限)、トークン超過エラー、ChatCompletionエラーといった主要なエラーが立ちはだかります。これらは発生原因や対処方法が異なるため、正しく理解して対応することが重要です。

エラー1:429「You exceeded your current quota」

症状と発生条件

APIリクエストを送信した際に、以下のエラーメッセージが返される場合があります。

エラーメッセージ(原文):

RateLimitError: 429 You exceeded your current quota, please check your plan and billing details

日本語訳: 「現在のクォータを超過しました。ご自身のプランと請求詳細を確認してください」

このエラーが出るのは、大きく分けて複数の原因があります。月間の利用上限に達した場合、無料トライアル期間の終了、クレジットカードの有効期限切れや無効、APIキーの不正などが代表的です。

想定される原因

原因1:クレジットカード期限切れ・未払い

OpenAI APIの有料プランを使う場合、クレジットカードの登録が必須です。カードの有効期限切れ、引き落とし失敗、または月単位の利用上限に達したままになっていると、APIへのアクセスがブロックされ429エラーが出ます。この状態では、たとえ新しいカードを登録しても反映に数分〜数時間かかることもあります。

原因2:月単位の利用枠超過(Usage Limits)

OpenAI APIダッシュボードで設定できる「Usage limits」(使用上限)に到達した場合です。上限には以下の2種類があります。

  • ハード上限(Hard limit): 月間の最大支出額。この額に達するとAPI呼び出しは即座に止まります
  • ソフト上限(Soft limit): 警告メールが届く額。ただし呼び出しは続行できます

月初めにUTC基準でリセットされるまで、この原因でのエラーは解除されません。

原因3:短時間の大量リクエスト(レート制限)

個人のAPIキーの場合、1分間に送信できるトークン数(文字数に相当)に制限があります。大量のバッチ処理やエージェント実装で同時に複数のリクエストを送ると、制限に引っかかり一時的に429が出ます。このエラーは数秒〜数分待つことで解除されることが多いです。

切り分け手順

  1. OpenAIの公式ダッシュボード(https://platform.openai.com)にログインする
  2. 左メニューから「Billing」→「Usage」を確認
  3. 現在の月間利用料金が「Billing」→「Usage limits」で設定したハード上限に達していないか確認
  4. 「Billing」→「Billing overview」で支払い情報(クレジットカードの有効期限など)を確認
  5. APIキーが正しく設定されているか、「Settings」→「API keys」で対象のキーが有効か確認
  6. 同じAPIキーで複数の環境やアプリケーションから並行してリクエストを送っていないか確認

対処方法(優先度順)

対処1:課金情報の更新・プランの確認(最優先)

ダッシュボードの「Billing」→「Billing overview」でクレジットカード情報や有効期限を確認・更新します。無料トライアルからの移行時は「Set up paid account」から明示的に有料プランを有効化する必要があります。また「Billing」→「Usage limits」セクションでハード上限を確認し、必要に応じて引き上げることで継続的にAPIを利用できます。テスト段階では$5〜$10の低めに設定し、本番運用では$50以上に引き上げるのが一般的です。上限変更は即座に反映されます。

なお、上限を引き上げた直後はシステムが変更を反映するのに数分かかることがあります。10分程度待ってから再度リクエストを送ってください。

対処2:リトライロジックを実装する

短時間に大量のリクエストを送っている場合、レート制限に引っかかる可能性があります。リトライロジック(一定時間待機後に再試行)を実装することで、一時的なレート制限を回避できます。

Python例:

import time
from openai import OpenAI

client = OpenAI(api_key="your-api-key")

def call_with_retry(prompt, max_retries=3):
    for attempt in range(max_retries):
        try:
            response = client.chat.completions.create(
                model="gpt-4o",
                messages=[{"role": "user", "content": prompt}]
            )
            return response
        except Exception as e:
            if "429" in str(e):
                wait_time = 2 ** attempt  # 1秒、2秒、4秒と指数関数的に待機
                print(f"Rate limited. Waiting {wait_time} seconds...")
                time.sleep(wait_time)
            else:
                raise

対処3:バッチ処理で利用料を最適化

多数のリクエストを同時に送らず、時間を分散させることでレート制限を回避します。また、OpenAIのBatch API(バッチ処理API)を使うと、低い優先度で大量処理が可能になり、月間利用料も通常より安くなる傾向があります。ただしバッチAPIは処理に数時間〜24時間かかるため、リアルタイム処理には向きません。夜間のデータ処理やレポート生成など、時間的な余裕がある用途に適しています。詳細はOpenAI公式ドキュメント(https://platform.openai.com/docs/guides/batch)で確認できます。

対処4:複数のAPIキーでリクエストを分散

エージェントシステムで大量のリクエストを処理する場合、複数のAPIキーでリクエストを分散する方法も効果的です。1つのキーが上限に達しても他のキーで続行できます。

import os
from openai import OpenAI

api_keys = [
    os.getenv("OPENAI_API_KEY_1"),
    os.getenv("OPENAI_API_KEY_2"),
    os.getenv("OPENAI_API_KEY_3"),
]

current_key_index = 0

def call_with_key_rotation(messages):
    global current_key_index
    api_key = api_keys[current_key_index % len(api_keys)]
    current_key_index += 1
    client = OpenAI(api_key=api_key)
    return client.chat.completions.create(
        model="gpt-4o",
        messages=messages
    )

エラー2:トークン超過「This model’s maximum context length is 4097 tokens」

症状と発生条件

プロンプトと入力テキストを合わせたトークン数(文字数換算)が、モデルの上限を超えた場合に発生します。

エラーメッセージ(原文):

"This model's maximum context length is 4097 tokens, however you requested 5000 tokens"

日本語訳: 「このモデルの最大コンテキスト長は4097トークンですが、5000トークンがリクエストされました」

このエラーはgpt-3.5-turboなど比較的古いモデルを使っている場合に頻発します。gpt-4-turboやgpt-4oといった新しいモデルはもっと大きなコンテキスト長を持つため、同じ量のテキストでは超過しにくくなります。

想定される原因

モデルごとに処理できるテキスト量の上限が決まっています。gpt-3.5-turboは約4096トークンが上限で、「入力プロンプト+max_tokens(生成文字数)」の合計がこれを超えると発生します。プロンプト、ユーザーの質問、会話履歴を全部合わせると容易にこの上限を超えるため、特に長めのドキュメント処理や会話が長くなったユースケースで問題になります。

切り分け手順

  1. 使用しているモデルの正確な名前を確認(gpt-3.5-turboなのかgpt-4なのか)
  2. OpenAIの公式ドキュメントでそのモデルの「max_tokens」を確認
  3. 送信しているプロンプト全体(システムメッセージ+ユーザーメッセージ+会話履歴)の文字数をざっくり数える
  4. max_tokensパラメータの値を確認し、合計値がモデルの上限を超えていないか計算
  5. オンラインのトークンカウンターツール(例:https://platform.openai.com/tokenizer)で正確なトークン数を測定

対処方法(優先度順)

対処1:新しいモデル(gpt-4oやgpt-4-turbo)に変更する

新しいモデルほどコンテキスト長が大きいため、同じテキスト量でもトークン超過しにくくなります。料金は若干上がりますが、実装の複雑さを減らせます。

response = client.chat.completions.create(
    model="gpt-4o",  # 古いgpt-3.5-turboからアップグレード
    messages=[{"role": "user", "content": prompt}]
)

対処2:max_tokensを調整し、会話履歴を古い順に削除する

max_tokensパラメータを小さくして生成テキストを制限します。またチャットアプリケーションで会話が長くなった場合、古いメッセージから順に削除することでトークン数を削減します。直近10会話だけを送信する、など制限をかけることが一般的です。

対処3:長いテキストは要約・分割してから送信する

ドキュメント処理の場合、元のテキストをそのまま送るのではなく、別のAPI呼び出しで先に要約してから、その要約を使うという2段階の処理パターンが有効です。長いテキストを複数のチャンクに分割して処理することも有効です。

エラー3:「This is a chat model and not supported in the v1/completions endpoint」

症状と発生条件

gpt-3.5-turboやgpt-4などのチャットモデルに対して、Completionsエンドポイント(v1/completions)でリクエストすると以下が返されます。

エラーメッセージ(原文):

"Invalid request error: This model is a chat model and not supported in the v1/completions endpoint. Did you mean to use /v1/chat/completions?"

日本語訳: 「このモデルはチャットモデルであり、v1/completionsエンドポイントではサポートされていません。/v1/chat/completionsを使用する意図でしたか?」

想定される原因

gpt-3.5-turboやgpt-4といったチャットモデルは、従来のCompletions APIではなく、Chat Completions APIの専用エンドポイント(/v1/chat/completions)に対応しています。古いCompletionsエンドポイントを利用しているコードをそのまま新しいモデルに流用すると発生します。

切り分け手順

  1. 使用しているモデル名を確認
  2. OpenAI公式ドキュメントでそのモデルがChat Completionsに対応しているか確認
  3. コード内でどのエンドポイントを呼び出しているか確認

対処方法(優先度順)

対処1:Chat Completions APIを使用する(推奨)

from openai import OpenAI

client = OpenAI(api_key="your-api-key")
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "system", "content": "あなたは有用なアシスタントです"},
        {"role": "user", "content": "こんにちは"}
    ]
)
print(response.choices[0].message.content)

対処2:従来のCompletionsモデルを使用する

チャットボット以外の用途(文章生成、翻訳など)では、従来のCompletions APIに対応したモデルを選択することも選択肢の一つです。ただしtext-davinci-003などの旧来モデルは非推奨となっていることが多いため、基本的には対処1が推奨です。

エラー4:ChatCompletionエラー「‘ChatCompletion’ object is not subscriptable」

症状と発生条件

APIレスポンスを取得した後、レスポンスをリスト形式でアクセスしようとすると発生するエラーです。

エラーメッセージ(原文):

"TypeError: 'ChatCompletion' object is not subscriptable"

日本語訳: 「ChatCompletionオブジェクトは添字でアクセスできません」

このエラーは主に、OpenAIのPythonライブラリのバージョン更新に伴う使い方の変更が原因になります。古いバージョン(1.0以前)ではレスポンスが辞書形式だったのに対し、新しいバージョン(v0.27.0以降)ではオブジェクト形式になりました。

想定される原因

OpenAI Pythonライブラリのアップデートにより、APIレスポンスの形式が変更されました。古いコード(response['choices'][0]といったリスト形式でアクセス)が新しいライブラリで動作しなくなります。混在環境や参考資料が古い場合に頻発します。

切り分け手順

  1. インストールされているOpenAIライブラリのバージョンを確認
    pip show openai
    
  2. バージョンがv0.27.0以降なら新しい形式での記述が必要
  3. コード内でレスポンスにアクセスしている部分を確認
  4. 古い形式の記述(response['choices'][0]['message']['content'])と新しい形式(response.choices[0].message.content)を識別

対処方法(優先度順)

対処1:ライブラリを最新版にアップグレードしてコードを修正

まずはライブラリを最新にアップグレードし、コードの記述方法を新形式に統一します。

pip install --upgrade openai

古いコード:

response = openai.ChatCompletion.create(
    model="gpt-3.5-turbo",
    messages=[{"role": "user", "content": "こんにちは"}]
)
answer = response['choices'][0]['message']['content']

新しいコード:

from openai import OpenAI

client = OpenAI(api_key="your-api-key")
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "こんにちは"}]
)
answer = response.choices[0].message.content

対処2:古いバージョンを継続利用する場合

どうしても古い環境を使う必要がある場合、古いライブラリを明示的にインストールします。ただしセキュリティ対応が受けられなくなるため、推奨できません。

pip install openai==0.26.5

対処3:複数のバージョン対応コードを書く

両方のバージョンに対応したコードを書くことで、移行期間を設けることができます。

try:
    # 新形式
    answer = response.choices[0].message.content
except AttributeError:
    # 古い形式
    answer = response['choices'][0]['message']['content']

エラー5:429 Too Many Requests(レート制限)

症状と発生条件

短時間に多数のリクエストを送信すると以下が返されます。

エラーメッセージ(原文):

RateLimitError: 429 Too Many Requests

日本語訳: 「リクエストが多すぎます」

429エラー(クォータ超過)と似ていますが、こちらは課金上限ではなく純粋なリクエスト頻度の問題です。エラーメッセージには制限の詳細が含まれており、以下のような情報が確認できます。

{
  "error": {
    "message": "Rate limit reached for gpt-4 in organization org-XXXX on tokens per min. Limit: 90000, Used: 90000, Requested: 5000. Please try again in 1s.",
    "type": "rate_limit_error",
    "param": null,
    "code": "rate_limit_exceeded"
  }
}

このメッセージから以下のことが分かります:

  • モデル: gpt-4
  • 制限タイプ: トークン数(tokens per min)
  • 制限値: 1分あたり90,000トークン
  • 既に使用済み: 90,000トークン
  • 今回要求した量: 5,000トークン
  • 再試行推奨時間: 1秒

想定される原因

OpenAI APIは、アカウントの種類とプランに応じてリクエスト数に制限を設けています。主な原因は以下の通りです。

  • 同時実行数が制限を超えている:並列処理(マルチスレッド、asyncio)で処理数を制限しないと瞬時に大量のリクエストが送られます
  • リトライロジックがない:失敗したリクエストを即座に再送すると、制限にすぐ引っかかります
  • プランのレート制限が厳しすぎる:無料プランは特に制限が厳しく(例:毎分3リクエスト)、ループ処理やバッチ処理で制限を超えた場合に発生します
  • APIキーの共有・複数プロジェクトでの流用:同じキーを使い回すと、他の処理のリクエストもカウントされ、気づかないうちに制限に達します

切り分け手順

  1. ダッシュボード → Billingで現在のプラン(Free / Pay As You Go)を確認
  2. 実装コードで同時実行やループ処理がないか確認
  3. 短時間に集中しているリクエストを分散できないか検討

対処方法(優先度順)

対処1:リクエスト間に待機を挿入する

import time
from openai import OpenAI

client = OpenAI(api_key="your-api-key")

messages_list = [
    [{"role": "user", "content": "質問1"}],
    [{"role": "user", "content": "質問2"}],
    [{"role": "user", "content": "質問3"}]
]

for messages in messages_list:
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=messages
    )
    print(response.choices[0].message.content)
    time.sleep(1)  # 各リクエスト間に1秒待機

対処2:指数バックオフでリトライする

失敗時に待機時間を段階的に増やしながら再試行します。

import time
from openai import OpenAI

client = OpenAI(api_key="your-api-key")

def call_openai_with_backoff(messages, max_retries=5):
    for attempt in range(max_retries):
        try:
            response = client.chat.completions.create(
                model="gpt-4o",
                messages=messages
            )
            return response
        except Exception as e:
            if "429" in str(e):
                if attempt == max_retries - 1:
                    raise
                wait_time = 2 ** attempt  # 1秒、2秒、4秒、8秒、16秒
                print(f"Rate limit. Waiting {wait_time}s before retry...")
                time.sleep(wait_time)
            else:
                raise

response = call_openai_with_backoff([{"role": "user", "content": "テスト"}])

対処3:同時実行数を制限する

並列処理を使う場合、Semaphoreやスレッドプールで同時実行数を制御します。

import asyncio
from openai import AsyncOpenAI
from asyncio import Semaphore

client = AsyncOpenAI(api_key="your-api-key")

# 同時実行数を3に制限
semaphore = Semaphore(3)

async def call_openai_async(prompt):
    async with semaphore:
        response = await client.chat.completions.create(
            model="gpt-4o",
            messages=[{"role": "user", "content": prompt}]
        )
        return response

prompts = ["質問1", "質問2", "質問3", "質問4", "質問5"]
tasks = [call_openai_async(p) for p in prompts]
results = await asyncio.gather(*tasks)

対処4:有料プランへの移行

無料トライアル終了後、有料プランに移行すると制限が緩和されます。ダッシュボードの「Billing」→「Overview」から「Set up paid account」を選択してクレジットカードを登録します。また、有料プランでもなお制限が厳しい場合は、OpenAIに直接クォータの引き上げを申請できます。使用実績とユースケースを説明すれば、対応してもらえることがあります。

APIコスト削減でエラーを回避

エラーを減らすだけでなく、月間利用料そのものを削減することも重要です。不要なリクエストを減らし、キャッシング機能を活用することで、結果的に429エラーのリスクも低減します。

例えば、同じプロンプトに対する回答をローカルで保存しておくことで、APIへのリクエスト数そのものを減らせます。また、より小さなモデル(gpt-3.5-turbo)と大きなモデル(gpt-4o)を使い分けることで、最適なコスト対効果を実現できます。

OpenAIのダッシュボードで「Usage」セクションを確認し、API呼び出し数とトークン消費量を定期的に追跡することも重要です。制限に近づいているかどうかを把握しておくことで、エラーが発生する前に対策を取れます。

APIキーは環境変数に保管し、ソースコードに直書きしないことも重要です。複数のプロジェクトやサービスがある場合は、それぞれ異なるAPIキーを作成しましょう。これにより、特定のプロジェクトがレート制限に達したときも、他のプロジェクトに影響しません。

import os
from openai import OpenAI

client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

それでも解決しないとき

これらの対処を試してもエラーが続く場合、以下を確認します:

  1. OpenAIの公式ステータスページ(https://status.openai.com)でサービス障害が発生していないか確認
  2. APIキーが意図せず漏洩していないか(最後に生成した日時を確認し、必要に応じて新しいキーを生成)
  3. シンプルなテストコードで最小限の動作確認(複雑な実装を取り除いた1行のメッセージ送信など)
  4. ネットワーク接続やファイアウォール設定で、OpenAI APIへのアクセスがブロックされていないか
  5. 使用しているプロキシやVPN経由でのアクセスの場合、IPホワイトリスト設定を確認
  6. OpenAIコミュニティフォーラムやStack Overflow、GitHub Discussionsで同じエラーが報告されていないか検索
  7. OpenAIの公式サポートに問い合わせ(https://support.openai.com)

あわせて読みたい

参考ソース