spinny:~/writing $ vim building-ai-agents-claude-agent-sdk.md
1~2Claude Agent SDKは、Claude Codeを動かしているものと同じエージェントループへのプログラムによるアクセスを提供します。エージェントはファイルの読み取り、シェルコマンドの実行、Web検索、コードの編集、MCPサーバーを介した外部APIの呼び出し、サブエージェントのオーケストレーションなど - すべてをTypeScriptまたはPythonの数行のコードで実現できます。3~4標準のAnthropic Client SDKでは自分でツールループを構築する必要がありますが、Agent SDKはツールの実行、コンテキスト管理、リトライ、オーケストレーションを内部で処理します。やりたいことを記述し、ツールを提供すれば、エージェントが残りを判断します。5~6## アーキテクチャ7~8SDKはシンプルなループに従います: **コンテキストの収集、アクションの実行、検証、繰り返し**。9~10```mermaid11graph TD12 Input[User Prompt] --> Loop[Agent Loop]13 Loop --> Reason[Claude Reasons]14 Reason --> Tool[Call Tool]15 Tool --> Result[Tool Result]16 Result --> Loop17 Reason --> Done[Final Response]18~19 subgraph "Built-in Tools"20 T1[Read / Write / Edit]21 T2[Bash / Terminal]22 T3[Glob / Grep]23 T4[WebSearch / WebFetch]24 end25~26 subgraph "Custom Tools via MCP"27 M1[Your API]28 M2[Database]29 M3[Slack / GitHub / etc.]30 end31~32 Tool --> T133 Tool --> M134```35~36コアのエントリポイントは `query()` で、エージェントが作業する間にメッセージをストリーミングする非同期イテレータを返します。各メッセージはエージェントが何をしているかを示します: 推論中、ツール呼び出し中、結果の受信中、または最終出力の配信中。37~38## はじめに39~40### インストール41~42```bash43# TypeScript44npm install @anthropic-ai/claude-agent-sdk45~46# Python47pip install claude-agent-sdk48```49~50環境変数として `ANTHROPIC_API_KEY` にAnthropic APIキーを設定する必要があります。51~52### 最初のエージェント53~54```typescript55import { query } from "@anthropic-ai/claude-agent-sdk";56~57const conversation = query({58 prompt: "Find all TODO comments in the codebase and create a summary",59 options: {60 allowedTools: ["Read", "Glob", "Grep"],61 },62});63~64for await (const message of conversation) {65 if (message.type === "assistant") {66 process.stdout.write(message.content);67 }68 if (message.type === "result" && message.subtype === "success") {69 console.log("\nDone:", message.result);70 }71}72```73~74これだけです。エージェントはGlobでファイルを検索し、GrepでTODOパターンを検索し、Readでマッチを確認し、構造化されたサマリーを返します。オーケストレーションロジックを書く必要はありません - SDKが処理します。75~76### Python版77~78```python79from claude_agent_sdk import query80~81async for message in query(82 prompt="Find all TODO comments in the codebase and create a summary",83 options={"allowed_tools": ["Read", "Glob", "Grep"]},84):85 if message.type == "assistant":86 print(message.content, end="")87 if message.type == "result" and message.subtype == "success":88 print(f"\nDone: {message.result}")89```90~91## ビルトインツール92~93SDKにはClaude Codeで利用可能なものと同じツールが付属しています:94~95| ツール | 説明 |96|------|-------------|97| **Read** | ファイルの内容を読み取る |98| **Write** | 新しいファイルを作成する |99| **Edit** | 既存のファイルに対象を絞った編集を行う |100| **Bash** | シェルコマンドを実行する |101| **Glob** | パターンでファイルを検索する |102| **Grep** | 正規表現でファイル内容を検索する |103| **WebSearch** | Webを検索する |104| **WebFetch** | URLを取得して内容を返す |105| **AskUserQuestion** | ユーザーに入力を求める |106~107`allowedTools` でエージェントが使用できるツールを制御します。リストにないツールは、エージェントから呼び出すことができません。108~109## パーミッションモード110~111エージェントは実際のシステム上で実際のコマンドを実行するため、パーミッションが重要です。112~113| モード | 動作 | ユースケース |114|------|----------|----------|115| `default` | カスタム `canUseTool` コールバックが呼び出しごとに判断 | きめ細かい制御 |116| `acceptEdits` | ファイル操作を自動承認、Bashはプロンプト | 開発ワークフロー |117| `dontAsk` | allowedToolsにないものはすべて拒否 | 制限されたエージェント |118| `bypassPermissions` | すべてを自動的に承認 | 信頼されたサンドボックス環境 |119| `auto` | モデルの分類器が安全性を判断 | バランスの取れた自動化 |120~121```typescript122const conversation = query({123 prompt: "Refactor the auth module to use JWT",124 options: {125 allowedTools: ["Read", "Edit", "Glob", "Grep", "Bash"],126 permissionMode: "acceptEdits",127 },128});129```130~131本番環境では、常にサンドボックス化された環境(コンテナ、VM)でエージェントを実行し、エージェントがタスクを遂行できる範囲で最も制限的なパーミッションモードを使用してください。132~133## MCPによるカスタムツールの構築134~135SDKの真の力は、独自のツールでエージェントを拡張できることにあります。カスタムツールはインプロセスMCPサーバーとして定義されます - サブプロセス管理もネットワークオーバーヘッドも不要です。136~137### 例: 天気ツール138~139```typescript140import { tool, createSdkMcpServer, query } from "@anthropic-ai/claude-agent-sdk";141import { z } from "zod";142~143const getTemperature = tool(144 "get_temperature",145 "Get the current temperature at a location",146 {147 latitude: z.number().describe("Latitude"),148 longitude: z.number().describe("Longitude"),149 },150 async ({ latitude, longitude }) => {151 const res = await fetch(152 `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}¤t=temperature_2m&temperature_unit=celsius`153 );154 const data = await res.json();155 return {156 content: [157 {158 type: "text",159 text: `Current temperature: ${data.current.temperature_2m}C`,160 },161 ],162 };163 }164);165~166const weatherServer = createSdkMcpServer({167 name: "weather",168 version: "1.0.0",169 tools: [getTemperature],170});171~172for await (const message of query({173 prompt: "What's the weather like in Rome?",174 options: {175 mcpServers: { weather: weatherServer },176 allowedTools: ["mcp__weather__get_temperature"],177 },178})) {179 if (message.type === "result" && message.subtype === "success") {180 console.log(message.result);181 }182}183```184~185カスタムツールは `mcp__{server_name}__{tool_name}` という命名規則に従います。`allowedTools` ではワイルドカードが使用できます: `"mcp__weather__*"` はweatherサーバーのすべてのツールを許可します。186~187### 例: データベースクエリツール188~189```typescript190const queryDb = tool(191 "query_database",192 "Run a read-only SQL query against the application database",193 {194 sql: z.string().describe("SQL SELECT query to execute"),195 },196 async ({ sql }) => {197 // Validate: only allow SELECT queries198 if (!sql.trim().toUpperCase().startsWith("SELECT")) {199 return {200 content: [{ type: "text", text: "Error: Only SELECT queries are allowed." }],201 };202 }203~204 const result = await pool.query(sql);205 return {206 content: [207 {208 type: "text",209 text: JSON.stringify(result.rows, null, 2),210 },211 ],212 };213 }214);215```216~217## 外部MCPサーバーへの接続218~219インプロセスツールに加えて、既存のMCPサーバーに接続することもできます - Claude Desktop、Cursor、その他のMCPクライアントで動作するものと同じサーバーです。220~221```typescript222for await (const message of query({223 prompt: "Check the latest issues in the frontend repo and summarize them",224 options: {225 mcpServers: {226 github: {227 command: "npx",228 args: ["-y", "@modelcontextprotocol/server-github"],229 env: { GITHUB_PERSONAL_ACCESS_TOKEN: process.env.GITHUB_TOKEN },230 },231 },232 allowedTools: ["mcp__github__*"],233 },234})) {235 // ...236}237```238~239複数のMCPサーバーを組み合わせることができます。エージェントは接続されたすべてのサーバーのすべてのツールを認識し、必要に応じて使用します。240~241```mermaid242graph LR243 Agent[Your Agent] --> SDK[Agent SDK]244 SDK --> InProcess[In-process MCP\nCustom Tools]245 SDK --> GitHub[GitHub MCP Server]246 SDK --> Postgres[PostgreSQL MCP Server]247 SDK --> Slack[Slack MCP Server]248```249~250## マルチエージェントオーケストレーション251~252複雑なワークフローでは、親エージェントがタスクを委任する専門的なサブエージェントを定義できます。各サブエージェントは独自のプロンプト、ツール、専門領域を持ちます。253~254```typescript255for await (const message of query({256 prompt: "Review the PR, check for security issues, and update the changelog",257 options: {258 allowedTools: ["Read", "Edit", "Bash", "Glob", "Grep", "Agent"],259 agents: [260 {261 name: "security-reviewer",262 description: "Reviews code for security vulnerabilities",263 prompt: "You are a security expert. Analyze code for OWASP Top 10 vulnerabilities.",264 allowedTools: ["Read", "Glob", "Grep"],265 },266 {267 name: "changelog-writer",268 description: "Updates the CHANGELOG.md file based on recent changes",269 prompt: "You maintain the project changelog. Follow Keep a Changelog format.",270 allowedTools: ["Read", "Edit", "Bash"],271 },272 ],273 },274})) {275 // The parent agent will:276 // 1. Read the PR diff277 // 2. Delegate security review to security-reviewer278 // 3. Delegate changelog update to changelog-writer279 // 4. Synthesize results280}281```282~283委任を有効にするには、親の `allowedTools` に `"Agent"` を含めてください。サブエージェントは独自のツールで動作し、明示的に許可されない限り親のツールにはアクセスできません。284~285```mermaid286graph TD287 Parent[Parent Agent] --> SR[Security Reviewer\nRead, Glob, Grep]288 Parent --> CW[Changelog Writer\nRead, Edit, Bash]289 SR --> Report[Security Report]290 CW --> Updated[Updated CHANGELOG]291 Report --> Parent292 Updated --> Parent293 Parent --> Final[Final Summary]294```295~296## セッションと継続性297~298エージェントはセッションを使って複数のクエリにわたってコンテキストを維持できます。最初のインタラクションから `session_id` を取得し、後続のクエリで `resume` に渡します。299~300```typescript301let sessionId: string | undefined;302~303// First query304for await (const message of query({305 prompt: "Read the project structure and understand the architecture",306 options: { allowedTools: ["Read", "Glob", "Grep"] },307})) {308 if (message.type === "init") {309 sessionId = message.session_id;310 }311}312~313// Follow-up query (same session, full context preserved)314for await (const message of query({315 prompt: "Now refactor the auth module based on what you learned",316 resume: sessionId,317 options: { allowedTools: ["Read", "Edit", "Bash"] },318})) {319 // Agent remembers the full project context from the first query320}321```322~323## Claude Managed Agents324~325エージェントのインフラを自分でホスティングしたくない場合、**Claude Managed Agents**(2026年4月ローンチ)がフルマネージドのクラウドサービスを提供します。Anthropicがコンテナを実行し、スケーリングを処理し、ストリーミングAPIを提供します。326~327```mermaid328graph LR329 subgraph "Self-hosted (Agent SDK)"330 Code[Your Code] --> SDK2[Agent SDK]331 SDK2 --> API[Claude API]332 SDK2 --> Tools[Your Tools]333 end334~335 subgraph "Managed Agents"336 App[Your App] --> MAPI[Managed Agents API]337 MAPI --> Container[Anthropic-hosted Container]338 Container --> API2[Claude API]339 Container --> Tools2[Tools in Container]340 end341```342~343主な違い: Agent SDKでは、自分のインフラでエージェントループを実行します。Managed Agentsでは、Anthropicがエージェントをホスティングして実行します。セッションベースのAPIでやり取りし、Server-Sent Eventsでイベントを受信します。344~345**料金:**346- **Agent SDK**: 標準のClaude APIトークン料金のみ。ホスティングは自分で行います。347- **Managed Agents**: トークン料金に加えて、セッション時間あたり$0.08(ミリ秒単位で課金)。348~349## 本番環境のベストプラクティス350~351### 1. 常にサンドボックス化する352~353本番マシンで無制限のパーミッションでエージェントを実行しないでください。コンテナ(Docker、Fly.io、Modal)やサンドボックス環境(E2B、Vercel Sandbox)を使用してください。354~355### 2. ツールアクセスを制限する356~357最小権限の原則に従ってください。レポートを生成するエージェントに `Bash` や `Write` は不要です。358~359```typescript360// Too permissive361allowedTools: ["Read", "Write", "Edit", "Bash", "Glob", "Grep"]362~363// Better: only what's needed364allowedTools: ["Read", "Glob", "Grep"]365```366~367### 3. フックでガードレールを設定する368~369フックを使うと、ツール呼び出しの実行前後にインターセプトできます。ログ記録、バリデーション、レート制限に使用してください。370~371```typescript372const conversation = query({373 prompt: "Analyze the codebase",374 options: {375 allowedTools: ["Read", "Glob", "Grep"],376 hooks: {377 PreToolUse: async (toolName, input) => {378 console.log(`Tool call: ${toolName}`, input);379 // Return false to block the call380 if (toolName === "Bash" && input.command.includes("rm")) {381 return false;382 }383 return true;384 },385 },386 },387});388```389~390### 4. エラーを適切に処理する391~392エージェントループはエラーを生成する可能性があります - ツールの失敗、APIレート制限、コンテキストウィンドウのオーバーフロー。常にメッセージタイプを確認してください。393~394```typescript395for await (const message of conversation) {396 switch (message.type) {397 case "assistant":398 // Agent reasoning399 break;400 case "tool_use":401 // Agent is calling a tool402 break;403 case "result":404 if (message.subtype === "error") {405 console.error("Agent failed:", message.error);406 }407 break;408 }409}410```411~412### 5. トークン使用量を監視する413~414エージェントループは、特に大規模なコードベースで大量のトークンを消費する可能性があります。SDKには自動コンテキスト圧縮が含まれていますが、使用量は引き続き監視すべきです。415~416## まとめ417~418Claude Agent SDKは、LLMを質問応答マシンからジュニアデベロッパーに近い存在に変えます。エージェントは読み取り、書き込み、実行、検証、反復が可能です - 人間が行うのと同じワークフローです。419~420小さく始めましょう: いくつかのビルトインツールでエージェントを構築してください。次に、特定のドメイン向けにカスタムMCPツールを追加してください。ワークフローに専門化が必要になったら、マルチエージェントオーケストレーションにスケールアップしてください。421~422エージェントループはClaude Codeを動かしているものと同じです。それがソフトウェアを構築できるなら、あなたのエージェントにもできます。423~424> **はじめるためのチェックリスト:**425>426> - [x] SDKをインストールする (`npm install @anthropic-ai/claude-agent-sdk`)427> - [x] 環境変数に `ANTHROPIC_API_KEY` を設定する428> - [x] ビルトインツール(Read、Glob、Grep)でシンプルなエージェントを構築する429> - [x] インプロセスMCPサーバーでカスタムツールを追加する430> - [x] 外部MCPサーバー(GitHub、PostgreSQLなど)に接続する431> - [x] サブエージェントによるマルチエージェントオーケストレーションを実装する432> - [x] 本番環境用にサンドボックス化された環境を構築する433> - [x] ログ記録とガードレール用のフックを追加する434~
NORMAL · building-ai-agents-claude-agent-sdk.md [readonly]434 lines · :q to close