Команда AI for Devs подготовила перевод подробного практического гайда по Claude Agent SDK. В статье разбирается, как устроены современные AI-агенты на практикеКоманда AI for Devs подготовила перевод подробного практического гайда по Claude Agent SDK. В статье разбирается, как устроены современные AI-агенты на практике

[Перевод] Как создавать AI-агентов на практике: полное руководство по Claude Agent SDK

Команда AI for Devs подготовила перевод подробного практического гайда по Claude Agent SDK. В статье разбирается, как устроены современные AI-агенты на практике: управление контекстом, инструменты, сабагенты, разрешения, структурированный вывод и продакшен-паттерны.


Если вы пользовались Claude Code, вы уже видели, на что на самом деле способен AI-агент: читать файлы, выполнять команды, редактировать код, самостоятельно определять шаги для выполнения задачи.
И вы знаете, что он не просто помогает писать код — он берёт ответственность за проблему и последовательно решает её так, как это сделал бы вдумчивый инженер.

Claude Agent SDK — это тот же самый движок, но теперь вы можете направить его на любую задачу по своему выбору и без лишних усилий создавать собственных агентов.
Это инфраструктура, лежащая в основе Claude Code, вынесенная в виде библиотеки. Вы получаете агентный цикл, встроенные инструменты, управление контекстом — по сути, всё то, что иначе пришлось бы реализовывать самостоятельно.

В этом руководстве мы с нуля создадим агента для код-ревью. В итоге у вас получится инструмент, который умеет анализировать кодовую базу, находить баги и проблемы безопасности и возвращать структурированную обратную связь.
Но что ещё важнее — вы разберётесь, как работает SDK, и сможете собрать именно того агента, который нужен вам на практике.

Что мы будем делать

Наш агент для код-ревью будет уметь:

  • Анализировать кодовую базу на наличие багов и проблем безопасности;

  • Автономно читать файлы и искать по коду;

  • Предоставлять структурированную, практичную обратную связь;

  • Отслеживать собственный прогресс в процессе работы.

Стек

  • Runtime — Claude Code CLI

  • SDK — @anthropic-ai/claude-agent-sdk

  • Язык — TypeScript

  • Модель — Claude Opus 4.5

Что даёт SDK

Если вы уже строили агентов на «сыром» API, то знаете этот паттерн: вызываете модель, проверяете, хочет ли она использовать инструмент, выполняете инструмент, передаёте результат обратно — и повторяете цикл до завершения задачи. При работе над чем-то более-менее сложным это быстро начинает утомлять.

SDK берёт этот цикл на себя:

// Without the SDK: You manage the loop let response = await client.messages.create({...}); while (response.stop_reason === "tool_use") { const result = yourToolExecutor(response.tool_use); response = await client.messages.create({ tool_result: result, ... }); } // With the SDK: Claude manages it for await (const message of query({ prompt: "Fix the bug in auth.py" })) { console.log(message); // Claude reads files, finds bugs, edits code }

Кроме того, вы сразу получаете готовые инструменты:

  • Read — чтение любых файлов в рабочей директории

  • Write — создание новых файлов

  • Edit — точечное редактирование существующих файлов

  • Bash — выполнение команд в терминале

  • Glob — поиск файлов по шаблону

  • Grep — поиск по содержимому файлов с помощью регулярных выражений

  • WebSearch — поиск в интернете

  • WebFetch — загрузка и парсинг веб-страниц

Ничего из этого не нужно реализовывать самостоятельно.

Предварительные требования

  • Установленный Node.js версии 18 или выше

  • API-ключ Anthropic (получить его можно здесь)

Начало работы

Шаг 1: Установка Claude Code CLI

Agent SDK использует Claude Code в качестве среды выполнения:

npm install -g @anthropic-ai/claude-code

После установки запустите claude в терминале и следуйте подсказкам для аутентификации.

Шаг 2: Создание проекта

mkdir code-review-agent && cd code-review-agent npm init -y npm install @anthropic-ai/claude-agent-sdk npm install -D typescript @types/node tsx

Шаг 3: Установка API-ключа

export ANTHROPIC_API_KEY=your-api-key

Ваш первый агент

Создайте файл agent.ts:

