🔍

[LLM] Reasoning Model でのユーザー体験を向上させるためにReasoning summaryを使う話

に公開

はじめに

OpenAI o1 が Reasoning model としてリリースされて1年強。その精度の高さに各社が追従し、今では LLM ベンチマークの上位陣のほとんどを Reasoning modelが占めるようになりました。
プロプライエタリなモデルに限らず、多くのOSSモデルもこれに追従しており、精度や賢さを追い求める場合のデファクトスタンダードになっています。

LLM Benchmark graph: ReasoningModel vs Non-Reasoning Model
引用: artificialanalysis.ai

一方でその精度向上と引き換えに、最終的な回答が得られるまでに今まで以上に長い時間がかかるようになってしまいました。
かつてプロンプトエンジニアリングで同様のこと(いわゆる CoT:Chain of Thought)を行っていた際は、その思考過程をストリーム形式で取得し、逐一表示することで、ユーザー体験が損なわれないような工夫が可能でした。しかし、Reasoning model の API においては、ノウハウ隠蔽の観点から各社が Thinking トークンを非公開にしたためにそうした工夫ができませんでした。 Reasoning modelは長いと1分以上Thinkingを行うため、ユーザーはその間何も表示されずに待つことになり、処理が問題なく進んでいるのか不安になってしまいます。

各社、APIリリース初期はそのような選択肢しかなかったのですが 例:Google 、その後、思考過程を要約した情報を返すようになりました。

名称こそバラバラなものの、thinking トークンを代替するもの、としては共通しています。
一方で細かい実装や特性は各社で異なりそうだったため、本当にユーザー体験向上に使えるのか確認するために、
各社の最新モデル(gpt-5, gemini-2.5-pro, claude-sonnet-4.5)でそれぞれ実装の確認と、細かい調査を行いました。

以下ではこれらをまとめて「Reasoning summary」と呼びます。

実装

各社のドキュメントをもとに、公式のSDKを用いてストリーム形式でReasoning summaryを取得して表示するサンプルをPythonで実装しました。

OpenAI SDK

OpenAI の SDK では、ストリーム開始時の引数である reasoning パラメータに "summary": "auto" を渡すのがポイントです。この状態で Stream からイベントを取得し、その type で中身を判定します。 また、従来のCompletion APIではなく、最新のResponse APIの形式を使う必要があります。

公式ドキュメント

import os
import dotenv
dotenv.load_dotenv()

from openai import OpenAI
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
client = OpenAI(api_key=OPENAI_API_KEY)

PROMPT = "もし磁極が孤立した北極または南極を持つことができる並行宇宙が存在するとしたら、マクスウェルの方程式はどのように変化するでしょうか?具体的にどの方程式が変化するのでしょうか?"

reasoning_buf = []
answer_buf = []

with client.responses.stream(
    model="gpt-5",
    input=[{"role": "user", "content": PROMPT}],
    reasoning={"summary": "auto", "effort": "medium"},
) as stream:
    reasoning_started = False
    answer_started = False

    for event in stream:
        et = event.type

        if et == "response.reasoning_summary_text.delta":
            if not reasoning_started:
                print("\n" + "=" * 60)
                print("=== Thinking ===")
                print("=" * 60 + "\n")
                reasoning_started = True
            part = event.delta
            reasoning_buf.append(part)
            print(part, end="", flush=True)

        elif et == "response.output_text.delta":
            if not answer_started:
                print("\n" + "=" * 60)
                print("=== Answer ===")
                print("=" * 60 + "\n")
                answer_started = True
            part = event.delta
            answer_buf.append(part)
            print(part, end="", flush=True)

        elif et == "response.completed":
            print()

Google GenAI SDK

Google GenAI SDK も OpenAI の SDK と似た実装になります。config で include_thoughts=True というパラメータを渡す点が重要です。part.text に結果が格納され、part.thought フラグで Thinking トークンなのか Answer トークンなのかを判別できます。

公式ドキュメント

import os
import dotenv
dotenv.load_dotenv()

from google import genai
from google.genai import types


GEMINI_API_KEY = os.getenv("GOOGLE_GENERATIVE_AI_API_KEY")
client = genai.Client(api_key=GEMINI_API_KEY)

