楽しいExtended Thinking

楽しいExtended Thinking

みなさんこんにちは。エンジニアの竹田です。

先日GoogleがGemini3を発表しましたね。 LLMのランキング(https://lmarena.ai/leaderboard)を見ると、すぐにText部門で1位になっていました(2025/11/20時点)。

今はGemini,ChatGPT,Claude,Grokの4強時代。この4つについての新しいモデルが出るごとに首位が入れ替わっていますね。 LLMが日進月歩で賢くなっていくところをリアルタイムで体験できるというのは本当に貴重な体験ですね。

さて、そんなLLMですが私がLLMで好きなところはモデルのreasoning能力です。 reasoningというのは、LLMにいきなり思考して回答させるのではなくて、問題を正確に捉え思考の段取りをして段階的に考えていく...というようなことで、内部的にはCoT(Chain of Thought)などの手法が使われています。 (日本語だとreasoningを「推論」と訳すことが多いですが、本来reasoningとは日本語の「推論」よりももっと広い意味の言葉で、論理的に考える思考プロセス全体です。ややこしい)

思考の仕方・段取りを思考するというメタなところがグッときますよね。 もうちょっというと、人間でいう意識的に考えるというところがLLMで再現されているようでいいですよね。我々もしっかり考えたいときにはまず最初に調べるべきものは何かとか当てはめるべき考え方などを考えますからね。 LLMが人間に近付いている感じがして大好きです。

各モデルのAPIでreasoningに対してできること

そんなreasoningですが、各モデルをAPI経由で使うとできることに違いがあります。正確にはユーザ側から指示・制御できることが違います。

まとめてみるとこんな感じです。 (ChatGPT-5に作ってもらいました)

機能Open AIClaudeGemini
推論トークン上限指定×
思考深度(レベル)指定
思考過程の返却×
推論の内部状態引き継ぎ×
Reasoning 制御の細かさ

なんとOpen AIではreasoningについてほとんどパラメータ指定できません。 正確にはどれだけ思考するか(reasoningさせるか)ということをreasoning.effortというパラメータをつかって指定できるのですが、これがどこまでreasoningに影響を与えるかは明確ではないのです。 どうやらセキュリティ上の理由でこのような方針になっているようです。 Webの画面からは明示的にThinkingモードを指定してreasoningを動かせるのにちょっと不思議な感じがします。

今回は、これらモデルのうちでも最もreasoningの制御が細やかなClaudeで遊んでみました。 Claudeの場合にはExtended Thinkingという名前でreasoningの機能が提供されています。 やったことは推論トークンの上限(budget_tokens )を変えて回答の変化を見たり、その思考過程がどうなっているかを見てみようということです。

推論トークンとはLLMが内部でreasoningのために使うトークンです。これをどれだけ使ってよいか指定できるんですね。 また、思考過程とはreasoningでどのように考えたかという結果そのものです。Claude3.7までは思考過程そのものをAPIが返却してくれたのですが、Claude4以降は要約されたものが返却されるとのこと。

まずは今回のために作ったコードからClaudeのAPIを呼んでいる部分を抜粋します。

    with client.messages.stream(
        model="claude-sonnet-4-5-20250929",
        max_tokens=50000,
        thinking={
            "type": "enabled",
            "budget_tokens": budget
        },
        messages=[{"role": "user", "content": question}]
    ) as stream:

Extended Thinkingを有効にするには、thinking オブジェクトを追加し、type パラメータを enabled に設定し、budget_tokens に推論トークンの上限値を指定します。 今回はClaude Sonnet4.5を使います。

さて、budget_tokens を変えて回答と思考過程がどう変わるかを見てみましょう。 使ったお題はこれです。この問題をClaudeに解いてもらいましょう。(このお題自体も事前にClaudeに考えてもらいました)

√2が無理数であることを証明してください。

さらに、以下の数についても有理数無理数かを判定し、その理由を説明してください:

1) √3
2) √4
3) √6
4) √2 + √3
5) (√2)√2

各判定に対して、厳密な数学的証明を示してください。

