---
title: 思考のステアリング
url: https://platform.claude.com/docs/ja/build-with-claude/thinking-steering-and-cost
description: エフォートレベル、システムプロンプトによるガイダンス、メッセージごとのステアリングを使って、Claudeがどのくらいの頻度で、どのくらい深く思考するかを制御し、思考のコストと料金について理解します。
---

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

Claudeの思考は適応的です。モデルは各リクエストを評価し、思考するかどうか、またどの程度思考するかを判断します。開発者は意図を設定し、必要に応じてエフォートを指定するだけで、モデルは推論が役立つと判断した箇所に推論を割り当てます。

このため、思考は、些細なリクエストと複雑なリクエストが混在するワークロードや、ステップごとに適切な推論量が変化する長期的なエージェントワークフローに非常に適しています。

思考を有効にする方法、思考出力の読み方、および[Claude Fable 5とClaude Mythos 5における思考出力](https://platform.claude.com/docs/ja/build-with-claude/thinking#thinking-output-on-claude-fable-5-and-claude-mythos-5)については、[思考](https://platform.claude.com/docs/ja/build-with-claude/thinking)の概要を参照してください。このページでは、Claudeがいつ思考するかをどのように判断するか、思考をどのようにステアリングするか、そしてそこから生じるキャッシング、コスト、料金の仕組みについて説明します。

## Claudeがいつ思考するかを判断する仕組み

思考はモデルにとって任意です。各リクエストにおいて、Claudeは入力の複雑さを考慮し、より深い推論によって回答が改善されるかどうかを判断します。単純な事実に関する質問には思考ブロックなしで直接回答することがあり、複数ステップの数学の問題や難しいデバッグタスクではより深い推論が行われます。

この決定はリクエストごとに行われます。同じ会話の中に、思考を伴うターンと伴わないターンが含まれることがあり、Claudeが思考しないことを選択したターンには思考ブロックが含まれません。すべてのアシスタントターンが思考ブロックで始まることを前提としたアプリケーションロジックを構築しないでください。

この決定に対する主要な制御手段は[effort](https://platform.claude.com/docs/ja/build-with-claude/effort)（エフォート）パラメータです。これは、Claudeがどの程度積極的に思考すべきか、またどの程度深く思考すべきかについてのソフトなガイダンスとして機能します。各レベルの動作については、このページの[エフォートレベル](https://platform.claude.com/docs/ja/build-with-claude/thinking-steering-and-cost#effort-levels)を参照してください。

Claudeに思考の頻度を減らしてほしい場合は、プロンプトベースのステアリングに手を伸ばす前に、エフォートレベルを下げてください。

思考はツール使用とも自動的にインターリーブされます。Claudeはツール呼び出しの合間に思考し、各ツール結果を検討してから次に何をするかを判断できます（[インターリーブ思考](https://platform.claude.com/docs/ja/build-with-claude/thinking#interleaved-thinking)）。これにはベータヘッダーや追加の設定は必要ありません。

思考の設定とエフォートパラメータがどのように相互作用するかの全体像については、[思考とエフォート](https://platform.claude.com/docs/ja/build-with-claude/thinking#thinking-and-effort)を参照してください。

## Claudeが思考する頻度のステアリング

Claudeが特定のターンで思考するかどうかは、プロンプトで制御可能です。エフォートは全体的な姿勢を設定しますが、システムプロンプトでグローバルに、またはユーザーターンからメッセージごとに、自然言語のガイダンスで決定を直接形作ることもできます。

2つのレバーを次の順序で組み合わせて使用してください。

1. ワークロードにおける品質とレイテンシのデフォルトのバランスに合ったエフォートレベルを設定します。
2. そのレベルでもClaudeのトリガー動作がニーズに合わない場合にのみ、プロンプトによるガイダンスを追加します。

<Note>
  Claude Sonnet 5.5とClaude Haiku 5.5で思考を減らすには、エフォートレベルを下げてください。システムプロンプトでClaude Sonnet 5.5に思考を減らすよう求めても、思考が確実に減るわけではありません。また、Anthropicのテストでは、プロンプトでClaude Haiku 5.5に直接回答するよう指示しても、思考は止まりませんでした。[Claude Sonnet 5.5へのプロンプト](https://platform.claude.com/docs/ja/build-with-claude/prompt-engineering/prompting-claude-sonnet-5-5#calibrate-effort)および[Claude Haiku 5.5へのプロンプト](https://platform.claude.com/docs/ja/build-with-claude/prompt-engineering/prompting-claude-haiku-5-5#use-effort-to-control-thinking)を参照してください。
</Note>

思考に関するより広範なプロンプティングのガイダンスについては、[思考とインターリーブ思考の機能を活用する](https://platform.claude.com/docs/ja/build-with-claude/prompt-engineering/claude-prompting-best-practices#leverage-thinking-and-interleaved-thinking-capabilities)を参照してください。

### エフォートレベル

エフォートは、思考をステアリングするための主要な手段です。各レベルは、Claudeが思考する頻度と深さについて、それぞれ異なるデフォルトを設定します。

| エフォートレベル                                          | 思考の動作                                            |
| ------------------------------------------------- | ------------------------------------------------ |
| `max`                                             | Claudeは最も積極的かつ最も深く思考し、思考の長さに制約はありません。            |
| `xhigh`                                           | Claudeは`high`よりも積極的かつ深く思考し、広範な探索に適しています。         |
| `high`（ほとんどのモデルでのデフォルト）                           | Claudeは思考が有益なほとんどのリクエストで思考します。複雑なタスクで深い推論を提供します。 |
| `medium`（Claude Opus 5.5とClaude Haiku 5.5でのデフォルト） | Claudeは適度に思考します。単純なクエリでは思考を省略することがあります。          |
| `low`                                             | Claudeは思考を最小限に抑えます。速度が最も重要な単純なタスクでは思考を省略します。     |

どのレベルでも、Claudeはリクエストごとに思考するかどうかを判断します。ツール使用のループでは、新しいユーザー入力後の最初のリクエストが通常、推論の大部分を担い、ツール結果を処理するだけの後続リクエストでは、`xhigh`や`max`であっても思考が省略されることがあります。また、会話が長くなるにつれて、リクエストあたりの思考は減少する傾向があります。すべてのリクエストで思考ブロックを保証するレベルはありません。

この表は、各レベルによって思考の動作がどのように変わるかを示しています。特定のワークロードでどのレベルを選ぶべきかのガイダンス（モデルごとの推奨事項を含む）については、エフォートのページの[エフォートパラメータを調整するタイミング](https://platform.claude.com/docs/ja/build-with-claude/effort#when-to-adjust-the-effort-parameter)を参照してください。

エフォートは`thinking`オブジェクト内ではなく、`output_config.effort`で設定します。言語ごとの完全な例については、[エフォート](https://platform.claude.com/docs/ja/build-with-claude/effort#basic-usage)を参照してください。

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

利用可能なレベルはモデルによって異なります。各モデルがサポートするレベルについては、エフォートのページにある[エフォートの利用可能性の表](https://platform.claude.com/docs/ja/build-with-claude/effort#effort-levels)を正式な情報源として参照してください。

### システムプロンプトによるガイダンス

システムプロンプトによるガイダンスは、会話内のすべてのリクエストに対してClaudeの思考のしきい値を変化させます。Claudeがワークロードに必要な以上に頻繁に思考している場合は、次のようなガイダンスをシステムプロンプトに追加してください。

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

逆に思考を促したい場合は、次のようなフレーズを使用してください。

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

ステアリングの効果は、正確な言い回しに左右されることがあります。ある言い回しで望む動作が得られない場合は、より直接的な表現を試してください。

### メッセージごとのステアリング

システムプロンプトとは独立して、ユーザーターンからメッセージごとに思考をステアリングすることもできます。ユーザーメッセージに`"Please think hard before responding."`を追加するとそのターンでClaudeの思考が促され、`"Answer directly without deliberating."`を追加すると思考が抑制されます。

メッセージごとのステアリングは、会話内の一部のリクエストだけが広範な推論を必要とする場合に便利です。たとえばエージェントハーネスでは、システムプロンプトに手を加えたりターン間でリクエストパラメータを変更したりすることなく、計画ステップでは促すフレーズを、定型的な確認では抑制するフレーズを追加できます。

Claude Haiku 5.5では、抑制するフレーズによって思考が確実に減るわけではありません。Claude APIとGoogle Cloudでは、代わりに[メッセージごとのエフォート変更](https://platform.claude.com/docs/ja/build-with-claude/effort#change-effort-mid-conversation-beta)（ベータ）を使用して、そのモデルで定型的なターンを少ない思考で実行してください。この方法ではプロンプトキャッシュも維持されます。

### ワークロードでステアリングを検証する

プロンプトベースのステアリングはモデルの動作を変化させるため、他のプロンプト変更と同様に扱ってください。つまり、リリース前に測定してください。トラフィックの代表的なサンプルをガイダンスありとなしで実行し、思考がトリガーされる頻度（応答内の思考ブロックの有無）、出力トークン使用量、レイテンシ、そして重要なケースにおける回答品質を比較してください。

<Warning>
  Claudeに思考の頻度を減らすようステアリングすると、推論の恩恵を受けるタスクで品質が低下する可能性があります。[エフォート](https://platform.claude.com/docs/ja/build-with-claude/effort)レベルを下げることは、言い回しに左右される指示ではなく調整済みの制御手段であるため、通常は最初に使うべきより良いレバーです。プロンプトベースのチューニングを本番環境にデプロイする前に、特定のワークロードへの影響を測定してください。
</Warning>

## 仕組み

Claudeが自身の思考を管理することから、3つの仕組みが生じます。ターンの検証、プロンプトキャッシング、そしてコストの上限設定方法です。

### ターンの検証

アシスタントターンは思考ブロックで始まる必要はありません。（レガシーの手動思考バジェットを使用するモデルでは、思考が有効なリクエストの最後のアシスタントターンが思考ブロックで始まることが強制されます。[手動モードにおけるターン構造](https://platform.claude.com/docs/ja/build-with-claude/extended-thinking#turn-structure-in-manual-mode)を参照してください。）

マルチターンアプリケーションにとって、これは会話履歴をどのような形であってもそのまま渡せることを意味します。

* Claudeが思考しないことを選択したアシスタントターンは、そのままで有効な履歴です。
* 思考なしで始まった会話や、異なる思考設定を使用していた会話を、履歴を書き換えることなく再開できます。
* 複数のソースから組み立てられた履歴は、検証を通過するために各アシスタントターンの先頭に思考ブロックを再挿入する必要はありません。

この緩和は検証に関するものであり、何を送信すべきかに関するものではありません。思考ブロックがある場合は、変更せずにそのまま渡してください。特にツール使用中は、思考ブロックがClaudeのツール呼び出しの背後にある推論を保持しているため重要です。完全なルールについては、[思考](https://platform.claude.com/docs/ja/build-with-claude/thinking)の概要を参照してください。

### プロンプトキャッシング

同じ思考設定とエフォートレベルを維持する連続したリクエストでは、プロンプトキャッシングが保持されます。完全なルールについては、[思考とプロンプトキャッシング](https://platform.claude.com/docs/ja/build-with-claude/thinking#thinking-and-prompt-caching)を参照してください。解決されたエフォート値はプロンプトに組み込まれます。そのため、リクエスト間でこの値を変更すると、キャッシュブレークポイントが無効になります。これは、従来の[`budget_tokens`](https://platform.claude.com/docs/ja/build-with-claude/extended-thinking#extended-thinking-with-prompt-caching)パラメータを使用するモデルで、その値を変更した場合と同じです。`effort`をモデルのデフォルト値に明示的に設定することは省略した場合と同等であり、キャッシュは無効になりません。

実際的な結論としては、会話ごとに思考設定とトップレベルのエフォートレベルを選び、それを維持してください。一部のターンでより多くまたはより少ない思考が必要な場合は、サポートしているモデルで[メッセージごとのエフォート変更](https://platform.claude.com/docs/ja/build-with-claude/effort#change-effort-mid-conversation-beta)（ベータ）を使用するか、[メッセージごとのプロンプティング](https://platform.claude.com/docs/ja/build-with-claude/thinking-steering-and-cost#tuning-thinking-behavior)でステアリングしてください。どちらも以前のキャッシュブレークポイントをそのまま維持しますが、思考設定やトップレベルのエフォートレベルの変更ではそうなりません。

次の例は、自分で実行できるマルチターンスクリプトで、この無効化を示しています。

<Accordion title="エフォートの変更によりプロンプトキャッシングが無効化される">
  <Tabs>
    <Tab title="cURL">
      <Note>
        このワークフローは、単発のシェルコマンドでは表現しにくいものです。マルチターンのパターンについてはSDKのタブを参照してください。ターンごとのHTTPリクエストは、[プロンプトキャッシング](https://platform.claude.com/docs/ja/build-with-claude/prompt-caching)ページの例に従います。
      </Note>
    </Tab>

    <Tab title="CLI">
      <Note>
        このワークフローは、単発のシェルコマンドでは表現しにくいものです。マルチターンのパターンについてはSDKのタブを参照してください。ターンごとのCLI呼び出しは、[プロンプトキャッシング](https://platform.claude.com/docs/ja/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)


      # 記事のコンテンツを取得します
      book_url = "https://www.gutenberg.org/cache/epub/1342/pg1342.txt"
      book_content = fetch_article_content(book_url)
      # キャッシュに十分な量のテキストのみを使用します（最初の数章）
      LARGE_TEXT = book_content[:10000]

      # システムプロンプトなし - 代わりにメッセージ内でキャッシュします
      MESSAGES = [
          {
              "role": "user",
              "content": [
                  {
                      "type": "text",
                      "text": LARGE_TEXT,
                      "cache_control": {"type": "ephemeral"},
                  },
                  {"type": "text", "text": "Analyze the tone of this passage."},
              ],
          }
      ]

      # 1回目のリクエスト - キャッシュを確立します
      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."})

      # 2回目のリクエスト - 同じ設定（キャッシュヒットを想定）
      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."})

      # 3回目のリクエスト - 異なる effort レベル（キャッシュミスを想定）
      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);

      // システムプロンプトなし - 代わりにメッセージ内でキャッシュします
      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."
            }
          ]
        }
      ];

      // 1回目のリクエスト - キャッシュを確立します
      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." }
      );

      // 2回目のリクエスト - 同じ設定です（キャッシュヒットが想定されます）
      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." }
      );

      // 3回目のリクエスト - effort レベルが異なります（キャッシュミスが想定されます）
      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]
      }

      // システムプロンプトなし - 代わりに messages 内でキャッシュします
      messages := []anthropic.MessageParam{
      	anthropic.NewUserMessage(
      		anthropic.ContentBlockParamUnion{OfText: &anthropic.TextBlockParam{
      			Text:         largeText,
      			CacheControl: anthropic.NewCacheControlEphemeralParam(),
      		}},
      		anthropic.NewTextBlock("Analyze the tone of this passage."),
      	),
      }

      // 1回目のリクエスト - キャッシュを確立します
      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.")))

      // 2回目のリクエスト - 同じ設定です（キャッシュヒットが想定されます）
      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.")))

      // 3回目のリクエスト - effort レベルが異なります（キャッシュミスが想定されます）
      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()));

          // 1回目のリクエスト - キャッシュを作成します
          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());

          // 2回目のリクエスト - 同じ設定です（キャッシュヒットが想定されます）
          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());

          // 3回目のリクエスト - effort レベルが異なります（キャッシュミスが想定されます）
          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>

  スクリプトの出力は次のとおりです（数値は多少異なる場合があります）。

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

  キャッシュブレークポイントがmessages配列内にある場合、エフォートをClaude Opus 5.5のデフォルトである`medium`から`low`に変更すると、そのブレークポイントが無効になります。2番目のリクエストではキャッシュ全体が読み取られていましたが、3番目のリクエストでは`cache_creation_input_tokens=3546`および`cache_read_input_tokens=0`となっています。
</Accordion>

### コスト制御

思考トークンのバジェットは設定しません。2つの制御手段がコストの上限を定めます。

* `max_tokens`は、思考と応答テキストを合わせた、リクエストの総出力に対するハードキャップです。Claudeがこれを超えて生成することはありません。ツール使用ループでは、ターン内の各リクエストがそれぞれ独自の`max_tokens`を持つため、ターン全体の消費量の上限にはなりません。
* `effort`は、その出力のうちClaudeがどれだけを思考に割り当てるかについてのソフトなガイダンスです。動作を形作りますが、トークン数を保証するものではありません。

思考は`max_tokens`にカウントされるため、推論と回答の両方に余裕を残せるよう十分に高く設定してください。思考なしの応答に合わせてサイズ設定された`max_tokens`は、Claudeが難しいリクエストで思考を始めると、小さすぎることがよくあります。

`high`以上のエフォートでは、Claudeは広範に思考する可能性があり、バジェットを使い切る可能性が高くなります。応答に[`stop_reason: "max_tokens"`](https://platform.claude.com/docs/ja/build-with-claude/thinking-troubleshooting#stopped-at-max-tokens)が表示される場合、2つの対処法があります。

* `max_tokens`を引き上げて、思考と回答のためにモデルにより多くの余裕を与えます。
* エフォートレベルを下げて、Claudeの思考を減らし、バジェットのより多くを応答テキストに残します。

どちらが正しいかは、切り捨てられた応答が推論を必要としていたかどうかによります。それらのリクエストの品質が重要であればキャップを引き上げ、過剰に思考していたのであればエフォートを下げてください。

## 料金

思考では、以下に対して料金が発生します。

* Claudeが思考中に使用するトークン（出力トークンとして課金）
* [保持のデフォルト](https://platform.claude.com/docs/ja/build-with-claude/thinking#thinking-block-preservation-by-model)に従ってコンテキストに残る、以前のアシスタントターンの思考ブロック。keep-allモデルではデフォルトですべてのターン、それ以外では最後のターンのみ（入力トークンとして課金）
* 標準のテキスト出力トークン

<Note>
  思考が有効な場合、この機能をサポートするために専用のシステムプロンプトが自動的に含まれます。
</Note>

課金対象は`display`設定に関係なく同じです。変わるのは表示される内容だけです。

|                  | `display: "summarized"` | `display: "omitted"`         |
| ---------------- | ----------------------- | ---------------------------- |
| **入力トークン**       | 元のリクエスト内のトークン           | summarizedと同じ                |
| **出力トークン（課金対象）** | Claudeが内部で生成した完全な思考トークン | summarizedと同じ                |
| **出力トークン（表示）**   | 要約された思考テキスト             | 思考トークンはゼロ（`thinking`フィールドは空） |
| **要約の生成**        | 料金なし                    | 該当なし                         |

<Warning>
  課金される出力トークン数は、応答内に表示されるトークン数と**一致しません**。応答内に表示される思考内容ではなく、完全な思考プロセスに対して課金されます。
</Warning>

内部推論に費やされた課金対象の出力トークン数を確認するには、応答内の`usage.output_tokens_details.thinking_tokens`を読み取ってください。この値は、モデルが生成した生の推論（本文で返される要約テキストではありません）を反映しており、常に`output_tokens`以下です。これを`output_tokens`から差し引くことで、出力の非推論部分を概算できます。ストリーミング時には、この内訳は最後の`message_delta`イベントにのみ表示されます。

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

`output_tokens`は引き続き、課金に使用される包括的で正式な合計値です。`output_tokens_details`は、オブザーバビリティのための読み取り専用の内訳です。基本料金、キャッシュ書き込み、キャッシュヒット、出力トークンを含む完全な料金情報については、[料金](https://platform.claude.com/docs/ja/about-claude/pricing)を参照してください。

## 次のステップ

<CardGroup cols={3}>
  <Card title="思考" icon="brain" href="https://platform.claude.com/docs/ja/build-with-claude/thinking">
    思考を有効にし、思考出力を読み取り、モデルごとのサポート状況を確認します。
  </Card>

  <Card title="ツールおよびマルチターンワークフローにおける思考" icon="wrench" href="https://platform.claude.com/docs/ja/build-with-claude/thinking-tool-workflows">
    ツール呼び出しをまたいで思考ブロックを保持し、マルチターン会話で思考を管理します。
  </Card>

  <Card title="エフォート" icon="sliders" href="https://platform.claude.com/docs/ja/build-with-claude/effort">
    Claudeがリクエストごとに割り当てる思考と出力の量を制御します。
  </Card>
</CardGroup>
