Claude Agent SDK完全ガイド【TypeScript/Python】|query()・セッション管理・ストリーミング・カスタムツール・サブエージェントの実装方法

Claude Agent SDK完全ガイド【TypeScript/Python】|query()・セッション管理・ストリーミング・カスタムツール・サブエージェントの実装方法 AI開発

「Claude Codeを自社ツールに組み込みたい」「AIエージェントをAPIから制御したい」というニーズに応えるのがClaude Agent SDKです。以前は「Claude Code SDK」という名称でしたが、現在はClaude Agent SDKに改名されています。このSDKを使うとClaude Codeが持つ機能——ファイル読み書き・Bash実行・Web検索——をTypeScript/Pythonプログラムから直接制御できます。

CI/CDパイプラインへの自動コードレビュー組み込み、社内カスタムCLIツール、大規模リファクタリングの自動化など、繰り返しの開発作業をプログラム可能なエージェントで自動化できます。Claude Codeの基本操作はClaude Code完全ガイドを、headlessモードとの違いはheadlessモード完全ガイドを参照してください。

Claude Code SDK → Claude Agent SDK へ
旧名「Claude Code SDK」は現在「Claude Agent SDK」に改名されています。パッケージ名・インポートパスも変更されているため、古い記事を参考にする場合は注意してください。公式移行ガイドに移行手順が記載されています。
スポンサーリンク

インストールとセットアップ

必要条件

TypeScript Python
ランタイム Node.js 18以上 Python 3.10以上
パッケージ @anthropic-ai/claude-agent-sdk claude-agent-sdk
認証 ANTHROPIC_API_KEY環境変数 ANTHROPIC_API_KEY環境変数

インストール

TypeScript / Node.js
npm install @anthropic-ai/claude-agent-sdk

# TypeScript用の型定義は同梱されています
Python
pip install claude-agent-sdk

# Python 3.10以上が必要
python --version

APIキーの設定

SDKはデフォルトでANTHROPIC_API_KEY環境変数を参照します。AWS Bedrock・Google Vertex AI・Azure AI Foundryも対応しており、それぞれの認証情報を設定することで切り替えられます。

.env ファイル(推奨)
ANTHROPIC_API_KEY=sk-ant-xxxxx

# Bedrock を使う場合
# CLAUDE_CODE_USE_BEDROCK=1
# AWS_REGION=us-east-1

# Vertex AI を使う場合
# CLAUDE_CODE_USE_VERTEX=1
# ANTHROPIC_VERTEX_PROJECT_ID=your-project-id

基本的な使い方:query()関数

query()はClaude Agent SDKのメインエントリポイントです。プロンプトを渡すとエージェントが自律的にツールを使いながらタスクを実行し、結果を非同期イテレータとして返します。

TypeScriptの基本例

TypeScript: query()の基本
import { query } from "@anthropic-ai/claude-agent-sdk";

async function main() {
  const messages = [];

  // query() は非同期イテレータを返す
  for await (const message of query({
    prompt: "package.json を読んで、依存パッケージの概要を教えてください",
    options: {
      maxTurns: 10,         // エージェントの最大ターン数
      permissionMode: "acceptEdits",  // ファイル編集を自動承認
    },
  })) {
    messages.push(message);

    // メッセージの種類に応じて処理
    if (message.type === "assistant") {
      for (const block of message.message.content) {
        if (block.type === "text") {
          console.log(block.text);
        }
      }
    }
  }
}

main().catch(console.error);

Pythonの基本例

Python: query()の基本
import asyncio
from claude_agent_sdk import query, ClaudeCodeOptions

async def main():
    messages = []

    async for message in query(
        prompt="package.json を読んで、依存パッケージの概要を教えてください",
        options=ClaudeCodeOptions(
            max_turns=10,
            permission_mode="acceptEdits",
        ),
    ):
        messages.append(message)

        if message.type == "assistant":
            for block in message.message.content:
                if block.type == "text":
                    print(block.text)

asyncio.run(main())

メッセージの種類

メッセージタイプ 内容
user ユーザーのプロンプト(最初のメッセージ)
assistant Claudeの応答。content配列にtexttool_useブロックが含まれる
tool_result ツール実行結果。Read/Bash/Editなどの実行後に自動挿入される
result セッション終了時のサマリー(cost・duration・最終メッセージ等を含む)

パーミッションモードの設定

エージェントがどのツールをどの範囲で使えるかはpermissionModeで制御します。セキュリティと自動化の度合いのバランスを用途に合わせて選択してください。

モード 動作 用途
default canUseToolコールバックで操作ごとに判断 対話的な操作・細かい制御が必要な場合
acceptEdits ファイル編集(Read/Write/Edit)を自動承認 自動化スクリプト・CI/CDで頻繁に使われる推奨設定
bypassPermissions 全ツールを確認なしで実行 完全自動化が必要な場合(慎重に使用)

canUseTool コールバックで細かく制御する

TypeScript: canUseToolで操作を制御
import { query, PermissionMode } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
  prompt: "src/ 以下のTypeScriptファイルを読んで改善提案をしてください",
  options: {
    permissionMode: PermissionMode.DEFAULT,
    // ツール使用前に呼ばれるコールバック
    canUseTool: async (toolName, toolInput) => {
      // 読み取り専用ツールは自動承認
      if (toolName === "Read" || toolName === "Glob" || toolName === "Grep") {
        return true;
      }
      // Bash は内容を確認してから承認
      if (toolName === "Bash") {
        const cmd = toolInput.command as string;
        const isSafe = !cmd.includes("rm") && !cmd.includes("sudo");
        if (!isSafe) {
          console.log(`ブロック: ${cmd}`);
          return false;
        }
        return true;
      }
      // その他(Write/Edit等)は確認
      console.log(`承認が必要: ${toolName} ${JSON.stringify(toolInput)}`);
      return false;
    },
  },
})) {
  // ...
}

セッション管理:マルチターン対話の実装

1回のquery()呼び出しで完結しない複雑なタスクや、複数の作業を同じコンテキストで続けたい場合にはセッション管理を使います。

ClaudeSDKClient によるマルチターン対話

Python: ClaudeSDKClientでマルチターン対話
import asyncio
from claude_agent_sdk import ClaudeSDKClient, ClaudeCodeOptions

async def main():
    # ClaudeSDKClient はセッションIDを内部管理する
    async with ClaudeSDKClient(
        options=ClaudeCodeOptions(permission_mode="acceptEdits")
    ) as client:
        # 1ターン目: コードを読む
        await client.query("src/app.ts の構造を分析してください")
        response1 = await client.receive_response()
        print("分析結果:", response1.text)

        # 2ターン目: 同じコンテキストで続ける
        await client.query("その中でリファクタリングが必要な箇所はどこですか?")
        response2 = await client.receive_response()
        print("改善提案:", response2.text)

asyncio.run(main())

セッションの continue / resume / fork

オプション 動作 用途
continue: true 最新のセッションを継続(IDなしで再開) 前回の作業を引き続き進める
resume: sessionId 特定のセッションIDで再開 特定の作業に戻る・並列作業の切り替え
forkSession: sessionId 既存セッションを分岐して別コンテキストで試行 失敗したアプローチをリセットせずに別案を試す
TypeScript: セッションの resume と fork
import { query } from "@anthropic-ai/claude-agent-sdk";

// セッションIDを保存しておく
let savedSessionId: string | undefined;

// 1回目の実行
for await (const message of query({ prompt: "バグを調査してください" })) {
  if (message.type === "result") {
    savedSessionId = message.sessionId;
  }
}

// 前回セッションを再開
for await (const message of query({
  prompt: "発見したバグを修正してください",
  options: {
    resume: savedSessionId,  // 前回の調査結果を引き継ぐ
  },
})) {
  // ...
}

// 別アプローチを試す(セッションを分岐)
for await (const message of query({
  prompt: "別の方法で同じバグを修正してください",
  options: {
    forkSession: savedSessionId,  // 同じ調査結果から分岐
  },
})) {
  // ...
}
セッションファイルの保存場所
セッションは~/.claude/projects/<プロジェクトパス>/*.jsonlに保存されます。persistSession: false(TypeScript)を設定するとディスクに保存しません。セッション一覧はclaude --list-sessionsコマンドでも確認できます。

ストリーミングでリアルタイム出力を受け取る

デフォルトではquery()は完成したメッセージ単位で返します。includePartialMessagesを有効にするとテキストが生成されるたびにイベントが流れ、ユーザーへのリアルタイム表示が可能になります。

TypeScript: ストリーミング処理
import { query, StreamEvent } from "@anthropic-ai/claude-agent-sdk";

for await (const event of query({
  prompt: "README.md の内容をもとに詳しいドキュメントを生成してください",
  options: {
    includePartialMessages: true,  // ストリーミングを有効化
  },
})) {
  // ストリームイベントの種類で分岐
  if (event.type === "content_block_delta") {
    if (event.delta.type === "text_delta") {
      // テキストをリアルタイムに出力
      process.stdout.write(event.delta.text);
    }
  } else if (event.type === "content_block_stop") {
    console.log(); // ブロック終了時に改行
  } else if (event.type === "result") {
    console.log(`
完了。コスト: $${event.cost_usd}`);
  }
}
Python: ストリーミング処理
import asyncio
import sys
from claude_agent_sdk import query, ClaudeCodeOptions

async def main():
    async for event in query(
        prompt="README.md の内容をもとに詳しいドキュメントを生成してください",
        options=ClaudeCodeOptions(include_partial_messages=True),
    ):
        if event.type == "content_block_delta":
            if event.delta.type == "text_delta":
                sys.stdout.write(event.delta.text)
                sys.stdout.flush()
        elif event.type == "result":
            print(f"
完了。コスト: ${event.cost_usd}")

asyncio.run(main())
ストリーミングと思考トークンの制限
maxThinkingTokens(またはmax_thinking_tokens)を明示的に設定すると、ストリーミングイベントが無効になることがあります。ストリーミングを使いながら思考量を調整したい場合は/effortコマンドを使ってください。

MCPサーバーの接続

SDK経由でMCP(Model Context Protocol)サーバーを接続すると、エージェントの能力をPlaywright・Figma・データベースなど外部システムに拡張できます。

TypeScript: MCPサーバーの接続
import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
  prompt: "GitHub のissue一覧を取得して、優先度順に並べてください",
  options: {
    mcpServers: {
      // GitHub MCP サーバー
      github: {
        command: "npx",
        args: ["-y", "@modelcontextprotocol/server-github"],
        env: {
          GITHUB_PERSONAL_ACCESS_TOKEN: process.env.GITHUB_TOKEN ?? "",
        },
      },
      // Playwright MCP サーバー(UI自動化)
      playwright: {
        command: "npx",
        args: ["@playwright/mcp@latest"],
      },
    },
  },
})) {
  // ...
}
Python: MCPサーバーの接続
import asyncio
import os
from claude_agent_sdk import query, ClaudeCodeOptions, MCPServerConfig

async def main():
    async for message in query(
        prompt="GitHub のissue一覧を取得して、優先度順に並べてください",
        options=ClaudeCodeOptions(
            mcp_servers={
                "github": MCPServerConfig(
                    command="npx",
                    args=["-y", "@modelcontextprotocol/server-github"],
                    env={"GITHUB_PERSONAL_ACCESS_TOKEN": os.environ["GITHUB_TOKEN"]},
                ),
            }
        ),
    ):
        pass  # メッセージ処理

asyncio.run(main())

サブエージェントの定義と委譲

複雑なタスクを複数のエージェントで分担するには、AgentDefinitionでサブエージェントを定義します。メインエージェントにallowedTools: ["Agent"]を付与すると、自律的にサブエージェントを起動して並列処理できます。サブエージェントの設計パターンの詳細はSubagents完全ガイドを参照してください。

TypeScript: サブエージェントの定義
import { query, AgentDefinition } from "@anthropic-ai/claude-agent-sdk";

// サブエージェントの定義
const testAgent: AgentDefinition = {
  name: "test-runner",
  description: "テストを実行して結果を報告するエージェント",
  prompt: "指定されたファイルのテストを実行し、失敗したテストの詳細を報告してください",
  options: {
    allowedTools: ["Bash", "Read"],  // 使用できるツールを制限
    permissionMode: "acceptEdits",
  },
};

const codeReviewAgent: AgentDefinition = {
  name: "code-reviewer",
  description: "コードレビューを行うエージェント",
  prompt: "コードを読んでバグ・セキュリティ問題・改善点を報告してください",
  options: {
    allowedTools: ["Read", "Glob", "Grep"],
  },
};

// メインエージェントにサブエージェントを使わせる
for await (const message of query({
  prompt: `src/ のコードをレビューし、問題があればテストを実行して確認してください。
           code-reviewer と test-runner エージェントを活用してください`,
  options: {
    allowedTools: ["Agent", "Read", "Bash"],  // Agent ツールを許可
    subagents: [testAgent, codeReviewAgent],
  },
})) {
  if (message.type === "assistant") {
    for (const block of message.message.content) {
      if (block.type === "text") {
        console.log(block.text);
      }
    }
  }
}

実用的なユースケースとサンプルコード

CI/CDパイプライン:PRの自動コードレビュー

GitHub Actions 連携スクリプト(TypeScript)
import { query } from "@anthropic-ai/claude-agent-sdk";
import { execSync } from "child_process";

async function reviewPR(prNumber: string) {
  // 変更差分を取得
  const diff = execSync(`git diff origin/main...HEAD`).toString();

  const reviewComments: string[] = [];

  for await (const message of query({
    prompt: `以下のPR差分をレビューしてください。
    バグ・セキュリティ問題・パフォーマンス問題・コードスタイルの指摘を
    箇条書きでまとめてください。

    ${diff}`,
    options: {
      maxTurns: 5,
      allowedTools: ["Read", "Glob"],  // 関連ファイルの参照のみ許可
    },
  })) {
    if (message.type === "assistant") {
      for (const block of message.message.content) {
        if (block.type === "text") {
          reviewComments.push(block.text);
        }
      }
    }
  }

  return reviewComments.join("
");
}

大規模リファクタリングの自動化

Python: 大規模リファクタリングスクリプト
import asyncio
import glob
from claude_agent_sdk import query, ClaudeCodeOptions

async def refactor_files(pattern: str, instruction: str):
    """指定パターンに一致するファイルを一括リファクタリング"""
    files = glob.glob(pattern, recursive=True)
    print(f"{len(files)}ファイルをリファクタリングします...")

    for file_path in files:
        print(f"処理中: {file_path}")

        async for message in query(
            prompt=f"{file_path} を以下の方針でリファクタリングしてください:
{instruction}",
            options=ClaudeCodeOptions(
                max_turns=5,
                permission_mode="acceptEdits",
                allowed_tools=["Read", "Edit"],  # 読み取りと編集のみ
            ),
        ):
            if message.type == "result":
                print(f"  完了 (コスト: ${message.cost_usd:.4f})")
                break

asyncio.run(refactor_files(
    "src/**/*.py",
    "型アノテーションを追加し、docstringをGoogle形式に統一してください"
))

