Claude Platform Docs
  • メッセージ
  • マネージドエージェント
  • 管理

Search...
⌘K
はじめに
Claudeの紹介クイックスタート
Claudeで構築する
機能の概要Messages APIの使用停止理由とフォールバック拒否とフォールバックフォールバッククレジット
モデルの機能
拡張思考適応型思考エフォートタスク予算(ベータ版)高速モード(リサーチプレビュー)構造化出力引用メッセージのストリーミングバッチ処理検索結果拒否のストリーミング多言語サポート埋め込み
ツール
概要ツール使用の仕組みチュートリアル:ツールを使うエージェントの構築ツールの定義ツール呼び出しの処理並列ツール使用Tool Runner(SDK)厳密なツール使用プロンプトキャッシングを使ったツール使用サーバーツールトラブルシューティングWeb検索ツールWeb取得ツールコード実行ツールアドバイザーツールメモリツールBashツールコンピュータ使用ツールテキストエディタツール
ツールインフラストラクチャ
ツールリファレンスツールコンテキストの管理ツールの組み合わせツール検索プログラムによるツール呼び出しきめ細かいツールストリーミング
コンテキスト管理
コンテキストウィンドウコンパクションコンテキスト編集プロンプトキャッシング会話途中のシステムメッセージオーケストレーションモードの構築キャッシュ診断(ベータ版)トークンカウント
ファイルの操作
Files APIPDFサポート画像とビジョン
スキル
概要クイックスタートベストプラクティスエンタープライズ向けスキルAPIでのスキル
MCP
リモートMCPサーバーMCPコネクタ
クラウドプラットフォーム上のClaude
Amazon BedrockAmazon Bedrock(レガシー)AWS上のClaude PlatformMicrosoft FoundryVertex AI

Log in
停止理由とフォールバック
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Claude Platform Docs

Solutions

  • AI agents
  • Code modernization
  • Coding
  • Customer support
  • Education
  • Financial services
  • Government
  • Life sciences

Partners

  • Claude on AWS
  • Claude on Google Cloud

Learn

  • Blog
  • Courses
  • Use cases
  • Connectors
  • Customer stories
  • Engineering at Anthropic
  • Events
  • Powered by Claude
  • Service partners
  • Startups program

Company

  • Anthropic
  • Careers
  • Economic Futures
  • Research
  • News
  • Responsible Scaling Policy
  • Security and compliance
  • Transparency

Learn

  • Blog
  • Courses
  • Use cases
  • Connectors
  • Customer stories
  • Engineering at Anthropic
  • Events
  • Powered by Claude
  • Service partners
  • Startups program

Help and security

  • Availability
  • Status
  • Support
  • Discord

Terms and policies

  • Privacy policy
  • Responsible disclosure policy
  • Terms of service: Commercial
  • Terms of service: Consumer
  • Usage policy
メッセージ/Claudeで構築する

停止理由とフォールバック

各stop_reason値の意味と、アプリケーションでの切り捨て、ツール使用、一時停止されたターン、拒否の処理方法について説明します。

Was this page helpful?

  • クイックリファレンス
  • stop_reasonフィールド
  • 停止理由の値
  • end_turn
  • max_tokens
  • stop_sequence
  • tool_use
  • pause_turn
  • refusal
  • model_context_window_exceeded
  • 停止理由を処理するためのベストプラクティス
  • 常にstop_reasonを確認する
  • 切り捨てられたレスポンスを適切に処理する
  • pause_turnの再試行ロジックを実装する
  • 停止理由とエラーの違い
  • 停止理由(成功したレスポンス)
  • エラー(失敗したリクエスト)
  • ストリーミングに関する考慮事項
  • 一般的なパターン
  • ツール使用ワークフローの処理
  • 完全なレスポンスの確保
  • 入力サイズを知らずに最大トークンを取得する
  • 次のステップ

すべてのMessages APIレスポンスには、Claudeが生成を停止した理由を示すstop_reasonフィールドが含まれています。このフィールドを確認して、レスポンスをそのまま使用するか、会話を続けるか、再試行するか、別のモデルにフォールバックするかを判断してください。

完全なレスポンススキーマについては、Messages APIリファレンスを参照してください。

クイックリファレンス

