CLAUDE LABEN
MCP — 2026-07-28 仕様への対応が Claude 製品群で広がっています。双方向ステートフルなプロトコルからリクエスト・レスポンス型へ移り、MCP サーバーをサーバーレスやエッジに置けるようになりましたEXTENSIONS — 公式拡張が3種そろいました。サーバー側で UI を描く MCP Apps、非同期の長時間処理を扱う Tasks、IdP 経由で組織単位に払い出す Enterprise Managed Auth ですADOPTION — MCP の月間 SDK ダウンロードが4億を超え、年内で約4倍になりました。エージェントとアプリケーションを繋ぐ標準としての位置づけが固まりつつありますQUOTA — Claude Code 契約者向けの週次利用枠 50% 上乗せは本日8月19日が最終日です。長時間のエージェント実行を回すなら今日が最後の機会になりますPRICING — Claude Sonnet 5 の導入価格 100万トークンあたり入力2ドル・出力10ドルは8月31日で終了し、9月1日から入力3ドル・出力15ドルへ移ります。残り12日ですFIX — タイムアウトが固定されたサーバーに対し MCP v2 接続がサブスクリプションを際限なく張り直す不具合が修正され、ユーザー帰属のための forward_user_identity 設定も追加されましたMCP — 2026-07-28 仕様への対応が Claude 製品群で広がっています。双方向ステートフルなプロトコルからリクエスト・レスポンス型へ移り、MCP サーバーをサーバーレスやエッジに置けるようになりましたEXTENSIONS — 公式拡張が3種そろいました。サーバー側で UI を描く MCP Apps、非同期の長時間処理を扱う Tasks、IdP 経由で組織単位に払い出す Enterprise Managed Auth ですADOPTION — MCP の月間 SDK ダウンロードが4億を超え、年内で約4倍になりました。エージェントとアプリケーションを繋ぐ標準としての位置づけが固まりつつありますQUOTA — Claude Code 契約者向けの週次利用枠 50% 上乗せは本日8月19日が最終日です。長時間のエージェント実行を回すなら今日が最後の機会になりますPRICING — Claude Sonnet 5 の導入価格 100万トークンあたり入力2ドル・出力10ドルは8月31日で終了し、9月1日から入力3ドル・出力15ドルへ移ります。残り12日ですFIX — タイムアウトが固定されたサーバーに対し MCP v2 接続がサブスクリプションを際限なく張り直す不具合が修正され、ユーザー帰属のための forward_user_identity 設定も追加されました
記事一覧/Claude Code
Claude Code/2026-08-02上級

予算上限で止まった実行の再開設計 — 停止点36通りを総当たりして分かったこと

ヘッドレス実行が予算上限で止まると、成功でも失敗でもない第三の終了が生まれます。停止点36通りを総当たりして再開の健全性と総支出を測った実験から、原子的な書き込みとインデックス優先の再開、上限をバッチ全体でなく最小の再開単位に掛ける設計へ至った記録です。

Claude Code226ヘッドレス実行予算上限冪等性5自動化77

プレミアム記事

朝、前夜に走らせておいた定期ジョブの出力を開いたら、記事の途中で文章が切れていました。エラーログは空。終了コードも、私が想定していたどのパターンとも一致しません。

ファイルは確かに存在していて、サイズもそれなりにありました。だから後続の処理は「もう作ってある」と判断して、そのまま次へ進んでいたのです。

壊れていたのは、ジョブではなく、私の再開ロジックの前提でした。

予算上限による停止は、成功でも失敗でもありません

Claude Code のヘッドレス実行には --max-budget-usd があり、累積コストが閾値を超えた時点で実行が打ち切られます。同時サブエージェント数の上限(現在は20)と同じく、暴走を止めるための安全装置です。

ここで見落としやすいのは、この停止が成功でも失敗でもない第三の終了だという点です。

