Claude Agent SDK: программная сборка агентов

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

До недавнего времени библиотека называлась «Claude Code SDK» — это важно учитывать, если встречаете старые статьи. Сейчас официальное название: Claude Agent SDK.

> Важно на сегодня. С 15 июня 2026 года использование Agent SDK на подписочных планах (Pro/Max/Team/Enterprise) тарифицируется отдельным месячным кредитом Agent SDK Credit, отдельно от интерактивного лимита. Подробности — в справочной статье Anthropic.


Установка

# TypeScript (Node.js 18+)
npm install @anthropic-ai/claude-agent-sdk

# Python (3.10+)
pip install claude-agent-sdk

TypeScript-пакет поставляется с нативным бинарником Claude Code для вашей платформы — отдельная установка CLI не нужна. Python требует 3.10+: если получаете No matching distribution found, проверьте python3 --version.

Аутентификация: переменная окружения ANTHROPIC_API_KEY. SDK также поддерживает Amazon Bedrock (CLAUDE_CODE_USE_BEDROCK=1), Google Vertex AI (CLAUDE_CODE_USE_VERTEX=1) и Microsoft Azure Foundry (CLAUDE_CODE_USE_FOUNDRY=1) — для корпоративных окружений, где нужен контроль над регионом данных.


query(): сердце SDK

Единственная точка входа — функция query(). Она запускает агентный цикл и возвращает асинхронный итератор: каждая итерация — одно событие из потока работы Claude.

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions

async def main():
    async for message in query(
        prompt="Find and fix the division-by-zero bug in utils.py",
        options=ClaudeAgentOptions(
            allowed_tools=["Read", "Edit", "Glob"],
            permission_mode="acceptEdits",
        ),
    ):
        if hasattr(message, "result"):
            print(message.result)

asyncio.run(main())

То же самое на TypeScript:

import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
  prompt: "Find and fix the division-by-zero bug in utils.ts",
  options: {
    allowedTools: ["Read", "Edit", "Glob"],
    permissionMode: "acceptEdits"
  }
})) {
  if ("result" in message) console.log(message.result);
}

Обратите внимание на разницу в именовании: Python использует snake_case (allowed_tools, permission_mode), TypeScript — camelCase (allowedTools, permissionMode). Концепции идентичны.

Цикл async for крутится, пока Claude думает, вызывает инструменты, наблюдает результаты — и сам решает, когда задача выполнена. Вы просто читаете поток.

sequenceDiagram participant App as Ваш код participant SDK as Agent SDK participant Claude as Claude participant Tools as Инструменты (Read/Edit/Bash...) App->>SDK: query(prompt, options) SDK->>Claude: промпт + список инструментов Claude-->>App: SystemMessage (session_id) loop Агентный цикл Claude->>Claude: рассуждение Claude-->>App: AssistantMessage (текст) Claude->>Tools: вызов инструмента Tools-->>Claude: результат инструмента Claude-->>App: AssistantMessage (tool call) end Claude-->>App: ResultMessage (success/error) SDK-->>App: итератор закрыт
sequenceDiagram
    participant App as Ваш код
    participant SDK as Agent SDK
    participant Claude as Claude
    participant Tools as Инструменты (Read/Edit/Bash...)

    App->>SDK: query(prompt, options)
    SDK->>Claude: промпт + список инструментов
    Claude-->>App: SystemMessage (session_id)
    loop Агентный цикл
        Claude->>Claude: рассуждение
        Claude-->>App: AssistantMessage (текст)
        Claude->>Tools: вызов инструмента
        Tools-->>Claude: результат инструмента
        Claude-->>App: AssistantMessage (tool call)
    end
    Claude-->>App: ResultMessage (success/error)
    SDK-->>App: итератор закрыт
Поток query(): каждый шаг агентного цикла — отдельное сообщение в async-итераторе

Быстрое повторение
query() в Agent SDK возвращает асинхронный _____—объект, который итерирует события агентного цикла.

