レッスン02で見たとおり、会話を続けるには履歴全体を毎回送り直す必要があります。長い会話ほど、同じ内容を何度も送ることになり、費用と待ち時間がかさんでいきます。このレッスンでは、その負担を減らす3つの仕組みを扱います。
プロンプトキャッシング: 同じ前置きを送り直さない
会話の先頭部分、たとえば長いsystemプロンプトや、毎回同じ形式で渡す参考資料は、リクエストのたびに内容が変わりません。この変わらない部分を、Anthropicのサーバー側に一時的に保存しておき、次のリクエストではそこから読み込むだけで済ませる仕組みが、プロンプトキャッシングです。
使い方は、cache_control を対象のブロックに付けるだけです。
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
system=[
{
"type": "text",
"text": "(長い社内マニュアルの全文がここに入る想定)",
"cache_control": {"type": "ephemeral"},
}
],
messages=messages,
)
キャッシュには、いくつか押さえておくべき条件があります。
モデルによって異なる。claude-sonnet-5は1,024トークン以上、これに満たない場合はエラーなく非キャッシュ扱いになる
1リクエストにつき最大4箇所まで cache_control を置ける
cache_controlより前の内容が完全一致しないと無効になる。1文字違うだけでもキャッシュは効かない
既定は5分(無料で更新)。1時間保持も選べるが、その分書き込みの費用が上がる
効いているかどうかは、レスポンスの usage を見て確認します。
print(response.usage.cache_read_input_tokens) # キャッシュから読んだ分
print(response.usage.cache_creation_input_tokens) # 新しくキャッシュに書き込んだ分
両方が0なら、キャッシュは使われていません。よくある原因は、キャッシュしたい部分より前に、リクエストごとに変わる値(タイムスタンプなど)が紛れ込んでいることです。キャッシュしたい安定した内容を先に、変わる内容をあとに置く順番を守ると、この事故を避けやすくなります。
補足
読み取りは書き込みよりずっと安い
キャッシュへの書き込みは通常の入力より高く(5分保持で1.25倍)、読み取りは逆に大幅に安くなります(モデルにより通常の1割前後)。長いsystemプロンプトを何十回も使い回す道具ほど、キャッシュの効果が大きくなります。正確な倍率は改定されることがあるので、金額を厳密に見積もるときは公式ページで確認してください。
拡張思考: 難しい問いに時間を割かせる
込み入った判断や、複数の条件を突き合わせる質問には、Claudeが答えを出す前に考える時間を長めに取ったほうが精度が上がることがあります。この「考える時間」を制御するのが thinking と effort です。
thinking は {"type": "adaptive"} を指定すると、どれだけ考えるかをClaude自身が状況に応じて判断します。考える深さそのものを人間側から大まかに指示したいときは、output_config の effort を使います。
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=2048,
thinking={"type": "adaptive"},
output_config={"effort": "high"},
messages=[{"role": "user", "content": "この3つの発注案のうち、納期・費用・在庫リスクを比べて、どれを選ぶべきか根拠つきで答えて"}],
)
effort は low から max まで数段階あります。単純な分類や短い抽出作業にまで高い段階を使う必要はありません。日常的な単純作業は低めの段階で十分なことが多く、複数の資料を突き合わせて判断させるような場面でこそ、高い段階の価値が出ます。モデルによって既定の段階が違うため、狙った深さで考えさせたいときは明示的に指定しておくと安心です。
Files API: 同じファイルを何度もアップロードしない
レッスン06で使った document ブロックは、Files APIで事前にアップロードしたファイルを指しています。毎回のリクエストでファイルの中身を送り直す代わりに、一度アップロードして file_id を受け取り、以後はそのIDだけを参照します。
uploaded = client.files.upload(
file=("manual.pdf", open("manual.pdf", "rb"), "application/pdf"),
)
file_id = uploaded.id
注意
アップロードしたファイルは、ワークスペース全体から見える
Files APIでアップロードしたファイルは、特定の利用者やセッションに紐づいているわけではありません。同じワークスペースの、どのAPIキーからでも参照できます。複数の顧客や部署のデータを扱う道具を作るときは、利用者から送られてきたfile_idをそのまま信用せず、どのファイルが誰のものかを、自分のアプリ側の記録で管理してください。
ファイルは最大500MBまで、組織全体で1TBまでという上限があります。アップロード自体は無料で、リクエストで実際に使った分だけが入力トークンとして課金されます。
やってみよう
演習1: キャッシュすべき部分を探す
自分が作ろうとしている道具で、リクエストのたびに内容が変わらない部分(システムプロンプト、参考資料、決まった指示など)を1つ挙げてください。そこにcache_controlを置くとどれくらい費用が減りそうか考えてみてください。
演習2: effortをどう選ぶか
その道具が答える質問は、単純な分類や抽出に近いですか、それとも複数の条件を突き合わせる判断に近いですか。理由とあわせて、low寄りかhigh寄りか考えてください。
今日のまとめ
3行で振り返ります。
- 変わらない前置きに
cache_controlを付けると、2回目以降はキャッシュから読むだけで済み、費用が大きく下がる thinkingは考えるかどうか、effortは考える深さの目安。単純作業にまで高い段階を使う必要はない- Files APIで一度アップロードした
file_idは使い回せるが、ワークスペース全体から見える点に注意する
次のレッスンでは、決められた手順で進めるワークフローと、Claude自身に手順を考えさせるエージェントの違いを扱います。
セルフチェック
1. プロンプトキャッシングが効かなくなる典型的な原因はどれですか。
2. thinkingとeffortの役割について正しい説明はどれですか。
3. Files APIでアップロードしたファイルの扱いとして正しいものはどれですか。