カスタムCLIツールの作成

TypeScript: カスタムCLIツール
#!/usr/bin/env node
import { query } from "@anthropic-ai/claude-agent-sdk";

// コマンドライン引数からタスクを受け取る
const task = process.argv.slice(2).join(" ");

if (!task) {
  console.error("使い方: npx my-agent <タスクの説明>");
  process.exit(1);
}

(async () => {
  process.stdout.write("エージェント実行中...
");

  for await (const message of query({
    prompt: task,
    options: {
      maxTurns: 20,
      permissionMode: "acceptEdits",
    },
  })) {
    if (message.type === "assistant") {
      for (const block of message.message.content) {
        if (block.type === "text") {
          console.log(block.text);
        }
      }
    } else if (message.type === "result") {
      console.log(`
実行時間: ${message.duration_ms}ms | コスト: $${message.cost_usd}`);
    }
  }
})();

headlessモード(-pフラグ)とSDKの使い分け

Claude Codeにはheadlessモード(-pフラグ)もあります。どちらを使うべきかは用途によって異なります。

比較項目 headlessモード(-p) Claude Agent SDK
言語 シェルスクリプト・任意の言語(サブプロセス) TypeScript / Python ネイティブ
セッション管理 --continue--resumeフラグ continueresumeオプション(プログラムから制御)
ストリーミング --output-format stream-json includePartialMessages: true
ツール制御 設定ファイルのallowedTools canUseToolコールバックで動的制御
サブエージェント 制限あり AgentDefinitionで柔軟に定義
適した用途 シェルスクリプト・既存CIへの簡易統合 カスタムアプリ・複雑なロジック・型安全な実装

よくある質問

QClaude Code SDKとClaude Agent SDKは別物ですか?

A同じSDKです。「Claude Code SDK」が「Claude Agent SDK」に改名されました。パッケージ名が変更されているため、古いコードを移行する場合は@anthropic-ai/claude-code-sdk@anthropic-ai/claude-agent-sdkに変更し、インポート名も更新してください。公式の移行ガイドも提供されています。

QmaxTurnsはどのくらいに設定すればいいですか?

Aタスクの複雑さによります。単純な1ファイル編集なら3〜5、複数ファイルにまたがる修正なら10〜15、大規模リファクタリングなら20以上が目安です。設定が低すぎるとタスクが途中で終わります。本番環境で使う場合はコスト上限と合わせて適切な値を決めてください。

Qエラーが起きたときのリトライはどう実装しますか?

ASDKはネットワークエラーに対して内部でリトライしますが、タスク失敗(バグ修正に失敗した等)には自動リトライはありません。resultメッセージのresult.type"error"かどうかを確認して、失敗時に別のアプローチのプロンプトで再実行するロジックをアプリ側で実装してください。

QSDKのコストはどのくらいかかりますか?

A使用するモデルとトークン数に依存します。resultメッセージのcost_usdフィールドで実行コストを取得できます。コスト管理のベストプラクティスはmaxTurnsallowedToolsで処理範囲を絞ること、そして--model claude-sonnet-4-6(安価)と--model claude-opus-4-6(高品質)をタスクの重要度で使い分けることです。

QSDKとClaude APIの違いは何ですか?

AClaude APIはテキスト生成に特化したAPIです。Claude Agent SDKはClaude CodeのエンジンをAPIラップしたもので、ファイル読み書き・Bash実行・Web検索などのツール使用が内蔵されています。コードや開発タスクを自動化したい場合はAgent SDK、チャットや文書生成はClaude API、という使い分けが基本です。