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 2026-10-21の破壊的変更を自作ツールで検証——SDK 2.0でtemperatureが消えた

0
Posted at

3行まとめ

  • 2026年10月21日、Claude APIに3年ぶりの新しいAPIバージョン 2026-10-21 が出た。temperature / top_p / top_k は既定値でも400エラー、SDKはAPIキーを Authorization: Bearer で送るようになり、MessageParam は役割ごとの型のunionに変わった
  • 新しいメジャーのSDK(Python 2.0.0、TypeScript 1.0.0など)は既定で 2026-10-21 を送る。Python SDK 0.97.0 と 2.3.0 をモックのHTTPトランスポートで比べると、送信ヘッダも temperature の扱いも実際に変わっていた
  • 自作の投資分析ツール RakuScan を棚卸しすると、APIの破壊的変更に当たる箇所はゼロ。ただし anthropic>=0.97.0 と上限なしで書いていたため、ロックを更新すると間の1.x系をまたいで2.3.0まで上がる。1.0.0で入った**httpx → httpx2 の入れ替え**も同時に踏むことがわかった

2026年10月21日、AnthropicがClaude APIの新バージョン 2026-10-21 をリリースした。APIバージョンが上がるのは 2023-06-01 以来で、約3年ぶりになる。

2023-06-01 も引き続き指定でき、移行ガイドでも「既定値以外の temperature に頼るリクエストは 2023-06-01 に残す」という選択肢が示されている。ただし、各言語のSDKも同時にメジャーバージョンが上がり、新しいSDKは既定で 2026-10-21 を送る。依存を更新しただけで挙動が変わるタイプの変更なので、自分のコードのどこが影響を受けるかを先に確認しておきたい。

この記事では、移行ガイドの破壊的変更を整理したうえで、Python SDKの新旧を実際に動かして差分を確かめ、Claude APIを使っている自作ツールRakuScanのコードを棚卸しした結果をまとめる。

破壊的変更の一覧

移行ガイドの内容を、APIの変更とSDK/CLIの変更に分けて整理する。

APIの変更(2026-10-21 を送ると変わる)

変更 影響を受ける書き方
サンプリングパラメータの削除 temperature / top_p / top_k を送ると、既定値でも400エラー。Message Batchesとトークンカウントも同様
assistantメッセージのdocumentブロック assistant メッセージに直接 document ブロックを置くと400エラー。user メッセージに置く
userメッセージのcitations user メッセージの text ブロックに空でない citations を付けると400エラー(search_result 内も含む)
Admin API / Analytics APIのフィールド名 actor.email → actor.email_address、APIキーの workspace_id → scope.workspace_id など。旧名は返らなくなる

一番影響が大きいのはサンプリングパラメータだろう。移行ガイドによると、パラメータを省略したリクエストは temperature 1.0 などの既定値でサンプリングされる。Claude 4.7以降のモデルはもともと既定値しか受け付けないので、挙動は変わらない。一方、Claude Sonnet 4.6のように別の値を受け付けるモデルで temperature を下げて出力を安定させていた場合、その効果はなくなり、代わりになる設定もない。どうしても必要なら、そのリクエストだけ 2023-06-01 に残すことになる。

SDK / CLIの変更(新しいSDKに上げると変わる)

変更 内容
APIバージョン 新SDKは anthropic-version: 2026-10-21 を送る。上の変更がすべて適用される
認証ヘッダ APIキーを X-Api-Key ではなく Authorization: Bearer <key> で送る。APIは両方受け付けるが、X-Api-Key を見ているプロキシやログフィルタは影響を受ける
MessageParam UserMessageParam / AssistantMessageParam / SystemMessageParam のunionになった。Pythonでは MessageParam(...) と呼ぶと TypeError。dictリテラルはそのまま使える
Text Completions TypeScript / Go / Java / Ruby SDKとCLIから削除(Python SDKからは1.0.0の時点で削除済み)
Models APIの betas 非betaの client.models.list() などから削除。client.beta.models を使う
ライセンス MITからApache 2.0へ

新しいAPIバージョンを最初に送るSDKのバージョンは、Python anthropic 2.0.0、TypeScript @anthropic-ai/sdk 1.0.0、Go 2.0.0、Java 3.0.0、C# 13.0.0、PHP 1.0.0、Ruby 2.0.0、ant CLI 2.0.0。Amazon Bedrockでは、2026-10-21 を使えるのはClaude 4.7以降のモデルだけという制約もある。