値発生するタイミング対処方法
end_turnClaudeがレスポンスを自然に完了した。レスポンスを使用します。
max_tokensレスポンスがmax_tokensの制限に達した。max_tokensを増やすか、レスポンスを継続します。
stop_sequenceClaudeが指定したstop_sequencesのいずれかを出力した。stop_sequenceを読み取り、どれがトリガーされたかを確認します。
tool_useClaudeがツールを呼び出している。ツールを実行し、結果を返します。
pause_turnサーバーツールのループが反復制限に達した。アシスタントのコンテンツを送り返して続行します。
refusalClaudeが応答を拒否した。stop_detailsを読み取り、フォールバックモデルで再試行します。
model_context_window_exceededレスポンスがモデルのコンテキストウィンドウを埋め尽くした。レスポンスを切り捨てられたものとして扱います。

stop_reasonフィールド

stop_reasonフィールドは、すべての成功したMessages APIレスポンスの一部です。リクエスト処理の失敗を示すエラーとは異なり、stop_reasonはClaudeがレスポンス生成を完了した理由を示します。

Example response
{
  "id": "msg_01234",
  "type": "message",
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "Here's the answer to your question..."
    }
  ],
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "stop_details": null,
  "usage": {
    "input_tokens": 100,
    "output_tokens": 50
  }
}

停止理由の値

end_turn

最も一般的な停止理由です。Claudeがレスポンスを自然に完了したことを示します。

max_tokens

Claudeがリクエストで指定されたmax_tokensの制限に達したため停止しました。

stop_sequence

Claudeがカスタム停止シーケンスのいずれかに遭遇しました。

tool_use

Claudeがツールを呼び出しており、実行することを期待しています。



ほとんどのツール使用の実装では、ツールの実行、結果のフォーマット、会話管理を自動的に処理するツールランナーを使用してください。

pause_turn

ウェブ検索やウェブフェッチなどのサーバーツールを実行中に、サーバー側のサンプリングループが反復制限に達した場合に返されます。デフォルトの制限はリクエストごとに10回の反復です。

これが発生した場合、レスポンスには対応するserver_tool_resultのないserver_tool_useブロックが含まれることがあります。Claudeに処理を完了させるには、レスポンスをそのまま送り返して会話を続けてください。



サーバーツールを使用するエージェントループでは、アプリケーションがpause_turnを処理する必要があります。アシスタントのレスポンスをメッセージ配列に追加し、別のAPIリクエストを行ってClaudeに続行させてください。

refusal

Claudeがレスポンスの生成を拒否しました。Claude Fable 5では、安全性分類器はこの停止理由をエラーではなく通常のHTTP 200レスポンスとして返します。



Claude Sonnet 4.5またはOpus 4.1(非推奨)の使用中にrefusal停止理由が頻繁に発生する場合は、異なる使用制限を持つHaiku 4.5(claude-haiku-4-5-20251001)を使用するようにAPI呼び出しを更新してみてください。Sonnet 4.5のAPI安全フィルターについての詳細をご覧ください。

拒否が発生した場合、stop_detailsオブジェクトがそれをトリガーしたポリシーカテゴリを識別します。カテゴリと完全な拒否レスポンスの形式については、拒否とフォールバックで説明しています。stop_detailsは、refusal以外のすべての停止理由ではnullです。

Claude Fable 5で拒否されたリクエストは、通常、別のClaudeモデルで再試行することで処理できます。拒否とフォールバックでは、サーバー側またはクライアントでその再試行を設定する方法を示しています。フォールバッククレジットでは、再試行を自分で構築する際にプロンプトキャッシュのコストを二重に支払わないようにする方法について説明しています。

model_context_window_exceeded

Claudeがモデルのコンテキストウィンドウの制限に達したため停止しました。これにより、正確な入力サイズを知らなくても、可能な限り最大のトークンをリクエストできます。



この停止理由は現在、SDKのbeta名前空間でのみ型付けされているため、以下の例ではclient.beta.messagesを呼び出し、Betaプレフィックス付きの型を使用しています。Sonnet 4.5以降のモデルでは、APIはベータヘッダーなしでこの値を返します。それ以前のモデルでは、model-context-window-exceeded-2025-08-26ベータヘッダーを追加して有効にしてください。

停止理由を処理するためのベストプラクティス

常にstop_reasonを確認する

レスポンス処理ロジックでstop_reasonを確認することを習慣にしてください:

切り捨てられたレスポンスを適切に処理する

トークン制限またはコンテキストウィンドウが原因でレスポンスが切り捨てられた場合は、出力が不完全であることを読者に知らせる通知を追加してください。代わりにレスポンスが途切れた箇所から生成を続ける方法については、完全なレスポンスの確保を参照してください。

pause_turnの再試行ロジックを実装する

サーバーツールを使用する場合、サーバー側のサンプリングループが反復制限(デフォルト10)に達すると、APIはpause_turnを返すことがあります。会話を続けることでこれを処理してください:

