ИНФО
| Сложность | Средняя |
| Время | 45-60 минут |
| Что нужно | Node.js 18+, API-ключ Anthropic, базовое знание TypeScript |
| Инструменты | Claude Code CLI, @anthropic-ai/claude-agent-sdk |
Чему научитесь:
- Настроить SDK и запустить первый запрос
- Собрать агента для код-ревью, который читает файлы и возвращает структурированные находки
- Создать субагентов для специализированных задач вроде проверки безопасности
- Работать с разрешениями, сессиями и кастомными инструментами через MCP
Agent SDK — это инфраструктура, на которой работает Claude Code, упакованная в библиотеку. Вы получаете готовый цикл агента, встроенные инструменты для работы с файловой системой и управление контекстом. В этом руководстве мы соберём агента для код-ревью с нуля. На выходе получится штука, которая сканирует кодовую базу, находит проблемы и возвращает структурированный отчёт.
Начинаем
Сначала ставим Claude Code CLI. Agent SDK использует его как рантайм:
npm install -g @anthropic-ai/claude-code
Запустите claude в терминале и пройдите аутентификацию. Потом настройте проект:
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
Задайте API-ключ:
export ANTHROPIC_API_KEY=your-api-key
SDK vs голый API
Если вы уже делали агентов на сыром Messages API, то знаете цикл: вызвать модель, проверить, хочет ли она инструмент, выполнить инструмент, скормить результат обратно, повторить. SDK берёт это на себя.
// Голый API: вы управляете циклом
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, ... });
}
// SDK: Claude управляет сам
for await (const message of query({ prompt: "Fix the bug in auth.py" })) {
console.log(message);
}
SDK также даёт инструменты из коробки: Read, Write, Edit, Bash, Glob, Grep, WebSearch, WebFetch. Ничего из этого реализовывать самим не нужно.
Первый агент
Создаём 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() возвращает асинхронный генератор. Основные типы сообщений:
for await (const message of query({ prompt: "..." })) {
switch (message.type) {
case "system":
// Инициализация сессии
if (message.subtype === "init") {
console.log("Session ID:", message.session_id);
}
break;
case "assistant":
// Ответы Claude и вызовы инструментов
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":
// Финальный результат
console.log("Status:", message.subtype);
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",
maxTurns: 250
}
})) {
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}...`);
}
}
}
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}`);
}
}
}
}
reviewCode(".");
Настройка permissionMode: "bypassPermissions" автоматически одобряет операции чтения. Для теста создайте файл с намеренными багами:
// example.ts
function processUsers(users: any) {
for (let i = 0; i <= users.length; i++) { // Off-by-one
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 credentials
}
Запускаем npx tsx review-agent.ts. Claude найдёт баги, проблему с логированием пароля и предложит исправления.
Структурированный вывод
Для программного использования нужен JSON. SDK поддерживает JSON Schema:
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;
console.log(`\nScore: ${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}] ${issue.file}${issue.line ? `:${issue.line}` : ""}`);
console.log(` ${issue.description}`);
}
}
}
}
Управление разрешениями
Доступны три режима:
options: {
permissionMode: "default", // Запрашивает одобрение
permissionMode: "acceptEdits", // Автоматически одобряет редактирование файлов
permissionMode: "bypassPermissions" // Без запросов
}
Для тонкой настройки есть canUseTool:
options: {
canUseTool: async (toolName, input) => {
// Разрешаем всё чтение
if (["Read", "Glob", "Grep"].includes(toolName)) {
return { behavior: "allow", updatedInput: input };
}
// Блокируем запись в .env
if (toolName === "Write" && input.file_path?.includes(".env")) {
return { behavior: "deny", message: "Cannot modify .env files" };
}
return { behavior: "allow", updatedInput: input };
}
}
Субагенты
Для комплексных ревью можно делегировать работу специализированным субагентам:
import { query, AgentDefinition } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: `Perform a comprehensive code review of ${directory}.
Use security-reviewer for vulnerability detection.`,
options: {
model: "opus",
allowedTools: ["Read", "Glob", "Grep", "Task"],
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`,
tools: ["Read", "Grep", "Glob"],
model: "sonnet"
} as AgentDefinition
}
}
})) {
// Главный агент может делегировать через инструмент Task
// Субагенты работают со своей моделью и ограничениями инструментов
}
Инструмент Task позволяет делегировать. Главный агент решает, когда передать работу. Для субагентов можно использовать более дешёвые модели (Sonnet, Haiku).
Управление сессиями
Для многооборотных разговоров сохраняйте session ID и продолжайте:
let sessionId: string | undefined;
// Первый запрос
for await (const message of query({
prompt: "Review this codebase and identify the top 3 issues",
options: { model: "opus", allowedTools: ["Read", "Glob", "Grep"], maxTurns: 250 }
})) {
if (message.type === "system" && message.subtype === "init") {
sessionId = message.session_id;
}
}
// Продолжение с сохранённым контекстом
if (sessionId) {
for await (const message of query({
prompt: "Now show me how to fix the most critical issue",
options: {
resume: sessionId,
allowedTools: ["Read", "Glob", "Grep"],
maxTurns: 250
}
})) {
// Claude помнит предыдущие находки
}
}
Хуки
Хуки перехватывают вызовы инструментов для логирования, валидации или блокировки:
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 {};
};
const blockDangerous: 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: 50,
hooks: {
PreToolUse: [
{ hooks: [auditLogger] },
{ matcher: "Bash", hooks: [blockDangerous] }
]
}
}
})) {
// ...
}
Поле matcher принимает регулярное выражение. "Bash" срабатывает только на Bash; "Bash|Write|Edit" — на любой из них.
Кастомные инструменты через MCP
Встроенные инструменты покрывают файловую систему и веб-операции. Для всего остального используйте Model Context Protocol:
import { query, tool, createSdkMcpServer } from "@anthropic-ai/claude-agent-sdk";
import { z } from "zod";
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) => {
// Реальная имплементация считала бы настоящую сложность
const complexity = Math.floor(Math.random() * 20) + 1;
return {
content: [{
type: "text",
text: `Cyclomatic complexity for ${args.filePath}: ${complexity}`
}]
};
}
)
]
});
for await (const message of query({
prompt: `Analyze the complexity of main.ts`,
options: {
model: "opus",
mcpServers: { "code-metrics": customServer },
allowedTools: ["Read", "mcp__code-metrics__analyze_complexity"],
maxTurns: 50
}
})) {
// Claude теперь может вызывать ваш кастомный инструмент
}
Инструменты MCP следуют шаблону именования mcp__<имя-сервера>__<имя-инструмента>. Схема Zod определяет входные данные; обработчик запускается, когда Claude вызывает инструмент.
Отслеживание расходов
if (message.type === "result" && message.subtype === "success") {
console.log("Total cost:", message.total_cost_usd);
// Разбивка по моделям (полезно с субагентами)
for (const [model, usage] of Object.entries(message.modelUsage)) {
console.log(`${model}: $${usage.costUSD.toFixed(4)}`);
}
}
Решение проблем
"Cannot find module '@anthropic-ai/claude-agent-sdk'"
Выполните npm install @anthropic-ai/claude-agent-sdk в директории проекта. Пакет должен быть локальным, не только глобальным.
Ошибки аутентификации при запуске запросов
Сначала запустите claude в терминале и пройдите авторизацию. SDK использует аутентификацию Claude Code.
Агент зависает или выдаёт таймаут
Проверьте настройку maxTurns. Сложные задачи могут требовать 100+ итераций. Также убедитесь, что есть доступ к сети, если инструменты требуют внешних ресурсов.
Структурированный вывод возвращает null
Убедитесь, что JSON-схема валидна. Попробуйте сначала более простую схему. Массив required должен содержать только существующие свойства.
Субагент не вызывается
Нужен Task в массиве allowedTools. Без него главный агент не может делегировать.
Что дальше
Полноценный продакшн-агент показан в коде выше. Дальше можно изучить чекпоинтинг файлов для отслеживания изменений, систему Skills для упаковки переиспользуемых возможностей или паттерны деплоя для интеграции в CI/CD.
СОВЕТЫ
Настройка maxTurns ограничивает количество итераций агента. Для код-ревью больших кодовых баз 250 — разумное значение. Для быстрых проверок одного файла хватит 50.
Для субагентов с простым анализом используйте модель haiku. Она быстрее и дешевле. Оставьте opus для главного оркестратора и сложных рассуждений.
При отладке добавьте хук, который логирует каждый вызов инструмента. Это быстрее, чем продираться через консольный вывод, пытаясь понять, что Claude сделал.
Если упираетесь в rate limits, SDK не делает автоматических повторов. Оберните запрос в try-catch и реализуйте exponential backoff.
ЧаВо
Можно использовать Python вместо TypeScript? Да, есть Python SDK с теми же возможностями. Ссылка на документацию ниже.
Как ограничить, к каким файлам агент может обращаться?
Используйте колбэк canUseTool. Проверяйте file_path или pattern во входных данных и возвращайте { behavior: "deny" } для закрытых путей.
Агент помнит предыдущие разговоры?
Только в рамках сессии. Используйте опцию resume с session ID, чтобы продолжить разговор. Постоянной памяти между сессиями нет.
Сколько стоит типичный код-ревью? Зависит от размера кодовой базы. Небольшой проект (10-20 файлов) на Opus обычно обходится в $0.10-0.30. Большие базы или множественные вызовы субагентов стоят дороже.
РЕСУРСЫ
- TypeScript SDK Reference: Полная документация API со всеми опциями запросов и типами сообщений
- Python SDK Reference: Те же возможности на Python
- Claude Code Documentation: Среда выполнения и использование CLI
- MCP Specification: Для создания собственных серверов инструментов