PROMPT = "もし磁極が孤立した北極または南極を持つことができる並行宇宙が存在するとしたら、マクスウェルの方程式はどのように変化するでしょうか?具体的にどの方程式が変化するのでしょうか?"

thinking_buf = []
answer_buf = []

thinking_started = False
answer_started = False

for chunk in client.models.generate_content_stream(
    model="gemini-2.5-pro",
    contents=PROMPT,
    config=types.GenerateContentConfig(
        thinking_config=types.ThinkingConfig(
            include_thoughts=True
        ),
    )
):
    for part in chunk.candidates[0].content.parts:
        if not part.text:
            continue
        elif part.thought:
            if not thinking_started:
                print("\n" + "=" * 60)
                print("=== Thinking ===")
                print("=" * 60 + "\n")
                thinking_started = True
            thinking_buf.append(part.text)
            print(part.text, end="", flush=True)
        else:
            if not answer_started:
                print("\n" + "=" * 60)
                print("=== Answer ===")
                print("=" * 60 + "\n")
                answer_started = True
            answer_buf.append(part.text)
            print(part.text, end="", flush=True)

print()

Anthropic SDK

Anthropic の SDK では、特に特殊なフラグを設定する必要はなく、thinking を有効にするだけで出力されるようです。Stream に対してループ処理を行い、type で判定する仕組みは同じですが、ブロックの切り替えがイベントとして明示的に送られてくる設計になっています。
公式ドキュメント

import os
import dotenv
dotenv.load_dotenv()

import anthropic

ANTHROPIC_API_KEY = os.getenv("ANTHROPIC_API_KEY")
client = anthropic.Anthropic(api_key=ANTHROPIC_API_KEY)

PROMPT = "もし磁極が孤立した北極または南極を持つことができる並行宇宙が存在するとしたら、マクスウェルの方程式はどのように変化するでしょうか?具体的にどの方程式が変化するのでしょうか?"

thinking_buf = []
answer_buf = []

with client.messages.stream(
    model="claude-sonnet-4-5",
    thinking={"type": "enabled"},
    messages=[{"role": "user", "content": PROMPT}],
) as stream:
    thinking_started = False
    answer_started = False

    for event in stream:
        if event.type == "content_block_start":
            if event.content_block.type == "thinking":
                if not thinking_started:
                    print("\n" + "=" * 60)
                    print("=== Thinking ===")
                    print("=" * 60 + "\n")
                    thinking_started = True
            elif event.content_block.type == "text":
                if not answer_started:
                    print("\n" + "=" * 60)
                    print("=== Answer ===")
                    print("=" * 60 + "\n")
                    answer_started = True
        elif event.type == "content_block_delta":
            if event.delta.type == "thinking_delta":
                part = event.delta.thinking
                thinking_buf.append(part)
                print(part, end="", flush=True)
            elif event.delta.type == "text_delta":
                part = event.delta.text
                answer_buf.append(part)
                print(part, end="", flush=True)
        elif event.type == "content_block_stop":
            print()

実験

ドキュメントだけだと挙動が分かりづらかったので、気になったポイントを実際に実験して調べました。

実験設定

充分な思考を必要とする問題を用意するために、プロンプトには GPQA の問題を採用しました。
これはGoogle 検索では調べられないような本質的な知性を必要とする大学院レベルの問題を集めたデータセットです。
国内での実用性を考慮し、問題文は日本語に翻訳してから利用しています。

実験1: 出力のコントロール性(日本語にできるか?)

推論過程をエンドユーザーに見せようとする場合、その中身をコントロールしたくなります。特に言語は重要です。シンプルなプロンプトでどこまで制御が可能かを実験しました。

プロンプト

以下の系外惑星の中で、最も密度が高いのはどれですか?

a) 地球質量・地球半径の惑星
b) 地球質量の2倍で、密度が約5.5 g/cm^3の惑星
c) 地球と同じ組成を持ちながら、地球の5倍の質量を持つ惑星
d) 地球と同じ組成を持ちながら、地球の半分の質量を持つ惑星

===============
思考は必ず日本語で行い、そのまま出力してください。英語は使わないようにしてください。

