CLAUDE LABEN
MODEL — Claude Fable 5が6/9に一般提供開始。100万トークン文脈・常時アダプティブ思考・128K出力を備えますPLATFORM — Developer Platformにcode execution・MCP connector・Files API・最大1時間のプロンプトキャッシュが追加されましたMCP — 管理者がOkta経由で組織全体にMCPコネクタをプロビジョニング可能に。初回ログインでゼロタッチ接続できますSANDBOX — Claude Managed Agentsが自前サンドボックス+プライベートMCPサーバー接続に対応しましたCODING — Opus 4.8はSWE-bench 72.5%・Terminal-bench 43.2%。長時間の連続作業に強みがありますLINEUP — 主力はOpus 4.8・Sonnet 4.6・Haiku 4.5。用途に応じて使い分けられますMODEL — Claude Fable 5が6/9に一般提供開始。100万トークン文脈・常時アダプティブ思考・128K出力を備えますPLATFORM — Developer Platformにcode execution・MCP connector・Files API・最大1時間のプロンプトキャッシュが追加されましたMCP — 管理者がOkta経由で組織全体にMCPコネクタをプロビジョニング可能に。初回ログインでゼロタッチ接続できますSANDBOX — Claude Managed Agentsが自前サンドボックス+プライベートMCPサーバー接続に対応しましたCODING — Opus 4.8はSWE-bench 72.5%・Terminal-bench 43.2%。長時間の連続作業に強みがありますLINEUP — 主力はOpus 4.8・Sonnet 4.6・Haiku 4.5。用途に応じて使い分けられます
記事一覧/API & SDK
API & SDK/2026-06-22上級

Claude Files API のファイルが知らぬ間に溜まる — 内容ハッシュ台帳で重複を止め、孤児を回収する

自動パイプラインで Files API を使うと、同じファイルが何度もアップロードされ孤児ファイルが静かに溜まります。内容ハッシュ台帳での重複排除と、参照されなくなったファイルの GC 設計を実装例つきで解説します。

Claude API83Files API2コスト最適化19運用設計6

プレミアム記事

Files API を自動パイプラインに組み込んで二週間ほど経った頃、ふと GET /v1/files を叩いてみたら、同じ参照データが日付違いで何十個も並んでいて少し青ざめました。アップロードのコードは正しく動いていました。問題は「一度上げたファイルをもう一度上げない」仕組みと「使わなくなったファイルを片付ける」仕組みが、どちらも私のコードに無かったことです。

Files API は「一度アップロードして何度でも参照する」ための機能ですが、その"一度"を保証するのは API ではなく呼び出し側の責任です。手作業で時々使う分には溜まりませんが、毎日同じ参照データを上げ直す自動運用では、孤児ファイルとストレージ課金が静かに積み上がります。ここからは、その積み上がりを内容ハッシュ台帳と孤児 GC の二段で止める設計を、私が Dolice Labs の自動投稿パイプラインで実際に組んだ形をもとにたどります。

基礎的なアップロード手順はClaude Files API の基本操作ガイドで扱っているので、ここでは「溜めない運用」に絞ります。

なぜ Files API は黙って溜まるのか

Files API のアップロードは冪等ではありません。同じ内容の PDF を二回 POST /v1/files すると、別々の file_id を持つ二つの実体ができます。API から見れば別物なので、エラーにもならず警告も出ません。

自動運用ではここが効いてきます。たとえば「参照データを毎朝アップロードして、その file_id を使って記事を生成する」というジョブを毎日回すと、中身が前日と一字一句同じでも、新しい file_id が毎回生まれます。一ヶ月で 30 個、四つのサイト分なら 120 個。一つ一つは小さくても、参照されなくなった実体がストレージに残り続けます。

Files API のストレージは保管しているバイト数に対して課金されます。つまり「使っていないのに消していないファイル」は、何の役にも立たないまま毎日課金対象であり続けるわけです。私の場合、気づいたときには本来 4 個で足りるはずの参照データが 80 個近くまで膨らんでいました。

落とし穴は二つに分けて考えると整理できます。ひとつは重複アップロード(同じ内容を二度上げる)、もうひとつは孤児ファイル(もう誰も参照していないのに残っている)です。前者は上げる前に止め、後者は定期的に回収します。

内容ハッシュ台帳という考え方

重複を止める一番素直な方法は、「上げる前に、この内容を前に上げたか確認する」ことです。確認の鍵になるのが内容のハッシュです。

