CLAUDE LABEN
2.1.273 — 接続まわりがまとめて整理されました。LLM ゲートウェイ向けの 5 ヘッダが opt-in で追加され、MCP が再接続を諦めたときにも通知が出ます09/29 — 廃止予定表にある claude-sonnet-4-5 の日付は残り 12 日ですが、これは「最も早い場合」の暫定日です。現在も Active で、公開モデルの廃止は最低 60 日前に告知されますMCP — セッションを畳まずに繋ぎ直したい、という要望が続いています。切断の通知は出るようになりましたが、再接続そのものはまだ手元の操作に委ねられていますNEW — 定期タスクが動く日と動かない日があったのは、フォルダを1つしか指定していなかったからでしたWINDOWS — Cowork が最初のタスクから失敗するときは、原因を探す前に開発者モードとセットアップの状態を確認しますHANDOFF — 会話が重くなった原稿を次のチャットへ渡すとき、要約に必ず残しておく項目を先に 3 つ決めておきます2.1.273 — 接続まわりがまとめて整理されました。LLM ゲートウェイ向けの 5 ヘッダが opt-in で追加され、MCP が再接続を諦めたときにも通知が出ます09/29 — 廃止予定表にある claude-sonnet-4-5 の日付は残り 12 日ですが、これは「最も早い場合」の暫定日です。現在も Active で、公開モデルの廃止は最低 60 日前に告知されますMCP — セッションを畳まずに繋ぎ直したい、という要望が続いています。切断の通知は出るようになりましたが、再接続そのものはまだ手元の操作に委ねられていますNEW — 定期タスクが動く日と動かない日があったのは、フォルダを1つしか指定していなかったからでしたWINDOWS — Cowork が最初のタスクから失敗するときは、原因を探す前に開発者モードとセットアップの状態を確認しますHANDOFF — 会話が重くなった原稿を次のチャットへ渡すとき、要約に必ず残しておく項目を先に 3 つ決めておきます
記事一覧/Claude Code
Claude Code/2026-08-18中級

調べ物タスクの WebFetch キャッシュ TTL を、自分の使い方に合わせて選ぶ

Claude Code の WebFetch には URL キャッシュの TTL 設定があります。同じページを何度も取りに行く調べ物タスクで、取得回数と情報の鮮度がどう入れ替わるのかを、観測用の小さなサーバと計算スクリプトで確かめながら決めていきます。

Claude Code254WebFetch2環境変数6キャッシュ個人開発127

複数のアプリを個人開発で運用していると、依存ライブラリのリリースノートやストアの規約ページを定期的に読み直す作業が積み上がっていきます。私はこの手の調べ物を Claude Code に任せているのですが、あるとき手元のプロキシログを眺めていて、ひとつのセッションの中で同じリリースノートのページを何度も取りに行っていることに気づきました。

読み返せば当然です。複数のページを横断して比較するとき、人間だって基準になるページに何度も戻ります。エージェントも同じことをします。

Claude Code の v2.1.233 で、WebFetch の URL キャッシュ TTL を CLAUDE_CODE_WEBFETCH_CACHE_TTL_MS で調整できるようになりました。既定は15分とされています。この数字を触るべきかどうかは、自分の調べ物がどういう形をしているかで変わります。ここでは、その形を自分の手で見てから決める手順を書きます。

まず「同じURLを何回踏んでいるか」を目で見る

設定値の話に入る前に、自分のタスクの実際のアクセスの形を知る必要があります。外部サイトを相手に数えるのは難しいので、手元に小さな観測用サーバを立てて、そこを取りに行かせるのが早道です。

# server.py — アクセスを数えるだけの観測用サーバ
import http.server, socketserver, datetime, collections
 
HITS = collections.Counter()
 
class Handler(http.server.BaseHTTPRequestHandler):
    def do_GET(self):
        HITS[self.path] += 1
        ts = datetime.datetime.now().strftime("%H:%M:%S")
        print(f"{ts}  GET {self.path}  (hit #{HITS[self.path]})", flush=True)
        body = f"doc for {self.path}\n".encode()
        self.send_response(200)
        self.send_header("Content-Type", "text/plain; charset=utf-8")
        self.send_header("Content-Length", str(len(body)))
        self.end_headers()
        self.wfile.write(body)
 
    def log_message(self, *args):
        pass  # 既定のアクセスログは重複するので黙らせる
 