停止理由とエラーの違い

stop_reason値と実際のエラーを区別することが重要です:

停止理由(成功したレスポンス)

  • レスポンスボディの一部
  • 生成が正常に停止した理由を示す
  • レスポンスには有効なコンテンツが含まれる

エラー(失敗したリクエスト)

  • HTTPステータスコード4xxまたは5xx
  • リクエスト処理の失敗を示す
  • レスポンスにはエラーの詳細が含まれる

ストリーミングに関する考慮事項

ストリーミングを使用する場合、stop_reasonは:

  • 最初のmessage_startイベントではnull
  • message_deltaイベントで提供される
  • その他のイベントでは提供されない

一般的なパターン

ツール使用ワークフローの処理



ツールランナーでよりシンプルに: 以下の例は手動でのツール処理を示しています。ほとんどのユースケースでは、ツールランナーがはるかに少ないコードでツール実行を自動的に処理します。

完全なレスポンスの確保

入力サイズを知らずに最大トークンを取得する

model_context_window_exceeded停止理由により、入力サイズを計算せずに可能な限り最大のトークンをリクエストできます:

次のステップ

拒否とフォールバック

拒否されたリクエストをサーバー側またはクライアントでフォールバックモデルに再試行します。


ツールランナー(SDK)

SDKにtool_useループ、結果のフォーマット、再試行を管理させます。


ストリーミングメッセージ

ストリーミング時にmessage_deltaイベントからstop_reasonを読み取ります。

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello!"}],
)
if response.stop_reason == "end_turn":
    # 完全なレスポンスを処理する
    print(response.content[0].text)
client = anthropic.Anthropic()
# トークン数を制限したリクエスト
response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=10,
    messages=[{"role": "user", "content": "Explain quantum physics"}],
)

if response.stop_reason == "max_tokens":
    # レスポンスが切り詰められました
    print("Response was cut off at token limit")
    # 続きを取得するには別のリクエストの送信を検討してください
client = anthropic.Anthropic()
response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    stop_sequences=["END", "STOP"],
    messages=[{"role": "user", "content": "Generate text until you say END"}],
)

if response.stop_reason == "stop_sequence":
    print(f"Stopped at sequence: {response.stop_sequence}")
client = anthropic.Anthropic()
weather_tool = {
    "name": "get_weather",
    "description": "Get the current weather in a given location",
    "input_schema": {
        "type": "object",
        "properties": {
            "location": {"type": "string", "description": "City and state"},
        },
        "required": ["location"],
    },
}


def execute_tool(name, tool_input):
    """Execute a tool and return the result."""
    return f"Weather in {tool_input.get('location', 'unknown')}: 72°F"


response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    tools=[weather_tool],
    messages=[{"role": "user", "content": "What is the weather in San Francisco?"}],
)

if response.stop_reason == "tool_use":
    # ツールを抽出して実行
    for block in response.content:
        if block.type == "tool_use":
            result = execute_tool(block.name, block.input)
            # 最終レスポンスのために結果をClaudeに返す
response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=4096,
    tools=[{"type": "web_search_20250305", "name": "web_search"}],
    messages=[{"role": "user", "content": "Search for latest AI news"}],
)

if response.stop_reason == "pause_turn":
    # レスポンスを送り返して会話を続けます
    messages = [
        {"role": "user", "content": "Search for latest AI news"},
        {"role": "assistant", "content": response.content},
    ]
    continuation = client.messages.create(
        model="claude-opus-4-8",
        max_tokens=4096,
        messages=messages,
        tools=[{"type": "web_search_20250305", "name": "web_search"}],
    )
client = anthropic.Anthropic()
response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    messages=[{"role": "user", "content": "[Unsafe request]"}],
)

if response.stop_reason == "refusal":
    # Claudeが応答を拒否しました
    print("Claude was unable to process this request")
    # リクエストの言い換えや修正を検討してください
# できるだけ多く取得するために最大トークン数でリクエスト
response = client.beta.messages.create(
    model="claude-opus-4-8",
    max_tokens=20000,  # Python SDK requires streaming for max_tokens above ~21k (Opus 4.8 supports 128k with streaming)
    messages=[
        {"role": "user", "content": "Large input that uses most of context window..."}
    ],
)

if response.stop_reason == "model_context_window_exceeded":
    # レスポンスが max_tokens より先にコンテキストウィンドウの上限に達しました
    print("Response reached model's context window limit")
    # レスポンスは有効ですが、コンテキストウィンドウによって制限されました
