Claude Media
Fable 5.1のxhigh/maxでmax_tokensに達し出力が切れる問題と対処

Fable 5.1のxhigh/maxでmax_tokensに達し出力が切れる問題と対処

Claude Fable 5.1をxhigh・maxのeffortで使うと、モデルが思考内で下書きしてから本文を書き直すためmax_tokensに達し出力が切れることがあります。原因と対処法をまとめます。

Fable 5.1のxhigh/maxでmax_tokensに達する問題とは

Claude Fable 5.1をxhighまたはmaxのeffortで動かすと、レスポンスが完成する前に打ち切られることがあります。stop_reason"max_tokens"になり、本文が途中で切れているのが典型的な症状です。原因はコードの不具合ではなく、モデルが思考の中で成果物の大半を下書きしてから、改めて本文として書き出す挙動にあります。この挙動はFable 5.1のプロンプトガイドが名指しする既知の失敗モードで、原因が分かっていれば事前に対処を仕込んでおける性質の問題です。

公式のプロンプトガイドは、xhighと特にmaxのeffortでモデルが返信を書き始める前により長く思考すると明記しています。文書全体の書き直しや大きな表、完全なコードファイルのような長い成果物を1リクエストで求めると、思考の中でその大半を下書きし、返信として改めて書き出すため、待ち時間と出力トークンが余分にかかります。max_tokensは思考と本文の合計にかかる厳格な上限なので、この二重下書きが起きると本文を書き切る前に上限へ達し、応答が尻切れで終わります。

ガイドの表現は「下書きすることがある」であって、毎回必ず起きるとは書かれていません。短い成果物や、思考の中で構成をまとめるだけで済む依頼では二重下書きは起きにくく、長文の丸ごと書き直しのような要求ほど再現しやすい失敗モードです。

なぜ二重下書きが起きるか — 思考と本文が同じ予算を共有する

Fable 5.1はアダプティブシンキングで思考の深さを自分で決めます。アダプティブシンキングとは、thinking.type: "adaptive"を使い、budget_tokensを手動指定せずeffortの値だけで思考量をモデル自身が調整する仕組みです。budget_tokensで予算を手動指定する旧来の拡張思考とは別方式です。手動の拡張思考ではbudget_tokensmax_tokens未満という制約がありますが、アダプティブシンキングに予算の上限指定はありません。その代わり、思考トークンと返信トークンはどちらも同じmax_tokensの中に収まる必要があります。

effortの公式ドキュメントもこの上限の性質を明確にしています。high以上のeffortでは「大きなmax_tokensを設定すること。これは総出力(思考+返信)にかかるハード上限」だと述べ、Opus 5・Opus 4.8・Opus 4.7では「64,000トークンから調整を始めるのが妥当な既定値」という具体的な目安まで示します。Fable 5.1向けの案内にはこの数値の既定値がなく、「high以上では大きなmax_tokensを設定すること」とだけ書かれています。他モデル向けの目安を流用せず、実際のリクエストで必要な思考量を測ってmax_tokensを決める必要があります。

古い拡張思考(thinking.type: "enabled"budget_tokensを手動指定する方式)には、思考ブロックが1回の応答内で複数に分かれる「インターリーブ思考」を使うとbudget_tokensmax_tokensを超えてよいという例外があります。Fable 5.1のアダプティブシンキングにこの逃げ道はありません。予算を自分で決める分、思考トークンと返信トークンを合わせた合計が常にmax_tokens以下に収まる必要があり、それを超えた時点で問答無用で打ち切られます。

APIレスポンスでの見分け方

stop_reasonは応答が終わった理由を示すフィールドです。APIリファレンスは"max_tokens"を「リクエストしたmax_tokens、またはモデルの上限を超えた」場合の値と定義しています。この値が返ってきたら、モデルは書きたい内容を書き切る前に止められたことを意味し、途中で終わった本文をそのまま使うことはできません。

const response = await client.messages.create({
  model: "claude-fable-5-1",
  max_tokens: 64000,
  output_config: { effort: "xhigh" },
  messages: [{ role: "user", content: "長い設計ドキュメントを全面的に書き直してください。" }],
});
 
if (response.stop_reason === "max_tokens") {
  // 思考の中で下書きし、本文でも書き直した可能性が高い
  // max_tokens を引き上げるか、下の対処2を試す
}

max_tokensと紛らわしい他のstop_reasonとの違い

