「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」に改名されています。パッケージ名・インポートパスも変更されているため、古い記事を参考にする場合は注意してください。公式移行ガイドに移行手順が記載されています。
インストールとセットアップ
必要条件
| TypeScript | Python | |
|---|---|---|
| ランタイム | Node.js 18以上 | Python 3.10以上 |
| パッケージ | @anthropic-ai/claude-agent-sdk |
claude-agent-sdk |
| 認証 | ANTHROPIC_API_KEY環境変数 |
ANTHROPIC_API_KEY環境変数 |
インストール
npm install @anthropic-ai/claude-agent-sdk # TypeScript用の型定義は同梱されています
pip install claude-agent-sdk # Python 3.10以上が必要 python --version
APIキーの設定
SDKはデフォルトでANTHROPIC_API_KEY環境変数を参照します。AWS Bedrock・Google Vertex AI・Azure AI Foundryも対応しており、それぞれの認証情報を設定することで切り替えられます。
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の基本例
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の基本例
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配列にtext・tool_useブロックが含まれる |
tool_result |
ツール実行結果。Read/Bash/Editなどの実行後に自動挿入される |
result |
セッション終了時のサマリー(cost・duration・最終メッセージ等を含む) |
パーミッションモードの設定
エージェントがどのツールをどの範囲で使えるかはpermissionModeで制御します。セキュリティと自動化の度合いのバランスを用途に合わせて選択してください。
| モード | 動作 | 用途 |
|---|---|---|
default |
canUseToolコールバックで操作ごとに判断 |
対話的な操作・細かい制御が必要な場合 |
acceptEdits |
ファイル編集(Read/Write/Edit)を自動承認 | 自動化スクリプト・CI/CDで頻繁に使われる推奨設定 |
bypassPermissions |
全ツールを確認なしで実行 | 完全自動化が必要な場合(慎重に使用) |
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 によるマルチターン対話
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 |
既存セッションを分岐して別コンテキストで試行 | 失敗したアプローチをリセットせずに別案を試す |
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を有効にするとテキストが生成されるたびにイベントが流れ、ユーザーへのリアルタイム表示が可能になります。
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}`);
}
}
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・データベースなど外部システムに拡張できます。
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"],
},
},
},
})) {
// ...
}
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完全ガイドを参照してください。
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の自動コードレビュー
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("
");
}
大規模リファクタリングの自動化
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ツールの作成
#!/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フラグ |
continue・resumeオプション(プログラムから制御) |
| ストリーミング | --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フィールドで実行コストを取得できます。コスト管理のベストプラクティスはmaxTurnsとallowedToolsで処理範囲を絞ること、そして--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、という使い分けが基本です。

