生成AI入門 2026.06.24

ChatGPT APIでトークン上限超過エラーが出た時の対処法|長文入力の3つの分割戦略【2026年版】

タグ:ChatGPT API / エラー対処 / 長文入力 / APIトラブル

ひとことで言うと

ChatGPT APIでトークン上限を超えるエラーが出た時は、入力テキストを複数に分割して送信するか、API側でレスポンスの上限を調整することで解決できます。予防策として、長文を扱う際は最初から分割処理を組み込むのがおすすめです。

トークン上限超過エラーって何?

ChatGPT APIを使う時、「トークン」という文字数の単位で課金・制限されます。1トークンはおおよそ英語で4文字、日本語で1~2文字分です。このトークンが上限に達すると、APIはリクエストを処理できず、エラーを返します。

エラーメッセージは典型的に以下のようなものです:

  • 「This model’s maximum context length is X tokens」
  • 「Prompt too long」
  • 「Request exceeded maximum token limit」

このエラーが出る場合、以下2つの原因が考えられます。

  1. 入力テキストが長すぎる:送信するテキスト(プロンプト+参考資料など)がモデルの上限を超えている
  2. 出力レスポンスの上限設定が高すぎる:APIのmax_tokensパラメーターが大きく設定されており、入力+出力の合計が上限を超えている

原因1:入力テキストが長すぎる場合の3つの対処法

対処法1:テキストを複数に分割して送信する(最も一般的)

長いテキストをいくつかのチャンクに分割し、複数回のリクエストに分けて送信します。StackOverflowのコミュニティでも、この方法が最も推奨されています。

具体的な手順:

  1. テキストを適切なサイズに分割する(例:1000~2000トークン単位)
  2. 各チャンクに「これは資料の○番目の部分です」といった文脈情報を付ける
  3. 複数回のAPI呼び出しを実行する
  4. 複数回のレスポンスを結合して処理する

Pythonでの実装例:

import openai

def split_text(text, chunk_size=2000):
    """テキストを指定サイズに分割する"""
    words = text.split()
    chunks = []
    current_chunk = []
    
    for word in words:
        current_chunk.append(word)
        if len(' '.join(current_chunk)) >= chunk_size:
            chunks.append(' '.join(current_chunk))
            current_chunk = []
    
    if current_chunk:
        chunks.append(' '.join(current_chunk))
    
    return chunks

def process_long_text(text, prompt_prefix):
    """長いテキストを分割して処理"""
    chunks = split_text(text)
    results = []
    
    for i, chunk in enumerate(chunks):
        message = f"{prompt_prefix}\n\n【パート {i+1}/{len(chunks)}\n{chunk}"
        
        response = openai.ChatCompletion.create(
            model="gpt-4",
            messages=[
                {"role": "user", "content": message}
            ],
            max_tokens=500
        )
        
        results.append(response['choices'][0]['message']['content'])
    
    return '\n\n---\n\n'.join(results)

# 使用例
long_document = "(ここに長いテキストを入れる)"
final_response = process_long_text(long_document, "このテキストを要約してください:")
print(final_response)

メリット:

  • 最も確実な方法
  • どのモデルでも使える
  • 細かく制御できる

デメリット:

  • APIを複数回呼び出すため、料金が増える可能性
  • 各チャンクを個別に処理するため、全体を一度に見たプロンプトより精度が落ちる可能性がある

対処法2:テキストを圧縮する

不要な情報を削減してから送信します。

具体的な方法:

  • 余白・改行の削除:複数の改行や連続したスペースを1つに
  • 重複部分の削除:同じ内容が何度も出てくる場合は1回だけに
  • 不要なマークアップの削除:HTMLタグなど不要な要素を削除
  • 要約してから送信:長いテキストを先に自分で簡潔にしてから送信
import re

def compress_text(text):
    """テキストを圧縮する"""
    # 複数の改行を1つに
    text = re.sub(r'\n+', '\n', text)
    # 複数のスペースを1つに
    text = re.sub(r' +', ' ', text)
    return text.strip()

compressed = compress_text(long_text)

メリット:

  • 実装がシンプル
  • API呼び出しの回数が増えない

デメリット:

  • 本当に重要な情報まで削られてしまう可能性
  • テキストの構造や整形が崩れることがある

対処法3:より大きいコンテキストウィンドウを持つモデルに変更する

StackOverflowでの報告によると、より新しく大きなコンテキストウィンドウ(一度に処理できる文字数)を持つモデルへの切り替えが有効です。

モデルごとのコンテキストウィンドウ目安:

