2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

前回、9モデルを叩き比べて gpt-oss-120b を判断エンジンに採用しました。最速級・素のJSON・正式提供の3拍子。文句なしの本命のはずでした。ところが実運用に載せた途端、その本命が黙りました

TL;DR

  • 判断エンジン(依頼の振り分け役)に採用した gpt-oss-120b が、実運用で答えを返さなくなる現象に遭遇しました。
  • 原因は、gpt-oss-120bが内部で大量に「考えてから」答えるモデルだったこと。答える前にトークンの上限を使い切ると、何も返さず終わります
  • max_tokensを増やせば回避はできますが、それでもトークンを大量消費して短い答えしか返らないという不安定さが残りました。
  • 判断エンジンに一番大事なのは「賢さ」より**「必ず返ってくること」**。この一点で、採用モデルを llm-jp-3.1-8x13b に切り替えました。
  • 10モデル・5ジャンルの横断ベンチも実施——gpt-oss-120bの実力自体は本物でした(5問全問正解)。だから今回の話は「モデルが悪い」ではなく、**「賢さと確実性は別の軸」**という教訓です。

1. 事件:判断エンジンが、突然だんまりになった

前回採用した gpt-oss-120b を判断エンジンに据えて、しばらく実運用に載せていました。ある日、依頼を投げてもエージェントへの振り分けが一向に終わらない——ログを見ると、gpt-oss-120bからの応答が 空文字列 で返ってきていました。

エラーが出るわけではありません。HTTPリクエストは成功し、200 OKで返ってくるのに、中身が空。一番タチが悪いパターンです。障害なら気づけますが、これは"正常に失敗している"ので、ログを見に行かない限り気づけません。

2. 何が起きていたか:実測データ

原因を切り分けるため、max_tokens(AIが1回の応答で使える最大トークン数)を変えて同じ依頼文を投げ直しました。

max_tokens 結果 消費トークン 実際に返った内容
400 空応答 400(上限まで使い切り) (何も返らない)
1,200 △ 応答あり 969 {"agent": "grants"}(実質20文字程度の答え)
600(対処後) ○ 安定 300〜500程度 正常なJSON

1,200トークン与えても、実際に使った"中身のある答え"はたった20文字程度です。残りの900トークン近くは、画面には出てこない内部の"考える"過程に消えていました。

3. なぜ黙るのか:"考えすぎる"モデルの構造

gpt-oss-120bは、答えを出す前に内部で長い推論を行ってから、最後に結論を出すタイプのモデルです。この推論自体もトークンを消費します。

つまり構造はこうです:

[内部推論に数百トークン] → [結論を数十トークン出力]

max_tokensという上限は、この2つを合わせた合計にかかります。上限が低いと、内部推論の途中で強制的に打ち切られ、結論を出す前に力尽きる——だから空応答になります。

gpt-oss-120bの内部処理とmax_tokens打ち切りの関係(400=推論の途中でカットされ結論に届かない/1,200・600=結論まで到達)
gpt-oss-token-cutoff.png

※ この図は @enomoso_pm さんの drawio-diagram-skills(MIT License) を利用して作成しました。

「賢く考える」ことと「トークン予算内に収まる」ことは、別のトレードオフです。大きく賢いモデルほど、この罠を踏みやすいというのが実感でした。

4. 対処と判断:直せても、選ばなかった

max_tokensを600〜1,200程度まで上げれば、空応答自体はほぼ回避できます。実際、その修正だけで「直った」ことにもできました。

でも、判断エンジンという役割を考え直しました。この振り分けは会社全体の"入口"です。ここが1件でも詰まると、後続の処理が止まります。前回の記事で「速い・賢い」を取りつつ「止まらない」設計にしたはずが、"止まらない"の内側に、もう一段別の不安定さが残っていたことになります。

判断基準を、「賢さ・速さ」から**「確実に返ってくるか」**に置き直しました。その結果——

  • llm-jp-3.1-8x13b:前置きは付くが、空応答を一度も起こしていない
  • gpt-oss-120b:賢く速いが、トークン予算の見積もりを誤ると黙る

判断エンジンの既定モデルを llm-jp-3.1-8x13b に切り替えました。 前回「最速級・素のJSON」で選んだ結論を、実運用のデータで裏返した形です。

