Claude マニュアル

API 入門 — Claude をアプリに組み込む

Anthropic の Claude API を使えば、自分のアプリケーションやサービスに Claude の AI 能力を組み込めます。チャット UI ではできない、バックエンド処理の自動化や独自インターフェースの構築、大量テキストの一括処理など、さまざまな可能性が広がります。

この記事では、API キーの取得から実際のリクエスト送信、Function Calling、ストリーミング、コスト最適化まで、実践的な内容を Python と TypeScript のコード例で解説します。

API の概要

エンドポイント体系

Claude API のベース URL は https://api.anthropic.com/v1 です。主なエンドポイントは以下のとおりです。

エンドポイント用途
POST /v1/messagesテキスト生成(最も基本的な API)
POST /v1/messages/batchesバッチ処理(大量リクエストを非同期処理)
POST /v1/messages/count_tokensトークン数の事前カウント

API キーの取得

Anthropic Console にアクセスし、アカウントを作成します。「API Keys」セクションで新しいキーを生成できます。

API キーは厳重に管理してください。 API キーが漏洩すると、第三者があなたのアカウントでリクエストを送り、費用が発生します。以下のルールを守ってください。

  • API キーをソースコードにハードコーディングしない
  • Git リポジトリ(特に公開リポジトリ)にコミットしない
  • .env ファイルは .gitignore に追加する
  • 本番環境では環境変数や Secret Manager(AWS Secrets Manager、Google Secret Manager 等)を使う

レート制限

Claude API にはリクエスト数(RPM)とトークン数(TPM)のレート制限があります。制限値はアカウントの利用状況や Tier によって異なります。制限に達した場合、API は 429 Too Many Requests を返します。

つまづきポイント: 本番アプリで 429 エラーが頻発する場合は、指数バックオフ(リトライ間隔を徐々に延ばす)で再試行するロジックを組み込んでください。Anthropic の公式 SDK にはこの機能が組み込まれています。

クイックスタート

SDK のインストール

まず、Anthropic の公式 SDK をインストールします。

Python:

pip install anthropic

TypeScript / Node.js:

npm install @anthropic-ai/sdk

環境変数の設定

API キーを環境変数に設定します。

export ANTHROPIC_API_KEY="sk-ant-..."

本番アプリでは .env ファイルを使い、.gitignore に追加することを推奨します。

# .env
ANTHROPIC_API_KEY=sk-ant-...

最初のリクエスト

Python:

import anthropic

client = anthropic.Anthropic()

message = client.messages.create(
    model="claude-opus-4-6",
    max_tokens=1024,
    messages=[
        {"role": "user", "content": "Hello, Claude!"}
    ]
)

print(message.content[0].text)

TypeScript:

import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

const message = await client.messages.create({
  model: "claude-opus-4-6",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Hello, Claude!" }],
});

console.log(message.content[0].text);

cURL(API の動作確認に便利):

curl https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-opus-4-6",
    "max_tokens": 1024,
    "messages": [
      {"role": "user", "content": "Hello, Claude!"}
    ]
  }'

レスポンスは以下のような JSON 形式で返ってきます。

{
  "id": "msg_01XFDUDYJgAACzvnptvVoYEL",
  "type": "message",
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "Hello! How can I assist you today?"
    }
  ],
  "model": "claude-opus-4-6",
  "stop_reason": "end_turn",
  "usage": {
    "input_tokens": 10,
    "output_tokens": 12
  }
}

Messages API の基本

リクエストパラメータ

/v1/messages エンドポイントの主要なパラメータです。

