# per-message effortでキャッシュを保つ切替設計

> Claude APIのper-message effortは、会話途中でeffortを切り替えてもプロンプトキャッシュを維持します。ベータヘッダー、配置ルール、対応モデル差、ターン単位の切替方針を整理します。

- Canonical: https://kuucorp.com/blog/claude-per-message-effort-cache-preserving-routing-design/
- Date: 2026-10-15
- Last modified: 2026-10-15
- Publisher: Kuu株式会社 (https://kuucorp.com)

---
長時間のエージェントセッションでは、最初の計画立案は深く考えさせたいが、その後の定型的な確認や要約は軽くこなさせたい、という場面が必ず出てきます。ところがトップレベルの `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](/blog/claude-mid-conversation-tool-changes-cache-design/) の延長です。ベータヘッダー `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通りで設計します。

1. **ターン単位**: ユーザー入力の種類（新規の調査依頼か、定型の追質問か）で effort を決め、user ターンの直前に effort メッセージを入れる
2. **サブエージェント単位**: 軽い探索や整形を別リクエストのサブエージェントに切り出し、そちらを `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ゲートウェイ](/blog/llm-gateway-routing-rate-limiting/) には、モデル別の能力テーブルを持たせ、非対応なら effort をリクエスト全体で固定する分岐を入れます。

### 規模別の運用留意点

数百のセッションが同じ基盤を共有する環境では、effort ポリシーをアプリ側ではなくゲートウェイで一元管理すると、チーム別の配賦と監査が容易になります。デフォルト値もモデルで異なる点（Opus 5.5 と Haiku 5.5 は `medium`、他は `high`）に注意が必要で、モデル更新時は effort を省略した呼び出しの挙動が1段階変わり得ます。モデル更新のたびに effort スイープを回すことが公式にも推奨されています。

## 参考

- [Effort — Claude Platform Docs](https://platform.claude.com/docs/en/build-with-claude/effort)
- [Mid-conversation system messages — Claude Platform Docs](https://platform.claude.com/docs/en/build-with-claude/mid-conversation-system-messages)
- [Prompt caching — Claude Platform Docs](https://platform.claude.com/docs/en/build-with-claude/prompt-caching)

## まとめ

per-message effort は、キャッシュを保ったまま推論深度をターン単位で切り替える仕組みです。ツールループ内部では切替できないこと、モデルとプラットフォームで対応が異なることを前提に、ゲートウェイでの能力判定と評価データに基づくルーティング規則を組み合わせます。大規模基盤での effort ポリシー設計や統制の相談は、[Kuuの大規模AI変革プログラム（RDE）](https://kuucorp.com/services/rde/)までお問い合わせください。