しかも後述のベンチで、速度の前提まで覆りました。前回の振り分け1タスクでは gpt-oss-120b の方が速かった(1.0秒 vs 4.0秒)のですが、5ジャンルの平均では llm-jp の方が速い(0.6秒 vs 1.5秒)。「速いから gpt-oss」という前回の根拠は、測るお題を変えただけで逆転しました。1つのお題での速度比較を一般化してはいけない、という反省です。

補足:llm-jpにも制約はあります。コンテキスト上限が4,096トークンで、長文の全文を渡すような用途には向きません(gpt-ossは広く受け付けます)。用途によって使い分ける、が正確な結論です。

5. それでも、gpt-oss-120bの実力は本物だった

ここで誤解してほしくないのは、「gpt-oss-120bが弱いモデルだった」わけではないという点です。念のため、推論・翻訳・要約・コード・日本語の制約順守という5ジャンルで、さくら9種+ローカル1種=計10モデル・50リクエストの横断ベンチを取りました(各ジャンル1お題・temperature=0・max_tokens=800)。

補足:採用値の600ではなく800にしたのは、判断エンジンの「短いJSONを返すだけ」の1タスクと違い、要約やコードなど出力の長さがジャンルごとにバラつくためです。実際、gpt-oss-120bは要約課題で620トークンを消費しており、600だとこの検証自体が空応答で壊れていた可能性があります。用途に応じて予算を変えている点は、前章の教訓と矛盾しません。

モデル 推論 翻訳 要約 コード 日本語制約 正解 平均速度
gpt-oss-120b 5/5 1.5s
llm-jp-3.1-8x13b ⚠️字数超過 ✅前置き有 4/5 0.6s
gemma-4-31B(preview) 5/5 0.4s
Qwen3-VL-30B(preview・画像) 5/5 0.5s
Qwen3.6-35B(preview) ✕空 ✕空 ✕空 2/5 3.4s
Kimi-K2.6(preview) ✕空 4/5 4.9s
Kimi-K2.7-Code(preview) ✅型注釈 5/5 14.0s(最大61.9s)
Phi-4-mini(preview・CPU) ✕誤答 4/5 1.9s
Qwen3-0.6B(preview・CPU) △冗長 ✕オウム返し ✕意味誤り 3/5 1.2s
gemma2:2b(ローカル) ✅冗長 5/5 6.0s

速さ×正解数の散布図。10モデルを平均応答時間と5ジャンル中の正解数でプロット
bench-speed-vs-accuracy.png

gpt-oss-120bは5ジャンルすべて正解でした。「振り分け1タスクだけ強い」のではなく、総合力も本物です。

ただし——正解数だけを見ると、満点は4モデルもいます(gpt-oss-120b・gemma-4-31B・Qwen3-VL-30B・そしてローカルの gemma2:2b)。ここが今回いちばん自戒したところで、「正解数」という1つの軸だけで並べると、選ぶべきモデルを完全に読み違えます

  • gemma2:2b(ローカル):5問とも正解。でも平均6.0秒で、そもそも前回「うるう年で脱落した」モデルです。易しいお題なら解けるが、難しいお題で崩れる——1問ずつのベンチでは、その差が出ません。
  • Kimi-K2.7-Code:5/5だが平均14.0秒・最大61.9秒。正確でも、待てなければ使えません。
  • gemma-4-31B・Qwen3-VL-30B:速くて満点。でも preview 枠で、予告なく終了・値上げがあり得ます。

散布図で「速い(左)× 正確(上)」に絞り、さらに正式提供空応答なしの条件を重ねると、残るのは結局 gpt-oss-120b と llm-jp の2つだけでした。軸を1つ足すたびに候補が減っていく——この絞り込みの過程こそが、モデル選定の実体だと思います。

実際にどう減っていったかを、実測値から並べるとこうなります。

モデル選定の絞り込み。10モデルに条件を1つずつ重ねると2モデルまで減る
model-selection-funnel.png

※ この図も @enomoso_pm さんの drawio-diagram-skills(MIT License) を利用して作成しました。