ここで、特に5)の(√2)√2有理数無理数かの判定は数学的に難しいわけですが、Claudeはどんな風に考えて答えを出してくれるのでしょうか?

budget_tokensは1024→ 2048 → 8192と変化させてみます。

■budget_tokensが1024の場合

思考過程としてはこんなものが返ってきました(長いので後ろの部分を省略しています)。

この問題は√2の無理数性の証明と、いくつかの数が有理数無理数かを判定する問題です。順番に解答していきます。

√2が無理数であることの証明(背理法
√3の判定
√4の判定
√6の判定
√2 + √3の判定
(√2)√2の判定

それぞれ厳密に証明していきます。...

ふむふむ、まず√2を判定してかつそれを背理法で証明しようとしていますね。その後順番に回答していこうとしています。

さて、回答はどうかというと... (問1-4の回答はいずれの場合も普通に回答できていて面白くないので省略)

5) (√2)√2

判定:不明(一般的には超越数と考えられる)

不明、だそうです。超越数というキーワードも出てきていますね。 そうか、有理数無理数かは不明なんだ...

■budget_tokensが2024の場合

思考過程としてはこんなものが返ってきました(長いので後ろの部分を省略しています)。

この問題は√2の無理数性の証明と、いくつかの数の有理数無理数の判定を求めています。順番に答えていきましょう。

まず√2が無理数であることの証明から始めます。

次に各数について:

1) √3 - 無理数(√2と同様の証明)
2) √4 = 2 - 有理数
3) √6 - 無理数
4) √2 + √3 - 無理数
5) (√2)√2 - 超越数として知られていますが、証明は非常に難しい

それぞれ厳密に証明していきます。...

ちょっと長くなって、よく見るとそれぞれの問いについて、一旦の結論が書いてありますね。考えるまでもなく知っていることをまずは書きだしたのかな?

気になる5) (√2)√2の回答は次の通り。

5) (√2)√2

結論:有理数無理数か不明(ただし超越数であることが知られている)

やはり不明なのか...前回とは違いもあって、「考えられる」から「知られている」ということに変わっていて、超越数であることは確定した事実であるというような口ぶりになっています。

■budget_tokensが8192の場合

思考過程としてはこんなものが返ってきました(長いので後ろの部分を省略しています)。

この問題では、まず√2が無理数であることを証明し、その後、他の数についても有理数無理数かを判定する必要があります。

√2が無理数であることの証明

背理法を使います。√2が有理数であると仮定します。

仮定:√2 = p/q(pとqは互いに素な正の整数)

両辺を2乗すると:
2 = p²/q²
2q² = p²

(中略)

5) (√2)√2

この問題は非常に複雑で、直感的な解決は困難です。

Gelfond-Schneiderの定理を適用することで、数の性質を探ります。代数的数の特性に注目し、この特殊な累乗の性質を解明しようとしています。

(後略)

おお、明らかに違う! 最初に√2が無理数であることを厳密に証明して、さらにその後事細かにどのように考えていくかを考えています。

そして気になる5) (√2)√2の回答は次の通り。

5) (√2)√2

判定:無理数超越数

この問題は初等的には困難で、ゲルフォント=シュナイダーの定理を用いる。

なるほど。明確に無理数と回答してくれました。 なんだか賢くなった感じがしますねー。 (実際に(√2)√2有理数なのか無理数なのかについては、身近にいる数学の専門家に聞いてみてください)

■最後に

さて、今回の取り組みで厳密に何が分かったということはできませんが、推論トークンの量でLLMの思考(reasoning)が変わることは感じられましたね。 普段LLMを使っていると、魔法の箱のようで「賢いなー」「すごいなー」と思うわけですが、今回のようにAPIを使って少しでもその思考過程見てみると、内部の仕組みを実感として把握できるようになっていいですね。 これが実務にすぐ活きるというわけはありませんが、もしLLMが期待するように動いてくれなかったら、reasoning部分で失敗したのかな?それともreasoning以外のどこかかな?みたいに考えられるようにはなりますね。 みなさんもたまにはLLMのAPIで遊んでみてください。