パラメータ必須説明
model使用するモデル ID(例: claude-opus-4-6
max_tokens生成するトークンの最大数
messages会話履歴の配列(role と content のペア)
systemシステムプロンプト(モデルの役割・制約を設定)
temperature出力のランダム性(0〜1、デフォルト 1)
top_p核サンプリングのしきい値
stop_sequences生成を停止するシーケンスの配列
streamストリーミングを有効にするか(true/false

システムプロンプト

システムプロンプトを使うと、モデルに役割や制約を設定できます。

Python:

message = client.messages.create(
    model="claude-opus-4-6",
    max_tokens=1024,
    system="あなたは日本語で回答するカスタマーサポートエージェントです。丁寧かつ簡潔に回答してください。",
    messages=[
        {"role": "user", "content": "返品ポリシーを教えてください。"}
    ]
)

TypeScript:

const message = await client.messages.create({
  model: "claude-opus-4-6",
  max_tokens: 1024,
  system:
    "あなたは日本語で回答するカスタマーサポートエージェントです。丁寧かつ簡潔に回答してください。",
  messages: [{ role: "user", content: "返品ポリシーを教えてください。" }],
});

マルチターン会話

会話の履歴を messages 配列に積み上げることでマルチターン会話を実現します。

Python:

conversation_history = []

def chat(user_message: str) -> str:
    conversation_history.append({
        "role": "user",
        "content": user_message
    })

    response = client.messages.create(
        model="claude-opus-4-6",
        max_tokens=1024,
        messages=conversation_history
    )

    assistant_message = response.content[0].text
    conversation_history.append({
        "role": "assistant",
        "content": assistant_message
    })

    return assistant_message

# 使用例
print(chat("自己紹介してください。"))
print(chat("あなたの得意なことは何ですか?"))

TypeScript:

const conversationHistory: { role: "user" | "assistant"; content: string }[] =
  [];

async function chat(userMessage: string): Promise<string> {
  conversationHistory.push({ role: "user", content: userMessage });

  const response = await client.messages.create({
    model: "claude-opus-4-6",
    max_tokens: 1024,
    messages: conversationHistory,
  });

  const assistantMessage = (response.content[0] as { text: string }).text;
  conversationHistory.push({ role: "assistant", content: assistantMessage });

  return assistantMessage;
}

// 使用例
console.log(await chat("自己紹介してください。"));
console.log(await chat("あなたの得意なことは何ですか?"));

つまづきポイント: 会話履歴を蓄積し続けると、いずれかのリクエストでコンテキストウィンドウの上限(モデルによって異なり、Claude Opus 4.6 / Sonnet 4.6 は最大 100 万トークン、Haiku 4.5 は 200K トークン)を超えます。長期的な会話では、古いメッセージを削除するか、要約してから新しいリクエストに渡す設計が必要です。

temperature の使い分け

temperature は出力の多様性を制御します。

temperature向いている用途
0.0分析、分類、事実確認(決定論的な出力が必要な場合)
0.3〜0.7チャットボット、Q&A(バランスの取れた出力)
0.8〜1.0創作、ブレインストーミング(多様な出力が欲しい場合)

Function Calling(ツール使用)

Function Calling(ツール使用)は、Claude に外部関数やツールを呼び出す能力を与える機能です。例えば、現在の天気情報の取得、データベースの検索、計算処理など、Claude 単体ではできない処理を組み込めます。

実行フロー

  1. アプリが「ツール定義」を含むリクエストを送る
  2. Claude がツールを呼び出す必要があると判断したら tool_use ブロックを返す
  3. アプリが実際の関数を実行し、結果を Claude に返す
  4. Claude が結果を使って最終的な回答を生成する

ツール定義の書き方

Python:

tools = [
    {
        "name": "get_weather",
        "description": "指定した都市の現在の天気情報を取得します。",
        "input_schema": {
            "type": "object",
            "properties": {
                "city": {
                    "type": "string",
                    "description": "天気を調べる都市名(例: 東京、大阪)"
                },
                "unit": {
                    "type": "string",
                    "enum": ["celsius", "fahrenheit"],
                    "description": "温度の単位"
                }
            },
            "required": ["city"]
        }
    }
]

response = client.messages.create(
    model="claude-opus-4-6",
    max_tokens=1024,
    tools=tools,
    messages=[
        {"role": "user", "content": "東京の今日の天気を教えてください。"}
    ]
)

# ツール呼び出しが返された場合の処理
if response.stop_reason == "tool_use":
    tool_use_block = next(
        block for block in response.content if block.type == "tool_use"
    )
    tool_name = tool_use_block.name
    tool_input = tool_use_block.input
    tool_use_id = tool_use_block.id

    # 実際のツール処理(ここでは仮のレスポンス)
    if tool_name == "get_weather":
        tool_result = {
            "temperature": 22,
            "condition": "晴れ",
            "humidity": 60
        }

    # ツール実行結果を Claude に返す
    final_response = client.messages.create(
        model="claude-opus-4-6",
        max_tokens=1024,
        tools=tools,
        messages=[
            {"role": "user", "content": "東京の今日の天気を教えてください。"},
            {"role": "assistant", "content": response.content},
            {
                "role": "user",
                "content": [
                    {
                        "type": "tool_result",
                        "tool_use_id": tool_use_id,
                        "content": str(tool_result)
                    }
                ]
            }
        ]
    )
    print(final_response.content[0].text)

TypeScript:

const tools: Anthropic.Messages.Tool[] = [
  {
    name: "get_weather",
    description: "指定した都市の現在の天気情報を取得します。",
    input_schema: {
      type: "object",
      properties: {
        city: {
          type: "string",
          description: "天気を調べる都市名(例: 東京、大阪)",
        },
        unit: {
          type: "string",
          enum: ["celsius", "fahrenheit"],
          description: "温度の単位",
        },
      },
      required: ["city"],
    },
  },
];

const response = await client.messages.create({
  model: "claude-opus-4-6",
  max_tokens: 1024,
  tools,
  messages: [{ role: "user", content: "東京の今日の天気を教えてください。" }],
});

if (response.stop_reason === "tool_use") {
  const toolUseBlock = response.content.find(
    (block): block is Anthropic.Messages.ToolUseBlock =>
      block.type === "tool_use"
  )!;

  // 実際のツール処理(ここでは仮のレスポンス)
  const toolResult = { temperature: 22, condition: "晴れ", humidity: 60 };

  const finalResponse = await client.messages.create({
    model: "claude-opus-4-6",
    max_tokens: 1024,
    tools,
    messages: [
      { role: "user", content: "東京の今日の天気を教えてください。" },
      { role: "assistant", content: response.content },
      {
        role: "user",
        content: [
          {
            type: "tool_result",
            tool_use_id: toolUseBlock.id,
            content: JSON.stringify(toolResult),
          },
        ],
      },
    ],
  });
  console.log(finalResponse.content[0]);
}

つまづきポイント: stop_reason"tool_use" でも "end_turn" でもない場合(例: "max_tokens")は、tool_use ブロックがないままに生成が打ち切られています。max_tokens を増やすか、ツールの呼び出しが必要かを事前に判断するロジックを追加してください。

ストリーミング

ストリーミングを使うと、レスポンスが完全に生成される前にトークンを逐次受け取れます。チャットアプリや長文生成で、ユーザーが結果を待ち続けることなくリアルタイムに表示できます。

Claude API は SSE(Server-Sent Events)形式でストリーミングをサポートしています。

Python:

with client.messages.stream(
    model="claude-opus-4-6",
    max_tokens=1024,
    messages=[
        {"role": "user", "content": "量子コンピュータについて詳しく説明してください。"}
    ]
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)
    print()  # 最後に改行

# ストリーム完了後に最終メッセージを取得
final_message = stream.get_final_message()
print(f"\nトークン使用量: {final_message.usage}")

TypeScript:

const stream = await client.messages.stream({
  model: "claude-opus-4-6",
  max_tokens: 1024,
  messages: [
    {
      role: "user",
      content: "量子コンピュータについて詳しく説明してください。",
    },
  ],
});

for await (const chunk of stream) {
  if (
    chunk.type === "content_block_delta" &&
    chunk.delta.type === "text_delta"
  ) {
    process.stdout.write(chunk.delta.text);
  }
}

// ストリーム完了後に最終メッセージを取得
const finalMessage = await stream.getFinalMessage();
console.log("\nトークン使用量:", finalMessage.usage);

Next.js での Server-Sent Events 実装例

TypeScript(Next.js App Router):

// app/api/chat/route.ts
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

export async function POST(req: Request) {
  const { messages } = await req.json();

  const encoder = new TextEncoder();

  const stream = new ReadableStream({
    async start(controller) {
      const anthropicStream = await client.messages.stream({
        model: "claude-opus-4-6",
        max_tokens: 1024,
        messages,
      });

      for await (const chunk of anthropicStream) {
        if (
          chunk.type === "content_block_delta" &&
          chunk.delta.type === "text_delta"
        ) {
          controller.enqueue(encoder.encode(chunk.delta.text));
        }
      }
      controller.close();
    },
  });

  return new Response(stream, {
    headers: { "Content-Type": "text/plain; charset=utf-8" },
  });
}

Extended Thinking(拡張思考)

Extended Thinking は、Claude が最終的な回答を出す前に内部的に思考プロセスを展開する機能です。複雑な数学問題、多段階の推論、詳細な分析など、高精度が求められるタスクで特に効果を発揮します。

thinking パラメータに budget_tokens(思考に使えるトークンの最大数)を指定して有効化します。

Python:

response = client.messages.create(
    model="claude-opus-4-6",
    max_tokens=16000,
    thinking={
        "type": "enabled",
        "budget_tokens": 10000  # 思考プロセスに使えるトークン数
    },
    messages=[
        {
            "role": "user",
            "content": "次の数学の証明を行ってください: 素数が無限に存在することを証明してください。"
        }
    ]
)

# レスポンスには thinking ブロックと text ブロックが含まれる
for block in response.content:
    if block.type == "thinking":
        print("=== 思考プロセス ===")
        print(block.thinking)
    elif block.type == "text":
        print("=== 最終回答 ===")
        print(block.text)

TypeScript:

const response = await client.messages.create({
  model: "claude-opus-4-6",
  max_tokens: 16000,
  thinking: {
    type: "enabled",
    budget_tokens: 10000,
  },
  messages: [
    {
      role: "user",
      content:
        "次の数学の証明を行ってください: 素数が無限に存在することを証明してください。",
    },
  ],
});

for (const block of response.content) {
  if (block.type === "thinking") {
    console.log("=== 思考プロセス ===");
    console.log(block.thinking);
  } else if (block.type === "text") {
    console.log("=== 最終回答 ===");
    console.log(block.text);
  }
}

Extended Thinking は claude-opus-4-6 などの対応モデルでのみ利用できます。budget_tokens を大きくするほど推論精度が上がりますが、その分コストも増加します。用途に応じて適切な値を設定してください。

バッチ処理

大量のリクエストを処理する場合、Message Batches API を使うと効率的です。通常の API と比べて最大 50% のコスト削減が可能で、非同期でバックグラウンド処理されます。

バッチリクエストの送信

Python:

# バッチジョブの作成
batch = client.messages.batches.create(
    requests=[
        {
            "custom_id": "request-1",
            "params": {
                "model": "claude-opus-4-6",
                "max_tokens": 1024,
                "messages": [
                    {"role": "user", "content": "東京について教えてください。"}
                ]
            }
        },
        {
            "custom_id": "request-2",
            "params": {
                "model": "claude-opus-4-6",
                "max_tokens": 1024,
                "messages": [
                    {"role": "user", "content": "大阪について教えてください。"}
                ]
            }
        }
    ]
)

print(f"バッチ ID: {batch.id}")
print(f"ステータス: {batch.processing_status}")

TypeScript:

const batch = await client.messages.batches.create({
  requests: [
    {
      custom_id: "request-1",
      params: {
        model: "claude-opus-4-6",
        max_tokens: 1024,
        messages: [{ role: "user", content: "東京について教えてください。" }],
      },
    },
    {
      custom_id: "request-2",
      params: {
        model: "claude-opus-4-6",
        max_tokens: 1024,
        messages: [{ role: "user", content: "大阪について教えてください。" }],
      },
    },
  ],
});

console.log(`バッチ ID: ${batch.id}`);
console.log(`ステータス: ${batch.processing_status}`);

バッチ結果の取得

バッチが完了するまで数分〜数時間かかる場合があります。ポーリングで状態を確認します。

Python:

import time

# バッチの完了待ち(ポーリング)
while True:
    batch = client.messages.batches.retrieve(batch.id)
    if batch.processing_status == "ended":
        break
    print(f"処理中... ({batch.request_counts.processing} 件残り)")
    time.sleep(60)  # 1分待って再確認

# 結果の取得
for result in client.messages.batches.results(batch.id):
    print(f"ID: {result.custom_id}")
    if result.result.type == "succeeded":
        print(result.result.message.content[0].text)
    else:
        print(f"エラー: {result.result.error}")

つまづきポイント: バッチ処理は最大 24 時間以内に完了しますが、それを超えるとタイムアウトします。処理件数が多い場合は複数の小さなバッチに分割することを検討してください。1 バッチあたりの最大リクエスト数は 10,000 件です。

コスト最適化

料金体系(概要)

Claude の API 料金は入力トークン数と出力トークン数に応じた従量課金制です。以下は 2026 年 3 月時点の目安です。最新の料金は必ず Anthropic の公式料金ページ で確認してください。

モデル入力(100万トークンあたり)出力(100万トークンあたり)特徴
Claude Haiku 4.5$1.00$5.00最速・最低コスト。シンプルなタスク向け
Claude Sonnet 4.6$3.00$15.00性能とコストのバランスが優れる
Claude Opus 4.6$5.00$25.00最高性能。複雑な推論・分析向け

上記の料金は目安です。Anthropic は料金を変更することがあります。実際の料金は https://www.anthropic.com/pricing で確認してください。

Prompt Caching でコストを削減

Prompt Caching は、繰り返し使う長いシステムプロンプトやコンテキストをキャッシュする機能です。キャッシュヒット時は入力トークンのコストが大幅に削減されます(約 90% オフ)。

長いシステムプロンプト、大量のドキュメント参照、Few-shot 例の繰り返しなど、毎回同じ内容を送るケースで効果的です。

Python:

response = client.messages.create(
    model="claude-opus-4-6",
    max_tokens=1024,
    system=[
        {
            "type": "text",
            "text": "あなたは日本の法律に精通した専門家AIアシスタントです。\n\n" + very_long_legal_document,  # 長い参照ドキュメント
            "cache_control": {"type": "ephemeral"}  # キャッシュを有効化
        }
    ],
    messages=[
        {"role": "user", "content": "第3条の解釈を教えてください。"}
    ]
)

# キャッシュの使用状況を確認
print(f"キャッシュ書き込みトークン: {response.usage.cache_creation_input_tokens}")
print(f"キャッシュ読み込みトークン: {response.usage.cache_read_input_tokens}")

モデル選定のガイドライン

ユースケース推奨モデル理由
分類・ルーティング・シンプルな Q&AClaude Haiku 4.5速度とコストを重視
チャットボット・文章生成・コード補完Claude Sonnet 4.6バランスが最も優れる
複雑な推論・分析・研究Claude Opus 4.6精度最優先
バッチ処理(大量の単純タスク)Claude Haiku 4.5低コストで大量処理

トークン数を事前に確認する

リクエストを送る前に、/v1/messages/count_tokens でトークン数を確認できます。

Python:

token_count = client.messages.count_tokens(
    model="claude-opus-4-6",
    messages=[
        {"role": "user", "content": "このリクエストは何トークンですか?"}
    ]
)
print(f"入力トークン数: {token_count.input_tokens}")

次のステップ

Claude API の基本を理解できたら、さらに活用の幅を広げましょう。