満点だった4モデルのうち3つは、②〜④のどこかで脱落します。「正解数だけ見て選ぶ」のがなぜ危ないか、この落ち方が答えだと思います。なお、条件の順番を変えれば残るモデルも変わります——たとえば「速度」を最優先にするなら gemma-4-31B が残る。用途が軸の順番を決め、軸の順番が結論を決めるわけです。

preview枠の不安定さ(Qwen3.6の空応答3/5、Kimi-Codeの61.9秒、Phi-4-miniの推論誤答)も、この横断ベンチで改めて裏付けられました。preview モデルを本番に据えない、という前回の判断も引き続き正しかったことになります。

正直な限界:各ジャンル1お題しか投げていません(N=1)。順位や正解数は誤差を含みますし、上に書いたとおり「1問正解できること」と「難問で崩れないこと」は別物です。傾向を掴むための粗いスクリーニングとして読んでください。

6. 状況別の使い分け

今回の一件から、判断エンジン以外にも応用できる基準を持ち帰りました。

用途 優先すべき軸 向くモデルの型
会社の"入口"となる振り分け・止まると困る処理 確実性(空応答しない) 内部推論が薄いモデル、または実績のある正式モデル
1回きりの調査・重い分析・じっくり考えさせたい処理 賢さ・精度 "考えすぎる"タイプのモデルでも可(トークン予算は多めに)
コスト・速度が最優先の軽い処理 速度 小型モデル(ただし字数制約や意味理解の精度は要確認)

同じモデルでも、当てる用途によって"良いモデル"は変わります。今回は「判断エンジン=止まってはいけない場所」という前提があったから、賢さより確実性を選びました。もし用途が「多少待ってでも精度が欲しい分析タスク」だったら、答えは逆になっていたはずです。

まとめ

  • 採用したgpt-oss-120bが、実運用で空応答を起こした。原因は「内部で考えすぎてトークン予算を使い切る」構造。
  • max_tokensを上げれば回避できるが、判断エンジンには**"賢さ"より"確実に返ること"**を優先し、llm-jp-3.1-8x13bに切り替えた
  • 10モデル・5ジャンルの横断ベンチで、gpt-oss-120b自体の実力は改めて実証済み(5問全問正解)。**「弱かった」のではなく「役割に対して軸が違った」**というのが正確な結論。
  • ただし満点は4モデルもいた。「正解数」1軸で並べると選定を誤る。速さ・正式提供・空応答なしを重ねて初めて候補が2つに絞れた。
  • 同一環境での比較はできない点(ローカルCPU vs クラウド)と、各ジャンル1お題(N=1)であることは、今回も変えられない限界としてそのまま開示します。
  • 用途ごとに「賢さ」と「確実性」のどちらを優先するか、意識して選ぶのが実務での教訓でした。

前回「速く・賢く・止まらない」と結論づけた判断エンジンは、今回の検証で見つかった落とし穴を踏まえてモデルを切り替えたことで、もう一段確実になりました。無料枠を使い倒すことで、初めて見えた落とし穴でした。

質問・ツッコミ歓迎です。「うちはこう対処した」などあれば、ぜひ教えてください。

余興:褒めた本人に、やらかしを読ませてみた

1次記事の余興で、gpt-oss-120b自身にあの記事を読ませたところ「実装の工夫や失敗談が参考になる」と、前置きゼロで褒めてもらいました。そして最後にこう書きました——「褒めた本人が実運用でやらかす、その一部始終を次の記事で。」

有言実行で、今回はそのやらかしの顛末を書いた本記事を、当のgpt-oss-120b自身に読ませました。以下は実際に返ってきた出力そのままです(temperature=0・max_tokens=1500・無加工)。

この記事は実運用での失敗と選定プロセスを丁寧に示していて、トークン上限が内部推論に消費される点やベンチマークの可視化は非常に参考になる。一方、gpt-oss-120bは"考えすぎ"ゆえに空応答を起こし、安定性が欠如していた。私自身、返答が途切れるリスクを想定せず設計した点は甘く、実装時に安全マージンを組むべきだった。

——自分の欠陥を、自分の言葉で認めてきました。しかも今回は空応答を起こさず、無事に返ってきています(本記事の教訓どおりmax_tokensに余裕を持たせたのが効いたのか、それともたまたまか——それはまた別の話です)。

関連記事

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?