終了の種類起きること再試行の意味
正常終了全工程が完了不要
例外・クラッシュ途中で異常終了一時的な要因なら有効
予算上限による停止正常な工程の途中で打ち切り同じ上限では同じ場所で止まります

クラッシュを前提にした設計は「異常な状態を検知して巻き戻す」ことを考えます。ところが予算停止は、ポリシー通りに正しく動いた結果です。巻き戻すべき異常が、どこにも記録されません。

そして停止する場所は、コストの累積が閾値を跨いだ瞬間に決まります。つまり私が設計したチェックポイントとは無関係な位置です。ファイルを書いている最中かもしれませんし、書き終えてインデックスを更新する直前かもしれません。

この「どこで止まるか分からない」性質を、感覚ではなく数字で把握したいと考えました。

停止点を総当たりする実験装置

実機で --max-budget-usd を少しずつ変えながら何十回も走らせれば、当然その分の費用が発生します。個人開発の予算でそれをやる合理性はありません。

代わりに、同じ構造を持つ再現環境を Linux サンドボックス上に作りました。工程ごとに「コスト単位」を加算し、閾値を超えた瞬間に os._exit(9) で即座に落ちるパイプラインです。後始末をせずに落ちる点が、予算停止の挙動と同じ形になります。

#!/usr/bin/env python3
"""停止点を総当たりするためのパイプライン。
   mode=naive : 直接上書き。再開はファイルの存在で判定
   mode=safe  : .part へ書き fsync してから os.replace。再開はインデックスで判定
"""
import json, os, sys, pathlib
 
ROOT, CAP, MODE = pathlib.Path(sys.argv[1]), float(sys.argv[2]), sys.argv[3]
ART, IDX = ROOT / "artifacts", ROOT / "index.json"
ITEMS = ["alpha", "bravo", "charlie", "delta"]
spent = 0.0
 
def charge(u):
    """工程完了ごとにコストを加算。閾値を超えたら巻き戻さずに落ちる"""
    global spent
    spent += u
    with open(ROOT / "spend.log", "a") as f:
        f.write(f"{u}\n")
    if spent > CAP:
        os._exit(9)          # ポリシー停止。例外ではないので finally も走りません
 
def read_index():
    return json.loads(IDX.read_text())["items"] if IDX.exists() else []
 
def write_index(items):
    if MODE == "safe":
        t = IDX.with_suffix(".json.part")
        with open(t, "w") as f:
            json.dump({"items": items}, f)
            f.flush(); os.fsync(f.fileno())
        os.replace(t, IDX)   # 同一ファイルシステム内なら原子的に差し替わります
    else:
        IDX.write_text(json.dumps({"items": items}))
 
ART.mkdir(parents=True, exist_ok=True)
if MODE == "safe":
    for p in ART.glob("*.part"):
        p.unlink()           # 前回の中断で残った書きかけを掃除します
 
items = read_index()
done = {e["name"] for e in items}
 
