Claude Agent SDKとは何か、Claude Code CLIとどう違うのか
「Claude Codeはターミナルで使うAIコーディングアシスタント」という認識は正しい。だが2026年3月、AnthropicはClaude Agent SDK(旧称: Claude Code SDK)をリネームと同時に大幅強化し、Claude Codeそのものをライブラリとして自分のアプリに組み込めるようにした。
違いを一言で言うと、こうだ。
Claude Code CLI = 開発者が手動でインタラクティブに使うターミナルアプリ
Claude Agent SDK = Claude Codeの能力をプログラムから呼び出すためのPython/TypeScriptライブラリ
もう少し具体的に比較してみよう。
| 項目 | Claude Code CLI | Claude Agent SDK |
|---|---|---|
| インターフェース | ターミナル(インタラクティブ) | Python / TypeScriptコード |
| ユースケース | 日常の開発作業、1回限りのタスク | CI/CD、本番自動化、カスタムアプリ |
| ツール実行 | Claude自身が対話的に確認 | プログラムで制御・フィルタリング可能 |
| Hooks | JSONファイルで設定(静的) | Pythonコールバック関数で定義(動的) |
| 認証 | サブスクリプション or APIキー | APIキーのみ(サブスク認証は不可) |
| MCPサーバー | 設定ファイルで外部プロセス起動 | In-process(同プロセス内)で動作 |
| 長時間稼働 | セッション終了で停止 | セッションID管理で継続可能 |
重要な点として、APIキーが必須でサブスクリプション(claude.aiログイン)は認証に使えない。Anthropicのポリシーで明示されており、SDKを使ったプロダクトには必ず ANTHROPIC_API_KEY での認証が必要になる(参照日: 2026-04-07)。
何が新しくなったのか — SDK 2026年版の主要変更点
SDKのリネーム(Claude Code SDK → Claude Agent SDK)は単なる名前変更ではない。具体的に変わった点を整理する。
1. MCP In-Process サーバーのネイティブ対応
従来、MCPサーバーは外部プロセスとして起動する必要があった。新SDKではカスタムMCPサーバーを同一Pythonプロセス内に定義できるようになった。これにより外部サービスやデータベースへの接続をSDK内でカプセル化できる。
# 動作環境: Python 3.10+, claude-agent-sdk>=0.2.0
# pip install claude-agent-sdk
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
# Playwright MCPをIn-processで使う例
async def main():
async for message in query(
prompt="https://aigentlab.tech のトップページを開いて、最新記事のタイトルを教えて",
options=ClaudeAgentOptions(
mcp_servers={
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest"]
}
}
),
):
if hasattr(message, "result"):
print(message.result)
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
asyncio.run(main())
ポイント:
mcp_serversオプションにサーバー定義を渡すだけでOK- 外部プロセスとして起動されるが、SDKがライフサイクルを管理する
- MCPのstdio通信はSDK内部で完結するため、ネットワーク設定が不要
2. Python コールバック関数としての Hooks
Claude Code CLIのHooksはJSONファイルにシェルコマンドを記述する形だった。SDKではPythonの非同期関数をフックとして直接登録できる。
import asyncio
from datetime import datetime
from claude_agent_sdk import query, ClaudeAgentOptions, HookMatcher
# ファイル変更を監査ログに記録するフック
async def log_file_change(input_data, tool_use_id, context):
file_path = input_data.get("tool_input", {}).get("file_path", "unknown")
with open("./audit.log", "a") as f:
f.write(f"{datetime.now().isoformat()}: modified {file_path}n")
return {} # 空dictを返すと「許可」
# 危険なBashコマンドをブロックするフック
async def block_dangerous_bash(input_data, tool_use_id, context):
cmd = input_data.get("tool_input", {}).get("command", "")
danger_patterns = ["rm -rf", "DROP TABLE", "truncate"]
for pattern in danger_patterns:
if pattern in cmd:
return {"decision": "block", "reason": f"危険なコマンドを検出: {pattern}"}
return {}
async def main():
async for message in query(
prompt="src/配下のPythonファイルをリファクタリングして",
options=ClaudeAgentOptions(
permission_mode="acceptEdits",
hooks={
"PostToolUse": [
HookMatcher(matcher="Edit|Write", hooks=[log_file_change])
],
"PreToolUse": [
HookMatcher(matcher="Bash", hooks=[block_dangerous_bash])
],
},
),
):
if hasattr(message, "result"):
print(message.result)
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
asyncio.run(main())
3. セッション継続(長時間稼働の核心)
長時間稼働エージェントの最大の課題は「セッションをまたぐと文脈を失う」ことだ。SDKは session_id を保存・再利用する仕組みを提供している。
import asyncio
import json
import os
from claude_agent_sdk import query, ClaudeAgentOptions, SystemMessage, ResultMessage
STATE_FILE = "./agent_state.json"
async def run_agent_session(resume_id=None):
"""セッションを実行し、IDをファイルに保存する"""
session_id = None
prompt = (
"大規模リファクタリングの続きをやって。claude-progress.txtを読んで前回の進捗を確認してから進めて"
if resume_id else
"auth.pyとutils.pyのリファクタリング計画を立てて。進捗をclaude-progress.txtに記録しながら進めて"
)
options = ClaudeAgentOptions(
allowed_tools=["Read", "Write", "Edit", "Bash", "Glob"],
resume=resume_id,
)
async for message in query(prompt=prompt, options=options):
if isinstance(message, SystemMessage) and message.subtype == "init":
session_id = message.data.get("session_id")
with open(STATE_FILE, "w") as f:
json.dump({"session_id": session_id}, f)
print(f"Session ID saved: {session_id}")
elif isinstance(message, ResultMessage):
print(f"Result: {message.result[:200]}")
return session_id
async def main():
# 前回のセッションIDがあれば再開
resume_id = None
if os.path.exists(STATE_FILE):
with open(STATE_FILE) as f:
resume_id = json.load(f).get("session_id")
print(f"Resuming session: {resume_id}")
await run_agent_session(resume_id=resume_id)
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
asyncio.run(main())
Anthropicのエンジニアリングブログ「Effective harnesses for long-running agents」では、初期化エージェント(init agent)でセットアップを行い、コーディングエージェントが claude-progress.txt を読み書きしながら段階的に作業を進めるパターンを推奨している。このSDKのセッション継続機能はそのパターンを実装するための中核となる。
実際に試したらどうなるか — 具体的なセットアップ手順
5分で試せるセットアップを順番に示す。
# 1. インストール(Python版)
pip install claude-agent-sdk
# 2. APIキーを環境変数に設定
export ANTHROPIC_API_KEY=your-api-key-here
# .envファイルを使う場合
echo "ANTHROPIC_API_KEY=your-key" >> .env
# 3. Amazon Bedrock経由で使う場合
export CLAUDE_CODE_USE_BEDROCK=1
# AWS credentialsを設定済みであれば動作する
# 4. TypeScript版
npm install @anthropic-ai/claude-agent-sdk
動作環境: Python 3.10+ / Node.js 18+ / claude-agent-sdk 0.2.0以上(2026-04-07時点)。
よくある誤解と正しい理解
SDKを使い始める前に、よく混同される点を整理しておく。
誤解1: 「SDKはAPIラッパーと同じもの」
正しくない。Anthropic Client SDK(anthropicパッケージ)はメッセージを送ってレスポンスを受け取るだけで、ツール実行ループは自分で実装する必要がある。Claude Agent SDKはツール実行ループ込みのエージェント実行エンジンだ。
# Client SDK: ツールループを自分で実装する必要がある
from anthropic import Anthropic
client = Anthropic()
response = client.messages.create(model="claude-opus-4-5", max_tokens=1024, messages=[...])
while response.stop_reason == "tool_use": # ← これを自分で書く
result = your_tool_executor(response.tool_use) # ← これも
response = client.messages.create(tool_result=result, ...)
# Agent SDK: ツールループが内蔵されている
from claude_agent_sdk import query
async for message in query(prompt="バグを修正して"):
print(message) # Claudeがファイルを読んで、修正して、完了するまで自動で続ける
誤解2: 「長時間稼働エージェントはAPIを呼び続けていいる」
実際には、各セッションは独立している。長時間稼働の正解は「セッションを継続するのではなく、引き継ぎ情報を永続化して新セッションに渡す」パターンだ。claude-progress.txt などのファイルに進捗を記録し、次のセッションで読み込む。
誤解3: 「Hooksは複雑な設定が必要」
SDKではPython関数を渡すだけでよい。JSONファイルやシェルスクリプトは一切不要。 async def my_hook(input_data, tool_use_id, context): return {} という最小の関数から始められる。
結局どう使えばいいのか — 用途別おすすめパターン
SDKは万能ではない。用途によって最適な選択が異なる。
| 用途 | おすすめ方法 | 理由 |
|---|---|---|
| 日常のコーディング補助 | Claude Code CLI | インタラクティブで確認しながら進められる |
| CI/CDでのコード品質チェック | Agent SDK(headlessモード) | プログラム制御、JSON出力、自動化に向く |
| カスタムUIからエージェント実行 | Agent SDK + deferフック | 独自UIで承認フローを実装できる |
| 大規模リファクタリング(数日) | Agent SDK + セッション継続 | session_idとprogress.txtで進捗管理 |
| 外部DBやAPIとの連携 | Agent SDK + MCPサーバー | In-processでMCPを定義、認証を安全に管理 |
【要注意】よくある失敗パターンと回避策
失敗1: サブスクリプション認証で動かそうとする
❌ Claude.aiのメールアドレス・パスワードをSDKに渡す
⭕ Console(platform.claude.com)でAPIキーを発行して ANTHROPIC_API_KEY に設定する
なぜ重要か: Anthropicのポリシーでサードパーティがサブスクリプション認証を提供することは禁止されている。SDKで作ったプロダクトには必ずAPIキー認証が必要だ。
失敗2: 全てのツールをallowed_toolsに入れる
❌ allowed_tools=["Bash", "Edit", "Write", "Read", "Glob", "WebFetch", "Agent"] をそのまま本番に使う
⭕ 最小権限原則で必要なツールだけを渡す(例: 読み取り専用なら ["Read", "Glob", "Grep"])
なぜ重要か: 不必要な Bash 権限があると、意図しないシステム操作が実行される可能性がある。PreToolUseフックと組み合わせて、許可するコマンドをホワイトリスト管理するのが安全だ。
失敗3: セッション継続を「状態の引き継ぎ」と混同する
❌ resume=session_id を渡せば前回の作業内容を全て覚えていると期待する
⭕ セッションは会話履歴を引き継ぐが、ファイルシステムの変更内容は別途ファイルで管理する
なぜ重要か: セッションIDはコンテキストウィンドウのトークン履歴を引き継ぐもの。コードの変更状態を管理するには claude-progress.txt などのファイルベースの記録が必要だ。
失敗4: PostToolUseフックでツールをブロックしようとする
❌ PostToolUseフックで {"decision": "block"} を返してツール実行を止めようとする
⭕ ツール実行前に止めたい場合はPreToolUseフックを使う(PostToolUseはツール実行後に呼ばれる)
なぜ重要か: PostToolUseフックは既にツールが実行された後の後処理用。フィードバックやログ記録に使い、ブロックはPreToolUseで行う。
参考・出典
- Agent SDK overview — Anthropic Platform Docs(参照日: 2026-04-07)
- Building agents with the Claude Agent SDK — Anthropic Engineering Blog(参照日: 2026-04-07)
- Effective harnesses for long-running agents — Anthropic Engineering Blog(参照日: 2026-04-07)
- GitHub: anthropics/claude-agent-sdk-python(参照日: 2026-04-07)
- Intercept and control agent behavior with hooks — Anthropic Platform Docs(参照日: 2026-04-07)
この記事はAIgent Lab編集部がお届けしました。
AIエージェントの構築パターンについては、Claude Agent Teamsの実装ガイドも参考にしてください。MCPの詳しい設定方法はFastMCPでMCPサーバーを構築する実践ガイドにまとめています。またセキュリティ観点からのエージェント設計についてはAIエージェントのセキュリティ検証アプローチも合わせてご覧ください。
まとめ:今日から始める3つのアクション
- 今日:
pip install claude-agent-sdkでインストールし、query()関数で最初のエージェントを5分で動かしてみる - 今週中: PreToolUseフックを1つ実装して、危険なBashコマンドをブロックする安全機構を追加する
- 今月中: セッション継続 + progress.txtパターンで、CI/CDパイプラインに組み込んだ本番エージェントを稼働させる
ご質問・ご相談は お問い合わせフォーム からお気軽にどうぞ。