ファイルのバイト列から SHA-256 を計算し、ハッシュ → file_id の対応を自分側の台帳に持ちます。アップロードしたい内容のハッシュが台帳にあれば、既存の file_id をそのまま使い回します。無ければ初めてアップロードして、結果を台帳に書き戻します。これだけで「中身が同じなら絶対に二度上げない」が保証できます。

台帳の置き場所はワークロードによります。私は最初ローカルの JSON ファイルで始め、複数プロセスが同時に走るようになってから KV ストアに移しました。要件はシンプルで、ハッシュをキーに file_id を引ければ何でも構いません。

ハッシュに SHA-256 を選んだのは、衝突の心配を実務上ゼロとみなせるからです。中身の違うファイルが偶然同じハッシュになって取り違える確率は天文学的に小さく、参照データの規模では考慮に値しません。逆に MD5 のような古いハッシュを避けたのは、いざ衝突を疑う場面が来たときに、原因の切り分けで余計な時間を取られたくなかったからです。台帳という長く使う仕組みほど、土台は安全側に倒しておくと後が楽になります。

import hashlib
import json
from pathlib import Path
from anthropic import Anthropic
 
client = Anthropic()  # ANTHROPIC_API_KEY は環境変数から
LEDGER_PATH = Path("file_ledger.json")
BETA = "files-api-2025-04-14"  # Files API はベータヘッダーが必要
 
 
def load_ledger() -> dict:
    if LEDGER_PATH.exists():
        return json.loads(LEDGER_PATH.read_text())
    return {}
 
 
def save_ledger(ledger: dict) -> None:
    # 一時ファイルに書いてから置き換え、書き込み途中の破損を防ぐ
    tmp = LEDGER_PATH.with_suffix(".tmp")
    tmp.write_text(json.dumps(ledger, ensure_ascii=False, indent=2))
    tmp.replace(LEDGER_PATH)
 
 
def content_hash(data: bytes) -> str:
    return hashlib.sha256(data).hexdigest()
 
 
def get_or_upload(path: str) -> str:
    """同じ内容なら既存の file_id を返し、初見ならアップロードする。"""
    data = Path(path).read_bytes()
    digest = content_hash(data)
 
    ledger = load_ledger()
    if digest in ledger:
        return ledger[digest]["file_id"]  # 再利用 — アップロードしない
 
    uploaded = client.beta.files.upload(
        file=(Path(path).name, data, "application/octet-stream"),
        betas=[BETA],
    )
    ledger[digest] = {"file_id": uploaded.id, "name": Path(path).name}
    save_ledger(ledger)
    return uploaded.id

このコードのポイントは、ハッシュ計算をファイル名ではなくバイト列に対して行っていることです。ファイル名で判定すると、同名で中身が変わったケースを取りこぼします。逆に内容で判定すれば、ファイル名が違っても中身が同じなら一つにまとめられます。

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

この記事の続きを読む

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

この記事で得られること
アップロードのたびに増える孤児ファイルとストレージ課金に気づかず放置していた人が、内容ハッシュ台帳で重複を根元から止められるようになる
list / delete を組み合わせた孤児 GC のロジックを、誤削除を防ぐ二重チェックつきの動くコードで手に入れられる
毎日ファイルを上げ続ける自動運用で、Files API のストレージを一定に保ちながら参照の再利用率を上げる設計判断ができるようになる
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

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

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

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

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

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

関連記事

API & SDK2026-04-04
Claude API Files API — ドキュメントを永続化してAPIコストを大幅削減
Claude API Files APIを使ってドキュメントを永続化し、繰り返しアップロードのコストを削減する方法を解説。PDFや長文ドキュメントを一度アップロードして複数リクエストで再利用する実践的な実装ガイドです。
API & SDK2026-06-21
service_tier で優先枠をユーザー応答だけに振り向ける
Priority Tier を契約しているのにピーク時だけユーザー向け応答が遅くなる——その原因を service_tier の auto と standard_only の挙動から切り分け、背景ジョブを優先枠から隔離する構成を、自動運用の実例とともにまとめました。
API & SDK2026-06-20
effort パラメータを工程ごとに振り分けて Claude の出力コストと待ち時間を整える
Claude API の effort パラメータは思考・本文・ツール呼び出しを含む出力トークン全体を制御します。一律 high をやめ、工程ごとに段階配分する実装と動的ルーターを、個人開発の自動運用での実測とともに解説します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →