Claude API(Anthropic SDK)入門:最初のリクエストからツール利用・プロンプトキャッシュまで
Anthropic の Claude API(Messages API)を、公式 SDK を使って一通り触るためのハンズオンです。環境構築から、最初のリクエスト、ストリーミング、システムプロンプト、マルチターン会話、ツール利用、プロンプトキャッシュ、エラーハンドリングまでを順に解説します。Python と TypeScript の両方でサンプルを示します。
本記事は公開ドキュメントの仕様に基づく一般的な解説です。料金・レート制限・モデル識別子は変動するため、本番利用の前に必ず公式ドキュメントで最新値を確認してください。
環境
- Python 3.9 以上 もしくは Node.js 18 以上
- Anthropic のアカウントと API キー
- 公式 SDK:
anthropic(Python)/@anthropic-ai/sdk(TypeScript)
インストール
pip install anthropic # または npm install @anthropic-ai/sdk
API キーの扱い
API キーはコードに直書きせず、環境変数に置きます。.env は必ず .gitignore に入れてください。SDK は既定で環境変数 ANTHROPIC_API_KEY を読み込みます。
export ANTHROPIC_API_KEY="sk-ant-..."
1. 最初のリクエスト
Claude API の中心は Messages API です。messages に会話履歴を配列で渡し、応答を受け取ります。
import anthropic
client = anthropic.Anthropic() # 環境変数 ANTHROPIC_API_KEY を自動で読む
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[
{"role": "user", "content": "こんにちは。あなたは何ができますか?"}
],
)
print(message.content[0].text)
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const message = await client.messages.create({
model: "claude-sonnet-4-6",
max_tokens: 1024,
messages: [{ role: "user", content: "こんにちは。あなたは何ができますか?" }],
});
const first = message.content[0];
if (first.type === "text") {
console.log(first.text);
}
ここで押さえるポイント
max_tokensは必須です。これは生成する応答の最大トークン数であり、入力側の上限ではありません。- レスポンスの
contentはブロックの配列です。テキスト応答はtype: "text"、ツール利用ではtype: "tool_use"のブロックが混在します。 message.stop_reasonで応答の終了理由(end_turn/max_tokens/tool_useなど)が分かります。message.usageに入力・出力トークン数が入ります。コスト計算やキャッシュ効果の確認に使います。
モデルの選び方
| 用途 | 傾向 | 識別子の例 |
|---|---|---|
| 最高精度・複雑な推論 | Opus | claude-opus-4-8 |
| バランス(日常の主力) | Sonnet | claude-sonnet-4-6 |
| 低レイテンシ・低コスト | Haiku | claude-haiku-4-5 |
まず Sonnet で試し、精度が足りなければ Opus、速度とコストを詰めたければ Haiku、という進め方が無難です。
2. ストリーミング
チャット UI のように応答を逐次表示したい場合はストリーミングを使います。
with client.messages.stream(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "再帰について3行で説明して"}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
final = stream.get_final_message()
const stream = client.messages.stream({
model: "claude-sonnet-4-6",
max_tokens: 1024,
messages: [{ role: "user", content: "再帰について3行で説明して" }],
});
stream.on("text", (delta) => process.stdout.write(delta));
const final = await stream.finalMessage();
stream.text_stream(Python)/ on("text")(TypeScript)はテキスト差分だけを受け取る簡易インターフェースです。まずはこの簡易版で十分です。
3. システムプロンプトとマルチターン会話
役割・制約・出力形式などの指示は messages ではなく、トップレベルの system パラメータに渡します。
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system="あなたは簡潔に回答する技術アシスタントです。",
messages=[{"role": "user", "content": "Pythonで標準入力を1行読む方法は?"}],
)
会話を続けるには、これまでのやり取りをすべて messages 配列に積み直して毎回送ります。API 側は状態を保持しないため、履歴管理はアプリ側の責務です。
messages = [{"role": "user", "content": "FizzBuzzをPythonで書いて"}]
resp = client.messages.create(
model="claude-sonnet-4-6", max_tokens=1024, messages=messages
)
messages.append({"role": "assistant", "content": resp.content}) # ブロック配列をそのまま戻す
messages.append({"role": "user", "content": "それを関数に切り出して"})
resp2 = client.messages.create(
model="claude-sonnet-4-6", max_tokens=1024, messages=messages
)
print(resp2.content[0].text)
assistant の応答を履歴に戻すときは resp.content(ブロック配列)をそのまま入れます。文字列に潰すとツール利用などの情報が落ちます。
4. ツール利用(tool use)
外部処理を Claude に使わせる機能です。流れは次の通りです。
- アプリが
tools(関数の定義)を添えてリクエスト - Claude が
tool_useブロックで呼び出しを要求 - アプリが実際に処理を実行し、結果を
tool_resultとして返す - Claude が結果を踏まえて最終応答を返す
tools = [
{
"name": "get_weather",
"description": "指定都市の現在の天気を取得する",
"input_schema": {
"type": "object",
"properties": {"city": {"type": "string", "description": "都市名"}},
"required": ["city"],
},
}
]
messages = [{"role": "user", "content": "東京の天気は?"}]
resp = client.messages.create(
model="claude-sonnet-4-6", max_tokens=1024, tools=tools, messages=messages
)
if resp.stop_reason == "tool_use":
tool_use = next(b for b in resp.content if b.type == "tool_use")
result = {"temperature": 18, "condition": "晴れ"} # 実処理のダミー
messages.append({"role": "assistant", "content": resp.content})
messages.append({
"role": "user",
"content": [{
"type": "tool_result",
"tool_use_id": tool_use.id,
"content": str(result),
}],
})
final = client.messages.create(
model="claude-sonnet-4-6", max_tokens=1024, tools=tools, messages=messages
)
print(final.content[0].text)
input_schemaは JSON Schema です。requiredと型を明示すると引数の抜け漏れが減ります。tool_resultのtool_use_idは、Claude が返したtool_use.idと一致させます。- 複数ツールが並列に要求されることもあるので、
tool_useブロックはループで全部処理するのが安全です。
5. プロンプトキャッシュ
長いシステムプロンプトや大きな参照ドキュメントを使い回す場合、プロンプトキャッシュでコストとレイテンシを削減できます。キャッシュ対象のブロックに cache_control を付けます。
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system=[
{"type": "text", "text": "あなたは社内規程アシスタントです。"},
{"type": "text", "text": LARGE_DOCUMENT, "cache_control": {"type": "ephemeral"}},
],
messages=[{"role": "user", "content": "有給の繰越ルールは?"}],
)
print(message.usage) # cache_creation / cache_read を確認
- 変化しない大きな部分を前に置き、その末尾に
cache_controlを付けます。キャッシュはプレフィックス単位で効くため、固定部分を前、可変部分(ユーザー入力)を後ろにする構成が重要です。 - 初回はキャッシュ書き込み(やや割高)、2回目以降は読み出し(大幅に割安)になります。
usageのcache_read_input_tokensで効果を確認します。 - 最小トークン数や有効期限(TTL)の条件があるため、「長い・使い回す・変わらない」ものに絞って使います。
6. エラーハンドリング
import anthropic
client = anthropic.Anthropic()
try:
resp = client.messages.create(
model="claude-sonnet-4-6", max_tokens=1024,
messages=[{"role": "user", "content": "テスト"}],
)
except anthropic.RateLimitError:
... # 429。指数バックオフでリトライ
except anthropic.APIStatusError as e:
print(e.status_code, e.response) # 4xx / 5xx
except anthropic.APIConnectionError:
... # ネットワーク系
stop_reason == "max_tokens" は応答が途中で切れているサインです。UI 上は「続きを生成」などの導線を用意すると親切です。
確認方法
- 最初のリクエストが返り、
message.content[0].textに日本語応答が入ること。 - ストリーミングで文字が逐次流れること。
- ツール利用で
stop_reason == "tool_use"になり、tool_resultを返した後に最終応答が返ること。 - プロンプトキャッシュで、2回目の
usageにcache_read_input_tokensが計上されること。
注意点
- API キーはサーバ側でのみ扱います。ブラウザから直接 Claude API を叩くとキーが露出するため、必ずバックエンド経由にします。
messagesは毎回全履歴を送る方式なので、会話が長くなるとコストが増えます。要約・古い履歴の切り捨て・プロンプトキャッシュの併用で制御します。- モデル識別子・料金・レート制限は変わりうるため、1か所に集約して切り替えやすくしておきます。
まとめ
Claude API は Messages API ひとつを軸に、ストリーミング・ツール利用・プロンプトキャッシュまで一貫して扱えます。入門としては「最初のリクエスト → ストリーミング → ツール利用 → キャッシュ」の順で触ると全体像がつかめます。まず Sonnet で動かし、要件に応じてモデルを切り替えていくのが実務的な進め方です。