Python SDKの新旧を実際に比べる

ドキュメントを読むだけでは実感がわかないので、Python SDKの0.97.0(RakuScanのロックファイルにある版)と、記事執筆時点の最新2.3.0を並べて動かした。実際のAPIは呼ばず、MockTransport で送信リクエストを捕まえてダミーのレスポンスを返す。

import anthropic, inspect

try:
    import httpx2 as hx  # 1.0.0以降は httpx2 に依存している
except ImportError:
    import httpx as hx

captured = {}

def handler(req):
    captured["headers"] = {
        k: v for k, v in req.headers.items()
        if k.lower() in ("anthropic-version", "x-api-key", "authorization")
    }
    return hx.Response(200, json={
        "id": "msg_x", "type": "message", "role": "assistant", "model": "m",
        "content": [{"type": "text", "text": "ok"}],
        "stop_reason": "end_turn", "stop_sequence": None,
        "usage": {"input_tokens": 1, "output_tokens": 1},
    })

client = anthropic.Anthropic(
    api_key="sk-ant-dummy",
    http_client=anthropic.DefaultHttpxClient(transport=hx.MockTransport(handler)),
)
client.messages.create(model="claude-haiku-4-5-20251001", max_tokens=10,
                       messages=[{"role": "user", "content": "hi"}])
print("headers", captured["headers"])
print("temperature in signature:", "temperature" in inspect.signature(client.messages.create).parameters)
# 以降、temperature=0.2 を付けた呼び出しと MessageParam(...) の生成も試す

uv run --isolated --with "anthropic==<版>" でバージョンを切り替えて実行した結果がこれ。

## 0.97.0
headers {'x-api-key': 'sk-ant-dummy', 'anthropic-version': '2023-06-01'}
temperature in signature: True
temperature call: OK
MessageParam(): OK

## 2.3.0
headers {'authorization': 'Bearer sk-ant-dummy', 'anthropic-version': '2026-10-21'}
temperature in signature: False
temperature call: TypeError Messages.create() got an unexpected keyword argument 'temperature'
MessageParam(): TypeError Cannot instantiate typing.Union

ドキュメントどおり、2.3.0では次の3点が変わっていた。

  • anthropic-version が 2026-10-21 になり、APIキーは Authorization: Bearer で送られる
  • temperature は引数から消えていて、APIに届く前にPython側で TypeError になる
  • MessageParam(role=..., content=...) は TypeError になる

temperature は「APIが400を返す」より手前の、SDKの引数の段階で落ちる。どこかで temperature=0 を渡しているコードは、SDKを上げた瞬間に例外を投げるので、テストがあれば気づける。注意したいのは extra_body={"temperature": 0} のようにSDKの引数チェックを通さずに渡しているケースで、こちらはSDKでは落ちず、APIの400エラーで初めてわかる。

RakuScanを棚卸しする

RakuScanは、日本株のスクリーニング結果をClaudeに渡して統合分析させる自分用のツールだ。Claude APIを呼んでいるのは2か所だけなので、全部見た。

呼び出し箇所:破壊的変更に当たるものはなかった

1か所目は日次レポートの統合分析 src/notify/claude_analyzer.py。

src/notify/claude_analyzer.py
client = anthropic.Anthropic(api_key=cfg.anthropic_api_key())
response = client.messages.create(
    model=cfg.claude_model_daily(),
    max_tokens=8192,
    system=[
        {
            "type": "text",
            "text": skill_content,
            "cache_control": {"type": "ephemeral"},
        }
    ],
    messages=[{"role": "user", "content": slim_json}],
)

2か所目はDiscord Botからの問い合わせ応答 src/discord_bot/bot.py。こちらは system を使わずタイムアウトを指定している違いはあるが、同様に messages はdictリテラルで、temperature などのサンプリングパラメータは送っていない。

チェックリストに当てはめるとこうなる。

確認項目 RakuScan
temperature / top_p / top_k 送っていない
MessageParam(...) のコンストラクタ呼び出し なし(dictリテラルのみ)
assistantメッセージのdocument / userメッセージのcitations 使っていない
X-Api-Key を見るプロキシ・ログフィルタ なし(APIを直接呼ぶ)
Admin API / Text Completions / Models APIの betas 使っていない

使っているモデルは、日次分析が claude-haiku-4-5-20251001、Bot応答が claude-sonnet-4-6(どちらも src/core/config.py の既定値)。どちらもClaude 4.7より前のモデルで temperature の値を変えられるが、RakuScanはもともと送っていないので挙動も変わらない。

