いずみこんな悩みを解決できる記事を書きました!
僕は現役フリーランスエンジニア(歴10年)で、資格は13個保有しています。
「Claude APIで、会話の途中で使えるツールを増やしたり減らしたりしたい」とお考えではありませんか?
長時間動くエージェントを作っていると、作業フェーズによって必要なツールが変わってきます。
ところがClaude APIでは、tools配列を書き換えるとプロンプトキャッシュが丸ごと無効になり、コストとレイテンシが跳ね上がります。



ベータ機能のMid-conversation tool changesを使うと、キャッシュを保ったままツール構成を切り替えられます。
ということで、本記事ではClaude APIで会話の途中でツールを変更する方法を解説します。



すぐ読み終わるので、ぜひ最後まで読んでくださいませ。
| 【当サイト】おすすめフリーランスエージェント3選 | |||
|---|---|---|---|
| エージェント | 評価 | ポイント | 公式サイト |
レバテックフリーランス | 5.0 | 業界最大級のエージェント。 高単価案件が豊富。 | 公式 |
Midworks | 4.8 | 満足度調査で 3年連続3冠を達成。 | 公式 |
ITプロパートナーズ | 4.6 | 週2〜3向けの案件が豊富。 | 公式 |
【AI】Claude APIで会話の途中でツールを変更する方法
早速ですが、Claude APIで会話の途中でツールを変更する方法を解説します。
会話の途中でツールを変えるとキャッシュが壊れる理由
プロンプトキャッシュは、tools → system → messagesの順でリクエストの先頭部分をハッシュ化します。
tools配列はハッシュ対象の一番先頭に位置します。
途中でツールを1つ足すだけでもハッシュが変わり、会話全体のキャッシュがヒットしなくなります。
数十ターン積み上げた会話だと、キャッシュ再作成のコストとレイテンシは無視できません。
仕組み:tools配列は固定して提供状態だけを切り替える
Mid-conversation tool changesでは、使う可能性のあるツールを最初にすべてtools配列へ宣言します。
tools配列は会話が終わるまで変更しません。
代わりにrole: “system”メッセージの中にtool_additionとtool_removalブロックを置き、ツールをモデルに見せるか隠すかをターンごとに切り替えます。
tools配列そのものが変わらないので、キャッシュ済みの先頭部分はそのまま残ります。



ツールの定義は動かさず、いまのターンで使えるかどうかだけを後付けで変える発想ですね。
前提として必要なもの
利用にはベータヘッダーmid-conversation-tool-changes-2026-07-01が必要です。
Python SDKではbetas引数にヘッダー名を渡し、client.beta.messages.createを呼びます。
対応モデルはClaude Opus 5・Opus 4.8・Fable 5・Mythos 5・Fable 5.1・Mythos 5.1です。
Claude Sonnet 5は非対応なので、Sonnet 5ではトップレベルのsystemと固定のtools配列を使います。
実装の手順
天気ツールを使った会話から、途中でコードレビューに切り替える流れで実装してみます。
会話の中で一度でも使う可能性があるツールは、最初のリクエストのtools配列にすべて並べます。
最初は隠しておきたいツールには、defer_loadingをtrueにして宣言します。



tools配列に無い名前を参照すると400エラーになるので、宣言済みの名前だけを指定します。
import anthropic
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-opus-5",
max_tokens=1024,
betas=["mid-conversation-tool-changes-2026-07-01"],
tools=[
{
"name": "get_weather",
"description": "指定した都市の現在の天気を返す",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "都市名"},
},
"required": ["location"],
},
},
],
messages=[
{"role": "user", "content": "東京の天気を教えて"},
{"role": "assistant", "content": "東京は晴れです。"},
{"role": "user", "content": "ありがとう。次はコードレビューを手伝って"},
{
"role": "system",
"content": [
{
"type": "tool_removal",
"tool": {"type": "tool_reference", "name": "get_weather"},
},
],
},
],
)
for block in response.content:
if block.type == "text":
print(block.text)天気の質問が終わってコードレビューに移るタイミングで、get_weatherをモデルから隠しています。
toolフィールドはtype: “tool_reference”とnameでツールを参照するだけで、スキーマや説明は書きません。
tools = [
{
"name": "run_sql",
"description": "分析用DBに対して読み取りクエリを実行する",
"input_schema": {
"type": "object",
"properties": {"query": {"type": "string"}},
"required": ["query"],
},
"defer_loading": True,
},
]
# 調査フェーズに入ったターンで run_sql を提供する
system_message = {
"role": "system",
"content": [
{"type": "text", "text": "ここから調査フェーズに入る。run_sqlは参照系クエリだけで使うこと。"},
{
"type": "tool_addition",
"tool": {"type": "tool_reference", "name": "run_sql"},
},
],
}defer_loadingで隠しておいたrun_sqlを、調査フェーズに入ったターンで初めて提供しています。
同じsystemメッセージにtextブロックを混ぜて、ツールの使い方の注意も一緒に渡せます。
一度tool_removalで外したツールを、後からtool_additionでもう一度提供することもできます。



