Цикл с первого взгляда
Каждая сессия агента следует одному и тому же циклу:- Получить запрос. Claude получает ваш запрос вместе с системным запросом, определениями инструментов и историей разговора. SDK выдает
SystemMessageс подтипом"init", содержащий метаданные сессии. - Оценить и ответить. Claude оценивает текущее состояние и определяет, как действовать дальше. Он может ответить текстом, запросить один или несколько вызовов инструментов или оба варианта. SDK выдает один или несколько объектов
AssistantMessage, по одному для каждого блока содержимого, такого как текстовый блок или запрос вызова инструмента. - Выполнить инструменты. SDK запускает каждый запрошенный инструмент и собирает результаты. Каждый набор результатов инструментов возвращается Claude для следующего решения. Вы можете использовать hooks для перехвата, изменения или блокировки вызовов инструментов перед их выполнением.
- Повторить. Шаги 2 и 3 повторяются как цикл. Каждый полный цикл — это один ход. Claude продолжает вызывать инструменты и обрабатывать результаты до тех пор, пока не выдаст ответ без вызовов инструментов.
- Вернуть результат. SDK выдает финальное
AssistantMessageс текстовым ответом (без вызовов инструментов), за которым следуетResultMessageс финальным текстом, использованием токенов, стоимостью и ID сессии.
Glob и ответа с результатами. Сложная задача («рефакторить модуль аутентификации и обновить тесты») может связать десятки вызовов инструментов на протяжении многих ходов, читая файлы, редактируя код и запуская тесты, при этом Claude корректирует свой подход на основе каждого результата.
Ходы и сообщения
Ход — это один цикл внутри цикла: Claude выдает выход, который включает вызовы инструментов, SDK выполняет эти инструменты, и результаты автоматически возвращаются Claude. Это происходит без возврата управления вашему коду. Ходы продолжаются до тех пор, пока Claude не выдаст выход без вызовов инструментов, после чего цикл заканчивается и доставляется финальный результат. Рассмотрим, как может выглядеть полная сессия для запроса «Исправить неудачные тесты в auth.ts». Сначала SDK отправляет ваш запрос Claude и выдаетSystemMessage с метаданными сессии. Затем начинается цикл:
- Ход 1: Claude вызывает
Bashдля запускаnpm test. SDK выдаетAssistantMessageс вызовом инструмента, выполняет команду, затем выдаетUserMessageс выводом (три ошибки). - Ход 2: Claude вызывает
Readнаauth.tsиauth.test.ts. SDK выдаетAssistantMessageдля каждого вызова и возвращает содержимое файлов. - Ход 3: Claude вызывает
Editдля исправленияauth.ts, затем вызываетBashдля повторного запускаnpm test. Все три теста проходят. SDK выдаетAssistantMessageдля каждого вызова. - Финальный ход: Claude выдает текстовый ответ без вызовов инструментов: «Исправлена ошибка аутентификации, все три теста теперь проходят.» SDK выдает финальное
AssistantMessageс этим текстом, затемResultMessageс тем же текстом плюс стоимость и использование.
max_turns / maxTurns, который считает только ходы с использованием инструментов. Например, max_turns=2 в цикле выше остановился бы перед шагом редактирования. Вы также можете использовать max_budget_usd / maxBudgetUsd для ограничения ходов на основе порога расходов.
Без ограничений цикл работает до тех пор, пока Claude не закончит самостоятельно, что хорошо для хорошо определенных задач, но может работать долго на открытых запросах («улучшить этот кодовую базу»). Установка бюджета — хороший стандарт для производственных агентов. См. Ходы и бюджет ниже для справки по опциям.
Типы сообщений
По мере выполнения цикла SDK выдает поток сообщений. Каждое сообщение имеет тип, который говорит вам, на каком этапе цикла оно пришло. Пять основных типов:-
SystemMessage: события жизненного цикла сессии. Полеsubtypeих различает:"init": метаданные сессии для запуска. Когда hookSessionStartилиSetupзапускается при инициализации сессии, его сообщения жизненного цикла hook прибывают перед сообщениемinit"compact_boundary": срабатывает после компактирования"informational": простые текстовые баннеры статуса из цикла"worker_shutting_down": хост выходит или Remote Control отключился
"init", является собственным типом в объединенииSDKMessage, а не подтипомSDKSystemMessage. -
AssistantMessage: выдается для каждого блока содержимого в ответах Claude, включая финальный текстовый. Каждое содержит один блок содержимого, такой как текст или вызов инструмента, и сообщения из одного ответа имеют общий ID сообщения. -
UserMessage: выдается после каждого выполнения инструмента с результатом инструмента, отправленным обратно Claude. Также выдается для любых пользовательских входов, которые вы транслируете в середине цикла. -
StreamEvent: выдается только при включении частичных сообщений. Содержит необработанные события потоковой передачи API (дельты текста, фрагменты входных данных инструмента). См. Потоковые ответы. -
ResultMessage: отмечает конец цикла агента. Содержит финальный текстовый результат, использование токенов, стоимость и ID сессии. Проверьте полеsubtype, чтобы определить, успешна ли задача или достигнут ли лимит. Небольшое количество завершающих системных событий, таких какprompt_suggestion, может прибыть после него, поэтому итерируйте поток до завершения, а не прерывайте на результате. См. Обработать результат.
Обработать сообщения
Какие сообщения вы обрабатываете, зависит от того, что вы создаете:- Только финальные результаты: обработайте
ResultMessage, чтобы получить выход, стоимость и то, успешна ли задача или достигнут ли лимит. - Обновления прогресса: обработайте
AssistantMessage, чтобы увидеть, что делает Claude на каждом ходу, включая какие инструменты он вызвал. - Прямая потоковая передача: включите частичные сообщения (
include_partial_messagesв Python,includePartialMessagesв TypeScript), чтобы получить сообщенияStreamEventв реальном времени. См. Потоковые ответы в реальном времени.
- Python: проверьте типы сообщений с помощью
isinstance()для классов, импортированных изclaude_agent_sdk(например,isinstance(message, ResultMessage)). - TypeScript: проверьте строковое поле
type(например,message.type === "result").AssistantMessageиUserMessageоборачивают необработанное сообщение API в поле.message, поэтому блоки содержимого находятся вmessage.message.content, а не вmessage.content.
Пример: Проверить типы сообщений и обработать результаты
Пример: Проверить типы сообщений и обработать результаты
Выполнение инструментов
Инструменты дают вашему агенту возможность действовать. Без инструментов Claude может только отвечать текстом. С инструментами Claude может читать файлы, запускать команды, искать код и взаимодействовать с внешними сервисами.Встроенные инструменты
SDK включает те же инструменты, которые питают Claude Code:
На моделях, которые не получают инструменты отслеживания задач, Claude Code предоставляет
TaskCreate и TaskUpdate только когда вы согласитесь.
Помимо встроенных инструментов, вы можете:
- Подключить внешние сервисы с помощью MCP servers (базы данных, браузеры, API)
- Определить пользовательские инструменты с помощью пользовательских обработчиков инструментов
- Загрузить skills проекта через источники настроек для повторно используемых рабочих процессов
Разрешения инструментов
Claude определяет, какие инструменты вызывать на основе задачи, но вы контролируете, разрешено ли выполнение этих вызовов. Вы можете автоматически одобрить определенные инструменты, полностью заблокировать другие или требовать одобрения для всего. Три опции работают вместе, чтобы определить, что работает:allowed_tools/allowedToolsавтоматически подтверждает перечисленные инструменты. Агент только для чтения с["Read", "Glob", "Grep"]в списке разрешенных инструментов запускает эти инструменты без запросов, за исключением чтения из сетевых путей. Инструменты, не указанные в списке, все еще доступны, и вызовы к ним, которые требуют подтверждения, переходят к режиму разрешений иcanUseTool.disallowed_tools/disallowedToolsблокирует перечисленные инструменты, независимо от других настроек. См. Разрешения для порядка, в котором правила проверяются перед запуском инструмента.permission_mode/permissionModeконтролирует, сколько человеческого надзора вы хотите. SDK оценивает активный режим вместе с вашими правилами разрешения и запрета в фиксированном порядке, описанном в Как оцениваются разрешения. См. Режим разрешения для доступных режимов.
"Bash(npm *)", чтобы разрешить только определенные команды. См. Разрешения для полного синтаксиса правил.
Когда инструмент отклоняется, Claude получает сообщение об отклонении как результат инструмента и обычно пытается использовать другой подход или сообщает, что не может продолжить.
Параллельное выполнение инструментов
Когда Claude запрашивает несколько вызовов инструментов в одном ходе, оба SDK могут запускать их одновременно или последовательно в зависимости от инструмента. Инструменты только для чтения (такие какRead, Glob, Grep и MCP инструменты, отмеченные как только для чтения) могут работать одновременно. Инструменты, которые изменяют состояние (такие как Edit, Write и Bash), работают последовательно, чтобы избежать конфликтов.
Пользовательские инструменты по умолчанию работают последовательно. Чтобы включить параллельное выполнение для пользовательского инструмента, установите readOnlyHint в его аннотациях. Оба SDK TypeScript и Python используют это имя поля из MCP SDK.
Контролировать, как работает цикл
Вы можете ограничить количество ходов, которые делает цикл, сколько он стоит, насколько глубоко Claude рассуждает, и требуют ли инструменты одобрения перед запуском. Все это поля наClaudeAgentOptions (Python) / Options (TypeScript).
Ходы и бюджет
Когда достигается любой лимит, SDK возвращает
ResultMessage с соответствующим подтипом ошибки (error_max_turns или error_max_budget_usd). См. Обработать результат для того, как проверить эти подтипы, и ClaudeAgentOptions / Options для синтаксиса.
Крышка бюджета охватывает подагентов: их расходы учитываются в общей сумме. Когда расходы достигают крышки, создание другого подагента не удается с Budget limit reached, и Claude Code останавливает любых фоновых подагентов, которые все еще работают. Поведение принудительного применения крышки требует Claude Code v2.1.217 или позже.
При потоковом вводе сообщение, которое все еще находится в очереди, когда ход заканчивается на пределе максимальных ходов, остается в очереди. Claude Code не добавляет его в последний вызов модели этого хода. Он начинает новый ход для сообщения, и счетчик максимальных ходов начинается заново для этого хода. Общий бюджет продолжает накапливаться между сообщениями, и как только расходы достигают maxBudgetUsd, более поздние сообщения в той же беседе заканчиваются результатом error_max_budget_usd. /clear начинает бюджет заново.
Запас бюджета
Claude Code сравнивает расходы с лимитомmax_budget_usd / maxBudgetUsd после получения ответов модели, поскольку стоимость каждого ответа определяется использованием токенов, которое API возвращает вместе с ним. Ответ, достигший лимита, все равно завершается и учитывается в total_cost_usd. Поэтому расходы могут превысить лимит не более чем на стоимость этого одного ответа плюс все, что потратят субагенты, еще работающие в этот момент, до своей остановки. Оставляйте запас на это при установке лимита.
Уровень усилий
Опцияeffort контролирует, сколько рассуждений применяет Claude. Более низкие уровни усилий используют меньше токенов за ход и снижают стоимость. Не все модели поддерживают параметр effort. См. Effort для того, какие модели его поддерживают.
Если вы не установите
effort, Claude Code разрешает уровень усилий сам по себе, в порядке, который описывает Adjust effort level.
effort обменивает задержку и стоимость токена на глубину рассуждения в каждом ответе. Extended thinking — это отдельная функция, которая выдает блоки thinking в выводе, и поле display на ThinkingConfig для Python или TypeScript контролирует, получаете ли вы их текст. Они независимы: вы можете установить effort: "low" с включенным extended thinking или effort: "max" без него.effort в опциях верхнего уровня query() для всей сессии или для каждого подагента с полем effort на AgentDefinition, чтобы переопределить уровень сессии.
Режим разрешения
Опция режима разрешения (permission_mode в Python, permissionMode в TypeScript) контролирует, просит ли агент одобрения перед использованием инструментов:
Для интерактивных приложений используйте
"default" с обратным вызовом одобрения инструмента для отображения подсказок одобрения. Для автономных агентов на машине разработки используйте "acceptEdits", чтобы автоматически одобрить редактирование файлов и общие команды файловой системы (mkdir, touch, mv, cp и т. д.), при этом все еще ограничивая другие команды Bash правилами разрешения. Зарезервируйте "bypassPermissions" для CI, контейнеров или других изолированных окружений. См. Разрешения для полных деталей.
Модель
Установите опциюmodel для выбора модели, которая запускает сессию. Для получения дополнительной информации см. Выбрать модель.
Контекстное окно
Контекстное окно — это общее количество информации, доступной Claude во время сессии. Оно не сбрасывается между ходами в пределах сессии. Все накапливается: системный промпт, определения инструментов, история диалога, входные данные инструментов и выходные данные инструментов. Содержимое, которое остается неизменным на протяжении ходов (системный промпт, определения инструментов, CLAUDE.md), автоматически кэшируется с помощью кэширования промптов, что снижает стоимость и задержку для повторяющихся префиксов. Информацию о том, как пользовательский системный промпт или текстappend влияет на повторное использование кэша между сессиями, см. в разделе Изменение системных промптов.
Что потребляет контекст
Вот как каждый компонент влияет на контекст в SDK:
Большие выходные данные инструментов потребляют значительный объем контекста. Чтение большого файла или запуск команды с подробным выводом может использовать тысячи токенов за один ход. Контекст накапливается на протяжении ходов, поэтому более длительные сессии с множеством вызовов инструментов накапливают значительно больше контекста, чем короткие.
Автоматическое сжатие контекста
Когда контекстное окно приближается к своему лимиту, SDK автоматически сжимает диалог: он кратко резюмирует более старую историю, чтобы освободить место, сохраняя нетронутыми ваши самые последние обмены сообщениями и ключевые решения. Когда это происходит, SDK выдает в поток сообщение сtype: "system" и subtype: "compact_boundary" (в Python это SystemMessage; в TypeScript это отдельный тип SDKCompactBoundaryMessage).
Сжатие контекста заменяет более старые сообщения резюме, поэтому конкретные инструкции из начала диалога могут не сохраниться. Постоянные правила следует размещать в CLAUDE.md (загружаемом через settingSources), а не в начальном промпте, потому что содержимое CLAUDE.md повторно добавляется в каждый запрос.
Вы можете настроить поведение сжатия контекста несколькими способами:
- Инструкции по резюмированию в CLAUDE.md: механизм сжатия читает ваш CLAUDE.md как любой другой контекст, поэтому вы можете добавить раздел, указывающий, что сохранять при резюмировании. Механизм сжатия ориентируется на смысл, поэтому заголовок раздела может быть произвольным.
- Хук
PreCompact: запускайте пользовательскую логику перед сжатием контекста, например для архивирования полного транскрипта. Хук получает полеtrigger(manualилиauto). См. хуки. - Ручное сжатие контекста: отправьте
/compactв качестве строки промпта, чтобы запустить сжатие по требованию. Команды, отправленные таким образом, — это обычные входные данные SDK. См. отправка команд по имени.
Пример: инструкции по резюмированию в CLAUDE.md
Пример: инструкции по резюмированию в CLAUDE.md
Добавьте в CLAUDE.md вашего проекта раздел, указывающий механизму сжатия, что сохранять. Название заголовка не имеет особого значения; используйте любую понятную метку.
CLAUDE.md
Эффективное использование контекста
Несколько стратегий для долго работающих агентов:- Используйте субагентов для подзадач. Каждый субагент начинает с нового диалога (без предыдущей истории сообщений, хотя он загружает собственный системный промпт и контекст уровня проекта, такой как CLAUDE.md). Он не видит ходы родительского агента, и родителю возвращается только его финальный ответ. Контекст основного агента увеличивается на это резюме, а не на полный транскрипт подзадачи. Подробности см. в разделе Что наследуют субагенты.
- Тщательно выбирайте инструменты. Каждое определение инструмента занимает место в контексте. Используйте поле
toolsвAgentDefinition, чтобы ограничить субагентов минимальным необходимым набором инструментов. - Следите за затратами на MCP-серверы. MCP Tool Search по умолчанию откладывает загрузку схем инструментов MCP и загружает их по требованию. Когда поиск инструментов отключен или переключился на предварительную загрузку, каждый MCP-сервер добавляет все свои схемы инструментов в каждый запрос, поэтому несколько серверов с множеством инструментов могут потребить значительный объем контекста еще до того, как агент выполнит какую-либо работу. Конфигурации, в которых применяется этот резервный вариант, см. в разделе Настройка поиска инструментов.
- Используйте более низкий уровень effort для рутинных задач. Установите effort в значение
"low"для агентов, которым нужно только читать файлы или выводить списки каталогов. Это снижает расход токенов и стоимость.
Сессии и непрерывность
Каждое взаимодействие с SDK создает или продолжает сессию. Захватите ID сессии изResultMessage.session_id (доступно в обоих SDK) для возобновления позже. TypeScript SDK также выставляет его как прямое поле на инициализирующем SystemMessage; в Python он вложен в SystemMessage.data.
Когда вы возобновляете, полный контекст из предыдущих ходов восстанавливается: файлы, которые были прочитаны, анализ, который был выполнен, и действия, которые были предприняты. Вы также можете разветвить сессию, чтобы ветвиться в другой подход без изменения оригинала.
См. Управление сессией для полного руководства по возобновлению, продолжению и разветвлению паттернов. Для возобновления сессий в контейнерах без состояния или бессерверных хостах передайте адаптер session_store / sessionStore, чтобы SDK зеркалировал стенограммы на ваш собственный бэкенд и другой хост мог их возобновить. Подпроцесс Claude Code по-прежнему сначала записывает на локальный диск. См. Архитектура двойной записи для того, какая копия пережидает свежую сессию в сравнении с запуском, возобновленным из хранилища, и как сохранить локальную копию эфемерной.
В Python
ClaudeSDKClient автоматически обрабатывает ID сессий на протяжении нескольких вызовов. См. справку Python SDK для деталей.Обработать результат
Когда цикл заканчивается,ResultMessage говорит вам, что произошло, и дает вам выход. Поле subtype (доступно в обоих SDK) — это основной способ проверить состояние завершения.
Поле
result содержит финальный текстовый выход и присутствует только в варианте success, поэтому всегда проверяйте подтип перед его чтением.
Все подтипы результатов содержат total_cost_usd, usage, num_turns и session_id, поэтому вы можете отслеживать стоимость и возобновлять даже после ошибок. Обратите внимание на эти случаи:
- После сбоя сеанса финальный результат — это
error_during_execution, чьи поля стоимости могут быть обнулены и чейstop_reasonравенnull, и процесс завершается после его выдачи. См. Восстановление итогов после сбоя сеанса. - В Python
total_cost_usd,usageиmodel_usageтипизированы как опциональные, поэтому проверьте, что они не равныNoneперед их чтением.
usage охватывает только основной цикл агента. Используйте modelUsage или model_usage в Python для полного учета токенов и стоимости дерева. См. Отслеживание стоимости и использования для деталей по интерпретации полей usage.
Когда запрос заканчивается на результате ошибки:
- Одиночный вызов
query()выдает финальное сообщение результата, затем вызывает ошибку, которая включает текст отказа, такой какReached maximum number of turns. Вызов ошибки намеренный. Оберните цикл в блок try, если вашему коду нужно продолжить работу после него. Базовый процесс Claude Code также завершается с ненулевым кодом. - Сеанс потоковой передачи входных данных остается активным, и вы можете продолжать отправлять сообщения, кроме случаев после сбоя сеанса, который выдает финальный результат
error_during_executionи завершает процесс.
stop_reason (string | null в TypeScript, str | None в Python), указывающее, почему модель остановила генерацию на своем финальном ходе. Общие значения — end_turn (модель закончила нормально), max_tokens (достигнут лимит выходных токенов) и refusal (модель отклонила запрос). На результатах ошибок, которые произвел цикл, stop_reason содержит значение из последнего ответа помощника перед завершением цикла; результат, который Claude Code синтезирует после сбоя сеанса, содержит null.
Для обнаружения отклонений проверьте stop_reason === "refusal" (TypeScript) или stop_reason == "refusal" (Python). См. SDKResultMessage (TypeScript) или ResultMessage (Python) для полного типа.
Hooks
Hooks — это обратные вызовы, которые срабатывают в определенных точках цикла: перед запуском инструмента, после его возврата, когда агент заканчивает, и так далее. Некоторые часто используемые hooks:
Hooks работают в процессе вашего приложения, а не внутри контекстного окна агента, поэтому они не потребляют контекст. Hooks также могут короткозамкнуть цикл: hook
PreToolUse, который отклоняет вызов инструмента, предотвращает его выполнение, и Claude получает сообщение об отклонении вместо этого.
Оба SDK поддерживают все события выше. TypeScript SDK включает дополнительные события, которые Python еще не поддерживает. См. Контролировать выполнение с помощью hooks для полного списка событий, доступности для каждого SDK и полного API обратного вызова.
Собрать все вместе
Этот пример объединяет ключевые концепции с этой страницы в одного агента, который исправляет неудачные тесты. Он конфигурирует агента с разрешенными инструментами (автоматически одобренными, поэтому агент работает автономно), настройками проекта и ограничениями безопасности на ходы и усилия рассуждения. По мере выполнения цикла он захватывает ID сессии для потенциального возобновления, обрабатывает финальный результат и выводит общую стоимость. Поскольку один вызовquery() вызывает исключение после выдачи результата ошибки, цикл обернут в блок try, чтобы скрипт корректно завершился при достижении лимита.
Done: с резюме исправления агента, а затем строку вроде Cost: $0.0312.
Следующие шаги
Теперь, когда вы понимаете цикл, вот куда идти в зависимости от того, что вы создаете:- Еще не запустили агента? Начните с quickstart, чтобы установить SDK и увидеть полный пример, работающий от начала до конца.
- Готовы подключиться к вашему проекту? Загрузите CLAUDE.md, skills и hooks файловой системы, чтобы агент автоматически следовал соглашениям вашего проекта.
- Создаете интерактивный UI? Включите потоковую передачу, чтобы показать живой текст и вызовы инструментов по мере выполнения цикла.
- Нужен более плотный контроль над тем, что может делать агент? Заблокируйте доступ к инструментам с помощью разрешений и используйте hooks для аудита, блокировки или преобразования вызовов инструментов перед их выполнением.
- Запускаете долгие или дорогие задачи? Перенесите изолированную работу на подагентов, чтобы держать ваш основной контекст стройным.
- Развертываете как сервис? См. Размещение Agent SDK для руководства по контейнерам и бессерверным решениям, и Хранилище сессий для сохранения сессий в вашем собственном бэкенде.