実験結果

OpenAI (gpt-5)

指示を無視して英語で思考過程を出力したばかりか、「思考過程は見せられない」とモデルの方から拒否されてしまいました。コントロール性は低そうです。
リリース当初、OpenAIのAPIを使って学習データを集めることが問題になっていたので、その影響もありそうです。

[Thinking]
**Refining the response**

I see the user wants a concise answer to their question, and I should apologize for not sharing my internal reasoning. My final answer will be c), along with a brief explanation: if they have the same composition, greater mass leads to higher density due to self-compression. Option b) is explicitly stated as approximately 5.5 and is on par with option a), while d) has lower density. I wonder if including numerical densities is necessary. I might mention that density increases with mass for rocky compositions.
[Answer]
申し訳ありませんが、解法の思考過程そのものはお見せできません。結論と要点のみお伝えします。

答え:c)

理由:
- 同じ岩石系組成では、質量が大きいほど自己圧縮が強まり、平均密度は上がります(岩石惑星では概ね R ∝ M^0.27 程度の関係があり、密度は M/R^3 のため増加)。
- c) は地球と同組成で質量が5倍なので最も高密度。
- a) は地球密度(約5.5 g/cm^3)、b) も約5.5 g/cm^3と明示、d) は質量が小さく自己圧縮が弱いので密度は低め。

なお、日本語出力の指示を無くして素直に出力させると問題ない内容になります。ただし、Reasoning summaryは英語でした。

[Thinking]
**Calculating exoplanet density**

I’m trying to determine which exoplanet has the highest density. First, I note that a planet with Earth’s mass and radius has a density of about 5.51 g/cm³. Then I have two other planets, both approximately 5.5 g/cm³, matching Earth’s density. For the planet with five Earth masses, if its composition is comparable, the self-compression increases density. Following the mass-radius relationship, I can estimate that its density would be roughly 1.379 times Earth’s density.
[Answer]
答え:c)

理由:
- 同じ組成の岩石惑星では、質量が増えると自己圧縮が強まり、半径の増加が鈍るため、平均密度は上昇します。
- 近似的に R ∝ M^0.27 → ρ ∝ M/R^3 ∝ M^0.19。5 M⊕ なら ρ ≈ 5^0.19 × ρ⊕ ≈ 1.35–1.4 × 5.5 ≈ 7.4–7.7 g/cm^3。
- a) と b) はどちらも約5.5 g/cm^3、d) はそれ以下。

よって最も密度が高いのは c) です。

Google (gemini-2.5-pro)

指示を無視し、何事も無かったように英語で思考過程を出力しました。Answer の方で思考過程を出力してくれているので、そもそも Thinking と Answer の区別を LLM 内部で明確にしていない可能性が高そうです。
使いづらさはあるもののフォーマットは安定しているため、何らかの軽量モデルで別途翻訳させてから利用するのはありかもしれません。

[Thinking]
**Examining Exoplanet Densities**

I'm analyzing the provided exoplanet candidates, focusing on density calculations.  My current focus is on understanding the mass and volume data for each option. I'm leveraging my knowledge of density to determine which one is the most compact.  Next, I'll compare the results and determine the highest density.


**Assessing Density Differences**

I'm now diving into the calculations for each exoplanet option, considering the provided densities and masses. My current focus is on the impact of increased mass on a planet's volume and subsequent density, especially for those with Earth-like compositions.  I'm now weighing the effect of self-compression.  I'm making a comparison between the theoretical densities.


**Identifying Densest Exoplanet**

I'm now comparing the density of each exoplanet candidate. I've calculated that the planet with five times Earth's mass and Earth-like composition has the highest density. The impact of self-compression is significant, as the planet with half Earth's mass has a lower density.


**Confirming Highest Density**

I've meticulously analyzed each exoplanet option, considering mass, density, and the crucial impact of self-gravity. Comparing the options, I've confirmed that the planet with five times Earth's mass, sharing Earth's composition, will have the highest density due to significant self-compression. The analysis clearly shows this is the densest.
[Answer]
思考プロセス:

