---
title: Dirigir el pensamiento
url: https://platform.claude.com/docs/es/build-with-claude/thinking-steering-and-cost
description: Dirige con qué frecuencia y con qué profundidad piensa Claude mediante niveles de esfuerzo, orientación en la indicación del sistema y dirección por mensaje, y comprende el costo y los precios del pensamiento.
---

<Note>
  Para saber cómo se aplica la "zero data retention" (retención cero de datos), o ZDR, a esta función, consulta [API y retención de datos](https://platform.claude.com/docs/es/manage-claude/api-and-data-retention).
</Note>

El "thinking" (pensamiento) de Claude es adaptativo: el modelo evalúa cada solicitud y determina si debe pensar y cuánto. Tú estableces una intención, opcionalmente especificas el esfuerzo, y el modelo asigna razonamiento donde considera que el razonamiento ayudará.

Esto hace que el pensamiento sea muy adecuado para cargas de trabajo que mezclan solicitudes triviales y complejas, y para flujos de trabajo agénticos de largo horizonte donde la cantidad correcta de razonamiento varía de un paso a otro.

Para aprender cómo activar el pensamiento, cómo leer la salida del pensamiento y sobre la [salida del pensamiento en Claude Fable 5 y Claude Mythos 5](https://platform.claude.com/docs/es/build-with-claude/thinking#thinking-output-on-claude-fable-5-and-claude-mythos-5), consulta la descripción general de [Pensamiento](https://platform.claude.com/docs/es/build-with-claude/thinking). Esta página cubre cómo Claude determina cuándo pensar, cómo dirigir el pensamiento y la mecánica de caché, costo y precios que se deriva de ello.

## Cómo Claude determina cuándo pensar

Pensar es opcional para el modelo. En cada solicitud, Claude sopesa la complejidad de la entrada y determina si un razonamiento más profundo mejoraría la respuesta. Una pregunta factual simple puede recibir una respuesta directa sin ningún bloque de pensamiento; un problema matemático de varios pasos o una tarea de depuración complicada desencadena un razonamiento más profundo.

La decisión ocurre por solicitud. La misma conversación puede contener turnos con y sin pensamiento, y un turno en el que Claude eligió no pensar no contiene ningún bloque de pensamiento. No construyas lógica de aplicación que asuma que cada turno del asistente comienza con uno.

El control principal sobre esta decisión es el parámetro [effort](https://platform.claude.com/docs/es/build-with-claude/effort) (esfuerzo), que actúa como orientación suave sobre qué tan dispuesto debe estar Claude a pensar y con qué profundidad; consulta [Niveles de esfuerzo](https://platform.claude.com/docs/es/build-with-claude/thinking-steering-and-cost#effort-levels) en esta página para ver qué hace cada nivel.

Si quieres que Claude piense con menos frecuencia, baja el nivel de esfuerzo antes de recurrir a la dirección basada en prompts.

El pensamiento también se intercala automáticamente con el "tool use" (uso de herramientas): Claude puede pensar entre llamadas a herramientas, reflexionando sobre cada resultado de herramienta antes de determinar qué hacer a continuación ([pensamiento intercalado](https://platform.claude.com/docs/es/build-with-claude/thinking#interleaved-thinking)). No necesitas un encabezado beta ni ninguna configuración adicional para esto.

Para ver el panorama completo de cómo interactúan la configuración de pensamiento y el parámetro de esfuerzo, consulta [Pensamiento y esfuerzo](https://platform.claude.com/docs/es/build-with-claude/thinking#thinking-and-effort).

## Dirigir con qué frecuencia piensa Claude

Si Claude piensa en un turno dado es algo que se puede controlar mediante prompts. El esfuerzo establece la postura general, pero también puedes moldear la decisión directamente con orientación en lenguaje natural, ya sea globalmente en la "system prompt" (indicación del sistema) o por mensaje desde el turno del usuario.

Usa las dos palancas juntas en este orden:

1. Establece el nivel de esfuerzo que coincida con el equilibrio predeterminado de calidad y latencia de tu carga de trabajo.
2. Agrega orientación en el prompt solo si la activación del pensamiento de Claude aún no coincide con tus necesidades en ese nivel.

<Note>
  Para obtener menos pensamiento en Claude Sonnet 5.5 y Claude Haiku 5.5, reduce el nivel de esfuerzo. Pedirle a Claude Sonnet 5.5 en la indicación del sistema que piense menos no reduce su pensamiento de forma fiable, y en las pruebas de Anthropic, indicarle a Claude Haiku 5.5 en el prompt que respondiera directamente no impidió que pensara. Consulta [Cómo escribir prompts para Claude Sonnet 5.5](https://platform.claude.com/docs/es/build-with-claude/prompt-engineering/prompting-claude-sonnet-5-5#calibrate-effort) y [Cómo escribir prompts para Claude Haiku 5.5](https://platform.claude.com/docs/es/build-with-claude/prompt-engineering/prompting-claude-haiku-5-5#use-effort-to-control-thinking).
</Note>

Para una orientación más amplia sobre prompts con pensamiento, consulta [aprovechar las capacidades de pensamiento y pensamiento intercalado](https://platform.claude.com/docs/es/build-with-claude/prompt-engineering/claude-prompting-best-practices#leverage-thinking-and-interleaved-thinking-capabilities).

### Niveles de esfuerzo

El esfuerzo es la palanca de dirección principal para el pensamiento. Cada nivel establece un valor predeterminado diferente para la frecuencia y la profundidad con que piensa Claude:

| Nivel de esfuerzo                                               | Comportamiento del pensamiento                                                                                                   |
| --------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `max`                                                           | Claude piensa con mayor disposición y con la mayor profundidad, sin restricción en la longitud del pensamiento.                  |
| `xhigh`                                                         | Claude piensa con más disposición y mayor profundidad que en `high`, adecuado para exploraciones extensas.                       |
| `high` (predeterminado en la mayoría de los modelos)            | Claude piensa en la mayoría de las solicitudes que se benefician de ello. Proporciona razonamiento profundo en tareas complejas. |
| `medium` (predeterminado en Claude Opus 5.5 y Claude Haiku 5.5) | Claude usa un pensamiento moderado. Puede omitir el pensamiento en consultas simples.                                            |
| `low`                                                           | Claude minimiza el pensamiento. Omite el pensamiento en tareas simples donde la velocidad es lo más importante.                  |

En todos los niveles, Claude determina por solicitud si debe pensar. En un bucle de uso de herramientas, la primera solicitud después de una nueva entrada del usuario normalmente concentra la mayor parte del razonamiento, y las solicitudes posteriores que solo procesan resultados de herramientas pueden omitir el pensamiento, incluso en `xhigh` y `max`. El pensamiento por solicitud también tiende a disminuir a medida que una conversación se alarga. Ningún nivel garantiza un bloque de pensamiento en cada solicitud.

Esta tabla describe cómo cada nivel cambia el comportamiento de pensamiento. Para orientación sobre qué nivel elegir para una carga de trabajo dada, incluidas recomendaciones por modelo, consulta [Cuándo ajustar el parámetro de esfuerzo](https://platform.claude.com/docs/es/build-with-claude/effort#when-to-adjust-the-effort-parameter) en la página de esfuerzo.

El esfuerzo se establece en `output_config.effort`, no dentro del objeto `thinking`; para ejemplos completos por lenguaje, consulta [Esfuerzo](https://platform.claude.com/docs/es/build-with-claude/effort#basic-usage).

```json
{
  "model": "claude-opus-5-5",
  "max_tokens": 4096,
  "output_config": { "effort": "medium" },
  "messages": [{ "role": "user", "content": "..." }]
}
```

La disponibilidad de niveles varía según el modelo; la [tabla de disponibilidad de esfuerzo](https://platform.claude.com/docs/es/build-with-claude/effort#effort-levels) en la página de esfuerzo es la autoridad sobre qué niveles admite cada modelo.

### Orientación en la indicación del sistema

La orientación en la indicación del sistema desplaza el umbral de pensamiento de Claude para cada solicitud en la conversación. Si Claude está pensando con más frecuencia de lo que tu carga de trabajo necesita, agrega orientación como esta a tu indicación del sistema:

```text wrap
Extended thinking adds latency and should only be used when it
will meaningfully improve answer quality, typically for problems
that require multistep reasoning. When in doubt, respond directly.
```

Para fomentar el pensamiento en su lugar, usa una frase como:

```text wrap
This task involves multistep reasoning. Think carefully before responding.
```

La efectividad de la dirección puede ser sensible a la redacción exacta. Si una formulación no produce el comportamiento que deseas, prueba una variante más directa.

### Dirección por mensaje

También puedes dirigir el pensamiento por mensaje desde el turno del usuario, independientemente de la indicación del sistema. Agregar `"Please think hard before responding."` a un mensaje del usuario anima a Claude a pensar en ese turno; `"Answer directly without deliberating."` lo desalienta.

La dirección por mensaje es útil cuando solo algunas solicitudes de una conversación justifican un razonamiento extendido. Un arnés de agente, por ejemplo, puede agregar la frase de estímulo en los pasos de planificación y la frase disuasoria en las confirmaciones rutinarias, sin tocar la indicación del sistema ni cambiar ningún parámetro de solicitud entre turnos.

En Claude Haiku 5.5, la frase disuasoria no reduce el pensamiento de forma fiable. En la Claude API y Google Cloud, ejecuta los turnos rutinarios en ese modelo con menos pensamiento usando en su lugar un [cambio de esfuerzo por mensaje](https://platform.claude.com/docs/es/build-with-claude/effort#change-effort-mid-conversation-beta) (beta), que además conserva la caché de prompts.

### Verifica la dirección en tu carga de trabajo

La dirección basada en prompts cambia el comportamiento del modelo, así que trátala como cualquier otro cambio de prompt: mide antes de lanzar. Ejecuta una muestra representativa de tu tráfico con y sin la orientación, y compara con qué frecuencia se activa el pensamiento (la presencia de bloques de pensamiento en las respuestas), el uso de tokens de salida, la latencia y la calidad de las respuestas en los casos que te importan.

<Warning>
  Dirigir a Claude para que piense con menos frecuencia puede reducir la calidad en tareas que se benefician del razonamiento. Bajar el nivel de [esfuerzo](https://platform.claude.com/docs/es/build-with-claude/effort) suele ser la mejor primera palanca, ya que es un control calibrado en lugar de una instrucción sensible a la redacción. Mide el impacto en tus cargas de trabajo específicas antes de implementar ajustes basados en prompts en producción.
</Warning>

## Mecánicas

Tres mecánicas se derivan de que Claude gestione su propio pensamiento: la validación de turnos, el almacenamiento en caché de prompts y cómo limitas el costo.

### Validación de turnos

Los turnos del asistente no necesitan comenzar con un bloque de pensamiento. (Los modelos que usan un presupuesto de pensamiento manual heredado exigen que el turno final del asistente de una solicitud con pensamiento habilitado comience con uno; consulta [Estructura de turnos en modo manual](https://platform.claude.com/docs/es/build-with-claude/extended-thinking#turn-structure-in-manual-mode).)

Para aplicaciones de múltiples turnos, esto significa que puedes devolver el historial de conversación en la forma en que lo tengas:

* Los turnos del asistente en los que Claude eligió no pensar son historial válido tal como están.
* Puedes reanudar una conversación que comenzó sin pensamiento, o que usó una configuración de pensamiento diferente, sin reescribir su historial.
* El historial ensamblado a partir de fuentes mixtas no necesita que se reinserten bloques de pensamiento al inicio de cada turno del asistente para pasar la validación.

La flexibilización se refiere a la validación, no a lo que deberías enviar. Cuando tengas bloques de pensamiento, devuélvelos sin modificar, particularmente durante el uso de herramientas, donde contienen el razonamiento detrás de las llamadas a herramientas de Claude. Consulta la descripción general de [Pensamiento](https://platform.claude.com/docs/es/build-with-claude/thinking) para ver las reglas completas.

### Almacenamiento en caché de prompts

Las solicitudes consecutivas que mantienen la misma configuración de pensamiento y nivel de esfuerzo preservan el "prompt caching" (almacenamiento en caché de prompts); consulta [Pensamiento y almacenamiento en caché de prompts](https://platform.claude.com/docs/es/build-with-claude/thinking#thinking-and-prompt-caching) para ver las reglas completas. El valor de esfuerzo resuelto se incorpora en el prompt, por lo que cambiarlo entre solicitudes invalida los puntos de interrupción de caché, al igual que lo hace cambiar el parámetro heredado [`budget_tokens`](https://platform.claude.com/docs/es/build-with-claude/extended-thinking#extended-thinking-with-prompt-caching) en los modelos que lo usan. Establecer `effort` explícitamente al valor predeterminado del modelo es equivalente a omitirlo y no rompe la caché.

La consecuencia práctica: elige una configuración de pensamiento y un valor de esfuerzo de nivel superior por conversación y mantenlos. Si algunos turnos necesitan más o menos pensamiento, usa un [cambio de esfuerzo por mensaje](https://platform.claude.com/docs/es/build-with-claude/effort#change-effort-mid-conversation-beta) (beta) en los modelos que lo admiten, o dirige con [prompting por mensaje](https://platform.claude.com/docs/es/build-with-claude/thinking-steering-and-cost#tuning-thinking-behavior). Ambos dejan intactos los puntos de interrupción de caché anteriores, mientras que un cambio en la configuración de pensamiento o en el valor de esfuerzo de nivel superior no lo hace.

El siguiente ejemplo demuestra la invalidación con un script de múltiples turnos que puedes ejecutar tú mismo:

<Accordion title="Los cambios de esfuerzo invalidan la caché de prompts">
  <Tabs>
    <Tab title="cURL">
      <Note>
        Este flujo de trabajo no se traduce bien a un comando de shell único. Consulta las pestañas de SDK para ver el patrón de múltiples turnos; las solicitudes HTTP por turno siguen los ejemplos de la página de [Almacenamiento en caché de prompts](https://platform.claude.com/docs/es/build-with-claude/prompt-caching).
      </Note>
    </Tab>

    <Tab title="CLI">
      <Note>
        Este flujo de trabajo no se traduce bien a un comando de shell único. Consulta las pestañas de SDK para ver el patrón de múltiples turnos; las invocaciones de CLI por turno siguen los ejemplos de la página de [Almacenamiento en caché de prompts](https://platform.claude.com/docs/es/build-with-claude/prompt-caching).
      </Note>
    </Tab>

    <Tab title="Python">
      ```python
      import requests

      client = Anthropic()


      def fetch_article_content(url):
          text = requests.get(url).text
          lines = (line.strip() for line in text.splitlines())
          return "\n".join(line for line in lines if line)


      # Obtén el contenido del artículo
      book_url = "https://www.gutenberg.org/cache/epub/1342/pg1342.txt"
      book_content = fetch_article_content(book_url)
      # Usa solo el texto suficiente para el almacenamiento en caché (primeros capítulos)
      LARGE_TEXT = book_content[:10000]

      # Sin indicación del sistema: el almacenamiento en caché se hace en los mensajes
      MESSAGES = [
          {
              "role": "user",
              "content": [
                  {
                      "type": "text",
                      "text": LARGE_TEXT,
                      "cache_control": {"type": "ephemeral"},
                  },
                  {"type": "text", "text": "Analyze the tone of this passage."},
              ],
          }
      ]

      # Primera solicitud: establece la caché
      print("First request - establishing cache")
      response1 = client.messages.create(
          model="claude-opus-5-5",
          max_tokens=16000,
          thinking={"type": "adaptive"},
          messages=MESSAGES,
      )

      print(f"First response usage: {response1.usage}")

      MESSAGES.append({"role": "assistant", "content": response1.content})
      MESSAGES.append({"role": "user", "content": "Analyze the characters in this passage."})

      # Segunda solicitud: misma configuración (se espera acierto de caché)
      print("\nSecond request - same configuration (cache hit expected)")
      response2 = client.messages.create(
          model="claude-opus-5-5",
          max_tokens=16000,
          thinking={"type": "adaptive"},
          messages=MESSAGES,
      )

      print(f"Second response usage: {response2.usage}")

      MESSAGES.append({"role": "assistant", "content": response2.content})
      MESSAGES.append({"role": "user", "content": "Analyze the setting in this passage."})

      # Tercera solicitud: distinto nivel de esfuerzo (se espera fallo de caché)
      print("\nThird request - different effort level (cache miss expected)")
      response3 = client.messages.create(
          model="claude-opus-5-5",
          max_tokens=16000,
          thinking={"type": "adaptive"},
          output_config={"effort": "low"},
          messages=MESSAGES,
      )

      print(f"Third response usage: {response3.usage}")
      ```
    </Tab>

    <Tab title="TypeScript">
      ```typescript

      const client = new Anthropic();

      async function fetchArticleContent(url: string): Promise<string> {
        const response = await fetch(url);
        const text = await response.text();
        const lines = text.split("\n").map((line) => line.trim());
        return lines.filter((line) => line).join("\n");
      }

      const bookUrl = "https://www.gutenberg.org/cache/epub/1342/pg1342.txt";
      const bookContent = await fetchArticleContent(bookUrl);
      const LARGE_TEXT = bookContent.substring(0, 10000);

      // Sin indicación del sistema: el almacenamiento en caché va en los mensajes
      const messages: Anthropic.MessageParam[] = [
        {
          role: "user",
          content: [
            {
              type: "text",
              text: LARGE_TEXT,
              cache_control: { type: "ephemeral" }
            },
            {
              type: "text",
              text: "Analyze the tone of this passage."
            }
          ]
        }
      ];

      // Primera solicitud: establece la caché
      console.log("First request - establishing cache");
      const response1 = await client.messages.create({
        model: "claude-opus-5-5",
        max_tokens: 16000,
        thinking: { type: "adaptive" },
        messages
      });

      console.log("First response usage: ", response1.usage);

      messages.push(
        { role: "assistant", content: response1.content },
        { role: "user", content: "Analyze the characters in this passage." }
      );

      // Segunda solicitud: misma configuración (se espera acierto de caché)
      console.log("\nSecond request - same configuration (cache hit expected)");
      const response2 = await client.messages.create({
        model: "claude-opus-5-5",
        max_tokens: 16000,
        thinking: { type: "adaptive" },
        messages
      });

      console.log("Second response usage: ", response2.usage);

      messages.push(
        { role: "assistant", content: response2.content },
        { role: "user", content: "Analyze the setting in this passage." }
      );

      // Tercera solicitud: distinto nivel de esfuerzo (se espera fallo de caché)
      console.log("\nThird request - different effort level (cache miss expected)");
      const response3 = await client.messages.create({
        model: "claude-opus-5-5",
        max_tokens: 16000,
        thinking: { type: "adaptive" },
        output_config: { effort: "low" },
        messages
      });

      console.log("Third response usage: ", response3.usage);
      ```
    </Tab>

    <Tab title="C#">
      ```csharp
      AnthropicClient client = new();

      string bookUrl = "https://www.gutenberg.org/cache/epub/1342/pg1342.txt";
      string bookContent = await FetchArticleContent(bookUrl);
      string largeText = bookContent.Substring(0, Math.Min(10000, bookContent.Length));

      Console.WriteLine("First request - establishing cache");
      var parameters1 = new MessageCreateParams
      {
          Model = Model.ClaudeOpus5_5,
          MaxTokens = 16000,
          Thinking = new ThinkingConfigAdaptive(),
          Messages =
          [
              new()
              {
                  Role = Role.User,
                  Content = new MessageParamContent(new List<ContentBlockParam>
                  {
                      new ContentBlockParam(new TextBlockParam()
                      {
                          Text = largeText,
                          CacheControl = new CacheControlEphemeral(),
                      }),
                      new ContentBlockParam(new TextBlockParam()
                      {
                          Text = "Analyze the tone of this passage."
                      }),
                  })
              }
          ]
      };

      var response1 = await client.Messages.Create(parameters1);
      Console.WriteLine($"First response usage: {response1.Usage}");

      Console.WriteLine("\nSecond request - same configuration (cache hit expected)");
      var parameters2 = new MessageCreateParams
      {
          Model = Model.ClaudeOpus5_5,
          MaxTokens = 16000,
          Thinking = new ThinkingConfigAdaptive(),
          Messages =
          [
              new()
              {
                  Role = Role.User,
                  Content = new MessageParamContent(new List<ContentBlockParam>
                  {
                      new ContentBlockParam(new TextBlockParam()
                      {
                          Text = largeText,
                          CacheControl = new CacheControlEphemeral(),
                      }),
                      new ContentBlockParam(new TextBlockParam()
                      {
                          Text = "Analyze the tone of this passage."
                      }),
                  })
              },
              new()
              {
                  Role = Role.Assistant,
                  Content = response1.Content.Select(block => new ContentBlockParam(block.Json)).ToList()
              },
              new()
              {
                  Role = Role.User,
                  Content = "Analyze the characters in this passage."
              }
          ]
      };

      var response2 = await client.Messages.Create(parameters2);
      Console.WriteLine($"Second response usage: {response2.Usage}");

      Console.WriteLine("\nThird request - different effort level (cache miss expected)");
      var parameters3 = new MessageCreateParams
      {
          Model = Model.ClaudeOpus5_5,
          MaxTokens = 16000,
          Thinking = new ThinkingConfigAdaptive(),
          OutputConfig = new OutputConfig
          {
              Effort = Effort.Low
          },
          Messages =
          [
              new()
              {
                  Role = Role.User,
                  Content = new MessageParamContent(new List<ContentBlockParam>
                  {
                      new ContentBlockParam(new TextBlockParam()
                      {
                          Text = largeText,
                          CacheControl = new CacheControlEphemeral(),
                      }),
                      new ContentBlockParam(new TextBlockParam()
                      {
                          Text = "Analyze the tone of this passage."
                      }),
                  })
              },
              new()
              {
                  Role = Role.Assistant,
                  Content = response1.Content.Select(block => new ContentBlockParam(block.Json)).ToList()
              },
              new()
              {
                  Role = Role.User,
                  Content = "Analyze the characters in this passage."
              },
              new()
              {
                  Role = Role.Assistant,
                  Content = response2.Content.Select(block => new ContentBlockParam(block.Json)).ToList()
              },
              new()
              {
                  Role = Role.User,
                  Content = "Analyze the setting in this passage."
              }
          ]
      };

      var response3 = await client.Messages.Create(parameters3);
      Console.WriteLine($"Third response usage: {response3.Usage}");

      static async Task<string> FetchArticleContent(string url)
      {
          using HttpClient httpClient = new();
          string content = await httpClient.GetStringAsync(url);
          return content;
      }
      ```
    </Tab>

    <Tab title="Go">
      ```go
      client := anthropic.NewClient()

      bookURL := "https://www.gutenberg.org/cache/epub/1342/pg1342.txt"
      bookContent, err := fetchArticleContent(bookURL)
      if err != nil {
      	log.Fatal(err)
      }

      largeText := bookContent
      if len(largeText) > 10000 {
      	largeText = largeText[:10000]
      }

      // Sin indicación del sistema: el almacenamiento en caché va en los mensajes
      messages := []anthropic.MessageParam{
      	anthropic.NewUserMessage(
      		anthropic.ContentBlockParamUnion{OfText: &anthropic.TextBlockParam{
      			Text:         largeText,
      			CacheControl: anthropic.NewCacheControlEphemeralParam(),
      		}},
      		anthropic.NewTextBlock("Analyze the tone of this passage."),
      	),
      }

      // Primera solicitud: establece la caché
      fmt.Println("First request - establishing cache")
      response1, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
      	Model:     anthropic.ModelClaudeOpus5_5,
      	MaxTokens: 16000,
      	Thinking: anthropic.ThinkingConfigParamUnion{
      		OfAdaptive: &anthropic.ThinkingConfigAdaptiveParam{},
      	},
      	Messages: messages,
      })
      if err != nil {
      	log.Fatal(err)
      }
      fmt.Printf("First response usage: %s\n", response1.Usage.RawJSON())

      messages = append(messages, response1.ToParam())
      messages = append(messages, anthropic.NewUserMessage(anthropic.NewTextBlock("Analyze the characters in this passage.")))

      // Segunda solicitud: misma configuración (se espera acierto de caché)
      fmt.Println("\nSecond request - same configuration (cache hit expected)")
      response2, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
      	Model:     anthropic.ModelClaudeOpus5_5,
      	MaxTokens: 16000,
      	Thinking: anthropic.ThinkingConfigParamUnion{
      		OfAdaptive: &anthropic.ThinkingConfigAdaptiveParam{},
      	},
      	Messages: messages,
      })
      if err != nil {
      	log.Fatal(err)
      }
      fmt.Printf("Second response usage: %s\n", response2.Usage.RawJSON())

      messages = append(messages, response2.ToParam())
      messages = append(messages, anthropic.NewUserMessage(anthropic.NewTextBlock("Analyze the setting in this passage.")))

      // Tercera solicitud: distinto nivel de esfuerzo (se espera fallo de caché)
      fmt.Println("\nThird request - different effort level (cache miss expected)")
      response3, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
      	Model:     anthropic.ModelClaudeOpus5_5,
      	MaxTokens: 16000,
      	Thinking: anthropic.ThinkingConfigParamUnion{
      		OfAdaptive: &anthropic.ThinkingConfigAdaptiveParam{},
      	},
      	OutputConfig: anthropic.OutputConfigParam{
      		Effort: anthropic.OutputConfigEffortLow,
      	},
      	Messages: messages,
      })
      if err != nil {
      	log.Fatal(err)
      }
      fmt.Printf("Third response usage: %s\n", response3.Usage.RawJSON())
      ```
    </Tab>

    <Tab title="Java">
      ```java
      import com.anthropic.models.messages.CacheControlEphemeral;
      // ...
      void main() throws Exception {
          AnthropicClient client = AnthropicOkHttpClient.fromEnv();

          String bookUrl = "https://www.gutenberg.org/cache/epub/1342/pg1342.txt";
          String bookContent = fetchArticleContent(bookUrl);
          String largeText = bookContent.substring(0, Math.min(10000, bookContent.length()));

          // Primera solicitud: se establece la caché
          IO.println("First request - establishing cache");
          MessageCreateParams params1 = MessageCreateParams.builder()
              .model(Model.CLAUDE_OPUS_5_5)
              .maxTokens(16000L)
              .thinking(ThinkingConfigAdaptive.builder().build())
              .addUserMessageOfBlockParams(List.of(
                  ContentBlockParam.ofText(TextBlockParam.builder()
                      .text(largeText)
                      .cacheControl(CacheControlEphemeral.builder().build())
                      .build()),
                  ContentBlockParam.ofText(TextBlockParam.builder()
                      .text("Analyze the tone of this passage.")
                      .build())
              ))
              .build();

          Message response1 = client.messages().create(params1);
          IO.println("First response usage: " + response1.usage());

          // Segunda solicitud: misma configuración (se espera acierto de caché)
          IO.println("\nSecond request - same configuration (cache hit expected)");
          MessageCreateParams params2 = MessageCreateParams.builder()
              .model(Model.CLAUDE_OPUS_5_5)
              .maxTokens(16000L)
              .thinking(ThinkingConfigAdaptive.builder().build())
              .addUserMessageOfBlockParams(List.of(
                  ContentBlockParam.ofText(TextBlockParam.builder()
                      .text(largeText)
                      .cacheControl(CacheControlEphemeral.builder().build())
                      .build()),
                  ContentBlockParam.ofText(TextBlockParam.builder()
                      .text("Analyze the tone of this passage.")
                      .build())
              ))
              .addAssistantMessageOfBlockParams(response1.content().stream()
                  .map(block -> block.toParam())
                  .collect(java.util.stream.Collectors.toList()))
              .addUserMessage("Analyze the characters in this passage.")
              .build();

          Message response2 = client.messages().create(params2);
          IO.println("Second response usage: " + response2.usage());

          // Tercera solicitud: distinto nivel de esfuerzo (se espera fallo de caché)
          IO.println("\nThird request - different effort level (cache miss expected)");
          MessageCreateParams params3 = MessageCreateParams.builder()
              .model(Model.CLAUDE_OPUS_5_5)
              .maxTokens(16000L)
              .thinking(ThinkingConfigAdaptive.builder().build())
              .outputConfig(OutputConfig.builder()
                  .effort(OutputConfig.Effort.LOW)
                  .build())
              .addUserMessageOfBlockParams(List.of(
                  ContentBlockParam.ofText(TextBlockParam.builder()
                      .text(largeText)
                      .cacheControl(CacheControlEphemeral.builder().build())
                      .build()),
                  ContentBlockParam.ofText(TextBlockParam.builder()
                      .text("Analyze the tone of this passage.")
                      .build())
              ))
              .addAssistantMessageOfBlockParams(response1.content().stream()
                  .map(block -> block.toParam())
                  .collect(java.util.stream.Collectors.toList()))
              .addUserMessage("Analyze the characters in this passage.")
              .addAssistantMessageOfBlockParams(response2.content().stream()
                  .map(block -> block.toParam())
                  .collect(java.util.stream.Collectors.toList()))
              .addUserMessage("Analyze the setting in this passage.")
              .build();

          Message response3 = client.messages().create(params3);
          IO.println("Third response usage: " + response3.usage());
      }

      String fetchArticleContent(String url) throws Exception {
          HttpClient client = HttpClient.newHttpClient();
          HttpRequest request = HttpRequest.newBuilder()
              .uri(URI.create(url))
              .build();
          HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
          return response.body();
      }
      ```
    </Tab>

    <Tab title="PHP">
      ```php
      function fetchArticleContent($url) {
          $content = file_get_contents($url);
          $lines = explode("\n", $content);
          $cleanedLines = array_filter(array_map('trim', $lines));
          return implode("\n", $cleanedLines);
      }

      $client = new Client();

      $bookUrl = "https://www.gutenberg.org/cache/epub/1342/pg1342.txt";
      $bookContent = fetchArticleContent($bookUrl);
      $largeText = substr($bookContent, 0, 10000);

      echo "First request - establishing cache\n";
      $response1 = $client->messages->create(
          maxTokens: 16000,
          messages: [[
              'role' => 'user',
              'content' => [
                  [
                      'type' => 'text',
                      'text' => $largeText,
                      'cache_control' => ['type' => 'ephemeral']
                  ],
                  [
                      'type' => 'text',
                      'text' => 'Analyze the tone of this passage.'
                  ]
              ]
          ]],
          model: 'claude-opus-5-5',
          thinking: ['type' => 'adaptive'],
      );

      echo "First response usage: " . json_encode($response1->usage) . "\n";

      echo "\nSecond request - same configuration (cache hit expected)\n";
      $response2 = $client->messages->create(
          maxTokens: 16000,
          messages: [
              [
                  'role' => 'user',
                  'content' => [
                      [
                          'type' => 'text',
                          'text' => $largeText,
                          'cache_control' => ['type' => 'ephemeral']
                      ],
                      [
                          'type' => 'text',
                          'text' => 'Analyze the tone of this passage.'
                      ]
                  ]
              ],
              [
                  'role' => 'assistant',
                  'content' => $response1->content
              ],
              [
                  'role' => 'user',
                  'content' => 'Analyze the characters in this passage.'
              ]
          ],
          model: 'claude-opus-5-5',
          thinking: ['type' => 'adaptive'],
      );

      echo "Second response usage: " . json_encode($response2->usage) . "\n";

      echo "\nThird request - different effort level (cache miss expected)\n";
      $response3 = $client->messages->create(
          maxTokens: 16000,
          messages: [
              [
                  'role' => 'user',
                  'content' => [
                      [
                          'type' => 'text',
                          'text' => $largeText,
                          'cache_control' => ['type' => 'ephemeral']
                      ],
                      [
                          'type' => 'text',
                          'text' => 'Analyze the tone of this passage.'
                      ]
                  ]
              ],
              [
                  'role' => 'assistant',
                  'content' => $response1->content
              ],
              [
                  'role' => 'user',
                  'content' => 'Analyze the characters in this passage.'
              ],
              [
                  'role' => 'assistant',
                  'content' => $response2->content
              ],
              [
                  'role' => 'user',
                  'content' => 'Analyze the setting in this passage.'
              ]
          ],
          model: 'claude-opus-5-5',
          thinking: ['type' => 'adaptive'],
          outputConfig: ['effort' => 'low'],
      );

      echo "Third response usage: " . json_encode($response3->usage) . "\n";
      ```
    </Tab>

    <Tab title="Ruby">
      ```ruby
      require "net/http"
      require "uri"

      def fetch_article_content(url)
        uri = URI.parse(url)
        response = Net::HTTP.get_response(uri)
        text = response.body

        lines = text.split("\n").map(&:strip)
        lines.reject(&:empty?).join("\n")
      end

      client = Anthropic::Client.new

      book_url = "https://www.gutenberg.org/cache/epub/1342/pg1342.txt"
      book_content = fetch_article_content(book_url)
      large_text = book_content[0...10000]

      puts "First request - establishing cache"
      response1 = client.messages.create(
        model: "claude-opus-5-5",
        max_tokens: 16000,
        thinking: {
          type: "adaptive"
        },
        messages: [{
          role: "user",
          content: [
            {
              type: "text",
              text: large_text,
              cache_control: { type: "ephemeral" }
            },
            {
              type: "text",
              text: "Analyze the tone of this passage."
            }
          ]
        }]
      )

      puts "First response usage: #{response1.usage}"

      puts "\nSecond request - same configuration (cache hit expected)"
      response2 = client.messages.create(
        model: "claude-opus-5-5",
        max_tokens: 16000,
        thinking: {
          type: "adaptive"
        },
        messages: [
          {
            role: "user",
            content: [
              {
                type: "text",
                text: large_text,
                cache_control: { type: "ephemeral" }
              },
              {
                type: "text",
                text: "Analyze the tone of this passage."
              }
            ]
          },
          {
            role: "assistant",
            content: response1.content
          },
          {
            role: "user",
            content: "Analyze the characters in this passage."
          }
        ]
      )

      puts "Second response usage: #{response2.usage}"

      puts "\nThird request - different effort level (cache miss expected)"
      response3 = client.messages.create(
        model: "claude-opus-5-5",
        max_tokens: 16000,
        thinking: {
          type: "adaptive"
        },
        output_config: {
          effort: "low"
        },
        messages: [
          {
            role: "user",
            content: [
              {
                type: "text",
                text: large_text,
                cache_control: { type: "ephemeral" }
              },
              {
                type: "text",
                text: "Analyze the tone of this passage."
              }
            ]
          },
          {
            role: "assistant",
            content: response1.content
          },
          {
            role: "user",
            content: "Analyze the characters in this passage."
          },
          {
            role: "assistant",
            content: response2.content
          },
          {
            role: "user",
            content: "Analyze the setting in this passage."
          }
        ]
      )

      puts "Third response usage: #{response3.usage}"
      ```
    </Tab>
  </Tabs>

  Esta es la salida del script (puede que veas números ligeramente diferentes):

  ```text Output wrap
  First request - establishing cache
  First response usage: { cache_creation_input_tokens: 3546, cache_read_input_tokens: 0, input_tokens: 15, output_tokens: 1033 }

  Second request - same configuration (cache hit expected)
  Second response usage: { cache_creation_input_tokens: 0, cache_read_input_tokens: 3546, input_tokens: 1062, output_tokens: 1630 }

  Third request - different effort level (cache miss expected)
  Third response usage: { cache_creation_input_tokens: 3546, cache_read_input_tokens: 0, input_tokens: 2706, output_tokens: 1468 }
  ```

  Con el punto de interrupción de caché en el arreglo de mensajes, cambiar el esfuerzo de `medium`, el valor predeterminado en Claude Opus 5.5, a `low` lo invalida: la tercera solicitud muestra `cache_creation_input_tokens=3546` y `cache_read_input_tokens=0`, mientras que la segunda mostraba una lectura completa de la caché.
</Accordion>

### Control de costos

No estableces un presupuesto de tokens de pensamiento. Dos controles limitan el costo:

* `max_tokens` es un límite estricto sobre la salida total de la solicitud, pensamiento y texto de respuesta combinados. Claude nunca genera más allá de él. En un bucle de uso de herramientas, cada solicitud en el turno tiene su propio `max_tokens`, por lo que no limita el gasto de todo el turno.
* `effort` es una orientación suave sobre cuánto de esa salida asigna Claude al pensamiento. Moldea el comportamiento pero no garantiza un conteo de tokens.

Dado que el pensamiento cuenta para `max_tokens`, establécelo lo suficientemente alto para dejar espacio tanto para el razonamiento como para la respuesta. Un `max_tokens` dimensionado para una respuesta sin pensamiento suele ser demasiado pequeño una vez que Claude comienza a pensar en solicitudes difíciles.

Con esfuerzo `high` y superior, Claude puede pensar extensamente y es más probable que agote el presupuesto. Si ves [`stop_reason: "max_tokens"`](https://platform.claude.com/docs/es/build-with-claude/thinking-troubleshooting#stopped-at-max-tokens) en las respuestas, tienes dos remedios:

* Aumenta `max_tokens` para darle al modelo más espacio para el pensamiento más la respuesta.
* Baja el nivel de esfuerzo para que Claude piense menos y deje más del presupuesto para el texto de respuesta.

Cuál es el correcto depende de si las respuestas truncadas necesitaban el razonamiento. Si la calidad en esas solicitudes importa, aumenta el límite; si se pensaron en exceso, baja el esfuerzo.

## Precios

El pensamiento genera cargos por:

* Tokens que Claude usa mientras piensa (facturados como tokens de salida)
* Bloques de pensamiento de turnos anteriores del asistente que permanecen en contexto, según el [valor predeterminado de preservación](https://platform.claude.com/docs/es/build-with-claude/thinking#thinking-block-preservation-by-model): todos los turnos de forma predeterminada en modelos que conservan todo, solo el último turno en los demás (facturados como tokens de entrada)
* Tokens de salida de texto estándar

<Note>
  Cuando el pensamiento está activo, se incluye automáticamente una indicación del sistema especializada para admitir esta función.
</Note>

Lo que se te factura es lo mismo independientemente de la configuración de `display`; solo cambia lo que ves:

|                                   | `display: "summarized"`                                            | `display: "omitted"`                                        |
| --------------------------------- | ------------------------------------------------------------------ | ----------------------------------------------------------- |
| **Tokens de entrada**             | Tokens en tu solicitud original                                    | Igual que summarized                                        |
| **Tokens de salida (facturados)** | Los tokens de pensamiento completos que Claude generó internamente | Igual que summarized                                        |
| **Tokens de salida (visibles)**   | El texto de pensamiento resumido                                   | Cero tokens de pensamiento (el campo `thinking` está vacío) |
| **Generación del resumen**        | Sin cargo                                                          | No aplica                                                   |

<Warning>
  El conteo de tokens de salida facturados **no** coincide con el conteo de tokens visibles en la respuesta. Se te factura por el proceso de pensamiento completo, no por el contenido de pensamiento visible en la respuesta.
</Warning>

Para ver cuántos tokens de salida facturados se gastaron en razonamiento interno, lee `usage.output_tokens_details.thinking_tokens` en la respuesta. Este valor refleja el razonamiento en bruto que generó el modelo (no el texto resumido devuelto en el cuerpo) y siempre es menor o igual que `output_tokens`. Réstalo de `output_tokens` para aproximar la porción de la salida que no es razonamiento. Al usar streaming, este desglose aparece solo en el evento final `message_delta`.

```json
{
  "usage": {
    "input_tokens": 25,
    "output_tokens": 348,
    "output_tokens_details": {
      "thinking_tokens": 312
    }
  }
}
```

`output_tokens` sigue siendo el total inclusivo y autoritativo usado para la facturación. `output_tokens_details` es un desglose de solo lectura para observabilidad. Para información completa de precios, incluidas tarifas base, escrituras en caché, aciertos de caché y tokens de salida, consulta [Precios](https://platform.claude.com/docs/es/about-claude/pricing).

## Próximos pasos

<CardGroup cols={3}>
  <Card title="Pensamiento" icon="brain" href="https://platform.claude.com/docs/es/build-with-claude/thinking">
    Activa el pensamiento, lee la salida del pensamiento y verifica la compatibilidad por modelo.
  </Card>

  <Card title="Pensamiento en flujos de trabajo con herramientas y de múltiples turnos" icon="wrench" href="https://platform.claude.com/docs/es/build-with-claude/thinking-tool-workflows">
    Preserva los bloques de pensamiento entre llamadas a herramientas y gestiona el pensamiento en conversaciones de múltiples turnos.
  </Card>

  <Card title="Esfuerzo" icon="sliders" href="https://platform.claude.com/docs/es/build-with-claude/effort">
    Controla cuánto pensamiento y salida asigna Claude por solicitud.
  </Card>
</CardGroup>
