---
title: ツールおよびマルチターンワークフローにおける思考
url: https://platform.claude.com/docs/ja/build-with-claude/thinking-tool-workflows
description: 思考ブロックを正しく保持する完全な2ターンのツール使用ラウンドトリップを順に確認し、インターリーブ思考によってフローがどのように変わるかを見ていきます。
---

<Note>
  「zero data retention」（ゼロデータ保持）、すなわちZDRがこの機能にどのように適用されるかについては、[APIとデータ保持](https://platform.claude.com/docs/ja/manage-claude/api-and-data-retention)を参照してください。
</Note>

このページでは、思考を有効にした完全な2ターンの「tool use」（ツール使用）ラウンドトリップを順に確認します。Claudeが思考し、ツール呼び出しをリクエストし、結果を受け取り、回答を完成させるまで、すべてのステップで思考ブロックが正しく扱われます。完全なルールは[思考](https://platform.claude.com/docs/ja/build-with-claude/thinking)ページの[ツール使用における思考](https://platform.claude.com/docs/ja/build-with-claude/thinking#thinking-with-tool-use)および[思考ブロックの保持](https://platform.claude.com/docs/ja/build-with-claude/thinking#preserving-thinking-blocks)に記載されています。このページでは、それらのルールを実行可能なコードに適用した例を示します。

## このウォークスルーで適用するルール

各リンクは思考ページの完全な記述につながっています。

* [手動モードではツール選択を`auto`または`none`に限定する](https://platform.claude.com/docs/ja/build-with-claude/thinking#thinking-with-tool-use)：ツール使用を強制する`tool_choice`オプションは、手動の「extended thinking」（拡張思考）（`thinking: {type: "enabled"}`）ではエラーを返します。アダプティブ思考は強制的なツール使用をサポートしますが、Claude Opus 5.5、Claude Sonnet 5.5、Claude Fable 5.1、Claude Mythos 5.1は例外で、400エラーを返します。強制的なツール使用が受け入れられる場合、思考はスキップされ、レスポンスはツール呼び出しから始まります。
* [アシスタントターンごとに1つの思考設定を維持する](https://platform.claude.com/docs/ja/build-with-claude/thinking#thinking-with-tool-use)：ツール使用ループは1つのアシスタントターンであるため、設定の変更はターン間でのみ行ってください。
* [思考ブロックを完全かつ変更せずに返す](https://platform.claude.com/docs/ja/build-with-claude/thinking#preserving-thinking-blocks)：ツール結果を返す際には、アシスタントメッセージの思考ブロックも一緒に返す必要があります。
* [アシスタントメッセージを受け取ったとおりにそのままエコーする](https://platform.claude.com/docs/ja/build-with-claude/thinking#preserving-thinking-blocks)：メッセージを再構築したり `redacted_thinking` ブロックを除外したりすると、400エラーが発生します。

サンプルではアダプティブ思考を使用しています。拡張思考のみをサポートするモデルでは、`thinking: {type: "enabled", budget_tokens: N}` に置き換えてください。ラウンドトリップのルールは同一です。

## 2ターンのツール使用ラウンドトリップを順に確認する

この例では `get_weather` ツールを定義し、Claudeに思考させてツール呼び出しをリクエストさせた後、思考ブロックを含めて受け取ったとおりにエコーしたアシスタントターンとともにツール結果を返します。

<Steps>
  <Step title="ツールを利用可能にして最初のリクエストを行う">
    アダプティブ思考を有効にし、ツールを定義したリクエストを送信します。`thinking` パラメータを除けば、これは標準的な[ツール使用](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/overview)リクエストです。

    <CodeGroup>
      ```bash cURL
      curl https://api.anthropic.com/v1/messages \
        -H "anthropic-version: 2023-06-01" \
        -H "content-type: application/json" \
        -H "x-api-key: $ANTHROPIC_API_KEY" \
        -d '{
          "model": "claude-opus-5-5",
          "max_tokens": 16000,
          "thinking": {"type": "adaptive"},
          "tools": [{
            "name": "get_weather",
            "description": "Get current weather for a location",
            "input_schema": {
              "type": "object",
              "properties": {
                "location": {"type": "string", "description": "City name"}
              },
              "required": ["location"]
            }
          }],
          "messages": [{"role": "user", "content": "What is the weather in Paris?"}]
        }'
      ```

      ```bash CLI
      ant messages create --transform content <<'YAML'
      model: claude-opus-5-5
      max_tokens: 16000
      thinking:
        type: adaptive
      tools:
        - name: get_weather
          description: Get current weather for a location
          input_schema:
            type: object
            properties:
              location:
                type: string
                description: City name
            required:
              - location
      messages:
        - role: user
          content: "What's the weather in Paris?"
      YAML
      ```

      ```python Python

      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-5-5",
          max_tokens=16000,
          thinking={"type": "adaptive"},
          tools=[weather_tool],
          messages=[{"role": "user", "content": "What's the weather in Paris?"}],
      )
      print(response)
      ```

      ```typescript TypeScript
      const client = new Anthropic();

      const weatherTool: Anthropic.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が思考とツールリクエストで応答します
      const response = await client.messages.create({
        model: "claude-opus-5-5",
        max_tokens: 16000,
        thinking: {
          type: "adaptive"
        },
        tools: [weatherTool],
        messages: [{ role: "user", content: "What's the weather in Paris?" }]
      });
      console.log(response);
      ```

      ```csharp C#
      AnthropicClient client = new();

      var weatherTool = new ToolUnion(new Tool()
      {
          Name = "get_weather",
          Description = "Get current weather for a location",
          InputSchema = new InputSchema()
          {
              Properties = new Dictionary<string, JsonElement>
              {
                  ["location"] = JsonSerializer.SerializeToElement(new { type = "string", description = "City name" }),
              },
              Required = ["location"],
          },
      });

      var parameters = new MessageCreateParams
      {
          Model = Model.ClaudeOpus5_5,
          MaxTokens = 16000,
          Thinking = new ThinkingConfigAdaptive(),
          Tools = [weatherTool],
          Messages = [new() { Role = Role.User, Content = "What's the weather in Paris?" }]
      };

      var message = await client.Messages.Create(parameters);
      Console.WriteLine(message);
      ```

      ```go Go
      client := anthropic.NewClient()

      weatherTool := anthropic.ToolUnionParam{
      	OfTool: &anthropic.ToolParam{
      		Name:        "get_weather",
      		Description: anthropic.String("Get current weather for a location"),
      		InputSchema: anthropic.ToolInputSchemaParam{
      			Properties: map[string]any{
      				"location": map[string]any{
      					"type":        "string",
      					"description": "City name",
      				},
      			},
      			Required: []string{"location"},
      		},
      	},
      }

      response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
      	Model:     anthropic.ModelClaudeOpus5_5,
      	MaxTokens: 16000,
      	Thinking: anthropic.ThinkingConfigParamUnion{
      		OfAdaptive: &anthropic.ThinkingConfigAdaptiveParam{},
      	},
      	Tools: []anthropic.ToolUnionParam{weatherTool},
      	Messages: []anthropic.MessageParam{
      		anthropic.NewUserMessage(anthropic.NewTextBlock("What's the weather in Paris?")),
      	},
      })
      if err != nil {
      	log.Fatal(err)
      }
      fmt.Println(response)
      ```

      ```java Java
      import com.anthropic.models.messages.ThinkingConfigAdaptive;
      // ...
          AnthropicClient client = AnthropicOkHttpClient.fromEnv();

          MessageCreateParams params = MessageCreateParams.builder()
              .model(Model.CLAUDE_OPUS_5_5)
              .maxTokens(16000L)
              .thinking(ThinkingConfigAdaptive.builder().build())
              .addTool(Tool.builder()
                  .name("get_weather")
                  .description("Get current weather for a location")
                  .inputSchema(Tool.InputSchema.builder()
                      .properties(JsonValue.from(Map.of(
                          "location", Map.of("type", "string", "description", "City name")
                      )))
                      .required(List.of("location"))
                      .build())
                  .build())
              .addUserMessage("What's the weather in Paris?")
              .build();

          Message response = client.messages().create(params);
          IO.println(response);
      ```

      ```php PHP
      $client = new Client();

      $weatherTool = [
          'name' => 'get_weather',
          'description' => 'Get current weather for a location',
          'input_schema' => [
              'type' => 'object',
              'properties' => [
                  'location' => ['type' => 'string', 'description' => 'City name']
              ],
              'required' => ['location']
          ]
      ];

      $message = $client->messages->create(
          maxTokens: 16000,
          messages: [
              ['role' => 'user', 'content' => "What's the weather in Paris?"]
          ],
          model: 'claude-opus-5-5',
          thinking: ['type' => 'adaptive'],
          tools: [$weatherTool],
      );
      echo $message;
      ```

      ```ruby Ruby
      client = Anthropic::Client.new

      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"]
        }
      }

      message = client.messages.create(
        model: "claude-opus-5-5",
        max_tokens: 16000,
        thinking: {
          type: "adaptive"
        },
        tools: [weather_tool],
        messages: [
          { role: "user", content: "What's the weather in Paris?" }
        ]
      )
      puts message
      ```
    </CodeGroup>
  </Step>

  <Step title="エコーバックするためにcontent配列を取得する">
    Claudeが思考することを選択した実行では、レスポンスのcontentに`thinking`ブロックと`tool_use`ブロックが含まれているはずです（より単純なリクエストでは、アダプティブモードは思考ブロックをスキップする場合があります）。Claudeがツール呼び出しの前に書くメモは、`text`ブロックとして返されるか、[進捗更新](https://platform.claude.com/docs/ja/build-with-claude/thinking#progress-updates)を書くモデルでは別の`thinking`ブロックとして返されます。このcontent配列はそのまま保持してください。次のステップでこれをそのまま送り返します。

    <Note>
      この出力のような思考テキストを表示するには、リクエストに`display: "summarized"`を追加してください。Claude Opus 5.5を含む、displayのデフォルトがomittedであるモデルでは、そうしない場合`thinking`フィールドは空文字列として返され、`signature`のみが設定されます。いずれの場合も、content配列は変更せずにエコーバックしてください。[思考表示の制御](https://platform.claude.com/docs/ja/build-with-claude/thinking#controlling-thinking-display)を参照してください。
    </Note>

    ```json 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": "tool_use",
          "id": "toolu_01CswdEQBMshySk6Y9DFKrfq",
          "name": "get_weather",
          "input": {
            "location": "Paris"
          }
        }
      ]
    }
    ```
  </Step>

  <Step title="アシスタントターンをそのままエコーしてツール結果を返す">
    自分の側でツールを実行し、会話に2つのメッセージを追加する2回目のリクエストを送信します。1つ目は受け取ったとおりにエコーバックしたアシスタントのcontentで、思考ブロックは `tool_use` ブロックとともに変更されないまま残ります。2つ目は `tool_result` を含むユーザーメッセージです。

    各サンプルは自己完結したスクリプトです。最初のリクエストを繰り返した後、受け取ったばかりのレスポンスを使用してすぐにフォローアップを送信します。

    <CodeGroup exclude="shell:cURL">
      <CodeGroupItem language="cURL">
        このワークフローには、単一のシェルコマンドでは実現できないロジックが必要です。実行するにはClaude SDKを使用してください。
      </CodeGroupItem>

      ```bash CLI
      # 最初のターン: assistant のコンテンツ配列（thinking ブロックと tool_use
      # ブロック、署名はそのまま）をファイルに書き出します。モデル生成テキストを
      # ファイル経由にすることで、後でシェル展開される位置に置かれるのを防ぎます。
      ant messages create --transform content --format jsonl \
        > assistant_content.json <<'YAML'
      model: claude-opus-5-5
      max_tokens: 16000
      thinking:
        type: adaptive
      tools:
        - name: get_weather
          description: Get current weather for a location
          input_schema:
            type: object
            properties:
              location:
                type: string
                description: City name
            required: [location]
      messages:
        - role: user
          content: What's the weather in Paris?
      YAML

      # 2 番目のターン: jq が取得済みファイルから 2 つの null プレースホルダーを埋めるため、
      # ブロックはそのまま assistant メッセージとして返されます。thinking
      # ブロックは必ず tool_use ブロックと一緒に送る必要があります。区切り文字を引用符で囲むと、
      # 本文中のシェル展開が一切行われなくなります。
      jq --slurpfile blocks assistant_content.json '
        .messages[1].content = $blocks[0] |
        .messages[2].content[0].tool_use_id =
          ($blocks[0][] | select(.type == "tool_use") | .id)
      ' <<'JSON' | ant messages create
      {
        "model": "claude-opus-5-5",
        "max_tokens": 16000,
        "thinking": {"type": "adaptive"},
        "tools": [{
          "name": "get_weather",
          "description": "Get current weather for a location",
          "input_schema": {
            "type": "object",
            "properties": {
              "location": {"type": "string", "description": "City name"}
            },
            "required": ["location"]
          }
        }],
        "messages": [
          {"role": "user", "content": "What's the weather in Paris?"},
          {"role": "assistant", "content": null},
          {"role": "user", "content": [{
            "type": "tool_result",
            "tool_use_id": null,
            "content": "Current temperature: 88°F"
          }]}
        ]
      }
      JSON
      ```

      ```python Python

      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-5-5",
          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-5-5",
          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)
      ```

      ```typescript TypeScript
      const client = new Anthropic();

      const weatherTool: Anthropic.Tool = {
        name: "get_weather",
        description: "Get current weather for a location",
        input_schema: {
          type: "object",
          properties: {
            location: { type: "string", description: "City name" }
          },
          required: ["location"]
        }
      };

      const response = await client.messages.create({
        model: "claude-opus-5-5",
        max_tokens: 16000,
        thinking: {
          type: "adaptive"
        },
        tools: [weatherTool],
        messages: [{ role: "user", content: "What's the weather in Paris?" }]
      });

      // ツール結果用のIDを取得するため、ツール使用ブロックを抽出します
      const toolUseBlock = response.content.find(
        (block): block is Anthropic.ToolUseBlock => block.type === "tool_use"
      );

      // 実際の天気APIを呼び出します。ここに実際のAPI呼び出しを記述します
      // これが返ってきた結果だと仮定します
      const weatherData = { temperature: 88 };

      if (toolUseBlock) {
        // 2回目のリクエスト - アシスタントのターンとツール結果を含めます
        const continuation = await client.messages.create({
          model: "claude-opus-5-5",
          max_tokens: 16000,
          thinking: {
            type: "adaptive"
          },
          tools: [weatherTool],
          messages: [
            { role: "user", content: "What's the weather in Paris?" },
            // アシスタントのコンテンツを受け取ったとおりにそのまま返します。thinking
            // ブロックが存在する場合は、tool_useブロックと一緒に含める必要があります。
            { role: "assistant", content: response.content },
            {
              role: "user",
              content: [
                {
                  type: "tool_result" as const,
                  tool_use_id: toolUseBlock.id,
                  content: `Current temperature: ${weatherData.temperature}°F`
                }
              ]
            }
          ]
        });
        console.log(continuation);
      }
      ```

      ```csharp C#
      AnthropicClient client = new();

      var weatherTool = new ToolUnion(new Tool()
      {
          Name = "get_weather",
          Description = "Get current weather for a location",
          InputSchema = new InputSchema()
          {
              Properties = new Dictionary<string, JsonElement>
              {
                  ["location"] = JsonSerializer.SerializeToElement(new { type = "string", description = "City name" }),
              },
              Required = ["location"],
          },
      });

      var parameters = new MessageCreateParams
      {
          Model = Model.ClaudeOpus5_5,
          MaxTokens = 16000,
          Thinking = new ThinkingConfigAdaptive(),
          Tools = [weatherTool],
          Messages = [
              new() { Role = Role.User, Content = "What's the weather in Paris?" }
          ]
      };

      var response = await client.Messages.Create(parameters);

      // tool_useブロックを抽出し、ツール結果用のIDを取得します
      ToolUseBlock? toolUseBlock = null;
      foreach (var block in response.Content)
      {
          if (block.TryPickToolUse(out var toolUse))
          {
              toolUseBlock = toolUse;
              break;
          }
      }

      var weatherData = new { temperature = 88 };

      // ツール結果を含む継続リクエストを構築します
      var continuationParams = new MessageCreateParams
      {
          Model = Model.ClaudeOpus5_5,
          MaxTokens = 16000,
          Thinking = new ThinkingConfigAdaptive(),
          Tools = [weatherTool],
          Messages = [
              new() { Role = Role.User, Content = "What's the weather in Paris?" },
              // response.Contentにはthinkingブロックが含まれます。これらをそのまま返すことが必須です
              new() { Role = Role.Assistant, Content = response.Content.Select(block => new ContentBlockParam(block.Json)).ToList() },
              new() { Role = Role.User, Content = new MessageParamContent(new List<ContentBlockParam>
              {
                  new ContentBlockParam(new ToolResultBlockParam()
                  {
                      ToolUseID = toolUseBlock?.ID ?? "",
                      Content = $"Current temperature: {weatherData.temperature}°F"
                  })
              })}
          ]
      };

      var continuation = await client.Messages.Create(continuationParams);
      Console.WriteLine(continuation);
      ```

      ```go Go
      client := anthropic.NewClient()

      weatherTool := anthropic.ToolUnionParam{
      	OfTool: &anthropic.ToolParam{
      		Name:        "get_weather",
      		Description: anthropic.String("Get current weather for a location"),
      		InputSchema: anthropic.ToolInputSchemaParam{
      			Properties: map[string]any{
      				"location": map[string]any{
      					"type":        "string",
      					"description": "City name",
      				},
      			},
      			Required: []string{"location"},
      		},
      	},
      }

      response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
      	Model:     anthropic.ModelClaudeOpus5_5,
      	MaxTokens: 16000,
      	Thinking: anthropic.ThinkingConfigParamUnion{
      		OfAdaptive: &anthropic.ThinkingConfigAdaptiveParam{},
      	},
      	Tools: []anthropic.ToolUnionParam{weatherTool},
      	Messages: []anthropic.MessageParam{
      		anthropic.NewUserMessage(anthropic.NewTextBlock("What's the weather in Paris?")),
      	},
      })
      if err != nil {
      	log.Fatal(err)
      }

      var toolUseBlock anthropic.ToolUseBlock
      for _, block := range response.Content {
      	if v, ok := block.AsAny().(anthropic.ToolUseBlock); ok {
      		toolUseBlock = v
      		break
      	}
      }

      weatherData := map[string]int{"temperature": 88}

      continuation, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
      	Model:     anthropic.ModelClaudeOpus5_5,
      	MaxTokens: 16000,
      	Thinking: anthropic.ThinkingConfigParamUnion{
      		OfAdaptive: &anthropic.ThinkingConfigAdaptiveParam{},
      	},
      	Tools: []anthropic.ToolUnionParam{weatherTool},
      	Messages: []anthropic.MessageParam{
      		anthropic.NewUserMessage(anthropic.NewTextBlock("What's the weather in Paris?")),
      		response.ToParam(),
      		anthropic.NewUserMessage(
      			anthropic.NewToolResultBlock(toolUseBlock.ID, fmt.Sprintf("Current temperature: %d°F", weatherData["temperature"]), false),
      		),
      	},
      })
      if err != nil {
      	log.Fatal(err)
      }

      fmt.Println(continuation)
      ```

      ```java Java
      import com.anthropic.models.messages.ThinkingConfigAdaptive;
      // ...

      void main() {
          AnthropicClient client = AnthropicOkHttpClient.fromEnv();

          Tool weatherTool = Tool.builder()
              .name("get_weather")
              .description("Get current weather for a location")
              .inputSchema(Tool.InputSchema.builder()
                  .properties(JsonValue.from(Map.of(
                      "location", Map.of("type", "string", "description", "City name")
                  )))
                  .required(List.of("location"))
                  .build())
              .build();

          MessageCreateParams initialParams = MessageCreateParams.builder()
              .model(Model.CLAUDE_OPUS_5_5)
              .maxTokens(16000L)
              .thinking(ThinkingConfigAdaptive.builder().build())
              .addTool(weatherTool)
              .addUserMessage("What's the weather in Paris?")
              .build();

          Message response = client.messages().create(initialParams);

          ToolUseBlock toolUseBlock = null;
          for (var block : response.content()) {
              if (block.toolUse().isPresent()) {
                  toolUseBlock = block.toolUse().get();
                  break;
              }
          }

          int temperature = 88;

          // 2回目のリクエスト: 受信したアシスタントのターンをそのまま返し、続けてツール結果を送信
          MessageCreateParams continuationParams = MessageCreateParams.builder()
              .model(Model.CLAUDE_OPUS_5_5)
              .maxTokens(16000L)
              .thinking(ThinkingConfigAdaptive.builder().build())
              .addTool(weatherTool)
              .addUserMessage("What's the weather in Paris?")
              .addMessage(response)
              .addUserMessageOfBlockParams(List.of(
                  ContentBlockParam.ofToolResult(
                      ToolResultBlockParam.builder()
                          .toolUseId(toolUseBlock.id())
                          .content("Current temperature: " + temperature + "°F")
                          .build()
                  )
              ))
              .build();

          Message continuation = client.messages().create(continuationParams);
          IO.println(continuation);
      }
      ```

      ```php PHP
      $client = new Client();

      $weatherTool = [
          '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(
          maxTokens: 16000,
          messages: [
              ['role' => 'user', 'content' => "What's the weather in Paris?"]
          ],
          model: 'claude-opus-5-5',
          thinking: ['type' => 'adaptive'],
          tools: [$weatherTool],
      );

      $toolUseBlock = null;
      foreach ($response->content as $block) {
          if ($block->type === 'tool_use') {
              $toolUseBlock = $block;
              break;
          }
      }

      $weatherData = ['temperature' => 88];

      $continuation = $client->messages->create(
          maxTokens: 16000,
          messages: [
              ['role' => 'user', 'content' => "What's the weather in Paris?"],
              ['role' => 'assistant', 'content' => $response->content],
              ['role' => 'user', 'content' => [
                  [
                      'type' => 'tool_result',
                      'tool_use_id' => $toolUseBlock->id,
                      'content' => "Current temperature: {$weatherData['temperature']}°F"
                  ]
              ]]
          ],
          model: 'claude-opus-5-5',
          thinking: ['type' => 'adaptive'],
          tools: [$weatherTool],
      );

      echo $continuation;
      ```

      ```ruby Ruby
      client = Anthropic::Client.new

      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-5-5",
        max_tokens: 16000,
        thinking: {
          type: "adaptive"
        },
        tools: [weather_tool],
        messages: [
          { role: "user", content: "What's the weather in Paris?" }
        ]
      )

      tool_use_block = response.content.find { |block| block.type == :tool_use }

      raise "No tool_use block found" unless tool_use_block

      weather_data = { temperature: 88 }

      continuation = client.messages.create(
        model: "claude-opus-5-5",
        max_tokens: 16000,
        thinking: {
          type: "adaptive"
        },
        tools: [weather_tool],
        messages: [
          { role: "user", content: "What's the weather in Paris?" },
          { role: "assistant", content: response.content },
          { role: "user", content: [
            {
              type: "tool_result",
              tool_use_id: tool_use_block.id,
              content: "Current temperature: #{weather_data[:temperature]}°F"
            }
          ] }
        ]
      )

      puts continuation
      ```
    </CodeGroup>
  </Step>

  <Step title="最終レスポンスを読む">
    Claudeがテキストでターンを完了するのが確認できるはずです。アダプティブモードでは[インターリーブ思考](https://platform.claude.com/docs/ja/build-with-claude/thinking#interleaved-thinking)が自動的に行われるため、継続部分は最終テキストの前に新しい思考ブロックで始まることもあります。

    ```json Output
    {
      "content": [
        {
          "type": "text",
          "text": "Currently in Paris, the temperature is 88°F (31°C)"
        }
      ]
    }
    ```
  </Step>
</Steps>

## インターリーブ思考によってフローがどのように変わるか

「interleaved thinking」（インターリーブ思考）により、Claudeはツール呼び出しの間に思考し、各ツール結果に基づいて行動する前にその結果について推論できます。概念とモデルごとの利用可否については、思考ページの[インターリーブ思考](https://platform.claude.com/docs/ja/build-with-claude/thinking#interleaved-thinking)で説明されています。インターリーブは思考ブロックが現れる場所を変えるものであり、ツール呼び出しを連鎖できるかどうかを変えるものではありません。以下の比較は、2つのツールを使うワークフローにおいてインターリーブ思考が何を変えるかを示しています。

<AccordionGroup>
  <Accordion title="インターリーブ思考なしのツール使用">
    インターリーブ思考がない場合、Claudeはアシスタントターンの開始時に一度だけ思考します。ツール結果の後に続くレスポンスは、新しい思考ブロックなしで継続します。

    ```text
    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
    ```
  </Accordion>

  <Accordion title="インターリーブ思考ありのツール使用">
    インターリーブ思考が有効な場合、Claudeは各ツール結果を受け取った後に思考でき、継続する前に中間結果について推論できます。

    ```text
    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
    ```
  </Accordion>
</AccordionGroup>

## 次のステップ

<CardGroup cols={3}>
  <Card title="思考" icon="brain" href="https://platform.claude.com/docs/ja/build-with-claude/thinking">
    概要：思考を有効にし、思考出力を読み、ツール使用、キャッシング、ストリーミングに関する完全なルールを確認します。
  </Card>

  <Card title="思考のステアリング" icon="compass" href="https://platform.claude.com/docs/ja/build-with-claude/thinking-steering-and-cost">
    エフォートレベルとプロンプトベースのガイダンスによって、Claudeが思考する頻度と深さを調整します。
  </Card>

  <Card title="拡張思考" icon="clock" href="https://platform.claude.com/docs/ja/build-with-claude/extended-thinking">
    旧モデルにおける手動の思考バジェット：`budget_tokens` の仕組みとアダプティブへの移行。
  </Card>
</CardGroup>