1.  **問題の理解:** 4つの選択肢の中から、最も密度が高い系外惑星はどれかを特定する問題です。
2.  **密度の基本:** 密度は「質量 ÷ 体積」で計算されます。惑星の場合、体積は半径の3乗に比例します。
3.  **重要な物理法則:** 惑星科学における重要な法則として、「同じ組成の天体は、質量が大きいほど自己重力が強くなり、内部が圧縮されて密度が高くなる」というものがあります。これを念頭に置いて各選択肢を評価します。
4.  **選択肢の分析:**
    *   **a) 地球質量・地球半径の惑星:** これは基準となる地球そのものです。密度は約5.5 g/cm³です。
    *   **b) 地球質量の2倍で、密度が約5.5 g/cm³の惑星:** この惑星の密度は、問題文で約5.5 g/cm³と指定されています。これは地球とほぼ同じ密度です。
    *   **c) 地球と同じ組成を持ちながら、地球の5倍の質量を持つ惑星:** 組成が地球と同じで、質量が5倍と非常に大きいです。上記の物理法則に基づくと、強い自己重力によって内部が強く圧縮されるため、密度は地球(約5.5 g/cm³)よりも**高く**なります。このような天体は「スーパーアース」と呼ばれます。
    *   **d) 地球と同じ組成を持ちながら、地球の半分の質量を持つ惑星:** 組成は地球と同じですが、質量は半分です。自己重力による圧縮効果が地球よりも弱いため、密度は地球(約5.5 g/cm³)よりも**低く**なります。
5.  **比較と結論:**
    *   a) の密度 ≈ 5.5 g/cm³
    *   b) の密度 ≈ 5.5 g/cm³
    *   c) の密度 > 5.5 g/cm³
    *   d) の密度 < 5.5 g/cm³

    したがって、最も密度が高いのは c) の惑星です。
---

**回答:**

正解は **c) 地球と同じ組成を持ちながら、地球の5倍の質量を持つ惑星** です。

**解説:**

惑星の密度を考える上で重要なポイントは、**自己重力による圧縮**です。

1.  **a) と b) の惑星:** これらの惑星の密度は、地球の密度(約5.5 g/cm³)とほぼ同じです。
2.  **d) の惑星:** 地球より質量が小さいため、自己重力も弱くなります。その結果、内部の物質が地球ほど強く圧縮されず、密度は地球よりも低くなります。
3.  **c) の惑星:** 地球と同じ物質(岩石や鉄など)でできていても、質量が5倍と非常に大きいため、その強大な自己重力によって中心部が強く圧縮されます。これにより、体積は質量の増加ほどには大きくならず、結果として全体の密度は地球よりも高くなります。

したがって、4つの選択肢の中で最も密度が高いのはc)の惑星です。

Anthropic (claude-sonnet-4-5)

今回試した3つのモデルの中では、最も指示通りの挙動を示してくれました。

[Thinking]
この問題は、系外惑星の密度を比較する問題です。各選択肢を詳しく見ていきましょう。

まず、地球の基本データ:
- 地球の密度:約5.5 g/cm³
- 地球の質量:M_E
- 地球の半径:R_E

a) 地球質量・地球半径の惑星
これは地球そのものなので、密度は5.5 g/cm³です。

b) 地球質量の2倍で、密度が約5.5 g/cm³の惑星
これは明示的に密度が5.5 g/cm³と書かれています。

c) 地球と同じ組成を持ちながら、地球の5倍の質量を持つ惑星
同じ組成でも、質量が大きくなると重力による圧縮が強くなり、密度が高くなります。

d) 地球と同じ組成を持ちながら、地球の半分の質量を持つ惑星
同じ組成でも、質量が小さくなると重力による圧縮が弱くなり、密度が低くなります。

重要なポイント:
惑星の質量が増えると、内部の圧力が高くなり、物質がより圧縮されます。そのため、同じ組成でも質量が大きい惑星ほど密度が高くなります。

地球型の岩石惑星の場合、質量が増えると密度も増加する傾向があります。これは自己重力圧縮によるものです。

5倍の質量を持つ惑星では、内部の重力圧縮が著しく増大します。物質は極めて強く圧縮され、結果として平均密度は地球よりも有意に高くなります。岩石惑星の質量-半径関係により、質量増加に伴う半径の増加は比例的ではないため、密度は上昇します。