import { query } from "@anthropic-ai/claude-agent-sdk"; async function main() { for await (const message of query({ prompt: "What files are in this directory?", options: { model: "opus", allowedTools: ["Glob", "Read"], maxTurns: 250 } })) { if (message.type === "assistant") { for (const block of message.message.content) { if ("text" in block) { console.log(block.text); } } } if (message.type === "result") { console.log("\nDone:", message.subtype); } } } main();

Запустите его:

npx tsx agent.ts

Claude воспользуется инструментом Glob, чтобы получить список файлов, и сообщит, что ему удалось найти.

Понимание потока сообщений

Функция query() возвращает асинхронный генератор, который стримит сообщения по мере работы Claude. Вот ключевые типы сообщений:

for await (const message of query({ prompt: "..." })) { switch (message.type) { case "system": // Session initialization info if (message.subtype === "init") { console.log("Session ID:", message.session_id); console.log("Available tools:", message.tools); } break; case "assistant": // Claude's responses and tool calls for (const block of message.message.content) { if ("text" in block) { console.log("Claude:", block.text); } else if ("name" in block) { console.log("Tool call:", block.name); } } break; case "result": // Final result console.log("Status:", message.subtype); // "success" or error type console.log("Cost:", message.total_cost_usd); break; } }

Создание агента для код-ревью

Теперь соберём что-то действительно полезное. Создайте файл review-agent.ts:

import { query } from "@anthropic-ai/claude-agent-sdk"; async function reviewCode(directory: string) { console.log(`\n🔍 Starting code review for: ${directory}\n`); for await (const message of query({ prompt: `Review the code in ${directory} for: 1. Bugs and potential crashes 2. Security vulnerabilities 3. Performance issues 4. Code quality improvements Be specific about file names and line numbers.`, options: { model: "opus", allowedTools: ["Read", "Glob", "Grep"], permissionMode: "bypassPermissions", // Auto-approve read operations maxTurns: 250 } })) { // Show Claude's analysis as it happens if (message.type === "assistant") { for (const block of message.message.content) { if ("text" in block) { console.log(block.text); } else if ("name" in block) { console.log(`\n📁 Using ${block.name}...`); } } } // Show completion status if (message.type === "result") { if (message.subtype === "success") { console.log(`\n✅ Review complete! Cost: $${message.total_cost_usd.toFixed(4)}`); } else { console.log(`\n❌ Review failed: ${message.subtype}`); } } } } // Review the current directory reviewCode(".");

Проверка на практике

Создайте файл с намеренно допущенными проблемами. Создайте example.ts:

function processUsers(users: any) { for (let i = 0; i <= users.length; i++) { // Off-by-one error console.log(users[i].name.toUpperCase()); // No null check } } function connectToDb(password: string) { const connectionString = `postgres://admin:${password}@localhost/db`; console.log("Connecting with:", connectionString); // Logging sensitive data } async function fetchData(url) { // Missing type annotation const response = await fetch(url); return response.json(); // No error handling }

Запустите ревью:

npx tsx review-agent.ts

Claude найдёт баги, проблемы безопасности и предложит варианты исправлений.

Добавление структурированного вывода

Для программного использования вам понадобится структурированный результат. SDK поддерживает вывод в формате JSON Schema:

import { query } from "@anthropic-ai/claude-agent-sdk"; const reviewSchema = { type: "object", properties: { issues: { type: "array", items: { type: "object", properties: { severity: { type: "string", enum: ["low", "medium", "high", "critical"] }, category: { type: "string", enum: ["bug", "security", "performance", "style"] }, file: { type: "string" }, line: { type: "number" }, description: { type: "string" }, suggestion: { type: "string" } }, required: ["severity", "category", "file", "description"] } }, summary: { type: "string" }, overallScore: { type: "number" } }, required: ["issues", "summary", "overallScore"] }; async function reviewCodeStructured(directory: string) { for await (const message of query({ prompt: `Review the code in ${directory}. Identify all issues.`, options: { model: "opus", allowedTools: ["Read", "Glob", "Grep"], permissionMode: "bypassPermissions", maxTurns: 250, outputFormat: { type: "json_schema", schema: reviewSchema } } })) { if (message.type === "result" && message.subtype === "success") { const review = message.structured_output as { issues: Array<{ severity: string; category: string; file: string; line?: number; description: string; suggestion?: string; }>; summary: string; overallScore: number; }; console.log(`\n📊 Code Review Results\n`); console.log(`Score: ${review.overallScore}/100`); console.log(`Summary: ${review.summary}\n`); for (const issue of review.issues) { const icon = issue.severity === "critical" ? "🔴" : issue.severity === "high" ? "🟠" : issue.severity === "medium" ? "🟡" : "🟢"; console.log(`${icon} [${issue.category.toUpperCase()}] ${issue.file}${issue.line ? `:${issue.line}` : ""}`); console.log(` ${issue.description}`); if (issue.suggestion) { console.log(` 💡 ${issue.suggestion}`); } console.log(); } } } } reviewCodeStructured(".");

Обработка разрешений

По умолчанию SDK запрашивает подтверждение перед выполнением инструментов. Это поведение можно настроить.

Режимы разрешений

options: { // Standard mode - prompts for approval permissionMode: "default", // Auto-approve file edits permissionMode: "acceptEdits", // No prompts (use with caution) permissionMode: "bypassPermissions" }

Пользовательский обработчик разрешений

Для более тонкого контроля используйте canUseTool:

options: { canUseTool: async (toolName, input) => { // Allow all read operations if (["Read", "Glob", "Grep"].includes(toolName)) { return { behavior: "allow", updatedInput: input }; } // Block writes to certain files if (toolName === "Write" && input.file_path?.includes(".env")) { return { behavior: "deny", message: "Cannot modify .env files" }; } // Allow everything else return { behavior: "allow", updatedInput: input }; } }

Создание сабагентов

Для сложных задач можно создавать специализированных сабагентов:

import { query, AgentDefinition } from "@anthropic-ai/claude-agent-sdk"; async function comprehensiveReview(directory: string) { for await (const message of query({ prompt: `Perform a comprehensive code review of ${directory}. Use the security-reviewer for security issues and test-analyzer for test coverage.`, options: { model: "opus", allowedTools: ["Read", "Glob", "Grep", "Task"], // Task enables subagents permissionMode: "bypassPermissions", maxTurns: 250, agents: { "security-reviewer": { description: "Security specialist for vulnerability detection", prompt: `You are a security expert. Focus on: - SQL injection, XSS, CSRF vulnerabilities - Exposed credentials and secrets - Insecure data handling - Authentication/authorization issues`, tools: ["Read", "Grep", "Glob"], model: "sonnet" } as AgentDefinition, "test-analyzer": { description: "Test coverage and quality analyzer", prompt: `You are a testing expert. Analyze: - Test coverage gaps - Missing edge cases - Test quality and reliability - Suggestions for additional tests`, tools: ["Read", "Grep", "Glob"], model: "haiku" // Use faster model for simpler analysis } as AgentDefinition } } })) { if (message.type === "assistant") { for (const block of message.message.content) { if ("text" in block) { console.log(block.text); } else if ("name" in block && block.name === "Task") { console.log(`\n🤖 Delegating to: ${(block.input as any).subagent_type}`); } } } } } comprehensiveReview(".");

Управление сессиями

Для многошаговых диалогов можно сохранять и возобновлять сессии:

import { query } from "@anthropic-ai/claude-agent-sdk"; async function interactiveReview() { let sessionId: string | undefined; // Initial review for await (const message of query({ prompt: "Review this codebase and identify the top 3 issues", options: { model: "opus", allowedTools: ["Read", "Glob", "Grep"], permissionMode: "bypassPermissions", maxTurns: 250 } })) { if (message.type === "system" && message.subtype === "init") { sessionId = message.session_id; } // ... handle messages } // Follow-up question using same session if (sessionId) { for await (const message of query({ prompt: "Now show me how to fix the most critical issue", options: { resume: sessionId, // Continue the conversation allowedTools: ["Read", "Glob", "Grep"], maxTurns: 250 } })) { // Claude remembers the previous context } } }

Использование хуков

Хуки позволяют перехватывать и настраивать поведение агента:

import { query, HookCallback, PreToolUseHookInput } from "@anthropic-ai/claude-agent-sdk"; const auditLogger: HookCallback = async (input, toolUseId, { signal }) => { if (input.hook_event_name === "PreToolUse") { const preInput = input as PreToolUseHookInput; console.log(`[AUDIT] ${new Date().toISOString()} - ${preInput.tool_name}`); } return {}; // Allow the operation }; const blockDangerousCommands: HookCallback = async (input, toolUseId, { signal }) => { if (input.hook_event_name === "PreToolUse") { const preInput = input as PreToolUseHookInput; if (preInput.tool_name === "Bash") { const command = (preInput.tool_input as any).command || ""; if (command.includes("rm -rf") || command.includes("sudo")) { return { hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "deny", permissionDecisionReason: "Dangerous command blocked" } }; } } } return {}; }; for await (const message of query({ prompt: "Clean up temporary files", options: { model: "opus", allowedTools: ["Bash", "Glob"], maxTurns: 250, hooks: { PreToolUse: [ { hooks: [auditLogger] }, { matcher: "Bash", hooks: [blockDangerousCommands] } ] } } })) { // ... }

Добавление пользовательских инструментов с помощью MCP

Расширяйте возможности Claude с помощью собственных инструментов, используя Model Context Protocol:

import { query, tool, createSdkMcpServer } from "@anthropic-ai/claude-agent-sdk"; import { z } from "zod"; // Create a custom tool const customServer = createSdkMcpServer({ name: "code-metrics", version: "1.0.0", tools: [ tool( "analyze_complexity", "Calculate cyclomatic complexity for a file", { filePath: z.string().describe("Path to the file to analyze") }, async (args) => { // Your complexity analysis logic here const complexity = Math.floor(Math.random() * 20) + 1; // Placeholder return { content: [{ type: "text", text: `Cyclomatic complexity for ${args.filePath}: ${complexity}` }] }; } ) ] }); // Use streaming input for MCP servers async function* generateMessages() { yield { type: "user" as const, message: { role: "user" as const, content: "Analyze the complexity of main.ts" } }; } for await (const message of query({ prompt: generateMessages(), options: { model: "opus", mcpServers: { "code-metrics": customServer }, allowedTools: ["Read", "mcp__code-metrics__analyze_complexity"], maxTurns: 250 } })) { // ... }

Отслеживание стоимости

Для биллинга можно отслеживать расходы на API:

for await (const message of query({ prompt: "..." })) { if (message.type === "result" && message.subtype === "success") { console.log("Total cost:", message.total_cost_usd); console.log("Token usage:", message.usage); // Per-model breakdown (useful with subagents) for (const [model, usage] of Object.entries(message.modelUsage)) { console.log(`${model}: $${usage.costUSD.toFixed(4)}`); } } }

Продакшен-агент для код-ревью

Ниже — готовый к использованию агент, который объединяет всё рассмотренное ранее:

import { query, AgentDefinition } from "@anthropic-ai/claude-agent-sdk"; interface ReviewResult { issues: Array<{ severity: "low" | "medium" | "high" | "critical"; category: "bug" | "security" | "performance" | "style"; file: string; line?: number; description: string; suggestion?: string; }>; summary: string; overallScore: number; } const reviewSchema = { type: "object", properties: { issues: { type: "array", items: { type: "object", properties: { severity: { type: "string", enum: ["low", "medium", "high", "critical"] }, category: { type: "string", enum: ["bug", "security", "performance", "style"] }, file: { type: "string" }, line: { type: "number" }, description: { type: "string" }, suggestion: { type: "string" } }, required: ["severity", "category", "file", "description"] } }, summary: { type: "string" }, overallScore: { type: "number" } }, required: ["issues", "summary", "overallScore"] }; async function runCodeReview(directory: string): Promise<ReviewResult | null> { console.log(`\n${"=".repeat(50)}`); console.log(`🔍 Code Review Agent`); console.log(`📁 Directory: ${directory}`); console.log(`${"=".repeat(50)}\n`); let result: ReviewResult | null = null; for await (const message of query({ prompt: `Perform a thorough code review of ${directory}. Analyze all source files for: 1. Bugs and potential runtime errors 2. Security vulnerabilities 3. Performance issues 4. Code quality and maintainability Be specific with file paths and line numbers where possible.`, options: { model: "opus", allowedTools: ["Read", "Glob", "Grep", "Task"], permissionMode: "bypassPermissions", maxTurns: 250, outputFormat: { type: "json_schema", schema: reviewSchema }, agents: { "security-scanner": { description: "Deep security analysis for vulnerabilities", prompt: `You are a security expert. Scan for: - Injection vulnerabilities (SQL, XSS, command injection) - Authentication and authorization flaws - Sensitive data exposure - Insecure dependencies`, tools: ["Read", "Grep", "Glob"], model: "sonnet" } as AgentDefinition } } })) { // Progress updates if (message.type === "assistant") { for (const block of message.message.content) { if ("name" in block) { if (block.name === "Task") { console.log(`🤖 Delegating to: ${(block.input as any).subagent_type}`); } else { console.log(`📂 ${block.name}: ${getToolSummary(block)}`); } } } } // Final result if (message.type === "result") { if (message.subtype === "success" && message.structured_output) { result = message.structured_output as ReviewResult; console.log(`\n✅ Review complete! Cost: $${message.total_cost_usd.toFixed(4)}`); } else { console.log(`\n❌ Review failed: ${message.subtype}`); } } } return result; } function getToolSummary(block: any): string { const input = block.input || {}; switch (block.name) { case "Read": return input.file_path || "file"; case "Glob": return input.pattern || "pattern"; case "Grep": return `"${input.pattern}" in ${input.path || "."}`; default: return ""; } } function printResults(result: ReviewResult) { console.log(`\n${"=".repeat(50)}`); console.log(`📊 REVIEW RESULTS`); console.log(`${"=".repeat(50)}\n`); console.log(`Score: ${result.overallScore}/100`); console.log(`Issues Found: ${result.issues.length}\n`); console.log(`Summary: ${result.summary}\n`); const byCategory = { critical: result.issues.filter(i => i.severity === "critical"), high: result.issues.filter(i => i.severity === "high"), medium: result.issues.filter(i => i.severity === "medium"), low: result.issues.filter(i => i.severity === "low") }; for (const [severity, issues] of Object.entries(byCategory)) { if (issues.length === 0) continue; const icon = severity === "critical" ? "🔴" : severity === "high" ? "🟠" : severity === "medium" ? "🟡" : "🟢"; console.log(`\n${icon} ${severity.toUpperCase()} (${issues.length})`); console.log("-".repeat(30)); for (const issue of issues) { const location = issue.line ? `${issue.file}:${issue.line}` : issue.file; console.log(`\n[${issue.category}] ${location}`); console.log(` ${issue.description}`); if (issue.suggestion) { console.log(` 💡 ${issue.suggestion}`); } } } } // Run the review async function main() { const directory = process.argv[2] || "."; const result = await runCodeReview(directory); if (result) { printResults(result); } } main().catch(console.error);

Запуск:

npx tsx review-agent.ts ./src

Что дальше

Агент для код-ревью покрывает базовые вещи: query(), allowedTools, структурированный вывод, сабагенты и управление разрешениями.
Если хочется копнуть глубже, есть куда развиваться.

Дополнительные возможности

  • Чекпоинты файлов — отслеживание изменений файлов и откат к предыдущим версиям

  • Skills — упаковка переиспользуемых возможностей

Продакшен-развёртывание

  • Хостинг — развёртывание в контейнерах и CI/CD

  • Безопасное развёртывание — sandboxing и управление учётными данными

Полная справка

  • Reference по TypeScript SDK

  • Reference по Python SDK

Это руководство описывает версию SDK V1. Версия V2 сейчас находится в разработке.

Русскоязычное сообщество про AI в разработке

e49d91116e8021878350d6d9209007d2.png

Друзья! Эту статью подготовила команда ТГК «AI for Devs» — канала, где мы рассказываем про AI-ассистентов, плагины для IDE, делимся практическими кейсами и свежими новостями из мира ИИ. Подписывайтесь, чтобы быть в курсе и ничего не упустить!

Источник

Возможности рынка
Логотип Sleepless AI
Sleepless AI Курс (AI)
$0.03934
$0.03934$0.03934
-3.46%
USD
График цены Sleepless AI (AI) в реальном времени
Отказ от ответственности: Статьи, размещенные на этом веб-сайте, взяты из общедоступных источников и предоставляются исключительно в информационных целях. Они не обязательно отражают точку зрения MEXC. Все права принадлежат первоисточникам. Если вы считаете, что какой-либо контент нарушает права третьих лиц, пожалуйста, обратитесь по адресу service@support.mexc.com для его удаления. MEXC не дает никаких гарантий в отношении точности, полноты или своевременности контента и не несет ответственности за любые действия, предпринятые на основе предоставленной информации. Контент не является финансовой, юридической или иной профессиональной консультацией и не должен рассматриваться как рекомендация или одобрение со стороны MEXC.