モデルコンテキストウィンドウ特徴
GPT-4 Turbo128,000トークン大型モデルで長文対応
GPT-48,192トークン標準的なサイズ
GPT-3.5 Turbo4,096トークン小さいモデル
response = openai.ChatCompletion.create(
    model="gpt-4-turbo",  # より大きなコンテキストウィンドウを持つモデルに変更
    messages=[{"role": "user", "content": long_text}],
    max_tokens=1000
)

メリット:

  • 実装が簡単(モデル名を変えるだけ)
  • 全体を一度に処理できる

デメリット:

  • より高いモデルほどAPI料金が高くなる
  • 新しいモデルはまだ安定していない可能性がある

原因2:レスポンス上限設定が高すぎる場合の対処法

APIのmax_tokensパラメーターが大きく設定されていると、入力と出力の合計がモデルの上限を超えることがあります。

# 問題のあるコード
response = openai.ChatCompletion.create(
    model="gpt-4",
    messages=[{"role": "user", "content": long_text}],
    max_tokens=4000  # 大きく設定しすぎている
)

# 改善版
response = openai.ChatCompletion.create(
    model="gpt-4",
    messages=[{"role": "user", "content": long_text}],
    max_tokens=500  # 必要最小限に設定
)

入力が長い場合は、出力のmax_tokensを下げることで解決します。

不完全なレスポンスが返ってきた場合の対処法

長めのテキストを送信すると、時々レスポンスが途中で途切れることがあります。Stackoverflowのコミュニティでは、このような場合「前の回答の続きを書いて」と明確に指示する方法が報告されています。

# 1回目のリクエスト
response1 = openai.ChatCompletion.create(
    model="gpt-4",
    messages=[{"role": "user", "content": "ここから長い文章を書いてください:..."}],
    max_tokens=1000
)

# レスポンスが途切れた場合、続きをリクエスト
first_response = response1['choices'][0]['message']['content']

if first_response.endswith('...') or len(first_response) < 50:  # 途切れたと判定
    response2 = openai.ChatCompletion.create(
        model="gpt-4",
        messages=[
            {"role": "user", "content": "ここから長い文章を書いてください:..."},
            {"role": "assistant", "content": first_response},
            {"role": "user", "content": "前の回答の続きをお願いします"}
        ],
        max_tokens=1000
    )
    
    second_response = response2['choices'][0]['message']['content']
    final_response = first_response + second_response

トークンの数え方を事前に確認する方法

エラーを未然に防ぐには、送信前にトークン数を計算しておくことが大切です。

OpenAIが提供するtiktokenライブラリを使うと、テキストが何トークンかを正確に数えられます。

import tiktoken

def count_tokens(text, model="gpt-4"):
    """テキストのトークン数を数える"""
    encoding = tiktoken.encoding_for_model(model)
    tokens = encoding.encode(text)
    return len(tokens)

# 使用例
long_text = "(ここに長いテキスト)"
token_count = count_tokens(long_text)
print(f"トークン数:{token_count}")

# モデルの上限との比較
max_tokens_for_model = 8192  # GPT-4の場合
if token_count > max_tokens_for_model:
    print("テキストが長すぎます!分割が必要です。")
else:
    print("大丈夫。送信できます。")

よくある質問と回答

Q:分割したテキストを送信すると、統一性がなくなりませんか?

A:確かに1つのリクエストで全体を見た方が統一性は高いです。ただし一般的には、各チャンクに「これは資料の○部分」と文脈情報をつけることで、かなり統一性を保てます。

Q:複数回のAPI呼び出しで料金はどのくらい増えますか?

A:分割の回数分だけ課金が増えます。例えば10分割した場合は、通常の10倍の料金になります。コストと精度のバランスを考えて、分割サイズを調整しましょう。

Q:最初から大きなモデル(GPT-4 Turbo)を使えばいいのでは?

A:その方法もありますが、料金がかなり高くなります。用途に合わせて選ぶのがおすすめです。

まとめと今後の対策

ChatGPT APIでトークン上限超過エラーが出た時の対処法は、大きく3つです。

  1. テキスト分割が最も一般的:確実で、細かく制御できます
  2. テキスト圧縮も有効:シンプルですが情報損失の可能性もあります
  3. より大きなモデルに変更:簡単ですが料金が増えます

長いテキストを扱う予定がある場合は、最初からtiktokenでトークン数を確認して、分割処理を組み込んでおくのが最善です。エラーが出てから対応するより、事前に予防する方が開発効率も上がります。


あわせて読みたい

参考ソース