stop_reasonにはmax_tokens以外にも複数の値があり、混同すると的外れな対処をしてしまいます。pause_turnは長時間実行のターンを一時停止した合図で、レスポンスをそのまま次のリクエストに含めて送り返せば続きを生成できます。打ち切りではなく再開できる一時停止なので、本記事の対処は不要です。model_context_window_exceededは出力ではなく入力側がモデルのコンテキストウィンドウを超えた場合の値で、入力サイズ不明でも最大出力を引き出す実装パターンが扱う別の問題です。refusalはストリーミング中の安全分類器が介入した結果を示す値で、出力トークンの上限とはまったく無関係です。今回対象にしているのは、これらと違って"max_tokens"が返ってきたケースに限られます。

対処1: max_tokensに思考分の余白を足す

最初の対処はmax_tokensの値そのものです。想定する返信の長さだけでなく、思考に使われる分の余白を見込んで設定します。既存のリクエストでstop_reason: "max_tokens"が返っているなら、まずmax_tokensを引き上げて症状が消えるか確認するのが手早い切り分けになります。

引き上げ幅に迷うときは、Opus系モデル向けにドキュメントが示す「64,000トークンから調整を始める」という目安を出発点にして、stop_reasonを見ながら倍々で調整する方法が現実的です。Fable 5.1固有の推奨値は公開されていないため、この数値はあくまで他モデルの例であり、実際に必要な余白はタスクの長さとeffortの組み合わせで変わります。

思考トークンは出力トークンとして課金されます。stop_reason: "max_tokens"で打ち切られたリクエストでも、下書きに使った思考分と書きかけの本文分の両方に料金がかかり、使える成果物は手に入りません。この問題を放置するほど、欲しい結果を得られないままコストだけがかさみます。

対処2: 二重下書きを防ぐ一文をユーザーメッセージに足す

max_tokensの引き上げだけでは、思考に使われるトークンとコストが増えたままです。プロンプトガイドは、ユーザーメッセージの末尾に次の一文を追加する対処も示しています。モデルへの指示として機能させる英文なので、翻訳せず原文のまま使います。[max_tokens]の部分はリクエストの実際のmax_tokens値に置き換えます(ガイドの例は64,000)。

Everything produced in one reply, including any reasoning or drafting done before the reply, counts toward a single limit of about [max_tokens] tokens. If that limit is reached before the reply is finished, the person receives a cut-off response and has to start over. Composing an entire output or deliverable in full as reasoning and then again as a reply would double the length of the turn without improving the result, so don't do that.
 
Instead, when the person has asked for a long or effort-intensive deliverable such as a multi-section document, a large table or dataset, or a complete code file, spend extra effort on understanding the request, checking the inputs the answer depends on, settling the structure and other difficult decisions, and otherwise using the reasoning space to reason and the output space to write an output. Usually it is not needed to draft an output multiple times.

公式の説明によれば、この一文は「プロンプトと文章生成のリクエストで思考をかなり短くする」効果があるとされています。実装例は次のとおりです。

import Anthropic from "@anthropic-ai/sdk";
 
const client = new Anthropic();
const maxTokens = 64000;
 
const guardNote = `Everything produced in one reply, including any reasoning or drafting done before the reply, counts toward a single limit of about ${maxTokens} tokens. If that limit is reached before the reply is finished, the person receives a cut-off response and has to start over. Composing an entire output or deliverable in full as reasoning and then again as a reply would double the length of the turn without improving the result, so don't do that.
 
Instead, when the person has asked for a long or effort-intensive deliverable such as a multi-section document, a large table or dataset, or a complete code file, spend extra effort on understanding the request, checking the inputs the answer depends on, settling the structure and other difficult decisions, and otherwise using the reasoning space to reason and the output space to write an output. Usually it is not needed to draft an output multiple times.`;
 
const response = await client.messages.create({
  model: "claude-fable-5-1",
  max_tokens: maxTokens,
  output_config: { effort: "xhigh" },
  messages: [
    { role: "user", content: `長い設計ドキュメントを全面的に書き直してください。\n\n${guardNote}` },
  ],
});

Claude Codeで使う場合 — max_tokensに対応するのはCLAUDE_CODE_MAX_OUTPUT_TOKENS