def handle_response(response):
    if response.stop_reason == "tool_use":
        return handle_tool_use(response)
    elif response.stop_reason == "max_tokens":
        return handle_truncation(response)
    elif response.stop_reason == "model_context_window_exceeded":
        return handle_context_limit(response)
    elif response.stop_reason == "pause_turn":
        return handle_pause(response)
    elif response.stop_reason == "refusal":
        return handle_refusal(response)
    else:
        # end_turnやその他のケースを処理
        return response.content[0].text
def handle_truncated_response(response):
    if response.stop_reason in ["max_tokens", "model_context_window_exceeded"]:
        if response.stop_reason == "max_tokens":
            note = "[Response truncated due to max_tokens limit]"
        else:
            note = "[Response truncated due to context window limit]"
        return f"{response.content[0].text}\n\n{note}"
    return response.content[0].text
def handle_server_tool_conversation(client, user_query, tools, max_continuations=5):
    """
    Handle server tool conversations that may require multiple continuations.

    The server runs a sampling loop when executing server tools. If the loop
    reaches its iteration limit, the API returns pause_turn. Continue the
    conversation by sending the response back to let Claude finish.
    """
    messages = [{"role": "user", "content": user_query}]

    for _ in range(max_continuations):
        response = client.messages.create(
            model="claude-opus-4-8", max_tokens=4096, messages=messages, tools=tools
        )

        if response.stop_reason != "pause_turn":
            # Claudeが処理を完了 - 最終レスポンスを返す
            return response

        # pause_turn: ロールの交互性を維持するためメッセージリスト全体を置き換える
        messages = [
            {"role": "user", "content": user_query},
            {"role": "assistant", "content": response.content},
        ]

    # 最大継続回数に到達 - 最後のレスポンスを返す
    return response
client = anthropic.Anthropic()

try:
    response = client.messages.create(
        model="claude-opus-4-8",
        max_tokens=1024,
        messages=[{"role": "user", "content": "Hello!"}],
    )

    # stop_reasonを含む成功レスポンスを処理
    if response.stop_reason == "max_tokens":
        print("Response was truncated")

except anthropic.APIStatusError as e:
    # 実際のエラーを処理
    if e.status_code == 429:
        print("Rate limit exceeded")
    elif e.status_code == 500:
        print("Server error")
client = anthropic.Anthropic()

with client.messages.stream(
    model="claude-opus-4-8",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello!"}],
) as stream:
    for event in stream:
        if event.type == "message_delta":
            stop_reason = event.delta.stop_reason
            if stop_reason:
                print(f"Stream ended with: {stop_reason}")
def complete_tool_workflow(client, user_query, tools):
    messages = [{"role": "user", "content": user_query}]

    while True:
        response = client.messages.create(
            model="claude-opus-4-8", max_tokens=1024, messages=messages, tools=tools
        )

        if response.stop_reason == "tool_use":
            # ツールを実行して続行
            tool_results = execute_tools(response.content)
            messages.append({"role": "assistant", "content": response.content})
            messages.append({"role": "user", "content": tool_results})
        else:
            # 最終レスポンス
            return response
def get_complete_response(client, prompt, max_attempts=3):
    messages = [{"role": "user", "content": prompt}]
    full_response = ""

    for _ in range(max_attempts):
        response = client.messages.create(
            model="claude-opus-4-8", messages=messages, max_tokens=4096
        )

        full_response += response.content[0].text

        if response.stop_reason != "max_tokens":
            break

        # 中断した箇所から続行
        messages = [
            {"role": "user", "content": prompt},
            {"role": "assistant", "content": full_response},
            {"role": "user", "content": "Please continue from where you left off."},
        ]

    return full_response
def get_max_possible_tokens(client, prompt):
    """
    Get as many tokens as possible within the model's context window
    without needing to calculate input token count
    """
    response = client.beta.messages.create(
        model="claude-opus-4-8",
        messages=[{"role": "user", "content": prompt}],
        max_tokens=20000,  # Python SDK requires streaming for max_tokens above ~21k
    )

    if response.stop_reason == "model_context_window_exceeded":
        # 入力サイズに対して可能な最大トークン数に達しました
        print(
            f"Generated {response.usage.output_tokens} tokens (context limit reached)"
        )
    elif response.stop_reason == "max_tokens":
        # リクエストされたトークン数に正確に達しました
        print(f"Generated {response.usage.output_tokens} tokens (max_tokens reached)")
    else:
        # 自然な完了
        print(f"Generated {response.usage.output_tokens} tokens (natural completion)")

    return response.content[0].text

エラー

停止理由とは異なる4xxおよび5xx HTTPエラーを処理します。