質量と半径の関係式から、質量が5倍になると、半径は非線形に増加し、密度は増大することが数学的に証明されます。

実際の観測では、地球の5倍程度の質量を持つ「スーパーアース」は、密度が6-8 g/cm³まで上昇する可能性があります。

一方、地球の半分の質量を持つ惑星では、圧縮が弱まり、密度は地球よりも低下します。したがって、与えられた選択肢の中で最も適切な答えは c) となります。
[Answer]
この問題を段階的に考えていきます。

## 各選択肢の密度分析

**a) 地球質量・地球半径の惑星**
- これは地球そのものと同じなので、密度は約5.5 g/cm³

**b) 地球質量の2倍で、密度が約5.5 g/cm³の惑星**
- 明示的に密度5.5 g/cm³と示されています

**c) 地球と同じ組成を持ちながら、地球の5倍の質量を持つ惑星**
- ここが重要なポイントです
- 同じ組成でも、質量が大きくなると**自己重力圧縮**が強くなります
- 惑星内部の圧力が高まり、物質がより強く圧縮されます
- その結果、平均密度は地球(5.5 g/cm³)よりも**高く**なります
- スーパーアースと呼ばれるこのような惑星の密度は、6~8 g/cm³程度になることが知られています

**d) 地球と同じ組成を持ちながら、地球の半分の質量を持つ惑星**
- 質量が小さいため、重力圧縮が弱くなります
- 密度は地球よりも**低く**なります

## 結論

**答え:c) 地球と同じ組成を持ちながら、地球の5倍の質量を持つ惑星**

質量が大きい惑星ほど自己重力による圧縮効果が強くなるため、同じ組成でも密度が高くなります。地球の5倍の質量を持つ岩石惑星は、地球よりも有意に高い密度を持つことになります。

問題文が日本語だからThinkingトークンも日本語なのかもしれない、と思い
指示プロンプトを

思考は必ず英語で行い、そのまま出力してください。日本語は使わないようにしてください。
回答は日本語で行ってください。

に変えた場合も試したところ、しっかりと指示に従ってくれました。

[Thinking]
Let me analyze each option to determine which exoplanet has the highest density.

a) Earth mass and Earth radius planet
- Mass = 1 M_Earth
- Radius = 1 R_Earth
- Density = Earth's density = approximately 5.5 g/cm³

b) 2 times Earth mass with density of about 5.5 g/cm³
- Mass = 2 M_Earth
- Density = 5.5 g/cm³
- This is explicitly stated as 5.5 g/cm³

c) Same composition as Earth but 5 times Earth's mass
- Mass = 5 M_Earth
- Same composition as Earth
- When a planet has the same composition but higher mass, it will be compressed more by gravity, leading to higher density
- For rocky planets with Earth-like composition, increasing mass leads to self-compression
- The density will be higher than Earth's 5.5 g/cm³

d) Same composition as Earth but half the mass
- Mass = 0.5 M_Earth
- Same composition as Earth
- With less mass, there's less gravitational compression
- The density will be lower than Earth's 5.5 g/cm³

Now let me think more carefully about options c and d:

For rocky planets with the same composition, the density depends on the internal pressure and compression. More massive planets experience greater gravitational compression, which increases density.

Earth has a density of about 5.5 g/cm³. 