Типы сообщений в потоке

Bез фильтрации вы получаете «сырой» поток. Три ключевых типа:

ТипКогдаЧто внутри
SystemMessage (subtype init)Первымsession_id — нужен для возобновления сессии
AssistantMessageПостоянноcontent — рассуждения Claude и вызовы инструментов
ResultMessageПоследнимresult — итог; subtypesuccess или error

Для production-кода фильтруйте только ResultMessage, для дебага — печатайте всё:

from claude_agent_sdk import AssistantMessage, ResultMessage, SystemMessage

async for message in query(prompt="...", options=opts):
    if isinstance(message, SystemMessage) and message.subtype == "init":
        session_id = message.data["session_id"]   # сохраняем для resume
    elif isinstance(message, AssistantMessage):
        for block in message.content:
            if hasattr(block, "text"):
                print("Claude:", block.text)        # рассуждение
            elif hasattr(block, "name"):
                print("Tool:", block.name)          # вызов инструмента
    elif isinstance(message, ResultMessage):
        print("Done:", message.subtype)             # success / error
Проверь себя
Вы запускаете query() и видите поток сообщений. Где именно находится session_id, если он понадобится для resume? Подумайте, прежде чем читать ответ.

Инструменты и режимы разрешений

allowed_tools — список инструментов, которые SDK одобряет автоматически без запроса. Доступны все инструменты Claude Code:

ИнструментЧто делает
Read, Write, EditФайловые операции
BashТерминальные команды, git, npm
Glob, GrepПоиск файлов и по содержимому
WebSearch, WebFetchПоиск в вебе
MonitorНаблюдение за фоновым процессом
AgentЗапуск субагентов (включать явно)
AskUserQuestionЗадать уточняющий вопрос пользователю

Режимы разрешений определяют, что происходит с инструментами вне allowed_tools:

РежимПоведениеКогда использовать
acceptEditsАвто-одобряет файловые операции, запрашивает остальноеДоверенные dev-сценарии
dontAskЗапрещает всё, чего нет в allowed_toolsHeadless-агенты с жёстким контролем
auto (только TS)Модель-классификатор решает самаАвтономные агенты с защитой
bypassPermissionsВыполняет всё без вопросовИзолированные CI-окружения, sandbox
defaultТребует колбэк canUseToolКастомные флоу с ручным одобрением
Проверь себя
Вы создали агента с allowed_tools=["Read", "Grep"] и permission_mode="dontAsk". Claude пытается запустить Bash-команду. Что произойдёт?

Быстрое повторение
Что происходит с инструментом, добавленным в allowed_tools?

Хуки: программные колбэки

В settings.json хуки — это shell-команды. В SDK хуки — это функции прямо в вашем коде. Концепция одна, реализация иная.

from claude_agent_sdk import query, ClaudeAgentOptions, HookMatcher
from datetime import datetime

async def audit_file_change(input_data, tool_use_id, context):
    path = input_data.get("tool_input", {}).get("file_path", "unknown")
    with open("audit.log", "a") as f:
        f.write(f"{datetime.now()}: modified {path}\n")
    return {}  # пустой dict = разрешить; {"decision": "block"} = запретить

async for message in query(
    prompt="Рефактори utils.py",
    options=ClaudeAgentOptions(
        permission_mode="acceptEdits",
        hooks={
            "PostToolUse": [
                HookMatcher(matcher="Edit|Write", hooks=[audit_file_change])
            ]
        },
    ),
):
    ...

Доступные события: PreToolUse, PostToolUse, Stop, SessionStart, SessionEnd, UserPromptSubmit. Хук возвращает {} (продолжить) или {"decision": "block", "reason": "..."} (заблокировать). Это даёт полный программный контроль над жизненным циклом агента.


Быстрое повторение
Как в Agent SDK реализуются хуки — как функции или как shell-команды?

Субагенты, сессии и MCP

Субагенты объявляются прямо в options и запускаются через инструмент Agent (его нужно добавить в allowed_tools):

from claude_agent_sdk import AgentDefinition

options = ClaudeAgentOptions(
    allowed_tools=["Read", "Glob", "Grep", "Agent"],
    agents={
        "code-reviewer": AgentDefinition(
            description="Expert code reviewer",
            prompt="Analyze code quality and security. Be concise.",
            tools=["Read", "Glob", "Grep"],
        )
    },
)

Сессии сохраняют контекст между несколькими вызовами query(). Захватите session_id из первого вызова и передайте как resume:

# Второй вызов продолжает первый — "it" понятен без повтора контекста
async for message in query(
    prompt="Now find all callers of the function we just analyzed",
    options=ClaudeAgentOptions(resume=session_id),
):
    ...

MCP-серверы подключаются через опцию mcp_servers с той же структурой, что и .mcp.json:

options = ClaudeAgentOptions(
    mcp_servers={
        "playwright": {"command": "npx", "args": ["@playwright/mcp@latest"]}
    }
)

Подробнее об MCP-серверах как концепции — в Model Context Protocol: архитектура и основы.


GitHub Action — обёртка над Agent SDK

Если вы разобрались с SDK, то GitHub Action стал прозрачнее. anthropics/claude-code-action официально описывается как «built on top of the Claude Agent SDK». Action запускает query() внутри GitHub runner, передавая контекст события (тело issue, diff PR, комментарий с @claude) как промпт.

# Фактически action делает примерно это:
for await (const message of query({
  prompt: buildPromptFromGitHubEvent(event),
  options: {
    allowedTools: parseAllowedTools(claude_args),
    permissionMode: "acceptEdits"
  }
})) { ... }

Это объясняет, почему claude_args в YAML-файле экшна принимает те же флаги, что и CLI: --max-turns, --model, --allowedTools. Под капотом — тот же движок.

Если встроенного Action недостаточно, вы можете использовать SDK напрямую внутри runs-on: ubuntu-latest и построить любую кастомную логику. Подробнее о самом Action — в GitHub Actions и автоматический code review.


SDK, CLI или Client SDK: что выбрать

Путь принятия решений простой.

Agent SDK vs CLI: один движок, разный интерфейс. CLI — для ежедневной разработки за терминалом. SDK — для CI/CD, custom-приложений, автоматизации. Многие команды используют оба.

Agent SDK vs Anthropic Client SDK (Claude API и Anthropic SDK: основы): принципиальная разница — кто реализует tool loop:

# Client SDK: вы сами реализуете цикл
response = client.messages.create(...)
while response.stop_reason == "tool_use":
    result = your_tool_executor(response.tool_use)
    response = client.messages.create(tool_result=result, ...)

# Agent SDK: Claude сам управляет циклом
async for message in query(prompt="Fix the bug"):
    print(message)

Client SDK даёт максимальный контроль над каждым шагом и стоимостью; Agent SDK — скорость разработки и готовую агентную инфраструктуру.

Agent SDK vs Managed Agents: SDK запускает агентный цикл в вашем процессе и на вашей инфраструктуре. Managed Agents (размещённый REST API) — Anthropic сама управляет sandbox и сессиями, вы только отправляете задачи. Типичный путь: прототипирование на SDK → перевод в Managed Agents для production при необходимости.


Что загружается из файловой системы

По умолчанию SDK подхватывает конфигурацию из директории запуска, как это делает обычный сеанс Claude Code:

ПутьЧто загружается
CLAUDE.md / .claude/CLAUDE.mdПамять проекта, инструкции
.claude/skills/*/SKILL.mdНавыки
.claude/commands/*.mdКастомные команды

Чтобы изолировать агента от локального окружения (например, в CI), используйте setting_sources=[] — SDK не будет читать ничего из файловой системы, только опции из кода.


See also