ツールおよびマルチターンワークフローにおける思考
思考ブロックを正しく保持する完全な2ターンのツール使用ラウンドトリップを順に確認し、インターリーブ思考によってフローがどのように変わるかを見ていきます。
このページでは、思考を有効にした完全な2ターンの「tool use」(ツール使用)ラウンドトリップを順に確認します。Claudeが思考し、ツール呼び出しをリクエストし、結果を受け取り、回答を完成させるまで、すべてのステップで思考ブロックが正しく扱われます。完全なルールは思考ページのツール使用における思考および思考ブロックの保持に記載されています。このページでは、それらのルールを実行可能なコードに適用した例を示します。
このウォークスルーで適用するルール
各リンクは思考ページの完全な記述につながっています。
- 手動モードではツール選択を
autoまたはnoneに限定する:ツール使用を強制するtool_choiceオプションは、手動の「extended thinking」(拡張思考)(thinking: {type: "enabled"})ではエラーを返します。アダプティブ思考は強制的なツール使用をサポートします。 - アシスタントターンごとに1つの思考設定を維持する:ツール使用ループは1つのアシスタントターンであるため、設定の変更はターン間でのみ行ってください。
- 思考ブロックを完全かつ変更せずに返す:ツール結果を返す際には、アシスタントメッセージの思考ブロックも一緒に返す必要があります。
- アシスタントメッセージを受け取ったとおりにそのままエコーする:メッセージを再構築したり
redacted_thinkingブロックを除外したりすると、400エラーが発生します。
サンプルではアダプティブ思考を使用しています。拡張思考のみをサポートするモデルでは、thinking: {type: "enabled", budget_tokens: N} に置き換えてください。ラウンドトリップのルールは同一です。
2ターンのツール使用ラウンドトリップを順に確認する
この例では get_weather ツールを定義し、Claudeに思考させてツール呼び出しをリクエストさせた後、思考ブロックを含めて受け取ったとおりにエコーしたアシスタントターンとともにツール結果を返します。
ツールを利用可能にして最初のリクエストを行う
アダプティブ思考を有効にし、ツールを定義したリクエストを送信します。
thinkingパラメータを除けば、これは標準的なツール使用リクエストです。client = anthropic.Anthropic() weather_tool = { "name": "get_weather", "description": "Get current weather for a location", "input_schema": { "type": "object", "properties": {"location": {"type": "string", "description": "City name"}}, "required": ["location"], }, } # 最初のリクエスト - Claudeが思考とツールリクエストで応答します response = client.messages.create( model="claude-opus-4-8", max_tokens=16000, thinking={"type": "adaptive"}, tools=[weather_tool], messages=[{"role": "user", "content": "What's the weather in Paris?"}], ) print(response)エコーバックするためにcontent配列を取得する
Claudeが思考することを選択した実行では、レスポンスのcontentに
thinking、text、tool_useブロックが含まれているはずです(より単純なリクエストでは、アダプティブモードが思考ブロックをスキップする場合があります)。このcontent配列はそのまま保持してください。次のステップでこれをそのまま送り返します。Output{ "content": [ { "type": "thinking", "thinking": "The user wants to know the current weather in Paris. I have access to a function `get_weather`...", "signature": "BDaL4VrbR2Oj0hO4XpJxT28J5T...." }, { "type": "text", "text": "I can help you get the current weather information for Paris. Let me check that for you" }, { "type": "tool_use", "id": "toolu_01CswdEQBMshySk6Y9DFKrfq", "name": "get_weather", "input": { "location": "Paris" } } ] }アシスタントターンをそのままエコーしてツール結果を返す
自分の側でツールを実行し、会話に2つのメッセージを追加する2回目のリクエストを送信します。1つ目は受け取ったとおりにエコーバックしたアシスタントのcontentで、思考ブロックは
tool_useブロックとともに変更されないまま残ります。2つ目はtool_resultを含むユーザーメッセージです。各サンプルは自己完結したスクリプトです。最初のリクエストを繰り返した後、受け取ったばかりのレスポンスを使用してすぐにフォローアップを送信します。
client = anthropic.Anthropic() weather_tool = { "name": "get_weather", "description": "Get current weather for a location", "input_schema": { "type": "object", "properties": {"location": {"type": "string", "description": "City name"}}, "required": ["location"], }, } response = client.messages.create( model="claude-opus-4-8", max_tokens=16000, thinking={"type": "adaptive"}, tools=[weather_tool], messages=[{"role": "user", "content": "What's the weather in Paris?"}], ) # tool_resultに使用するIDを取得するため、tool_useブロックを抽出します tool_use_block = next(block for block in response.content if block.type == "tool_use") # 実際の天気APIを呼び出します。ここに実際のAPI呼び出しを記述します # これが返ってきた結果だと仮定します weather_data = {"temperature": 88} # 2回目のリクエスト - アシスタントのターンとtool_resultを含めます continuation = client.messages.create( model="claude-opus-4-8", max_tokens=16000, thinking={"type": "adaptive"}, tools=[weather_tool], messages=[ {"role": "user", "content": "What's the weather in Paris?"}, # アシスタントのコンテンツを受け取ったとおりにそのまま返します。thinking # ブロックが存在する場合は、tool_useブロックと一緒に含める必要があります。 {"role": "assistant", "content": response.content}, { "role": "user", "content": [ { "type": "tool_result", "tool_use_id": tool_use_block.id, "content": f"Current temperature: {weather_data['temperature']}°F", } ], }, ], ) print(continuation)最終レスポンスを読む
Claudeがテキストでターンを完了するのが確認できるはずです。アダプティブモードではインターリーブ思考が自動的に行われるため、継続部分は最終テキストの前に新しい思考ブロックで始まることもあります。
Output{ "content": [ { "type": "text", "text": "Currently in Paris, the temperature is 88°F (31°C)" } ] }
インターリーブ思考によってフローがどのように変わるか
「interleaved thinking」(インターリーブ思考)により、Claudeはツール呼び出しの間に思考し、各ツール結果に基づいて行動する前にその結果について推論できます。概念とモデルごとの利用可否については、思考ページのインターリーブ思考で説明されています。インターリーブは思考ブロックが現れる場所を変えるものであり、ツール呼び出しを連鎖できるかどうかを変えるものではありません。以下の比較は、2つのツールを使うワークフローにおいてインターリーブ思考が何を変えるかを示しています。
インターリーブ思考がない場合、Claudeはアシスタントターンの開始時に一度だけ思考します。ツール結果の後に続くレスポンスは、新しい思考ブロックなしで継続します。
User: "What's the total revenue if we sold 150 units at $50 each,
and how does this compare to our average monthly revenue?"
Response 1: [thinking] "I need to calculate 150 * $50, then check the database..."
[tool_use: calculator] { "expression": "150 * 50" }
↓ tool result: "7500"
Response 2: [tool_use: database_query] { "query": "SELECT AVG(revenue)..." }
↑ no thinking block
↓ tool result: "5200"
Response 3: [text] "The total revenue is $7,500, which is 44% above your
average monthly revenue of $5,200."
↑ no thinking blockインターリーブ思考が有効な場合、Claudeは各ツール結果を受け取った後に思考でき、継続する前に中間結果について推論できます。
User: "What's the total revenue if we sold 150 units at $50 each,
and how does this compare to our average monthly revenue?"
Response 1: [thinking] "I need to calculate 150 * $50 first..."
[tool_use: calculator] { "expression": "150 * 50" }
↓ tool result: "7500"
Response 2: [thinking] "Got $7,500. Now I should query the database to compare..."
[tool_use: database_query] { "query": "SELECT AVG(revenue)..." }
↑ thinking after receiving calculator result
↓ tool result: "5200"
Response 3: [thinking] "$7,500 vs $5,200 average - that's a 44% increase..."
[text] "The total revenue is $7,500, which is 44% above your
average monthly revenue of $5,200."
↑ thinking before final answer次のステップ
Was this page helpful?