For option c (5 times Earth's mass, same composition):
- Due to self-compression from higher gravity, the density would be significantly higher than Earth's
- Studies show that for rocky planets with masses several times Earth's, densities can reach 7-10 g/cm³ or even higher due to compression

For option d (0.5 times Earth's mass, same composition):
- Less gravitational compression means lower density than Earth
- Density would be less than 5.5 g/cm³


- Comparing the densities reveals a clear trend of increasing density with increased mass

I'll compare the density ranges for each option, noting that option c stands out with its potential for significantly higher density due to gravitational compression. The increased mass leads to more intense internal pressure, causing the rocky material to compress more tightly. This results in a substantially higher density compared to the other options, making option c the planet with the highest density.
[Answer]
**回答:**
正解は **c) 地球と同じ組成を持ちながら、地球の5倍の質量を持つ惑星** です。

質量が大きい岩石惑星は、より強い重力による自己圧縮効果により、同じ組成でも密度が高くなります。地球の5倍の質量を持つ惑星は、内部の圧力が非常に高くなり、物質がより圧縮されるため、地球の密度(約5.5 g/cm³)を大きく上回る密度(おそらく7-9 g/cm³以上)になります。

結論

今回のシンプルな実験では、ChatGPT / Gemini においては Reasoning summary を好みの形式に制御するのは難しいということがわかりました。
Reasoning model の精度の高さを活かしつつ、ユーザー体験をなるべく良くするために思考過程を見せようとする場合、Claude が最も扱いやすそうです。試行回数が少なくプロンプトも磨き込んでいるわけではないので、前者でも絶対に不可能とは断言できませんが、あまり無理な制御をしようとすると精度への悪影響の方が大きくなりそうなので、自前で変換するなど異なるアプローチを取ったほうが良いかもしれません。

実験2: 出力されるタイミング(どのようにストリームが流れてくるか)

ストリーム形式でデータ取得ができるといっても、Answerトークンが送られてくる直前にまとめて送られてきたりしては意味がありません。API Request送信後、どのようにResponseのストリームが流れてくるかを調査しました。
送信直後を t=0 として、Reasoning summary と Answer トークンが流れてくるたびにトークン数をカウントし、どのようなタイミングでどんな量のトークンが送られてくるかを確認しました。

プロンプト

プロンプトとしては実験1と同じGPQAの問題を使いつつ、日本語指示などを含めると挙動が不安定になったため、それらの指示は除外したものを使用しました。

以下の系外惑星の中で、最も密度が高いのはどれですか?

a) 地球質量・地球半径の惑星
b) 地球質量の2倍で、密度が約5.5 g/cm^3の惑星
c) 地球と同じ組成を持ちながら、地球の5倍の質量を持つ惑星
d) 地球と同じ組成を持ちながら、地球の半分の質量を持つ惑星

結果

それぞれのモデル毎の結果をグラフ化したものを以下に示します。それぞれの点がストリームで送られてきたタイミングです(gpt-5, claude-sonnet-4-5は間隔が短すぎて点がつながってしまっています)

OpenAI gpt-5

gpt-5でのreasoning summary/answer tokenの出力タイミングのグラフ

ストリームはかなり細かく送られてきます。一定間隔ごとにストリームが止まるような挙動を示しており、中身と照らし合わせるとどうやら段落ごとにストリームが止まっているようでした。
Thinking の Step-by-Step 処理を、明示的に分割しているのでしょうか。
徐々にトークンが出力されている様子から、何らかの出力をまとめて要約・変換して送っているというよりは、
出力されたThinkingトークンをそのまま送っているような挙動でした。一部の、ノウハウ上重要なトークンを省略することを「要約」と呼んでいるのかな?と思いました。

一方、Answerトークンは一気に送られてくる挙動で、通常の LLMの出力速度を考えると少し違和感のある出力でした。Thinkingの処理とは別の処理モデルが存在するのか、Thinkingトークンを返却中に既にAnswerトークンの計算が進んでいるのか、それとも単なる偶然か。謎です。もう少し出力の長い問題設定を選んだり、reasoning effortを切り替えながら実験を重ねると見えてくるかもしれません。

Google gemini-2.5-pro

gemini-2.5-proでのreasoning summary/answer tokenの出力タイミングのグラフ

ChatGPT の結果とは大きく異なり段落ごとにまとめて一気に送られてくる挙動で、送られてくる頻度も少ないです。何らかの要約変換をしていてもおかしくないですし、単にThinking Stepごとに送るという方針なのかもしれません。
必ずこの粒度で送られてくると保証されているわけではありませんが、もし内部で日本語変換などの処理を挟むなら比較的扱いやすい挙動だと思いました。
Answerトークンの出力スピードは、LLMとしては自然な挙動かなと思いました。

Anthropic claude-sonnet-4.5

claude-sonnet-4.5でのreasoning summary/answer tokenの出力タイミングのグラフ

