Claude Platform Docs
Управляемые агентыДелегирование работы агенту

Поток событий сеанса

Отправляйте события, получайте ответы в режиме потоковой передачи, а также прерывайте или перенаправляйте сеанс во время выполнения.

Взаимодействие с Claude Managed Agents основано на событиях. Вы открываете поток, чтобы следить за сеансом, отправляете события, чтобы управлять им, и отвечаете ему, когда он приостанавливается в ожидании ввода.

Типы событий

События передаются в двух направлениях: вы отправляете события агенту, а сеанс отправляет события обратно вам.

  • События, которые вы отправляете: события user.* запускают сеанс и направляют его по мере выполнения. События system.message добавляют контекст системного уровня.
  • События, которые вы получаете: события сеанса, события интервалов (span events) и события агента сообщают о состоянии сеанса и ходе работы агента.

Строки типов событий следуют соглашению об именовании {domain}.{action}. Полный каталог см. в разделе Типы событий справочника.

Типы событий вебхуков определены отдельно, и некоторые их имена отличаются от имён в потоке. Например, вебхуки используют session.status_idled вместо session.status_idle.

Потоковая передача событий

Получайте события сеанса в режиме «streaming» (потоковая передача), чтобы видеть обновления в реальном времени по мере работы агента. Поток доставляет только события, созданные после его открытия, поэтому открывайте поток до отправки событий, чтобы избежать состояния гонки.

# Сначала откройте поток, затем отправьте сообщение пользователя
with client.beta.sessions.events.stream(session.id) as stream:
    client.beta.sessions.events.send(
        session.id,
        events=[
            {
                "type": "user.message",
                "content": [{"type": "text", "text": "Summarize the repo README"}],
            },
        ],
    )

    for event in stream:
        match event.type:
            case "agent.message":
                for block in event.content:
                    if block.type == "text":
                        print(block.text, end="")
            case "session.status_idle":
                break
            case "session.error":
                error_message = event.error.message if event.error else "unknown"
                print(f"\n[Error: {error_message}]")
                break

Сеанс сообщает об ошибках через событие session.error. Его поля описаны в разделе Типы событий.

Текст ответа агента поступает в виде буферизованных событий agent.message, каждое из которых создаётся только после завершения породившего его запроса к модели. Чтобы отображать текст, пока модель ещё генерирует его, см. Предварительный просмотр ответов с помощью дельт событий.

Переподключение без пропуска событий

Чтобы переподключиться к существующему сеансу без пропуска событий, объедините новый поток с историей событий:

  1. Откройте новый поток.
  2. Получите полную историю событий, чтобы заполнить набор уже просмотренных идентификаторов событий.
  3. Читайте живой поток, пропуская события, которые уже были возвращены в списке истории.
with client.beta.sessions.events.stream(session.id) as stream:
    # Поток открыт и буферизуется. Получите историю перед чтением живых событий.
    history = client.beta.sessions.events.list(session.id)
    seen_event_ids = {past_event.id for past_event in history}

    # Читаем живые события, пропуская уже увиденные
    for event in stream:
        if event.type == "event_start" or event.type == "event_delta":
            # Превью дельт не включены для этого соединения.
            continue
        if event.id in seen_event_ids:
            continue
        seen_event_ids.add(event.id)
        match event.type:
            case "agent.message":
                for block in event.content:
                    if block.type == "text":
                        print(block.text, end="")
            case "session.status_idle":
                break

Отправка событий

Отправьте событие user.message, чтобы начать или продолжить работу агента:

client.beta.sessions.events.send(
    session.id,
    events=[
        {
            "type": "user.message",
            "content": [
                {
                    "type": "text",
                    "text": "Analyze the performance of the sort function in utils.py",
                },
            ],
        },
    ],
)

Каждое событие в истории сеанса содержит временную метку processed_at, которая устанавливается, когда обработка события завершается. У отправленных вами событий processed_at имеет значение None, пока событие ещё стоит в очереди за более ранними событиями. Исключения — user.define_outcome, user.custom_tool_result и user.tool_result: они обрабатываются при получении и возвращаются с уже заполненным processed_at.

Ответ, когда сеанс переходит в режим ожидания

Событие session.status_idle означает, что агент остановился и ожидает ввода. Его поле stop_reason.type указывает причину:

stop_reason.typeПочему сеанс остановилсяЧто делать
end_turnАгент завершил свой ход, или вы его прервали.Отправьте user.message, когда у вас появится новая работа для агента.
requires_actionОдин или несколько вызовов инструментов требуют вашего ответа, например вызов пользовательского инструмента или запрос подтверждения.Ответьте на каждый блокирующий вызов инструмента.
budget_reachedОтслеживаемая прейскурантная стоимость сеанса достигла его бюджета.Измените или удалите бюджет.

Никакое отправленное вами событие не возобновляет сеанс, приостановленный из-за достижения бюджета. Работа, приостановленная бюджетом, возобновляется автоматически, когда вы меняете бюджет на значение выше израсходованной прейскурантной стоимости или удаляете его. При возобновлении работы сеанс создаёт событие workflow_run.status_running для каждого запуска рабочего процесса, приостановленного бюджетом. Запуск, приостановленный прерыванием, остаётся приостановленным; см. Возобновление сеанса, достигшего бюджета. События, отмечающие приостановку, и события, которые сеанс по-прежнему принимает, описаны в разделе Когда сеанс достигает бюджета.

Ответ на вызовы инструментов, приостанавливающие сеанс

Сеанс приостанавливается, когда агент вызывает пользовательский инструмент, а также когда вызов инструмента требует вашего подтверждения согласно политике разрешений. Обе приостановки проходят по одной и той же последовательности:

  1. Сеанс создаёт вызов инструмента в виде события agent.custom_tool_use, agent.tool_use или agent.mcp_tool_use.
  2. Сеанс приостанавливается с событием session.status_idle, у которого stop_reason.type равно requires_action. Идентификаторы блокирующих событий находятся в массиве stop_reason.event_ids.
  3. Для каждого идентификатора блокирующего события отправьте событие user.custom_tool_result или user.tool_confirmation. Результату пользовательского инструмента не обязательно ждать шага 2.
  4. Когда все блокирующие события разрешены, сеанс возвращается в состояние running.

В многоагентном сеансе блокирующие события субагента дублируются в основной поток. См. Разрешения инструментов и пользовательские инструменты.

Возврат результата пользовательского инструмента

Событие agent.custom_tool_use содержит имя инструмента и входные данные. Выполните инструмент в своей системе. Затем отправьте событие user.custom_tool_result, передав идентификатор события в параметре custom_tool_use_id вместе с содержимым результата.

Вы можете отправить результат сразу после поступления события agent.custom_tool_use, не дожидаясь session.status_idle. Сеанс всё равно создаст session.status_idle с причиной остановки requires_action для этого вызова, и ваш клиент может его проигнорировать. Повторный результат для того же вызова принимается и ни на что не влияет.

Когда вы переподключаетесь к приостановленному сеансу, stop_reason.event_ids в последнем событии session.status_idle перечисляет вызовы, на которые нужно ответить.

В следующем примере на каждый вызов отвечают по мере его поступления:

with client.beta.sessions.events.stream(session.id) as stream:
    for event in stream:
        match event.type:
            case "agent.custom_tool_use":
                # Выполнить инструмент
                result = call_tool(event.name, event.input)

                # Отправить результат обратно
                client.beta.sessions.events.send(
                    session.id,
                    events=[
                        {
                            "type": "user.custom_tool_result",
                            "custom_tool_use_id": event.id,
                            "content": [{"type": "text", "text": result}],
                        },
                    ],
                )
            case "session.status_idle":
                if event.stop_reason and event.stop_reason.type == "end_turn":
                    break

Если у агента открыты запуски рабочих процессов, вызов пользовательского инструмента может поступить, пока сеанс остаётся в состоянии running. Событие ожидания requires_action поступает только тогда, когда ни один из потоков сеанса не работает. Не ждите его: отвечайте на каждый вызов, когда поступает его событие agent.custom_tool_use. Как это сделать, показано в примере из раздела Отслеживание запуска.

Подтверждение вызова инструмента

Отправьте событие user.tool_confirmation, передав идентификатор события в параметре tool_use_id. Установите result в значение "allow" или "deny". О том, какие вызовы ожидают подтверждения и как объяснить отказ, см. в разделе Ответ на запросы подтверждения.

В следующем примере одобряются все ожидающие вызовы:

with client.beta.sessions.events.stream(session.id) as stream:
    for event in stream:
        if event.type == "session.status_idle" and (stop_reason := event.stop_reason):
            match stop_reason.type:
                case "requires_action":
                    for event_id in stop_reason.event_ids:
                        # Одобряем ожидающий вызов инструмента
                        client.beta.sessions.events.send(
                            session.id,
                            events=[
                                {
                                    "type": "user.tool_confirmation",
                                    "tool_use_id": event_id,
                                    "result": "allow",
                                },
                            ],
                        )
                case "end_turn":
                    break

Предыдущий пример одобряет каждый вызов после того, как сеанс переходит в режим ожидания. Если у агента открыты запуски рабочих процессов, вызов инструмента может ожидать вашего подтверждения, пока сеанс остаётся в состоянии running. Не ждите события ожидания: когда поступает событие agent.tool_use или agent.mcp_tool_use, у которого evaluated_permission равно ask, ответьте на него. Пример из раздела Отслеживание запуска отвечает таким образом на вызовы пользовательских инструментов, а во введении к нему описано, как добавить подтверждения.

Возобновление сеанса в режиме ожидания

Сеансы сохраняются между взаимодействиями. Чтобы возобновить сеанс, отправьте ему событие user.message как обычно:

# Возобновляем ранее созданную сессию, отправив ей новое событие user.message.
# В продакшене передавайте сохранённый ID сессии, которую нужно возобновить.
client.beta.sessions.events.send(
    session.id,
    events=[
        {
            "type": "user.message",
            "content": [
                {
                    "type": "text",
                    "text": "Now run the tests against the changes you made earlier.",
                },
            ],
        },
    ],
)

История разговора сохраняется, если сеанс не был явно удалён. Когда сеанс переходит в режим ожидания, для его песочницы создаётся контрольная точка. Контрольная точка сохраняет полное состояние песочницы, включая файловую систему, установленные пакеты и все файлы, созданные агентом.

Прерывание агента

Отправьте событие user.interrupt, чтобы остановить агента во время выполнения, а затем отправьте событие user.message, чтобы перенаправить его:

# Агент в данный момент анализирует файл...
# Прерываем с новым направлением:
client.beta.sessions.events.send(
    session.id,
    events=[
        {"type": "user.interrupt"},
        {
            "type": "user.message",
            "content": [
                {
                    "type": "text",
                    "text": "Instead, focus on fixing the bug in line 42.",
                },
            ],
        },
    ],
)

Вызов возвращается сразу после постановки событий в очередь. Затем прерывание вступает в силу в следующем порядке:

  1. Агент применяет прерывание. До этого момента processed_at прерывания остаётся None, а сеанс остаётся в состоянии running. Генерируемый ответ модели останавливается немедленно, но применение прерывания может занять больше времени, пока выполняются вызовы инструментов.
  2. Событие user.interrupt появляется в потоке, и прерванный ход завершается событием session.status_idle.
  3. Агент начинает следующий ход с user.message, которое вы отправили после прерывания.

Значение stop_reason.type у события ожидания — end_turn, то же, что и у хода, завершившегося самостоятельно. Если открыты запуски рабочих процессов, прерывание не завершает ни один из них. Выполняющийся запуск может удерживать сеанс в состоянии running, поэтому событие session.status_idle на шаге 2 может не поступить. См. Прерывание сеанса с открытыми запусками.

Получение списка прошлых событий

Получите полную историю событий сеанса:

events = client.beta.sessions.events.list(session.id)
for event in events.data:
    print(f"[{event.type}] {event.processed_at}")

Передайте фильтр types, чтобы получить только определённые типы событий:

events = client.beta.sessions.events.list(
    session.id,
    types=["agent.tool_use", "agent.tool_result"],
)
for event in events.data:
    print(f"[{event.type}] {event.processed_at}")

Отправка системных сообщений

На поддерживаемой модели отправьте событие system.message, чтобы предоставить агенту привилегированный контекст системного уровня. Контекст применяется к сопутствующему ходу и ко всем последующим ходам. Используйте его, когда агенту нужны обновлённые указания системного уровня в середине сеанса, например другая роль, пересмотренные ограничения или контекст, полученный во время выполнения.

Поле content события принимает от 1 до 1000 текстовых элементов. Содержимое добавляется к системному контексту сеанса как ход role: "system". Оно не заменяет «system prompt» (системная подсказка) верхнего уровня, которую задаёт поле system в определении агента.

client.beta.sessions.events.send(
    session.id,
    events=[
        {
            "type": "system.message",
            "content": [
                {
                    "type": "text",
                    "text": "The user's current timezone is America/New_York.",
                },
            ],
        },
    ],
)

Поддерживаемые модели

system.message поддерживается следующими моделями:

  • Claude Fable 5.1
  • Claude Mythos 5.1
  • Claude Fable 5
  • Claude Mythos 5
  • Claude Opus 5.5
  • Claude Opus 5
  • Claude Opus 4.8
  • Claude Sonnet 5.5
  • Claude Haiku 5.5

Если основная модель агента не поддерживает внедрение системного контекста в середине разговора, событие отклоняется с ошибкой валидации model_does_not_support_mid_conversation_system. Модели субагентов не проверяются, поскольку system.message попадает только в основной поток.

Системные сообщения при ожидающем вызове инструмента

Пока сеанс находится в режиме ожидания с причиной остановки requires_action, system.message должно следовать за событием результата инструмента в том же запросе. Если отправить его отдельно или вместе с user.message, оно будет отклоняться, пока ожидающие события инструментов не будут разрешены.

Следующие шаги

Отображайте текст ответа агента, пока модель ещё генерирует его.

Проверяйте сеанс в Claude Console и просматривайте использование токенов и прейскурантную стоимость.

Получайте уведомления о важных событиях без опроса.

Найдите любой тип события, который сеанс может отправить или получить.

Was this page helpful?