for name in ITEMS:
    if MODE == "naive":
        if (ART / f"{name}.md").exists():
            continue         # 「ファイルがある=完了」という素朴な判定
    else:
        if name in done:
            continue         # インデックスだけを唯一の真実として扱います
 
    charge(1.0)              # 計画
    body = f"# {name}\n" + "x" * 200_000 + "\nEND\n"
    charge(2.0)              # 生成
 
    target = ART / f"{name}.md"
    path = target.with_suffix(".md.part") if MODE == "safe" else target
    with open(path, "w") as f:
        f.write(body[: len(body) // 2])
        f.flush(); os.fsync(f.fileno())
        charge(0.5)          # 書き込みの「最中」に置いた停止点
        f.write(body[len(body) // 2 :])
        f.flush(); os.fsync(f.fileno())
    if MODE == "safe":
        os.replace(path, target)
    charge(0.5)
 
    items.append({"name": name, "bytes": len(body)})
    write_index(items)       # コミットしてから課金する順序が後で効いてきます
    charge(0.5)
 
print("COMPLETE")

1件あたりのコストは 1.0 + 2.0 + 0.5 + 0.5 + 0.5 で 4.5 単位、4件で 18.0 単位が理想値になります。上限を 0.5 刻みで 0.5 から 18.0 まで動かせば、36通りの停止点を機械的に踏み分けられます。

検証側は、再開が終わった後の状態を厳しく見ます。インデックスに載っている全件について、ファイルが存在し、バイト数が一致し、末尾に終端マーカーがあること。加えて、書きかけの .part が残っていないこと。

#!/usr/bin/env python3
"""再開完了後の厳格な検証。サイズ一致と終端マーカーの両方を見ます"""
import json, sys, pathlib
 
ROOT = pathlib.Path(sys.argv[1])
ART, IDX = ROOT / "artifacts", ROOT / "index.json"
EXPECT = ["alpha", "bravo", "charlie", "delta"]
bad = []
 
idx = {e["name"]: e["bytes"]
       for e in (json.loads(IDX.read_text())["items"] if IDX.exists() else [])}
 
for n in EXPECT:
    p = ART / f"{n}.md"
    if n not in idx:
        bad.append(f"missing-index:{n}"); continue
    if not p.exists():
        bad.append(f"missing-file:{n}"); continue
    data = p.read_bytes()
    if len(data) != idx[n]:
        bad.append(f"size-mismatch:{n}({len(data)}!={idx[n]})")
    elif not data.endswith(b"END\n"):
        bad.append(f"truncated:{n}")
 
for p in ART.glob("*.part"):
    bad.append(f"leftover-part:{p.name}")
 
print(("CORRUPT " + ",".join(bad)) if bad else "OK")

なお、ここで得られる数値は再現環境のものであり、Claude Code 実機の課金点そのものではありません。課金がどの粒度で載るかは実装依存です。それでも、停止が内部の課金点と外部の設計上の境界のズレで起きるという構造は共通しています。今回知りたいのはその構造の方でした。

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

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
ファイルの存在を完了とみなす再開が、100,006バイトで切れた成果物を完成品として通した実測(36停止点中8点で最終出力が壊れました)
原子的な書き込みを入れた途端に現れる「進捗ゼロで予算を焼き続ける再試行」と、それを3.5コスト単位で打ち切る進捗ゲートの実装
総支出は上限値に対して単調ではありません。cap=8.0で30.0、cap=8.5で18.0。上限を最小再開単位に掛け直すと値によらず無駄0%になりました
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

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

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

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

関連記事

Claude Code2026-06-24
修正済みのファイルを、もう一度直そうとしました — 浅い永続クローンの陳腐化と「読む前に取り直す」判断
無人のエージェントが、すでに直したファイルをもう一度直そうとしていました。原因は数日前の浅い永続クローンを読み続けていたことです。ローカルHEADとリモートHEADの突き合わせで陳腐化を数値で検知し、判断の前にだけ取り直す設計と、二重作業を防ぐ冪等性の考え方を整理します。
Claude Code2026-08-09
一時的な401が長期トークンを置き換える — ヘッドレス実行の資格情報に「出所」を持たせる
共有した資格情報ファイルは、たった一度の一時的な401で長期トークンを失うことがあります。24並列の実行に401を1回だけ注入して被害範囲を実測し、資格情報に出所フィールドを持たせるガードと隔離のコストを比較、24マイクロ秒で現在地を確定する起動時カナリアまで検証しました。
Claude Code2026-08-05
秘密を渡さず、リクエストだけ通す — サンドボックス資格情報マスキングの差し替えが効く境界
Claude Code のサンドボックス資格情報マスキングは、センチネル値を読ませて送信時に実値へ差し替える設計です。差し替えが効く認証方式と効かない方式、そしてボディに載せたときに生じる長さのずれを、最小プロキシを自作して実測しました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →