0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Claude API の Files API で同じ PDF・画像を毎回 Base64 送信するのをやめる実装手順 — beta ヘッダー2箇所・アップロード済みファイルは再取得不可など3つのハマりどころ【2026】

0
Posted at

はじめに / 対象と前提

Claude API で PDF や画像を扱うとき、毎回 Base64 エンコードして messages に埋め込んでいた。同じ 10MB の PDF に質問を 5 回投げると、5 回とも同じデータを送信することになる。リクエストが重い・遅い・コードが汚い、の三重苦。

Files API を使うと、ファイルを一度アップロードして file_id で参照できるようになる。この記事では実装手順と、自分が実際にハマった 3 点をまとめる。

想定読者:

  • Claude API(Messages API)を Python で叩いたことがある
  • PDF / 画像入力(Vision)を使っている、または使いたい

環境:

  • Python 3.13
  • anthropic SDK 1.x
  • モデル: claude-opus-5(2026-09 時点)

TL;DR

  • client.beta.files.upload() でアップロード → 返ってきた id{"type": "document", "source": {"type": "file", "file_id": ...}} で参照する
  • beta 指定 files-api-2025-04-14アップロードと Messages 呼び出しの両方に必要
  • アップロードしたファイルは API 経由で再ダウンロードできない(取れるのはメタデータのみ)。元ファイルは自分で保管する

手順 / 動かし方

1. ファイルをアップロードする

import anthropic

client = anthropic.Anthropic()

uploaded = client.beta.files.upload(
    file=("report.pdf", open("report.pdf", "rb"), "application/pdf"),
)
print(uploaded.id)
print(uploaded.size_bytes)

file 引数は (ファイル名, バイナリ, MIME タイプ) のタプルのほか、pathlib.Path をそのまま渡してもよい。アップロード側の beta ヘッダーは SDK が自動で付けてくれる。

実行結果:

file_011CNha8iCJcU1wXNR6q4V8w
1048576

2. Messages API から file_id で参照する

response = client.beta.messages.create(
    model="claude-opus-5",
    max_tokens=16000,
    messages=[{
        "role": "user",
        "content": [
            {"type": "text", "text": "このレポートの要点をまとめて"},
            {
                "type": "document",
                "source": {"type": "file", "file_id": uploaded.id},
            },
        ],
    }],
    betas=["files-api-2025-04-14"],
)
print(response.content[0].text)

ポイントは 2 つ。

  • client.messages.create ではなく client.beta.messages.create を使い、betas=["files-api-2025-04-14"] を渡す
  • Base64 のときの "source": {"type": "base64", ...}"source": {"type": "file", "file_id": ...} に変わるだけで、content block の構造は同じ

同じ file_id は何度でも使い回せるので、「1 つの PDF に質問を 10 回」のようなユースケースでもアップロードは 1 回で済む。

3. ファイルの管理(一覧・メタデータ・削除)

# 一覧(SDK が自動でページネーションする)
for f in client.beta.files.list():
    print(f.id, f.filename, f.size_bytes)

# メタデータ取得
info = client.beta.files.retrieve_metadata(uploaded.id)
print(info.mime_type)

# 削除
client.beta.files.delete(uploaded.id)

ファイルは削除するまで残り続ける。上限は 1 ファイル 500MB、組織全体で 100GB。アップロード・一覧・削除の操作自体は無料で、課金されるのは Messages で参照したときに入力トークンとして数えられる分だけ。

ハマりどころ

1. beta 指定は「2 箇所」に必要

最初にハマったのがこれ。アップロードは SDK が勝手にヘッダーを付けるので成功する。ところが Messages 側で betas=["files-api-2025-04-14"] を渡し忘れると、file_id を参照した時点で 400 系エラーになる。

「アップロードは成功しているのに参照で落ちる」ため、file_id の値が間違っていると勘違いして 30 分溶かした。アップロードと参照は別リクエストで、beta 指定はそれぞれに必要、と覚えておく。

2. content block の型と MIME タイプの不一致

PDF・テキストは "type": "document"、画像(PNG / JPEG など)は "type": "image" で参照する必要がある。image/png でアップロードしたファイルを document ブロックで参照するとエラーになる。

Base64 時代は media_type を毎回自分で書くので意識するが、file_id 参照だと「どの MIME でアップロードしたか」がコード上から見えなくなる。変数名で区別できるようにしておくと事故らない。迷ったら retrieve_metadata()mime_type で確認できる。

3. アップロードしたファイルは再ダウンロードできない

client.beta.files.download() という API はあるが、ダウンロードできるのはコード実行ツールや Skills が生成したファイルだけ。自分がアップロードしたファイルを取り出そうとするとエラーになる。

つまり Files API は「ストレージ」ではなく「Messages 参照用の置き場」。ローカルの元ファイルを消して file_id だけ控えておく、という運用は詰むのでやってはいけない。元ファイルの保管は別途自分で行う。

補足

  • Amazon Bedrock / Google Vertex AI では Files API は使えない(2026-09 時点)。Anthropic API を直接叩いている場合のみ
  • PDF のページ上限(600 ページ、200K コンテキストのモデルは 100 ページ)は Base64 送信のときと同じく適用される
  • document ブロックに "citations": {"enabled": True} を付ければ引用機能もそのまま併用できる

まとめ

  • Files API は「一度アップロードして file_id で使い回す」仕組み。同じファイルへの複数質問で特に効く
  • beta 指定 files-api-2025-04-14 はアップロードと Messages の両方に必要
  • ブロック型(document / image)は MIME タイプと一致させる
  • アップロードしたファイルは再取得不可。元ファイルは自分で保管する
  • 操作は無料、課金は参照時の入力トークンのみ。使い終わったら delete でストレージを空ける
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?