---
title: La réflexion dans les flux de travail avec outils et multi-tours
url: https://platform.claude.com/docs/fr/build-with-claude/thinking-tool-workflows
description: Parcourez un aller-retour complet d'utilisation d'outils en deux tours qui préserve correctement les blocs de réflexion, et découvrez comment la réflexion entrelacée modifie le déroulement.
---

<Note>
  Pour savoir comment la « zero data retention » (rétention zéro des données), ou ZDR, s'applique à cette fonctionnalité, consultez [API et rétention des données](https://platform.claude.com/docs/fr/manage-claude/api-and-data-retention).
</Note>

Cette page parcourt un aller-retour complet d'« tool use » (utilisation d'outils) en deux tours avec la réflexion activée : Claude réfléchit, demande un appel d'outil, reçoit le résultat et termine sa réponse, les blocs de réflexion étant correctement gérés à chaque étape. Les règles complètes se trouvent sur la page [Réflexion](https://platform.claude.com/docs/fr/build-with-claude/thinking), dans [Réflexion avec utilisation d'outils](https://platform.claude.com/docs/fr/build-with-claude/thinking#thinking-with-tool-use) et [Préservation des blocs de réflexion](https://platform.claude.com/docs/fr/build-with-claude/thinking#preserving-thinking-blocks) ; cette page montre ces règles appliquées dans du code exécutable.

## Les règles appliquées dans ce guide pas à pas

Chaque lien mène à l'énoncé complet sur la page Réflexion :

* [Limiter le choix d'outil à `auto` ou `none` en mode manuel](https://platform.claude.com/docs/fr/build-with-claude/thinking#thinking-with-tool-use) : les options `tool_choice` qui forcent l'utilisation d'outils renvoient une erreur avec la « extended thinking » (réflexion étendue) manuelle (`thinking: {type: "enabled"}`). La réflexion adaptative prend en charge l'utilisation forcée d'outils, sauf sur Claude Opus 5.5, Claude Sonnet 5.5, Claude Fable 5.1 et Claude Mythos 5.1, qui renvoient une erreur 400. Lorsque l'utilisation forcée d'outils est acceptée, elle ignore la réflexion : la réponse commence par l'appel d'outil.
* [Conserver une seule configuration de réflexion par tour d'assistant](https://platform.claude.com/docs/fr/build-with-claude/thinking#thinking-with-tool-use) : une boucle d'utilisation d'outils constitue un seul tour d'assistant, ne modifiez donc la configuration qu'entre les tours.
* [Renvoyer les blocs de réflexion complets et non modifiés](https://platform.claude.com/docs/fr/build-with-claude/thinking#preserving-thinking-blocks) : lorsque vous renvoyez un résultat d'outil, les blocs de réflexion du message de l'assistant doivent revenir avec lui.
* [Renvoyer le message de l'assistant exactement tel que reçu](https://platform.claude.com/docs/fr/build-with-claude/thinking#preserving-thinking-blocks) : reconstruire le message ou filtrer les blocs `redacted_thinking` déclenche une erreur 400.

Les exemples utilisent la réflexion adaptative ; sur les modèles qui ne prennent en charge que la réflexion étendue, remplacez par `thinking: {type: "enabled", budget_tokens: N}`. Les règles de l'aller-retour sont identiques.

## Parcourir un aller-retour d'utilisation d'outils en deux tours

L'exemple définit un outil `get_weather`, laisse Claude réfléchir et demander un appel d'outil, puis renvoie le résultat de l'outil accompagné du tour de l'assistant renvoyé exactement tel que reçu, bloc de réflexion inclus.

<Steps>
  <Step title="Effectuer la première requête avec un outil disponible">
    Envoyez une requête avec la réflexion adaptative activée et l'outil défini. Hormis le paramètre `thinking`, il s'agit d'une requête d'[utilisation d'outils](https://platform.claude.com/docs/fr/agents-and-tools/tool-use/overview) standard :

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

      # Première requête - Claude répond avec une réflexion et une demande d'outil
      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"]
        }
      };

      // Première requête - Claude répond avec une réflexion et une demande d'outil
      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="Capturer le tableau de contenu à renvoyer">
    Vous devriez voir des blocs `thinking` et `tool_use` dans le contenu de la réponse lors d'une exécution où Claude a choisi de réfléchir (pour des requêtes plus simples, le mode adaptatif peut omettre le bloc de réflexion). Une note que Claude écrit avant l'appel d'outil est renvoyée sous forme de bloc `text` ou, sur les modèles qui écrivent des [mises à jour de progression](https://platform.claude.com/docs/fr/build-with-claude/thinking#progress-updates), sous forme d'un autre bloc `thinking`. Conservez ce tableau de contenu intact : l'étape suivante le renvoie tel quel.

    <Note>
      Pour voir un texte de réflexion comme dans cette sortie, ajoutez `display: "summarized"` à la requête. Sur les modèles où l'affichage est omis par défaut, y compris Claude Opus 5.5, le champ `thinking` est sinon renvoyé sous forme de chaîne vide, seul le champ `signature` étant renseigné. Dans tous les cas, renvoyez le tableau de contenu sans modification ; consultez [Contrôler l'affichage de la réflexion](https://platform.claude.com/docs/fr/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="Renvoyer le résultat de l'outil, en renvoyant le tour de l'assistant tel quel">
    Exécutez l'outil de votre côté, puis envoyez une seconde requête qui ajoute deux messages à la conversation. Le premier est le contenu de l'assistant renvoyé exactement tel que reçu, de sorte que le bloc de réflexion reste inchangé aux côtés du bloc `tool_use`. Le second est un message utilisateur contenant le `tool_result`.

    Chaque exemple est un script autonome : il répète la première requête, puis envoie immédiatement la suite en utilisant la réponse qu'il vient de recevoir.

    <CodeGroup exclude="shell:cURL">
      <CodeGroupItem language="cURL">
        Ce flux de travail nécessite plus de logique qu'une seule commande shell. Utilisez le SDK Claude pour l'exécuter.
      </CodeGroupItem>

      ```bash CLI
      # Premier tour : écrivez le tableau de contenu de l'assistant (blocs thinking et tool_use,
      # signatures intactes) dans un fichier. Faire transiter le texte généré par le modèle
      # via un fichier l'empêche ensuite de se retrouver en position d'expansion shell.
      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

      # Second tour : jq remplit les deux espaces réservés null à partir du fichier capturé,
      # afin que les blocs soient renvoyés tels quels comme message de l'assistant. Le bloc
      # thinking DOIT accompagner le bloc tool_use. Le délimiteur entre guillemets empêche le
      # shell d'interpréter quoi que ce soit dans le corps.
      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?"}],
      )
      # Extraire le bloc tool_use pour obtenir son ID destiné au tool_result
      tool_use_block = next(block for block in response.content if block.type == "tool_use")

      # Appelez votre véritable API météo ; c'est ici que se placerait votre appel API réel
      # Supposons que c'est ce que nous recevons en retour
      weather_data = {"temperature": 88}

      # Deuxième requête - Inclure le tour de l'assistant et le 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?"},
              # Renvoyer le contenu de l'assistant exactement tel que reçu. Lorsqu'un bloc
              # thinking est présent, il doit accompagner le bloc 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?" }]
      });

      // Extraire le bloc tool_use pour obtenir son ID destiné au tool_result
      const toolUseBlock = response.content.find(
        (block): block is Anthropic.ToolUseBlock => block.type === "tool_use"
      );

      // Appelez votre véritable API météo ; c'est ici que se placerait votre appel API réel
      // Supposons que c'est ce que nous recevons en retour
      const weatherData = { temperature: 88 };

      if (toolUseBlock) {
        // Deuxième requête - Inclure le tour de l'assistant et le tool_result
        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?" },
            // Renvoyer le contenu de l'assistant exactement tel que reçu. Lorsqu'un bloc
            // thinking est présent, il doit accompagner le bloc 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);

      // Extraire le bloc tool_use pour obtenir son ID destiné au tool_result
      ToolUseBlock? toolUseBlock = null;
      foreach (var block in response.Content)
      {
          if (block.TryPickToolUse(out var toolUse))
          {
              toolUseBlock = toolUse;
              break;
          }
      }

      var weatherData = new { temperature = 88 };

      // Construire la suite avec le résultat de l'outil
      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 inclut les blocs de réflexion ; il est obligatoire de les renvoyer
              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;

          // Deuxième requête : renvoyer le tour de l'assistant tel que reçu, puis le résultat de l'outil
          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="Lire la réponse finale">
    Vous devriez voir Claude terminer le tour avec du texte. Comme la [réflexion entrelacée](https://platform.claude.com/docs/fr/build-with-claude/thinking#interleaved-thinking) est automatique en mode adaptatif, la suite peut également s'ouvrir sur un nouveau bloc de réflexion avant le texte final :

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

## Comment la réflexion entrelacée modifie le déroulement

L'« interleaved thinking » (réflexion entrelacée) permet à Claude de réfléchir entre les appels d'outils, en raisonnant sur chaque résultat d'outil avant d'agir en conséquence. Le concept et la disponibilité par modèle sont traités dans [Réflexion entrelacée](https://platform.claude.com/docs/fr/build-with-claude/thinking#interleaved-thinking) sur la page Réflexion ; l'entrelacement modifie l'endroit où apparaissent les blocs de réflexion, et non la possibilité d'enchaîner les appels d'outils. La comparaison suivante montre ce que la réflexion entrelacée change dans un flux de travail à deux outils :

<AccordionGroup>
  <Accordion title="Utilisation d'outils sans réflexion entrelacée">
    Sans réflexion entrelacée, Claude réfléchit une seule fois au début du tour de l'assistant. Les réponses suivantes après les résultats d'outils se poursuivent sans nouveaux blocs de réflexion.

    ```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="Utilisation d'outils avec réflexion entrelacée">
    Avec la réflexion entrelacée activée, Claude peut réfléchir après avoir reçu chaque résultat d'outil, ce qui lui permet de raisonner sur les résultats intermédiaires avant de continuer.

    ```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>

## Étapes suivantes

<CardGroup cols={3}>
  <Card title="Réflexion" icon="brain" href="https://platform.claude.com/docs/fr/build-with-claude/thinking">
    La vue d'ensemble : activer la réflexion, lire la sortie de réflexion et consulter les règles complètes pour l'utilisation d'outils, la mise en cache et le streaming.
  </Card>

  <Card title="Orienter la réflexion" icon="compass" href="https://platform.claude.com/docs/fr/build-with-claude/thinking-steering-and-cost">
    Orientez la fréquence et la profondeur de la réflexion de Claude grâce aux niveaux d'effort et aux indications basées sur les prompts.
  </Card>

  <Card title="Réflexion étendue" icon="clock" href="https://platform.claude.com/docs/fr/build-with-claude/extended-thinking">
    Budgets de réflexion manuels sur les modèles plus anciens : fonctionnement de `budget_tokens` et migration vers le mode adaptatif.
  </Card>
</CardGroup>
