生成AI入門 2026.06.24
APIトークン上限エラーの完全解決ガイド【Claude・ChatGPT 2026年版】長文入力の3つの分割戦略
コンテキストウィンドウの比較(2026年版)
| モデル | コンテキスト | 約何文字(日本語) |
|---|---|---|
| GPT-4o mini | 128K | 約9万字 |
| GPT-5 | 128K | 約9万字 |
| Claude Haiku/Sonnet/Opus | 200K | 約15万字 |
長文処理が多い場合はClaude(200K)への移行が根本解決になる場合が多いです。
Step 1: まずトークン数を計測する
# count_tokens.py
# 送信前にトークン数を確認する
import anthropic
import os
client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
def count_claude_tokens(text: str, model: str = "claude-sonnet-4-5") -> int:
"""Claudeでトークン数を無料でカウントする(APIコストなし)"""
response = client.messages.count_tokens(
model=model,
messages=[{"role": "user", "content": text}]
)
return response.input_tokens
# 使用例
long_text = "..." * 10000 # 長いテキスト
token_count = count_claude_tokens(long_text)
CLAUDE_MAX = 200_000
print(f"トークン数: {token_count:,}")
print(f"Claudeの上限: {CLAUDE_MAX:,}")
if token_count > CLAUDE_MAX:
print("⚠️ 上限超過 → チャンク分割が必要")
elif token_count > CLAUDE_MAX * 0.8:
print("⚠️ 上限に近い → 余裕を持たせた分割を推奨")
else:
print("✅ 上限内 → そのまま送信可能")
Step 2: チャンク分割で長文を処理する
# chunk_processor.py
# 長い文書を分割してClaudeで処理する
import anthropic
import os
client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
def process_long_document(document: str, task: str, chunk_chars: int = 60000) -> str:
"""長い文書をチャンクに分割して処理し結果を統合する"""
# 文書を分割(日本語は約3文字/トークン)
chunks = []
for i in range(0, len(document), chunk_chars):
chunks.append(document[i:i + chunk_chars])
print(f"文書: {len(document):,}文字 → {len(chunks)}チャンクに分割")
# 各チャンクを処理
results = []
for i, chunk in enumerate(chunks):
response = client.messages.create(
model="claude-haiku-4-5-20251001", # 大量処理はHaikuでコスト削減
max_tokens=1024,
messages=[{"role": "user", "content": f"""
{task}
※ これは文書の{i + 1}番目の部分(全{len(chunks)}部分)です。
文書内容:
{chunk}
"""}]
)
results.append(response.content[0].text)
print(f" チャンク {i + 1}/{len(chunks)} 処理完了")
# 結果を統合
if len(results) == 1:
return results[0]
combined = "\n\n---\n\n".join(f"[Part {i+1}]\n{r}" for i, r in enumerate(results))
final = client.messages.create(
model="claude-sonnet-4-5", # 統合はSonnetで品質向上
max_tokens=2048,
messages=[{"role": "user", "content": f"""
以下の{len(results)}つのパートの結果を統合して、一つの一貫した回答にまとめてください。
{combined}
"""}]
)
return final.content[0].text
# 使用例
with open("long_contract.txt") as f:
contract = f.read()
summary = process_long_document(contract, "この契約書の重要なリスク事項を箇条書きで挙げてください")
print(summary)
Step 3: 途中で切れたレスポンスを続けさせる
# continue_response.py
# max_tokensに達して途中で切れた回答を続けさせる
def ask_with_continuation(prompt: str, max_continuation_attempts: int = 3) -> str:
"""必要に応じて回答を続けさせる"""
full_response = ""
messages = [{"role": "user", "content": prompt}]
for attempt in range(max_continuation_attempts):
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=2048,
messages=messages
)
chunk = response.content[0].text
full_response += chunk
# 終了理由が「stop_sequence」または「end_turn」なら完了
if response.stop_reason in ("end_turn", "stop_sequence"):
break
# 「max_tokens」で止まった場合は続きを要求
if response.stop_reason == "max_tokens":
messages.append({"role": "assistant", "content": chunk})
messages.append({"role": "user", "content": "続きをお願いします。前の文の続きから再開してください。"})
else:
break
return full_response
result = ask_with_continuation("Pythonの設計パターンを10個詳しく説明してください")
print(result)
あわせて読みたい
- Claude Sonnet APIコスト完全解説|トークン計算・バッチ割引・月額試算
- 生成AIとは?仕組み・料金・API使い方を10分で理解
- LangChain vs LlamaIndex【2026年版】RAGコードで比較