フェーズごとに見せるツールを絞ると、モデルが余計なツールを呼ぶ事故も減らせます。
systemメッセージを置ける位置
tool_additionやtool_removalを含むrole: “system”メッセージは、userターンの直後に置きます。
tool_resultブロックを持つuserメッセージの直後も、userターンとして扱われます。
エージェントループでは、ツール結果を返すuserメッセージのすぐ後ろにsystemメッセージを置きます。
[
{"role": "user", "content": "テストを実行して失敗を直して"},
{"role": "assistant", "content": [
{"type": "tool_use", "id": "toolu_01", "name": "run_tests", "input": {}}
]},
{"role": "user", "content": [
{"type": "tool_result", "tool_use_id": "toolu_01", "content": "12 passed"}
]},
{"role": "system", "content": [
{"type": "tool_removal",
"tool": {"type": "tool_reference", "name": "run_tests"}}
]}
]assistantのtool_useブロックと、対応するtool_resultの間には置けません。
位置のルールを外れると400エラーが返ります。
MCPツールをまとめて切り替える
MCPコネクタ経由のツールは、mcp_tool_referenceで1つずつ、またはmcp_toolset_referenceでサーバー単位でまとめて参照できます。
{
"type": "tool_removal",
"tool": {"type": "mcp_toolset_reference", "server_name": "github"},
}server_nameを指定すると、名前を挙げたMCPサーバーのツール群を一括で外したり戻したりできます。
| 【当サイト】おすすめフリーランスエージェント3選 | |||
|---|---|---|---|
| エージェント | 評価 | ポイント | 公式サイト |
レバテックフリーランス | 5.0 | 業界最大級のエージェント。 高単価案件が豊富。 | 公式 |
Midworks | 4.8 | 満足度調査で 3年連続3冠を達成。 | 公式 |
ITプロパートナーズ | 4.6 | 週2〜3向けの案件が豊富。 | 公式 |
【厳選】フリーランスエンジニアにおすすめなエージェント3選


フリーランスエンジニアになるにはエージェントから案件をもらう必要があります。
僕が実際に利用しているおすすめエージェントを紹介しますね。



エージェントは必ず複数登録してください。
担当者によっては「全然案件紹介してくれない…」みたいなこともあるので…
僕は実際に5つのエージェントを使い回していますよ。
フリーランスを始めるなら「レバテックフリーランス


」
- 業界最大級の案件数。
- 業界トップクラスの高単価報酬、低マージン(平均年収862万円)。
- 案件参画中のフォローの充実。
※詳細は「【業界最大手】レバテックフリーランスとは?メリットや利用手順を解説!」を参照。
レバテックフリーランス
![]()
![]()
とにかく案件数が多いので、とりあえず登録しておけば間違いないエージェントです!



僕もはじめてフリーランスの案件を貰ったのはレバテックフリーランス
![]()
![]()
保有している案件数が多いので、業務経験がなくても何かしらの案件は紹介してもらえますよ(僕はJavaの経験3年でも案件を貰えました)。
手厚い保障を重視したいなら「Midworks


」
- 手厚い保障で正社員並みの安心感。
- 還元率60%超え&単価公開でクリアな契約。
- 給与保障制度(審査あり)。
Midworks
![]()
![]()
フリーランスを目指しているけど不安な方や保障を重視したい方におすすめです。



僕も何度か案件を紹介してもらいました。
自分のスキルに合った案件を紹介してもらえましたし、電話のやり取りも非常に丁寧でした。
週2〜3日の案件探しなら「ITプロパートナーズ


」
- IT案件に特化したフリーランスエージェント。
- 週2〜3日の案件が豊富。
- リモート案件が多く、直エンドなので単価も高い。
※詳細は「【週2・3案件】ITプロパートナーズとは?メリットや利用手順を解説!」を参照。
ITプロパートナーズ
![]()
![]()
週2〜3日から参画できる案件が豊富なので、起業したい人にもおすすめです。



週2〜3日の案件はある程度スキルがないと紹介してもらえない印象です。
とはいえ、週5の案件ももちろんありますし、僕が利用した時は迅速・丁寧に対応していただきました!
よくある質問
tools配列を毎回書き換える方法と何が違いますか?
tools配列を書き換えると、プロンプトキャッシュのハッシュが変わり、会話全体がキャッシュミスになります。
tool_additionとtool_removalはtools配列を触らないので、過去ターンのキャッシュがそのまま効きます。
どのモデルで使えますか?
Claude Opus 5・Opus 4.8・Fable 5・Mythos 5・Fable 5.1・Mythos 5.1で使えます。
Claude Sonnet 5は非対応です。
あるタイミングで初めて出すツールはどう定義しますか?
tools配列で対象ツールにdefer_loadingをtrueにして宣言します。
tool_additionブロックが登場するまで、モデルには対象ツールが見えません。
ベータヘッダーは何を指定しますか?
mid-conversation-tool-changes-2026-07-01を指定します。
Python SDKならbetas引数にリストで渡します。
まとめ
今回は、Claude APIで会話の途中でツールを変更する方法について解説しました。
以下が本記事のまとめになります。



最後までお読みいただき、ありがとうございました!
| 【当サイト】おすすめフリーランスエージェント3選 | |||
|---|---|---|---|
| エージェント | 評価 | ポイント | 公式サイト |
レバテックフリーランス | 5.0 | 業界最大級のエージェント。 高単価案件が豊富。 | 公式 |
Midworks | 4.8 | 満足度調査で 3年連続3冠を達成。 | 公式 |
ITプロパートナーズ | 4.6 | 週2〜3向けの案件が豊富。 | 公式 |
- クソおすすめ本



海外のエンジニアがどういった思考で働いているかが理解できます。
海外に行く気はないけど海外エンジニアの動向が気になる雑魚エンジニアにおすすめです(本当におすすめな本しか紹介しないのでご安心を)。