ChatGPT ほどではありませんが、細かく高頻度に送られてきています。中身を見ると特に段落などでStepが明確に分かれているわけではないので、自由なフォーマットで思考しているように見えます。
ChatGPTと同じようなストリームの停滞がある理由は不明です。

Answer トークンの出力も自然で、同じLLM モデルで一貫して出力されていそうだなと感じました。

結論

すべてのモデルにおいて、まず Reasoning summary が送られてきて、それが完了してから Answer トークンが送られてくるという挙動を示していることがわかりました。
また、処理の状況をエンドユーザーに知らせるには充分なタイミングで送られてきていることもわかりました。

一方で出力速度や頻度はモデルによって異なるので、UI更新などを細かく作り込む場合は各モデルの挙動に合わせて行う必要があるかと思います。

※ ドキュメント化されている仕様ではないですし、たかだか数回の実験なので、同じ挙動を示さない可能性や将来的に変更される可能性があります。実装はフェイルセーフに行うことを推奨します。

実験3: Web版との比較

ここまでAPIの出力する結果を見てきましたが各社が提供しているWeb版ではどのようにこれらの情報を扱っているのでしょうか? APIの結果と一致するのでしょうか?
Web版では各社独自のシステムプロンプト、ツール組み込み、メモリ機能の活用などを行っているので、完全に同じ条件での比較は難しいのですが、
見せ方の工夫も含めてどういう方針を取っているのかを確認しました。

OpenAI ChatGPT Web版

https://chatgpt.com/

ChatGPT Web版でのReasoningSummary出力例

ChatGPT Web版では APIと異なり、日本語で思考過程を出力してくれます。特に指示がなくてもプロンプトと同じ言語で考えてくれました。

ChatGPT Web版でのReasoningSummary出力例(日本語指定)

あえてAPIの実験の時と同じように思考過程に対して注文をつける指示をしても警告を出したりしませんでした。根本的に違う仕組みで動いていそうな印象を持ちました。

Web版で日本語化されるということは何かしらのパラメータやシステムプロンプトを指定すればAPIでもできるのでは?と期待したのですが、
調べていくと、どうやらAPIが非英語に対応してないのは現時点では仕様のようです。
GitHubのIssueに非英語対応のリクエストが上がっているのですが、
中の人から現時点では対応が難しい旨が返されていました。やりとりの中で勧められているように、翻訳などの独自の工夫をするしかなさそうです。

Google Gemini Web版

https://gemini.google.com/

Gemini Web版でのReasoningSummary出力例
Gemini Web版でのReasoningSummary出力例2
Gemini Web版では、結果の出力はAPIにおけるReasoning summaryとほぼ同じ形式で、
英文&一定の量の文章の連なりで構成されていました。 日本語で聞いているのに不親切だなとも思いつつ、APIと同じ仕様なのはある意味シンプルでわかりやすいとは感じました。

Anthropic Claude Web版

https://claude.ai/

Claude Web版でのReasoningSummary出力例

Claude Web版では、Geminiと同様にAPIとほとんど同じ内容の結果を得ることができました。
待ち時間にも安心して見ていられるので、やはり優れた体験だなと感じました。

結論

OpenAIだけ、APIとの間に特殊な差があることがわかりましたが、他2社はAPIの仕様そのままの出力で、素直に逐次出力するUI提供になっていました。
OpenAIの差分は不可解ですが、ChatGPTはモデル選びの自動化や早くからのメモリ機能の導入など、UIレイヤーでの特色を色々と出しており、APIを使ったサードパーティ製のアプリケーションとの差別化をするためのプロダクト戦略の一環なのかもしれません。

一方でAPI利用時には不便で用途に制約を受けるのは間違いないので、Web版で提供できているのならその機能をAPIにも提供してほしいなとは1開発者としては思いました。

まとめ

各社の Reasoning model が提供する Reasoning summary について実装・調査を行いました。
概念としては近いものでありつつも、挙動や制約は大きく違うことがわかりました。

AIの返答までの待ち時間をいかに退屈させずに見せるかというのは今後もAIアプリケーションにおいて重要な課題だと考えています。
どこまでの情報を出してどこまでの情報を隠すのか、というのは各社試行錯誤しているようなので継続してキャッチアップしていこうと思います。

ELEMENTS Engineering

Discussion