Claude CodeでFable 5.1を動かすときは、APIのmax_tokensパラメーターを直接編集できません。代わりに環境変数CLAUDE_CODE_MAX_OUTPUT_TOKENSが同じ役割を担います。公式ドキュメントは、この変数がほとんどのリクエストの出力トークン上限を決め、既定値と上限はモデルごとに異なると説明しています。値を引き上げると、オートコンパクションが発動するまでに使えるコンテキストウィンドウが狭くなる代償も明記されています。

effortの変更は/effortコマンドか/modelから行います。公式ドキュメントは「Fableモデルでは思考をオフにできず、常に拡張思考を使う」と明記しており、Claude CodeでFable 5.1をxhighmaxにする限り思考は必ず有効です。したがって対処1にあたる余白の確保は、CLAUDE_CODE_MAX_OUTPUT_TOKENSを引き上げる形になります。対処2のプロンプト一文はユーザーメッセージやシステムプロンプトを直接組み立てるAPI利用者向けの対処で、Claude Codeの対話セッションでは適用しにくいため、まずはCLAUDE_CODE_MAX_OUTPUT_TOKENSの引き上げと/effort highへの切り戻しを試すのが現実的です。既定値と上限の詳細はCLAUDE_CODE_MAX_OUTPUT_TOKENSの環境変数ガイドにまとめています。

使い分け早見表 — effortごとの二重下書きリスク

effort二重下書きのリスク対応の目安
high(既定・推奨の出発点)二重下書きのリスク低い。プロンプトガイドが最初に試すよう案内する水準対応の目安通常運用はここに留める
xhigh二重下書きのリスク中〜高。長い成果物で下書きが発生しうる対応の目安max_tokensに余白を足し、対処2の一文も追加する
max二重下書きのリスク最も高い。公式ガイドが「特にmaxで」と名指しする水準対応の目安同上に加え、品質差を測ってから常用するか判断する

highからxhighmaxへ上げる判断そのものは、Fable 5.1の仕様記事の「Fable 5と同じプロンプトで何が変わるか」節が扱っています。本記事はその先、実際にmax_tokensへ到達して出力が切れた後の切り分けと対処に絞ります。

よくあるつまずき

  • [max_tokens]を置き換え忘れる: プレースホルダーの文字列のまま送ると、モデルは実際の上限を把握できず効果が薄れます。
  • 短い応答にも一文を足してしまう: ガイドが対象にしているのは長い成果物を求めるプロンプトです。分類や短い回答が中心のリクエストでは二重下書き自体が起きにくく、余分な指示文がコンテキストを圧迫するだけになります。
  • max_tokensだけ上げてeffortを見直さない: 上限を上げれば打ち切りは防げますが、xhighmaxの思考コストと待ち時間はそのままです。品質差が実測できていないならhighへ戻す選択肢も検討します。
  • Claude CodeでMAX_THINKING_TOKENSを設定して解決しようとする: この環境変数は思考予算を手動で固定するものですが、Fable 5.1のようなアダプティブ推論モデルでは、Claude Codeが0以外の値を無視します。効くのは/effortによるeffortの調整とCLAUDE_CODE_MAX_OUTPUT_TOKENSの引き上げだけです。
  • Sonnet 5の同種の症状と混同する: Claude Sonnet 5でも同じstop_reason: "max_tokens"が起きますが、原因はアダプティブシンキングが既定でオンになったことです。思考の中で下書きしてから本文を書き直すという固有の挙動が説明されているのはFable 5.1のプロンプトガイドだけです。

まとめ

Fable 5.1をxhighmaxのeffortで動かし、長い成果物を1リクエストで求めると、モデルが思考の中で下書きしてから本文として書き直すため、max_tokensに到達して応答が途中で切れることがあります。切り分けの第一歩はstop_reason"max_tokens"になっているかの確認、対処はmax_tokensに思考分の余白を足すことと、ユーザーメッセージ末尾へ公式の一文を原文のまま追加することの2つです。それでもxhighmaxのコストが見合わないなら、effortの使い分けを確認し、highへ戻す判断も選択肢に入ります。思考と本文が同じmax_tokensを共有する設計は他モデルのxhighでも共通しています。Claude Codeで発生している場合は、操作対象がAPIのmax_tokensではなくCLAUDE_CODE_MAX_OUTPUT_TOKENSになる点も忘れないようにします。stop_reasonpause_turnmodel_context_window_exceededなど別の値なら、出力上限とは別の原因なので、本記事の対処ではなく該当する原因を疑います。

この記事を共有:XはてブLinkedIn