Reasoning Model Hands-on

この手順では、自作の推論ループを小さく作りながら、推論モデルの構成要素を確認します。

ここで作るものは、LLMを追加学習して作る本物の reasoning model ではありません。既存の Mini Transformer の横に、推論時の controller を置く教材です。hidden scratchpad、reasoning effort、candidate path、verifier、self-consistency を実行結果として見られるようにします。

概念説明を先に確認したい場合は Reasoning Model Story を読んでください。このページでは、そこで出てきた用語を小さな CLI として動かします。

0. 準備

devbox run install
devbox run test

直接 uv run ... を試す場合は devbox shell に入ります。

devbox shell

1. 最小の推論ループを動かす

まず、低い effort で数式を解きます。

uv run mini-transformer-reason --prompt "12 + 7" --effort low

観察する点:

  • answer: visible answer。ユーザーに返す答え。
  • summary: 内部作業量と検証結果の要約。
  • reasoning_tokens_estimate: hidden scratchpad の概算 token 数。
  • verification: verifier の結果。

この段階では、答えを出すことよりも「最終回答と内部作業を分けて扱う」ことが目的です。

2. effort を上げる

同じ問題を medium と high で実行します。

uv run mini-transformer-reason --prompt "12 + 7" --effort medium
uv run mini-transformer-reason --prompt "12 + 7" --effort high

--effort high では candidate path を複数作り、self-consistency vote を行います。小さな数式なので答えは同じですが、内部作業量が増えます。

比較する点:

low    -> direct answer
medium -> direct answer + verify
high   -> candidate paths + self-consistency + verify

実際の reasoning model でも、reasoning effort は正答率だけでなく、latency、token budget、cost に影響します。

3. hidden scratchpad を表示する

学習用に内部 trace を表示します。

uv run mini-transformer-reason --prompt "8 * 6 - 5" --effort high --show-trace

この lab では --show-trace で hidden scratchpad を表示できます。ただし、これは教材用です。実際の推論APIでは、内部の reasoning tokens をそのまま公開せず、要約や最終回答だけを返す設計があります。

観察する点:

  • parse expression
  • candidate evaluation
  • self-consistency vote
  • verify result

4. candidate 数を変える

high effort で候補数を変えます。

uv run mini-transformer-reason --prompt "8 * 6 - 5" --effort high --samples 1
uv run mini-transformer-reason --prompt "8 * 6 - 5" --effort high --samples 5

この実装は deterministic なので候補は同じ答えになります。それでも、candidate path を増やすと hidden scratchpad と reasoning token estimate が増えることを確認できます。

実際のLLMでは、candidate を複数作ることで異なる経路や異なる間違いが出る場合があります。そこで vote や verifier が重要になります。

5. コードを読む

対象ファイル:

src/mini_transformer_lab/reasoning.py

読む順番:

  1. run_reasoning: prompt から final answer までの controller。
  2. extract_arithmetic_expression: prompt から数式だけを取り出す前処理。
  3. safe_evaluate: 外部 tool 相当の決定的 evaluator。
  4. _build_hidden_steps: hidden scratchpad を作る場所。
  5. main: CLI として表示する場所。

この分割は、agent 開発でも重要です。model、tool、verifier、formatter を分けると、どこで間違えたのかを追いやすくなります。

6. 付け加え実験

次の順番で拡張すると、推論モデルの設計差分を体感できます。

A. 対応演算子を増やす

safe_evaluate は最初 +, -, * だけを扱います。割り算を入れる場合は、整数除算なのか小数なのか、ゼロ除算をどう扱うのかを決める必要があります。

影響:

  • tool の能力が増える。
  • verifier の責務も増える。
  • エラー処理が必要になる。

B. verifier を厳しくする

今の verifier は再評価だけです。次のような検査を追加できます。

  • final answer が整数文字列か。
  • expression に許可していない文字が混ざっていないか。
  • samples の候補が一致しているか。

影響:

  • 誤答や壊れた出力を止めやすくなる。
  • 厳しすぎる verifier は正しい答えも落とす可能性がある。

C. visible summary を短くする

推論過程を長く見せるほど理解しやすいとは限りません。agent では、内部判断はログに残し、ユーザーには短い根拠だけ返す設計もあります。

影響:

  • user experience。
  • debug しやすさ。
  • 秘密情報や内部方針の露出リスク。

7. 基礎編との接続

この応用編は docs/LLM_FOUNDATIONS_STORY.md の続きです。

対応関係:

基礎概念応用編での役割
tokenhidden scratchpad と visible answer の単位
logits / decoding候補 token を選ぶ前段
context_lengthprompt、tool result、reasoning tokens が共有する予算
datasetmodel がどの reasoning trace を自然に出しやすいかに影響
prompt推論時の条件であり、重みを書き換えるものではない
validationverifier、schema validation、tool result check として外側に置く

次は src/mini_transformer_lab/reasoning.py を編集し、1つずつ実験してください。