with socketserver.TCPServer(("127.0.0.1", 8731), Handler) as httpd:
    print("listening on http://127.0.0.1:8731", flush=True)
    httpd.serve_forever()

python3 server.py で起動し、同じ URL を3回叩くと、こう出ます。

15:06:33  GET /release-notes  (hit #1)
15:06:33  GET /release-notes  (hit #2)
15:06:33  GET /release-notes  (hit #3)
15:06:33  GET /policy  (hit #1)

素朴な仕掛けですが、これで十分です。標準出力へ即時に流すために flush=True を付け、既定のアクセスログを log_message で止めています。この2点を省くと、行が遅れて出たり二重に出たりして、回数の判断がぶれます。

あとは http://127.0.0.1:8731/release-notes のようなローカル URL を含む調べ物を Claude Code に投げ、ヒット数の伸び方を眺めます。同じパスの hit # が伸び続けるなら、そのタスクは再取得の多い形をしています。伸びないなら、TTL を触っても得るものはほとんどありません。

なお TTL の効き方そのもの(どの単位で共有されるのか、セッションをまたぐのか)は環境によって差が出るところなので、断定せずに、この観測サーバで自分の環境の挙動を確かめるのが確実です。

取得回数と鮮度は、片方を取れば片方が下がる

自分のアクセスの形が見えたら、TTL を変えたときに何がどう動くかを見積もります。実際のセッションを何度も回すのは時間がかかるので、アクセス列を入力にして計算してしまうほうが早いです。

# ttl_model.py — アクセス列から、取得回数と手元データの古さを出す
import random
 
def build_trace(minutes=90, seed=7):
    """基準ページに何度も戻り、たまに新しいリンク先を踏む調べ物の形"""
    rnd = random.Random(seed)
    core = [f"https://example.test/core/{i}" for i in range(4)]
    trace = []
    for t in range(minutes):
        for _ in range(rnd.choice([0, 1, 1, 2])):
            if rnd.random() < 0.62:
                trace.append((t, rnd.choice(core)))
            else:
                trace.append((t, f"https://example.test/leaf/{rnd.randrange(400)}"))
    return trace
 
def count_fetches(trace, ttl_min):
    last, fetches = {}, 0
    for t, url in trace:
        prev = last.get(url)
        if prev is None or t - prev >= ttl_min:
            fetches += 1
            last[url] = t
    return fetches
 
def staleness(trace, ttl_min):
    """各アクセス時点で、手元にある内容が何分前のものかを集計する"""
    last, ages = {}, []
    for t, url in trace:
        prev = last.get(url)
        if prev is None or t - prev >= ttl_min:
            last[url] = t
            ages.append(0)
        else:
            ages.append(t - prev)
    return max(ages), sum(ages) / len(ages)
 
trace = build_trace()
for ttl in (0, 5, 15, 60, 240):
    mx, av = staleness(trace, ttl)
    print(f"TTL={ttl:>3}分  取得={count_fetches(trace, ttl):>3}回  "
          f"最大の古さ={mx:>2}分  平均の古さ={av:>4.1f}分")

私の手元でこのスクリプトを走らせた結果です。アクセス総数86回・ユニーク URL 30本という、90分ぶんの調べ物を想定した列になっています。

TTL実取得回数再取得を省けた割合手元データの最大の古さ平均の古さ
0分(毎回取得)86回0.0%0分0.0分
5分64回25.6%4分0.6分
15分(既定)45回47.7%14分3.8分
60分34回60.5%59分14.4分
240分30回65.1%85分24.3分

これはあくまで、この入力に対する計算結果です。数字そのものを持ち帰るのではなく、build_trace を自分のログから作った実際のアクセス列に差し替えて、自分の形での傾きを見てください。

私自身、この表を作るまでは「長くしておけば得だろう」と漠然と考えていました。実際には、そう単純ではありませんでした。15分から60分へ伸ばして減らせる取得は13%ぶんしかないのに、手元データの平均の古さは3.8分から14.4分へ、およそ4倍になります。効きが大きいのは0分から15分までの区間で、そこから先は鮮度だけが一方的に削られていきます。既定の15分が、ちょうど曲がり角の手前に置かれていることがわかります。

用途ごとに、どちらを重く見るかを決める

ここまでの2つの数字をどう天秤にかけるかは、調べている対象の変化の速さで決まります。私が普段扱う3種類の調べ物で言うと、こうなります。

調べ物の種類対象の変わりやすさ寄せる方向理由
リリースノート・変更履歴の追跡日単位で変わる既定のまま、あるいは短く作業中に更新が入る可能性は低いものの、古い記述のまま結論を出すと手戻りが重い
規約・ポリシーの読み合わせ月単位で変わる長めに寄せる同じ条文へ何度も戻る形になりやすく、セッション中に変わることはまず考えなくてよい
公開中のページの表示確認自分の手で変える短く、または無効に寄せる直したものを取りに行っているので、古い内容が返ると確認の意味がなくなる

3行目が、私が一番失敗しやすかったところです。自分で直したページを確認させているのに、直す前の内容をもとに「問題ありません」と返ってくる。原因が自分の設定にあると気づくまで、直しかたのほうを疑って時間を使いました。キャッシュは、自分が書き換える対象に対しては、ただの嘘つきになります。

設定を当てて、当たっていることを確かめる

値はミリ秒で渡します。1時間なら以下です。

# そのコマンドの間だけ効かせる
CLAUDE_CODE_WEBFETCH_CACHE_TTL_MS=3600000 claude
 
# 確認用途など、キャッシュを寄せたくないとき
CLAUDE_CODE_WEBFETCH_CACHE_TTL_MS=0 claude

シェルの設定ファイルへ書き込んで常時有効にすることもできますが、私は用途ごとに前置きで渡す形に落ち着きました。調べ物と、自分が直したページの確認とでは、望ましい向きが正反対になるからです。片方に合わせて固定すると、もう片方で必ず困ります。

設定したら、先ほどの観測サーバへ戻って当たっているかを見ます。値を変える前と後で同じ調べ物を投げ、同じパスの hit # の伸び方が変わっていれば効いています。変わらないなら、値の書き方か、渡しているプロセスの範囲が違っています。

環境変数の全体像は「Claude Code 環境変数 完全リファレンス」に整理してあります。同じ v2.1.233 で入った Bash ツールのメモリ上限については「ビルドがメモリを食い尽くしたときの止まり方は、cgroup と ulimit で別物でした」で扱っています。

次の一歩

まずは観測サーバを起動して、いつも投げている調べ物をそのまま一度流してみてください。hit # が2桁まで伸びるパスがあるなら、TTL を伸ばす価値があります。伸びないなら、既定のままで構いません。設定値を決める前に、自分のタスクの形を一度見ておくと、迷いが減ります。

小さな環境変数ひとつですが、こうして数字にしてみると、何を犠牲にして何を得ているのかがはっきりします。お読みいただきありがとうございました。

シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥2,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

Claude Code2026-09-12
巡回タスクが朝まで返らなかった原因は、WebFetch の待ち時間に上限がなかったことでした
Claude Code v2.1.268 で WebFetch に 300 秒の期限が付きました。応答を閉じないサーバーに当たると無人実行がどこで止まるのか、CLAUDE_CODE_WEBFETCH_DEADLINE_MS の 0 がなぜ「待たない」ではないのかを、手元で再現できる形で整理します。
Claude Code2026-09-10
「Not signed in to the Cloud gateway」で全リクエストが止まる朝に、設定より先に版を見ます
Claude Code 2.1.265 でゲートウェイ・プロキシ構成が全リクエスト失敗した回帰を入口に、認証の入力面を一枚に並べて「設定と版のどちらが変わったか」を数秒で切り分ける小さな手順をまとめます。
Claude Code2026-09-10
plugin.json を1枚置くと、スキルの棚がまとめて外せる単位になります
スキルを用途ごとに色分けしたら、毎日使う一群は全体の5パーセントしかありませんでした。.claude-plugin/plugin.json を1枚置いてフォルダをプラグインに変え、その日に使わない棚をグループごと外せるようにするまでの手順と、途中で二度つまずいた読み込みの規則を書き残します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます