agent-sdk/agent-loop.md +395 −0 created
1> ## Documentation Index
2> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
3> Use this file to discover all available pages before exploring further.
4
5# Как работает цикл агента
6
7> Поймите жизненный цикл сообщений, выполнение инструментов, контекстное окно и архитектуру, которые питают ваших агентов SDK.
8
9Agent SDK позволяет встроить автономный цикл агента Claude Code в ваши собственные приложения. SDK — это отдельный пакет, который дает вам программный контроль над инструментами, разрешениями, ограничениями затрат и выводом. Вам не нужно устанавливать Claude Code CLI для его использования.
10
11Когда вы запускаете агента, SDK запускает тот же [цикл выполнения, который питает Claude Code](/ru/how-claude-code-works#the-agentic-loop): Claude оценивает ваш запрос, вызывает инструменты для выполнения действий, получает результаты и повторяет до завершения задачи. На этой странице объясняется, что происходит внутри этого цикла, чтобы вы могли эффективно создавать, отлаживать и оптимизировать своих агентов.
12
13## Цикл с первого взгляда
14
15Каждая сессия агента следует одному и тому же циклу:
16
17<img src="https://mintcdn.com/claude-code/gvy2DIUELtNA8qD3/images/agent-loop-diagram.svg?fit=max&auto=format&n=gvy2DIUELtNA8qD3&q=85&s=192e1bd6c8a2950a16e5ee0b94e27e26" alt="Цикл агента: запрос входит, Claude оценивает, ветвится на вызовы инструментов или финальный ответ" width="680" height="150" data-path="images/agent-loop-diagram.svg" />
18
191. **Получить запрос.** Claude получает ваш запрос вместе с системным запросом, определениями инструментов и историей разговора. SDK выдает [`SystemMessage`](#message-types) с подтипом `"init"`, содержащий метаданные сессии.
202. **Оценить и ответить.** Claude оценивает текущее состояние и определяет, как действовать дальше. Он может ответить текстом, запросить один или несколько вызовов инструментов или оба варианта. SDK выдает [`AssistantMessage`](#message-types), содержащее текст и любые запросы вызовов инструментов.
213. **Выполнить инструменты.** SDK запускает каждый запрошенный инструмент и собирает результаты. Каждый набор результатов инструментов возвращается Claude для следующего решения. Вы можете использовать [hooks](/ru/agent-sdk/hooks) для перехвата, изменения или блокировки вызовов инструментов перед их выполнением.
224. **Повторить.** Шаги 2 и 3 повторяются как цикл. Каждый полный цикл — это один ход. Claude продолжает вызывать инструменты и обрабатывать результаты до тех пор, пока не выдаст ответ без вызовов инструментов.
235. **Вернуть результат.** SDK выдает финальное [`AssistantMessage`](#message-types) с текстовым ответом (без вызовов инструментов), за которым следует [`ResultMessage`](#message-types) с финальным текстом, использованием токенов, стоимостью и ID сессии.
24
25Быстрый вопрос («какие файлы здесь?») может занять один или два хода вызова `Glob` и ответа с результатами. Сложная задача («рефакторить модуль аутентификации и обновить тесты») может связать десятки вызовов инструментов на протяжении многих ходов, читая файлы, редактируя код и запуская тесты, при этом Claude корректирует свой подход на основе каждого результата.
26
27## Ходы и сообщения
28
29Ход — это один цикл внутри цикла: Claude выдает выход, который включает вызовы инструментов, SDK выполняет эти инструменты, и результаты автоматически возвращаются Claude. Это происходит без возврата управления вашему коду. Ходы продолжаются до тех пор, пока Claude не выдаст выход без вызовов инструментов, после чего цикл заканчивается и доставляется финальный результат.
30
31Рассмотрим, как может выглядеть полная сессия для запроса «Исправить неудачные тесты в auth.ts».
32
33Сначала SDK отправляет ваш запрос Claude и выдает [`SystemMessage`](#message-types) с метаданными сессии. Затем начинается цикл:
34
351. **Ход 1:** Claude вызывает `Bash` для запуска `npm test`. SDK выдает [`AssistantMessage`](#message-types) с вызовом инструмента, выполняет команду, затем выдает [`UserMessage`](#message-types) с выводом (три ошибки).
362. **Ход 2:** Claude вызывает `Read` на `auth.ts` и `auth.test.ts`. SDK возвращает содержимое файлов и выдает `AssistantMessage`.
373. **Ход 3:** Claude вызывает `Edit` для исправления `auth.ts`, затем вызывает `Bash` для повторного запуска `npm test`. Все три теста проходят. SDK выдает `AssistantMessage`.
384. **Финальный ход:** Claude выдает текстовый ответ без вызовов инструментов: «Исправлена ошибка аутентификации, все три теста теперь проходят.» SDK выдает финальное `AssistantMessage` с этим текстом, затем [`ResultMessage`](#message-types) с тем же текстом плюс стоимость и использование.
39
40Это было четыре хода: три с вызовами инструментов, один финальный текстовый ответ.
41
42Вы можете ограничить цикл с помощью `max_turns` / `maxTurns`, который считает только ходы с использованием инструментов. Например, `max_turns=2` в цикле выше остановился бы перед шагом редактирования. Вы также можете использовать `max_budget_usd` / `maxBudgetUsd` для ограничения ходов на основе порога расходов.
43
44Без ограничений цикл работает до тех пор, пока Claude не закончит самостоятельно, что хорошо для хорошо определенных задач, но может работать долго на открытых запросах («улучшить этот кодовую базу»). Установка бюджета — хороший стандарт для производственных агентов. См. [Ходы и бюджет](#turns-and-budget) ниже для справки по опциям.
45
46## Типы сообщений
47
48По мере выполнения цикла SDK выдает поток сообщений. Каждое сообщение имеет тип, который говорит вам, на каком этапе цикла оно пришло. Пять основных типов:
49
50* **`SystemMessage`:** события жизненного цикла сессии. Поле `subtype` их различает: `"init"` — это первое сообщение (метаданные сессии), а `"compact_boundary"` срабатывает после [компактирования](#automatic-compaction). В TypeScript граница компактирования — это собственный тип [`SDKCompactBoundaryMessage`](/ru/agent-sdk/typescript#sdkcompactboundarymessage) вместо подтипа `SDKSystemMessage`.
51* **`AssistantMessage`:** выдается после каждого ответа Claude, включая финальный текстовый. Содержит блоки текстового содержимого и блоки вызовов инструментов из этого хода.
52* **`UserMessage`:** выдается после каждого выполнения инструмента с результатом инструмента, отправленным обратно Claude. Также выдается для любых пользовательских входов, которые вы транслируете в середине цикла.
53* **`StreamEvent`:** выдается только при включении частичных сообщений. Содержит необработанные события потоковой передачи API (дельты текста, фрагменты входных данных инструмента). См. [Потоковые ответы](/ru/agent-sdk/streaming-output).
54* **`ResultMessage`:** отмечает конец цикла агента. Содержит финальный текстовый результат, использование токенов, стоимость и ID сессии. Проверьте поле `subtype`, чтобы определить, успешна ли задача или достигнут ли лимит. Небольшое количество завершающих системных событий, таких как `prompt_suggestion`, может прибыть после него, поэтому итерируйте поток до завершения, а не прерывайте на результате. См. [Обработать результат](#handle-the-result).
55
56Эти пять типов охватывают полный жизненный цикл цикла агента в обоих SDK. TypeScript SDK также выдает дополнительные события наблюдаемости (события hooks, прогресс инструмента, ограничения скорости, уведомления задач), которые предоставляют дополнительные детали, но не требуются для управления циклом. См. [справку по типам сообщений Python](/ru/agent-sdk/python#message-types) и [справку по типам сообщений TypeScript](/ru/agent-sdk/typescript#message-types) для полных списков.
57
58### Обработать сообщения
59
60Какие сообщения вы обрабатываете, зависит от того, что вы создаете:
61
62* **Только финальные результаты:** обработайте `ResultMessage`, чтобы получить выход, стоимость и то, успешна ли задача или достигнут ли лимит.
63* **Обновления прогресса:** обработайте `AssistantMessage`, чтобы увидеть, что делает Claude на каждом ходу, включая какие инструменты он вызвал.
64* **Прямая потоковая передача:** включите частичные сообщения (`include_partial_messages` в Python, `includePartialMessages` в TypeScript), чтобы получить сообщения `StreamEvent` в реальном времени. См. [Потоковые ответы в реальном времени](/ru/agent-sdk/streaming-output).
65
66Как вы проверяете типы сообщений, зависит от SDK:
67
68* **Python:** проверьте типы сообщений с помощью `isinstance()` для классов, импортированных из `claude_agent_sdk` (например, `isinstance(message, ResultMessage)`).
69* **TypeScript:** проверьте строковое поле `type` (например, `message.type === "result"`). `AssistantMessage` и `UserMessage` оборачивают необработанное сообщение API в поле `.message`, поэтому блоки содержимого находятся в `message.message.content`, а не в `message.content`.
70
71<Accordion title="Пример: Проверить типы сообщений и обработать результаты">
72 <CodeGroup>
73 ```python Python theme={null}
74 from claude_agent_sdk import query, AssistantMessage, ResultMessage
75
76 async for message in query(prompt="Summarize this project"):
77 if isinstance(message, AssistantMessage):
78 print(f"Turn completed: {len(message.content)} content blocks")
79 if isinstance(message, ResultMessage):
80 if message.subtype == "success":
81 print(message.result)
82 else:
83 print(f"Stopped: {message.subtype}")
84 ```
85
86 ```typescript TypeScript theme={null}
87 import { query } from "@anthropic-ai/claude-agent-sdk";
88
89 for await (const message of query({ prompt: "Summarize this project" })) {
90 if (message.type === "assistant") {
91 console.log(`Turn completed: ${message.message.content.length} content blocks`);
92 }
93 if (message.type === "result") {
94 if (message.subtype === "success") {
95 console.log(message.result);
96 } else {
97 console.log(`Stopped: ${message.subtype}`);
98 }
99 }
100 }
101 ```
102 </CodeGroup>
103</Accordion>
104
105## Выполнение инструментов
106
107Инструменты дают вашему агенту возможность действовать. Без инструментов Claude может только отвечать текстом. С инструментами Claude может читать файлы, запускать команды, искать код и взаимодействовать с внешними сервисами.
108
109### Встроенные инструменты
110
111SDK включает те же инструменты, которые питают Claude Code:
112
113| Категория | Инструменты | Что они делают |
114| :--------------------- | :----------------------------------------------- | :---------------------------------------------------------------------------------------------- |
115| **Операции с файлами** | `Read`, `Edit`, `Write` | Читать, изменять и создавать файлы |
116| **Поиск** | `Glob`, `Grep` | Найти файлы по шаблону, искать содержимое с помощью regex |
117| **Выполнение** | `Bash` | Запускать команды оболочки, скрипты, операции git |
118| **Веб** | `WebSearch`, `WebFetch` | Искать в веб, получать и анализировать страницы |
119| **Обнаружение** | `ToolSearch` | Динамически находить и загружать инструменты по требованию вместо предварительной загрузки всех |
120| **Оркестрация** | `Agent`, `Skill`, `AskUserQuestion`, `TodoWrite` | Порождать подагентов, вызывать skills, спрашивать пользователя, отслеживать задачи |
121
122Помимо встроенных инструментов, вы можете:
123
124* **Подключить внешние сервисы** с помощью [MCP servers](/ru/agent-sdk/mcp) (базы данных, браузеры, API)
125* **Определить пользовательские инструменты** с помощью [пользовательских обработчиков инструментов](/ru/agent-sdk/custom-tools)
126* **Загрузить skills проекта** через [источники настроек](/ru/agent-sdk/claude-code-features) для повторно используемых рабочих процессов
127
128### Разрешения инструментов
129
130Claude определяет, какие инструменты вызывать на основе задачи, но вы контролируете, разрешено ли выполнение этих вызовов. Вы можете автоматически одобрить определенные инструменты, полностью заблокировать другие или требовать одобрения для всего. Три опции работают вместе, чтобы определить, что работает:
131
132* **`allowed_tools` / `allowedTools`** автоматически одобряет перечисленные инструменты. Агент только для чтения с `["Read", "Glob", "Grep"]` в списке разрешенных инструментов запускает эти инструменты без подсказок. Инструменты, не указанные в списке, все еще доступны, но требуют разрешения.
133* **`disallowed_tools` / `disallowedTools`** блокирует перечисленные инструменты, независимо от других настроек. См. [Разрешения](/ru/agent-sdk/permissions) для порядка, в котором правила проверяются перед запуском инструмента.
134* **`permission_mode` / `permissionMode`** контролирует, что происходит с инструментами, которые не охватываются правилами разрешения или запрета. См. [Режим разрешения](#permission-mode) для доступных режимов.
135
136Вы также можете ограничить отдельные инструменты правилами, такими как `"Bash(npm *)"`, чтобы разрешить только определенные команды. См. [Разрешения](/ru/agent-sdk/permissions) для полного синтаксиса правил.
137
138Когда инструмент отклоняется, Claude получает сообщение об отклонении как результат инструмента и обычно пытается использовать другой подход или сообщает, что не может продолжить.
139
140### Параллельное выполнение инструментов
141
142Когда Claude запрашивает несколько вызовов инструментов в одном ходе, оба SDK могут запускать их одновременно или последовательно в зависимости от инструмента. Инструменты только для чтения (такие как `Read`, `Glob`, `Grep` и MCP инструменты, отмеченные как только для чтения) могут работать одновременно. Инструменты, которые изменяют состояние (такие как `Edit`, `Write` и `Bash`), работают последовательно, чтобы избежать конфликтов.
143
144Пользовательские инструменты по умолчанию работают последовательно. Чтобы включить параллельное выполнение для пользовательского инструмента, установите `readOnlyHint` в его аннотациях. Оба SDK [TypeScript](/ru/agent-sdk/typescript#tool) и [Python](/ru/agent-sdk/python#tool) используют это имя поля из MCP SDK.
145
146## Контролировать, как работает цикл
147
148Вы можете ограничить количество ходов, которые делает цикл, сколько он стоит, насколько глубоко Claude рассуждает, и требуют ли инструменты одобрения перед запуском. Все это поля на [`ClaudeAgentOptions`](/ru/agent-sdk/python#claudeagentoptions) (Python) / [`Options`](/ru/agent-sdk/typescript#options) (TypeScript).
149
150### Ходы и бюджет
151
152| Опция | Что она контролирует | По умолчанию |
153| :--------------------------------------------------- | :------------------------------------------ | :-------------- |
154| Максимум ходов (`max_turns` / `maxTurns`) | Максимум раундов использования инструментов | Без ограничений |
155| Максимум бюджета (`max_budget_usd` / `maxBudgetUsd`) | Максимальная стоимость перед остановкой | Без ограничений |
156
157Когда достигается любой лимит, SDK возвращает `ResultMessage` с соответствующим подтипом ошибки (`error_max_turns` или `error_max_budget_usd`). См. [Обработать результат](#handle-the-result) для того, как проверить эти подтипы, и [`ClaudeAgentOptions`](/ru/agent-sdk/python#claudeagentoptions) / [`Options`](/ru/agent-sdk/typescript#options) для синтаксиса.
158
159### Уровень усилий
160
161Опция `effort` контролирует, сколько рассуждений применяет Claude. Более низкие уровни усилий используют меньше токенов за ход и снижают стоимость. Не все модели поддерживают параметр effort. См. [Effort](https://platform.claude.com/docs/en/build-with-claude/effort) для того, какие модели его поддерживают.
162
163| Уровень | Поведение | Хорошо для |
164| :--------- | :-------------------------------------- | :-------------------------------------------------------- |
165| `"low"` | Минимальное рассуждение, быстрые ответы | Поиск файлов, список каталогов |
166| `"medium"` | Сбалансированное рассуждение | Обычные редактирования, стандартные задачи |
167| `"high"` | Тщательный анализ | Рефакторинг, отладка |
168| `"xhigh"` | Расширенная глубина рассуждения | Задачи кодирования и агентские; рекомендуется на Opus 4.7 |
169| `"max"` | Максимальная глубина рассуждения | Многошаговые проблемы, требующие глубокого анализа |
170
171Если вы не установите `effort`, Python SDK оставляет параметр неустановленным и полагается на поведение модели по умолчанию. TypeScript SDK по умолчанию использует `"high"`.
172
173<Note>
174 `effort` обменивает задержку и стоимость токена на глубину рассуждения в каждом ответе. [Extended thinking](https://platform.claude.com/docs/en/build-with-claude/extended-thinking) — это отдельная функция, которая выдает видимые блоки цепочки мыслей в выводе. Они независимы: вы можете установить `effort: "low"` с включенным extended thinking или `effort: "max"` без него.
175</Note>
176
177Используйте более низкие усилия для агентов, выполняющих простые, хорошо определенные задачи (такие как список файлов или запуск одного grep), чтобы снизить стоимость и задержку. Установите `effort` в опциях верхнего уровня `query()` для всей сессии или для каждого подагента с полем `effort` на [`AgentDefinition`](/ru/agent-sdk/subagents#agentdefinition-configuration), чтобы переопределить уровень сессии.
178
179### Режим разрешения
180
181Опция режима разрешения (`permission_mode` в Python, `permissionMode` в TypeScript) контролирует, просит ли агент одобрения перед использованием инструментов:
182
183| Режим | Поведение |
184| :--------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
185| `"default"` | Инструменты, не охватываемые правилами разрешения, запускают ваш обратный вызов одобрения; отсутствие обратного вызова означает отклонение |
186| `"acceptEdits"` | Автоматически одобряет редактирование файлов и общие команды файловой системы (`mkdir`, `touch`, `mv`, `cp` и т. д.); другие команды Bash следуют правилам по умолчанию |
187| `"plan"` | Инструменты только для чтения работают; Claude исследует и выдает план без редактирования ваших исходных файлов |
188| `"dontAsk"` | Никогда не подсказывает. Инструменты, предварительно одобренные [правилами разрешения](/ru/settings#permission-settings), работают, все остальное отклоняется |
189| `"auto"` (только TypeScript) | Использует классификатор модели для одобрения или отклонения каждого вызова инструмента. См. [Режим Auto](/ru/permission-modes#eliminate-prompts-with-auto-mode) для доступности и поведения |
190| `"bypassPermissions"` | Запускает все разрешенные инструменты без запроса. Не может использоваться при запуске от root на Unix. Используйте только в изолированных окружениях, где действия агента не могут повлиять на системы, которые вам важны |
191
192Для интерактивных приложений используйте `"default"` с обратным вызовом одобрения инструмента для отображения подсказок одобрения. Для автономных агентов на машине разработки используйте `"acceptEdits"`, чтобы автоматически одобрить редактирование файлов и общие команды файловой системы (`mkdir`, `touch`, `mv`, `cp` и т. д.), при этом все еще ограничивая другие команды `Bash` правилами разрешения. Зарезервируйте `"bypassPermissions"` для CI, контейнеров или других изолированных окружений. См. [Разрешения](/ru/agent-sdk/permissions) для полных деталей.
193
194### Модель
195
196Если вы не установите `model`, SDK использует значение по умолчанию Claude Code, которое зависит от вашего метода аутентификации и подписки. Установите его явно (например, `model="claude-sonnet-4-6"`), чтобы закрепить определенную модель или использовать меньшую модель для более быстрых и дешевых агентов. См. [models](https://platform.claude.com/docs/en/about-claude/models) для доступных ID.
197
198## Контекстное окно
199
200Контекстное окно — это общее количество информации, доступной Claude во время сессии. Оно не сбрасывается между ходами в пределах сессии. Все накапливается: системный запрос, определения инструментов, история разговора, входные данные инструментов и выходные данные инструментов. Содержимое, которое остается неизменным на протяжении ходов (системный запрос, определения инструментов, CLAUDE.md), автоматически [кэшируется в запросе](https://platform.claude.com/docs/en/build-with-claude/prompt-caching), что снижает стоимость и задержку для повторяющихся префиксов.
201
202### Что потребляет контекст
203
204Вот как каждый компонент влияет на контекст в SDK:
205
206| Источник | Когда он загружается | Влияние |
207| :--------------------------- | :-------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
208| **Системный запрос** | Каждый запрос | Небольшая фиксированная стоимость, всегда присутствует |
209| **CLAUDE.md файлы** | Начало сессии, через [`settingSources`](/ru/agent-sdk/claude-code-features) | Полное содержимое в каждом запросе (но кэшировано в запросе, поэтому только первый запрос платит полную стоимость) |
210| **Определения инструментов** | Каждый запрос | Каждый инструмент добавляет свою схему; используйте [поиск инструментов MCP](/ru/agent-sdk/mcp#mcp-tool-search) для загрузки инструментов по требованию вместо всех сразу |
211| **История разговора** | Накапливается на протяжении ходов | Растет с каждым ходом: запросы, ответы, входные данные инструментов, выходные данные инструментов |
212| **Описания skills** | Начало сессии, через источники настроек | Короткие резюме; полное содержимое загружается только при вызове |
213
214Большие выходные данные инструментов потребляют значительный контекст. Чтение большого файла или запуск команды с подробным выводом может использовать тысячи токенов в одном ходе. Контекст накапливается на протяжении ходов, поэтому более длительные сессии с множеством вызовов инструментов накапливают значительно больше контекста, чем короткие.
215
216### Автоматическое компактирование
217
218Когда контекстное окно приближается к своему лимиту, SDK автоматически компактирует разговор: он суммирует более старую историю, чтобы освободить место, сохраняя ваши самые последние обмены и ключевые решения нетронутыми. SDK выдает сообщение с `type: "system"` и `subtype: "compact_boundary"` в потоке, когда это происходит (в Python это `SystemMessage`; в TypeScript это отдельный тип `SDKCompactBoundaryMessage`).
219
220Компактирование заменяет более старые сообщения резюме, поэтому конкретные инструкции с начала разговора могут не сохраниться. Постоянные правила должны находиться в CLAUDE.md (загружаемые через [`settingSources`](/ru/agent-sdk/claude-code-features)), а не в начальном запросе, потому что содержимое CLAUDE.md повторно вводится в каждом запросе.
221
222Вы можете настроить поведение компактирования несколькими способами:
223
224* **Инструкции по суммированию в CLAUDE.md:** Компактор читает ваш CLAUDE.md как любой другой контекст, поэтому вы можете включить раздел, рассказывающий ему, что сохранить при суммировании. Заголовок раздела свободной формы (не волшебная строка); компактор совпадает по намерению.
225* **Hook `PreCompact`:** Запустите пользовательскую логику перед компактированием, например для архивирования полной транскрипции. Hook получает поле `trigger` (`manual` или `auto`). См. [hooks](/ru/agent-sdk/hooks).
226* **Ручное компактирование:** Отправьте `/compact` как строку запроса для запуска компактирования по требованию. (Slash commands, отправленные таким образом, — это входные данные SDK, а не только ярлыки CLI. См. [slash commands в SDK](/ru/agent-sdk/slash-commands).)
227
228<Accordion title="Пример: Инструкции по суммированию в CLAUDE.md">
229 Добавьте раздел в CLAUDE.md вашего проекта, рассказывающий компактору, что сохранить. Имя заголовка не является специальным; используйте любой четкий ярлык.
230
231 ```markdown CLAUDE.md theme={null}
232 # Summary instructions
233
234 When summarizing this conversation, always preserve:
235 - The current task objective and acceptance criteria
236 - File paths that have been read or modified
237 - Test results and error messages
238 - Decisions made and the reasoning behind them
239 ```
240</Accordion>
241
242### Держите контекст эффективным
243
244Несколько стратегий для долгоживущих агентов:
245
246* **Используйте подагентов для подзадач.** Каждый подагент начинает со свежего разговора (без предыдущей истории сообщений, хотя он загружает свой собственный системный запрос и контекст уровня проекта, такой как CLAUDE.md). Он не видит ходы родителя, и только его финальный ответ возвращается родителю как результат инструмента. Контекст основного агента растет на эту резюме, а не на полную транскрипцию подзадачи. См. [Что наследуют подагенты](/ru/agent-sdk/subagents#what-subagents-inherit) для деталей.
247* **Будьте избирательны с инструментами.** Каждое определение инструмента занимает место контекста. Используйте поле `tools` на [`AgentDefinition`](/ru/agent-sdk/subagents#agentdefinition-configuration) для ограничения подагентов минимальным набором, который им нужен, и используйте [поиск инструментов MCP](/ru/agent-sdk/mcp#mcp-tool-search) для загрузки инструментов по требованию вместо предварительной загрузки всех.
248* **Следите за стоимостью MCP сервера.** Каждый MCP сервер добавляет все свои схемы инструментов в каждый запрос. Несколько серверов с множеством инструментов могут потребить значительный контекст перед тем, как агент выполнит какую-либо работу. Инструмент `ToolSearch` может помочь, загружая инструменты по требованию вместо предварительной загрузки всех. См. [поиск инструментов MCP](/ru/agent-sdk/mcp#mcp-tool-search) для конфигурации.
249* **Используйте более низкие усилия для обычных задач.** Установите [effort](#effort-level) на `"low"` для агентов, которым нужно только читать файлы или список каталогов. Это снижает использование токенов и стоимость.
250
251Для подробного разбора стоимости контекста для каждой функции см. [Понять стоимость контекста](/ru/features-overview#understand-context-costs).
252
253## Сессии и непрерывность
254
255Каждое взаимодействие с SDK создает или продолжает сессию. Захватите ID сессии из `ResultMessage.session_id` (доступно в обоих SDK) для возобновления позже. TypeScript SDK также выставляет его как прямое поле на инициализирующем `SystemMessage`; в Python он вложен в `SystemMessage.data`.
256
257Когда вы возобновляете, полный контекст из предыдущих ходов восстанавливается: файлы, которые были прочитаны, анализ, который был выполнен, и действия, которые были предприняты. Вы также можете разветвить сессию, чтобы ветвиться в другой подход без изменения оригинала.
258
259См. [Управление сессией](/ru/agent-sdk/sessions) для полного руководства по возобновлению, продолжению и разветвлению паттернов.
260
261<Note>
262 В Python `ClaudeSDKClient` автоматически обрабатывает ID сессий на протяжении нескольких вызовов. См. [справку Python SDK](/ru/agent-sdk/python#choosing-between-query-and-claudesdkclient) для деталей.
263</Note>
264
265## Обработать результат
266
267Когда цикл заканчивается, `ResultMessage` говорит вам, что произошло, и дает вам выход. Поле `subtype` (доступно в обоих SDK) — это основной способ проверить состояние завершения.
268
269| Подтип результата | Что произошло | Поле `result` доступно? |
270| :------------------------------------ | :------------------------------------------------------------------------------- | :---------------------: |
271| `success` | Claude нормально завершил задачу | Да |
272| `error_max_turns` | Достигнут лимит `maxTurns` перед завершением | Нет |
273| `error_max_budget_usd` | Достигнут лимит `maxBudgetUsd` перед завершением | Нет |
274| `error_during_execution` | Ошибка прервала цикл (например, отказ API или отмененный запрос) | Нет |
275| `error_max_structured_output_retries` | Валидация структурированного выхода не прошла после настроенного лимита повторов | Нет |
276
277Поле `result` (финальный текстовый выход) присутствует только в варианте `success`, поэтому всегда проверяйте подтип перед его чтением. Все подтипы результатов содержат `total_cost_usd`, `usage`, `num_turns` и `session_id`, поэтому вы можете отслеживать стоимость и возобновлять даже после ошибок. В Python `total_cost_usd` и `usage` типизированы как опциональные и могут быть `None` на некоторых путях ошибок, поэтому охраняйте перед форматированием. См. [Отслеживание стоимости и использования](/ru/agent-sdk/cost-tracking) для деталей по интерпретации полей `usage`.
278
279Результат также включает поле `stop_reason` (`string | null` в TypeScript, `str | None` в Python), указывающее, почему модель остановила генерацию на своем финальном ходе. Общие значения — `end_turn` (модель закончила нормально), `max_tokens` (достигнут лимит выходных токенов) и `refusal` (модель отклонила запрос). На подтипах результатов ошибок `stop_reason` содержит значение из последнего ответа помощника перед завершением цикла. Для обнаружения отклонений проверьте `stop_reason === "refusal"` (TypeScript) или `stop_reason == "refusal"` (Python). См. [`SDKResultMessage`](/ru/agent-sdk/typescript#sdkresultmessage) (TypeScript) или [`ResultMessage`](/ru/agent-sdk/python#resultmessage) (Python) для полного типа.
280
281## Hooks
282
283[Hooks](/ru/agent-sdk/hooks) — это обратные вызовы, которые срабатывают в определенных точках цикла: перед запуском инструмента, после его возврата, когда агент заканчивает, и так далее. Некоторые часто используемые hooks:
284
285| Hook | Когда он срабатывает | Общие использования |
286| :------------------------------- | :----------------------------------------- | :------------------------------------------------------- |
287| `PreToolUse` | Перед выполнением инструмента | Валидировать входные данные, блокировать опасные команды |
288| `PostToolUse` | После возврата инструмента | Аудировать выходные данные, запускать побочные эффекты |
289| `UserPromptSubmit` | Когда запрос отправляется | Вводить дополнительный контекст в запросы |
290| `Stop` | Когда агент заканчивает | Валидировать результат, сохранять состояние сессии |
291| `SubagentStart` / `SubagentStop` | Когда подагент порождается или завершается | Отслеживать и агрегировать результаты параллельных задач |
292| `PreCompact` | Перед компактированием контекста | Архивировать полную транскрипцию перед суммированием |
293
294Hooks работают в процессе вашего приложения, а не внутри контекстного окна агента, поэтому они не потребляют контекст. Hooks также могут короткозамкнуть цикл: hook `PreToolUse`, который отклоняет вызов инструмента, предотвращает его выполнение, и Claude получает сообщение об отклонении вместо этого.
295
296Оба SDK поддерживают все события выше. TypeScript SDK включает дополнительные события, которые Python еще не поддерживает. См. [Контролировать выполнение с помощью hooks](/ru/agent-sdk/hooks) для полного списка событий, доступности для каждого SDK и полного API обратного вызова.
297
298## Собрать все вместе
299
300Этот пример объединяет ключевые концепции с этой страницы в одного агента, который исправляет неудачные тесты. Он конфигурирует агента с разрешенными инструментами (автоматически одобренными, поэтому агент работает автономно), настройками проекта и ограничениями безопасности на ходы и усилия рассуждения. По мере выполнения цикла он захватывает ID сессии для потенциального возобновления, обрабатывает финальный результат и выводит общую стоимость.
301
302<CodeGroup>
303 ```python Python theme={null}
304 import asyncio
305 from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
306
307
308 async def run_agent():
309 session_id = None
310
311 async for message in query(
312 prompt="Find and fix the bug causing test failures in the auth module",
313 options=ClaudeAgentOptions(
314 allowed_tools=[
315 "Read",
316 "Edit",
317 "Bash",
318 "Glob",
319 "Grep",
320 ], # Listing tools here auto-approves them (no prompting)
321 setting_sources=[
322 "project"
323 ], # Load CLAUDE.md, skills, hooks from current directory
324 max_turns=30, # Prevent runaway sessions
325 effort="high", # Thorough reasoning for complex debugging
326 ),
327 ):
328 # Handle the final result
329 if isinstance(message, ResultMessage):
330 session_id = message.session_id # Save for potential resumption
331
332 if message.subtype == "success":
333 print(f"Done: {message.result}")
334 elif message.subtype == "error_max_turns":
335 # Agent ran out of turns. Resume with a higher limit.
336 print(f"Hit turn limit. Resume session {session_id} to continue.")
337 elif message.subtype == "error_max_budget_usd":
338 print("Hit budget limit.")
339 else:
340 print(f"Stopped: {message.subtype}")
341 if message.total_cost_usd is not None:
342 print(f"Cost: ${message.total_cost_usd:.4f}")
343
344
345 asyncio.run(run_agent())
346 ```
347
348 ```typescript TypeScript theme={null}
349 import { query } from "@anthropic-ai/claude-agent-sdk";
350
351 let sessionId: string | undefined;
352
353 for await (const message of query({
354 prompt: "Find and fix the bug causing test failures in the auth module",
355 options: {
356 allowedTools: ["Read", "Edit", "Bash", "Glob", "Grep"], // Listing tools here auto-approves them (no prompting)
357 settingSources: ["project"], // Load CLAUDE.md, skills, hooks from current directory
358 maxTurns: 30, // Prevent runaway sessions
359 effort: "high" // Thorough reasoning for complex debugging
360 }
361 })) {
362 // Save the session ID to resume later if needed
363 if (message.type === "system" && message.subtype === "init") {
364 sessionId = message.session_id;
365 }
366
367 // Handle the final result
368 if (message.type === "result") {
369 if (message.subtype === "success") {
370 console.log(`Done: ${message.result}`);
371 } else if (message.subtype === "error_max_turns") {
372 // Agent ran out of turns. Resume with a higher limit.
373 console.log(`Hit turn limit. Resume session ${sessionId} to continue.`);
374 } else if (message.subtype === "error_max_budget_usd") {
375 console.log("Hit budget limit.");
376 } else {
377 console.log(`Stopped: ${message.subtype}`);
378 }
379 console.log(`Cost: $${message.total_cost_usd.toFixed(4)}`);
380 }
381 }
382 ```
383</CodeGroup>
384
385## Следующие шаги
386
387Теперь, когда вы понимаете цикл, вот куда идти в зависимости от того, что вы создаете:
388
389* **Еще не запустили агента?** Начните с [quickstart](/ru/agent-sdk/quickstart), чтобы установить SDK и увидеть полный пример, работающий от начала до конца.
390* **Готовы подключиться к вашему проекту?** [Загрузите CLAUDE.md, skills и hooks файловой системы](/ru/agent-sdk/claude-code-features), чтобы агент автоматически следовал соглашениям вашего проекта.
391* **Создаете интерактивный UI?** Включите [потоковую передачу](/ru/agent-sdk/streaming-output), чтобы показать живой текст и вызовы инструментов по мере выполнения цикла.
392* **Нужен более плотный контроль над тем, что может делать агент?** Заблокируйте доступ к инструментам с помощью [разрешений](/ru/agent-sdk/permissions) и используйте [hooks](/ru/agent-sdk/hooks) для аудита, блокировки или преобразования вызовов инструментов перед их выполнением.
393* **Запускаете долгие или дорогие задачи?** Перенесите изолированную работу на [подагентов](/ru/agent-sdk/subagents), чтобы держать ваш основной контекст стройным.
394
395Для более широкой концептуальной картины цикла агента (не специфичной для SDK) см. [Как работает Claude Code](/ru/how-claude-code-works).