長時間のエージェントセッションでは、最初の計画立案は深く考えさせたいが、その後の定型的な確認や要約は軽くこなさせたい、という場面が必ず出てきます。ところがトップレベルの output_config.effort を次のリクエストで書き換えると、プロンプトキャッシュは先頭から作り直しになります。複数チームが共有する基盤では、この再構築コストがそのまま入力トークンの増加として現れます。per-message effort はこの問題を、会話履歴の末尾に差し込むメッセージ1つで解決するベータ機能です。
なぜトップレベルのeffort変更はキャッシュを壊すのか
トップレベルのeffortはレンダリング後のプロンプトを形作るため、リクエスト間で値を変えると過去ターンのキャッシュ済みプレフィックスは再利用できなくなります。
公式ドキュメントは「トップレベルの effort はレンダリングされたプロンプトに影響するため、リクエスト間で変えると以前のターンのキャッシュ済みプレフィックスは保持されない」と明記しています。対応モデルでなければ、キャッシュに依存する長いセッションでは最初に effort を決めて固定することが推奨されています。
Claude Fable 5.1 ではさらに別の問題があります。過去の返信は以前の effort で書かれているため、モデルがその一貫性に引きずられやすく、トップレベル変更では切替が効きにくいとされています。キャッシュコストと挙動の両面で、会話内でトップレベル値を動かす設計は避けるべきです。
per-message effortはどう書くのか
role: "system"でcontentを空にしoutput_config.effortだけを載せたメッセージを追記すると、既存プレフィックスを変えずに次のuserターンから効きます。
仕組みは mid-conversation system messages の延長です。ベータヘッダー mid-conversation-output-config-2026-07-01 を付け、messages に effort だけを持つ system メッセージを入れます。
``python``
response = client.beta.messages.create(
model="claude-fable-5-1",
max_tokens=4096,
output_config={"effort": "high"},
messages=[
{"role": "user", "content": "移行計画を3ステップで立ててください。"},
{"role": "assistant", "content": "1. ... 2. ... 3. ..."},
{"role": "system", "content": [], "output_config": {"effort": "low"}},
{"role": "user", "content": "計画を1文で要約してください。"},
],
betas=["mid-conversation-output-config-2026-07-01"],
)
effort だけを持つメッセージはテキストを含まないため、コンテンツ付き system メッセージの配置ルールは適用されず、messages の任意の位置に置けます。新しい値は、新しい入力を持つ次の user ターンから有効になり、後続のメッセージが変えるまで保たれます。変更点より前は一切書き換わらないので、キャッシュ済みのプレフィックスはそのまま一致します。なお、隣り合う system メッセージはまとめて判定されるため、コンテンツ付きメッセージの隣に置く場合はそちらの配置ルールに従います。
切替の粒度はどこまで細かくできるのか
ツール結果だけを返すuserターンは「新しい入力」に数えられないため、effortの切替粒度はツールループの1ステップ単位ではなくuserターン単位です。
ここが設計上の最大の制約です。tool_result ブロックだけを持つ user ターンは新しい入力として扱われず、その後ろに置いた effort 変更は次の本物の user ターンまで待たされます。したがって、1つのツールループの途中で「検索は軽く、統合判断は重く」と切り替えることはできません。
粒度を細かくしたい場合は、次の2通りで設計します。
- ターン単位: ユーザー入力の種類(新規の調査依頼か、定型の追質問か)で effort を決め、user ターンの直前に effort メッセージを入れる
- サブエージェント単位: 軽い探索や整形を別リクエストのサブエージェントに切り出し、そちらを
lowで走らせる。公式の effort 表でも、lowの典型用途にサブエージェントが挙がっている
ルーティング規則は評価データで決めます。effort は厳密なトークン上限ではなく挙動への信号で、低い設定では検索や確認を省く傾向が出ます。Claude Haiku 5.5 は長いエージェントプロンプトで low にすると、検索を飛ばす、早く止まる、確認を省くといった挙動が出やすいと明記されています。規則を本番に載せる前に、自社の評価セットで effort ごとの完了率を測ってください。
モデルとプラットフォームの差をどう吸収するか
対応モデルはプラットフォームで異なり、Bedrockでは範囲が狭いため、ゲートウェイ側で能力判定して未対応時はトップレベル固定にフォールバックさせます。
公式ドキュメント上の対応状況は次のとおりです。
| 環境 | per-message effort 対応モデル |
|---|---|
| Claude API / Google Cloud | Claude Fable 5.1、Mythos 5.1、Opus 5.5、Opus 5、Sonnet 5.5、Haiku 5.5 |
| Amazon Bedrock | Claude Fable 5.1、Mythos 5.1、Opus 5.5(Opus 5 は対象外) |
さらに、Claude Sonnet 5.5 の thinking: {"type": "between_tools"} と、Claude Haiku 5.5 の thinking: {"type": "disabled"} では、現在値と異なる per-message effort が400エラーになります。ターンごとに effort を変えたい経路では adaptive thinking を使ってください。
未対応モデルにベータ値付きで送ると400になります(output_config.effort requires a model that supports per-turn effort)。Bedrock では Extra inputs are not permitted が返ります。エンタープライズの LLMゲートウェイ には、モデル別の能力テーブルを持たせ、非対応なら effort をリクエスト全体で固定する分岐を入れます。
規模別の運用留意点
数百のセッションが同じ基盤を共有する環境では、effort ポリシーをアプリ側ではなくゲートウェイで一元管理すると、チーム別の配賦と監査が容易になります。デフォルト値もモデルで異なる点(Opus 5.5 と Haiku 5.5 は medium、他は high)に注意が必要で、モデル更新時は effort を省略した呼び出しの挙動が1段階変わり得ます。モデル更新のたびに effort スイープを回すことが公式にも推奨されています。
参考
- Effort — Claude Platform Docs
- Mid-conversation system messages — Claude Platform Docs
- Prompt caching — Claude Platform Docs
まとめ
per-message effort は、キャッシュを保ったまま推論深度をターン単位で切り替える仕組みです。ツールループ内部では切替できないこと、モデルとプラットフォームで対応が異なることを前提に、ゲートウェイでの能力判定と評価データに基づくルーティング規則を組み合わせます。大規模基盤での effort ポリシー設計や統制の相談は、Kuuの大規模AI変革プログラム(RDE)までお問い合わせください。