ひとつ別件として気をつけたいのが、response.content[0].text で先頭のブロックを読んでいる箇所だ。これは 2026-10-21 とは関係ないが、思考(thinking)がデフォルトで有効なモデルに切り替えると、先頭が思考ブロックになって壊れる。詳しくはHaiku 5.5の記事に書いた。

本当の注意点は依存の指定だった

コード側は無傷だったが、依存の書き方には穴があった。pyproject.toml はこうなっている。

pyproject.toml
dependencies = [
    "anthropic>=0.97.0",
    # ...
]

上限がないので、ロックを更新すれば最新のメジャーまで一気に上がる。uv lock のドライランで確かめた。

uv lock --upgrade-package anthropic --dry-run
Resolved 62 packages in 164ms
Update anthropic v0.97.0 -> v2.3.0
Remove distro v1.9.0
Remove httpcore v1.0.9
Add httpcore2 v2.16.0
Remove httpx v0.28.1
Add httpx2 v2.16.0
Add httpx2-jsfetch v1.0
Update idna v3.11 -> v3.20
Add opentelemetry-api v1.45.1
Add truststore v0.10.5

0.97.0から2.3.0へ、間の1.x系をまたいで2メジャー分上がる。目を引くのは、httpx がロックから消えて httpx2 に入れ替わる点だ。PyPIの依存情報を見ると、これは 2026-10-21 対応の2.0.0ではなく、2026年8月20日の1.0.0で入った変更だった(0.125.0は httpx<1,>=0.25.0、1.0.0は httpx2<3,>=2.0.0 に依存)。RakuScanの環境に入っていた httpx は、anthropic が間接的に入れていたものだ。自分のコードで import httpx を書いていないことは grep で確認したので今回は問題ない。ただ、もし「anthropicが入れてくれているから」と httpx を直接importしていたら、ロック更新で ModuleNotFoundError になっていた。

SDKのCHANGELOGとMIGRATION.mdを見ると、1.0.0の破壊的変更として httpx2 への移行がきちんと書かれている。ただ、2026-10-21 の移行ガイドだけを読んでいると、この変更には気づけない。メジャーを複数またぐときは、間のメジャーの移行ガイドも読む必要がある。ロックファイルの差分は、それに気づくきっかけとして役に立つ。

上げるときの手順

RakuScanではまだSDKを上げていない。上げるときは次の順で進める。

  1. 自分のコードが直接importしているパッケージを、すべて dependencies に明記する(推移的な依存に頼らない)
  2. 1.0.0と2.0.0、両方の移行ガイド(SDKのMIGRATION.mdと 2026-10-21 の移行ガイド)を確認する
  3. anthropic>=2.3.0,<3 のように上限付きで書き、uv lock --upgrade-package anthropic でロックを更新する
  4. 日次分析とBot応答をそれぞれ1回ずつ実際に動かして、レスポンスを確認する

<3 のような上限を付けておけば、次に新しいAPIバージョンとSDKのメジャーが出たときも、ロック更新で勝手にメジャーをまたがない。1.0.0のようにAPIバージョンを変えないメジャーもあるが、少なくとも今回、APIバージョンの切り替えはSDKのメジャーと同時に行われた。メジャーの上限は、APIバージョンを勝手に変えないための固定としても効く。

まとめ

  • 2026-10-21 は約3年ぶりの新APIバージョン。サンプリングパラメータの削除、documentブロックとcitationsの制約、Admin APIのフィールド名変更が入った。2023-06-01 も引き続き指定できる
  • 新しいメジャーのSDK(Python 2.0.0以降など)は既定で新バージョンを送る。Python SDK 2.3.0では、temperature を渡すと引数の段階で TypeError になり、APIキーは Authorization: Bearer で送られる
  • RakuScanのコードはAPIの破壊的変更に当たらなかった。注意点はむしろ依存の書き方で、上限なしの指定のせいで2メジャー分上がり、1.0.0で入った httpx → httpx2 の入れ替えも同時に踏む

APIの破壊的変更は移行ガイドで確認できるが、複数のメジャーをまたぐと、間のメジャーの変更も一緒に入ってくる。SDKを上げる前に --dry-run でロックの差分を見ておくと、読むべき移行ガイドの見落としに気づける。


この記事は Zenn にも同じ内容を投稿しています。

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?