Claude Platform Docs
Managed AgentsДелегирование работы агенту

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

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

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

Типы событий

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

  • Пользовательские события и системные события вы отправляете агенту. События user.* запускают сессию и направляют её по ходу выполнения. system.message добавляет контекст системного уровня, который применяется к сопутствующему ходу и всем последующим ходам.
  • События сессии, события span и события агента отправляются вам, чтобы вы могли наблюдать за состоянием сессии и ходом работы агента. Подключения к «stream» (потоку), в которых эта опция включена, также получают «event deltas» (дельты событий).

Строки типов событий сессии, span, агента, пользователя и системы следуют соглашению об именовании {domain}.{action}. Исключение составляют события предварительного просмотра дельт, доступные только в потоке (event_start, event_delta). Полный каталог см. в разделе Типы событий справочника. Типы событий вебхуков определены отдельно, и некоторые их имена отличаются от имён в потоке (например, session.status_idled вместо session.status_idle).

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

Интеграция событий

Отправьте событие 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",
                },
            ],
        },
    ],
)

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

# Agent is currently analyzing a file...
# Interrupt with a new direction:
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.",
                },
            ],
        },
    ],
)

Вызов возвращается сразу после постановки событий в очередь. processed_at прерывания остаётся null, пока агент не применит прерывание. Генерируемый ответ модели останавливается немедленно. Если в этот момент выполняются вызовы инструментов, применение прерывания может занять больше времени, и до тех пор сессия остаётся в состоянии running. Затем в потоке появляется событие user.interrupt, а прерванный ход завершается событием session.status_idle. Его stop_reason равен end_turn — так же, как у хода, завершившегося самостоятельно. Отдельной причины остановки для прерывания нет. Следующий ход агент начинает с user.message, которое вы отправили после прерывания.

Дельты событий

По умолчанию текст ответа агента поступает в поток в виде буферизованных событий agent.message. Каждое такое событие генерируется только после завершения запроса к модели, который его породил. Дельты событий позволяют отображать этот текст постепенно, в виде «preview» (предварительного просмотра) в реальном времени, пока модель ещё генерирует его. Предварительный просмотр — это не сам ответ. Он лишь помогает с отображением и работает по принципу «best effort» (по мере возможности), а авторитетной записью всегда остаётся буферизованное agent.message. Клиент, который игнорирует предварительные просмотры, всё равно получает полный и корректный поток.

Включение предварительного просмотра

Предварительный просмотр включается отдельно для каждого подключения к потоку. Добавьте к читаемому потоку параметр запроса event_deltas[] и повторите его по одному разу для каждого типа событий, для которого нужен предварительный просмотр. В оболочке [] является шаблоном glob, поэтому при формировании запроса в оболочке всегда заключайте URL в кавычки. В примерах скобки закодированы как %5B%5D — такой вариант тоже работает. Параметр принимают обе конечные точки потока:

  • поток уровня сессии: GET /v1/sessions/{session_id}/events/stream;
  • собственный поток каждого «session thread» (треда сессии): GET /v1/sessions/{session_id}/threads/{thread_id}/stream.

Допустимые значения — agent.message и agent.thinking. Любое другое значение приводит к ошибке 400, как и запрос с более чем 100 значениями. Предварительные просмотры субагента появляются в собственном потоке треда этого субагента.

Когда начинается событие с предварительным просмотром, поток генерирует event_start с типом и id предстоящего события:

{
  "type": "event_start",
  "event": {
    "type": "agent.message",
    "id": "sevt_01abc..."
  }
}

Для agent.message за началом следуют события event_delta с инкрементальным текстом. Каждая дельта указывает в event_id событие, которое она дополняет, а в delta.index — дополняемый блок содержимого:

{
  "type": "event_delta",
  "event_id": "sevt_01abc...",
  "delta": {
    "type": "content_delta",
    "index": 0,
    "content": {
      "type": "text",
      "text": "Here is the summary"
    }
  }
}

Для события agent.thinking с предварительным просмотром генерируется только event_start. События event_delta за ним не следуют. Буферизованное событие agent.thinking, которое завершает предварительный просмотр, не содержит содержимого размышлений: это сигнал о ходе выполнения, а не носитель содержимого.

В отличие от сохраняемых событий, у event_start и event_delta нет собственных id или processed_at. Единственный идентификатор в них — id события, для которого выполняется предварительный просмотр.

Накопление и согласование

Каждый SDK с поддержкой дельт событий включает вспомогательный аккумулятор, который сам ведёт учёт index. Вспомогательные средства для Go, Java, Ruby и C# также индексируют накапливаемый предварительный просмотр по id события. При работе со вспомогательными средствами для Python, TypeScript и PHP это сопоставление ведёте вы сами: добавляйте каждую дельту в запись для её id. Если вам нужен собственный учёт, ручной шаблон работает на любом языке — применяйте его к сгенерированным типам событий.

В ручном шаблоне предварительный просмотр служит черновым буфером, а буферизованное событие — записью. Индексируйте буфер по (event_id, index). Согласование выполняется для каждого запроса к модели. Ход начинается с одного события session.status_running. Если ход завершается нормально, каждый запрос к модели порождает по порядку:

  1. span.model_request_start;
  2. event_start;
  3. события event_delta;
  4. буферизованное agent.message;
  5. span.model_request_end (на вкладке Span events).

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

event_start     {"event": {"type": "agent.message", "id": "sevt_01abc..."}}
event_delta     {"event_id": "sevt_01abc...", "delta": {"type": "content_delta", "index": 0, "content": {"type": "text", "text": "..."}}}
...
agent.message   {"id": "sevt_01abc...", "content": [...]}

Строка event_delta повторяется для каждого фрагмента текста. Обрабатывайте каждое событие по мере поступления:

  1. При event_start запомните объявленный id. Идентификаторы всегда совпадают: event_start.event.id, каждый event_delta.event_id и id буферизованного agent.message имеют одно и то же значение.
  2. При каждом event_delta добавляйте delta.content.text к записи с ключом (event_id, delta.index) и отображайте текущий текст. Первая дельта для index создаёт эту запись.
  3. Когда поступит буферизованное agent.message, сопоставьте его по id, отбросьте накопленный предварительный просмотр и отобразите вместо него содержимое сообщения.
  4. При span.model_request_end закройте все предварительные просмотры, которые не были согласованы со своими буферизованными событиями. Дельт для них больше не будет. Если в ходе возникла ошибка или он был прерван, буферизованное событие может так и не поступить, но span.model_request_end поступит в любом случае.

Этот шаблон опирается на следующие гарантии:

  • Если объединить дельты предварительного просмотра с ключом (event_id, index) в порядке поступления, получится префикс content[index].text буферизованного события. Это именно префикс, а не обязательно весь текст, поскольку под нагрузкой дельты могут отбрасываться.
  • Подключение генерирует не более одного event_start на event_id. Буферизованное событие — последнее, что это подключение доставляет для данного id.
# Preview snapshots, keyed by event id. accumulate_managed_agents_event folds each
# event_start / event_delta into an agent.message snapshot; the buffered
# agent.message replaces it.
previews: dict[str, BetaManagedAgentsAgentMessageEvent] = {}

# Opt in to agent.message previews on this connection
with client.beta.sessions.events.stream(
    session.id, event_deltas=["agent.message"]
) as stream:
    client.beta.sessions.events.send(
        session.id,
        events=[
            {
                "type": "user.message",
                "content": [{"type": "text", "text": "Describe the repo in one sentence."}],
            },
        ],
    )

    for event in stream:
        match event.type:
            case "event_start":
                snapshot = accumulate_managed_agents_event(None, event)
                if snapshot is not None:
                    previews[event.event.id] = snapshot
                print(f"event_start             {event.event.type} {event.event.id}")
            case "event_delta":
                preview = accumulate_managed_agents_event(previews.get(event.event_id), event)
                if preview is not None:
                    previews[event.event_id] = preview
                    text = "".join(block.text for block in preview.content)
                    print(f"event_delta             preview: {text!r}")
            case "agent.message":
                # The buffered event is the record: it replaces and closes the preview
                preview = accumulate_managed_agents_event(previews.pop(event.id, None), event)
                text = "".join(block.text for block in preview.content)
                print(f"agent.message           {event.id} {text!r}")
            case "span.model_request_end":
                # No more deltas are coming. Close any preview whose
                # buffered event never arrived.
                for event_id in previews:
                    print(f"span.model_request_end  closing preview for {event_id}")
                previews.clear()
            case "session.status_idle":
                break

Предварительный просмотр событий тредов сессии

В мультиагентной сессии у каждого треда сессии есть собственный поток событий по адресу GET /v1/sessions/{session_id}/threads/{thread_id}/stream. Он принимает тот же параметр event_deltas[] с теми же значениями. Предварительные просмотры намеренно ограничены тредом: подключение показывает их только для того треда, который оно читает. Предварительные просмотры дочернего треда доставляются только в собственный поток этого треда и никогда не дублируются в поток уровня сессии. Предварительные просмотры потока уровня сессии ограничены основным тредом. Чтобы видеть текст субагента по мере того, как модель его генерирует, откройте поток треда этого субагента.

В пути потока треда легко ошибиться. Правильный путь — /threads/{thread_id}/stream, а не /events/stream: последний существует только на уровне сессии. Конечной точки /threads/{thread_id}/events/stream не существует.

Сами события предварительного просмотра не меняются. event_start и event_delta имеют одинаковую структуру в потоке треда и в потоке уровня сессии, и шаблон накопления и согласования применяется без изменений. Единственное отличие касается учёта: используйте отдельный экземпляр аккумулятора для каждого подключения к потоку.

# List the session's threads and pick a child: child threads carry a non-null
# parent_thread_id, and the primary thread's parent_thread_id is null.
child_thread = next(
    thread
    for thread in client.beta.sessions.threads.list(session.id)
    if thread.parent_thread_id is not None
)

# The child thread's stream takes the same event_deltas parameter as the
# session stream.
with client.beta.sessions.threads.events.stream(
    child_thread.id,
    session_id=session.id,
    event_deltas=["agent.message"],
) as stream:
    for event in stream:
        match event.type:
            case "event_delta":
                print(event.delta.content.text, end="")
            case "agent.message":
                # The buffered event is the authoritative record; render its content
                print()
                for block in event.content:
                    if block.type == "text":
                        print(block.text, end="")
                print()
            case "session.thread_status_idle":
                break

Цикл чтения завершается при получении session.thread_status_idle. Это событие генерируется, когда ход треда сессии завершается и тред переходит в состояние простоя.

Ограничения

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

  • Без гарантий доставки. Под нагрузкой сервер может отбрасывать дельты события. В этом случае вы получаете непрерывный префикс текста, после которого дельты для этого события больше не поступают. Буферизованное agent.message при этом всё равно поступает полностью. Никогда не считайте накопленный предварительный просмотр окончательным.
  • Нет повторной доставки при переподключении. Дельты доставляются только тому подключению, в котором включена эта опция, и только пока оно открыто. Это относится и к потоку уровня сессии, и к потоку каждого треда сессии. Подключение, открытое после начала запроса к модели, не получает дельт для этого выполняющегося события. Если поток оборвался, выполните процедуру переподключения с вкладки «Потоковая передача событий»: заново откройте поток и получите историю событий. В истории будут все буферизованные события, сгенерированные за время отключения, в том числе agent.message, которого ожидал ваш предварительный просмотр. Повторно запросить пропущенные дельты невозможно.
  • Один тред, только текст. Предварительные просмотры охватывают только текст ассистента в треде, который читает подключение. Использование инструментов, результаты инструментов, результаты MCP и активность в любом другом треде сессии в этом подключении никогда не попадают в предварительный просмотр.
  • Для agent.thinking — только начало. Предварительный просмотр agent.thinking генерирует только event_start как сигнал о начале блока размышлений. События event_delta за ним не следуют.
  • Не сохраняются. event_start и event_delta существуют только в живом потоке. Их нет ни в истории событий сессии (GET /v1/sessions/{session_id}/events), ни в истории событий какого-либо треда сессии.

Устранение неполадок с предварительным просмотром

Если поток ведёт себя не так, как вы ожидаете:

Что вы видитеЧто это означает
В потоке есть буферизованные события, но нет event_start или event_deltaВозможны две причины. Первая: в читаемом подключении опция не включена (event_deltas[] действует для отдельного подключения, а не для всей сессии). Вторая: ход вообще не затронул тред, поток которого вы читаете. Предварительные просмотры ограничены тредом, поэтому получите список тредов сессии (GET /v1/sessions/{session_id}/threads) и найдите тот, который выполнялся.
Ошибка 404 для URL потокаНеверен путь или ID, либо в запросе вообще нет бета-заголовка managed-agents. Конечные точки тредов доступны только с бета-заголовком, поэтому без него они не существуют.
Ошибка 400 с упоминанием event_deltasДопустимы только значения agent.message и agent.thinking.

Дополнительные сценарии

Обработка вызовов пользовательских инструментов

Когда агент вызывает пользовательский инструмент:

  1. Сессия генерирует событие agent.custom_tool_use с именем инструмента и входными данными.
  2. Сессия приостанавливается и генерирует событие session.status_idle с stop_reason: requires_action. ID блокирующих событий находятся в массиве stop_reason.event_ids.
  3. Выполните инструмент в своей системе и отправьте событие user.custom_tool_result для каждого блокирующего события. Передайте ID события в параметре custom_tool_use_id вместе с содержимым результата.
  4. Когда все блокирующие события будут разрешены, сессия снова перейдёт в состояние running.
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:
                        # Look up the custom tool use event and execute it
                        tool_event = events_by_id[event_id]
                        result = call_tool(tool_event.name, tool_event.input)

                        # Send the result back
                        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 "end_turn":
                    break

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

Вызов инструмента ожидает вашего подтверждения в двух случаях: при политике разрешений always_ask и при политике auto, если сервер не смог принять решение. В этом случае:

  1. Сессия генерирует событие agent.tool_use или agent.mcp_tool_use.
  2. Сессия приостанавливается и генерирует событие session.status_idle, у которого stop_reason.type равен requires_action. ID блокирующих событий находятся в массиве stop_reason.event_ids.
  3. Отправьте событие user.tool_confirmation для каждого блокирующего события и передайте ID события в параметре tool_use_id. Установите для result значение "allow" или "deny". Чтобы объяснить причину отказа, используйте deny_message.
  4. Когда все блокирующие события будут разрешены, сессия снова перейдёт в состояние running.

Каждое событие agent.tool_use и agent.mcp_tool_use содержит поле evaluated_permission со значением allow, ask или deny. Подтверждения ожидают только события, у которых evaluated_permission равно "ask". Большинство событий также содержат объект evaluation, в котором указано, какая политика привела к этому результату. Он описан в разделе Как узнать, как был оценён каждый вызов. Например, вызов bash, приостановленный политикой always_ask, выглядит в потоке так:

{
  "type": "agent.tool_use",
  "id": "sevt_01def...",
  "name": "bash",
  "input": {
    "command": "pip install -r requirements.txt"
  },
  "evaluated_permission": "ask",
  "evaluation": {
    "type": "always_ask"
  },
  "processed_at": "2026-03-25T14:01:45Z"
}
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:
                        # Approve the pending tool call
                        client.beta.sessions.events.send(
                            session.id,
                            events=[
                                {
                                    "type": "user.tool_confirmation",
                                    "tool_use_id": event_id,
                                    "result": "allow",
                                },
                            ],
                        )
                case "end_turn":
                    break

Возобновление простаивающей сессии

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

Чтобы возобновить сессию, отправьте ей событие user.message как обычно:

# Resume a previously created session by sending it a new user.message event.
# In production, pass the stored ID of the session you want to resume.
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.",
                },
            ],
        },
    ],
)

Достижение бюджета сессии

Сессия, созданная с бюджетом, не превышает расходы, а приостанавливается. Когда отслеживаемая прейскурантная стоимость сессии достигает лимита, платформа приостанавливает каждый тред перед его следующим запросом к модели. Сессия при этом не завершается, а переходит в состояние простоя с stop_reason, равным budget_reached. Запрос, из-за которого итог превысил лимит, выполняется до конца. Поэтому значение list_cost в снимке session.usage может быть равно лимиту или немного превышать его. В потоке приостановка выглядит как три события в следующем порядке:

  1. session.thread_status_idle с stop_reason: budget_reached — для каждого треда в момент его приостановки.
  2. session.usage — снимок совокупного использования сессии и отслеживаемой прейскурантной стоимости.
  3. session.status_idle с stop_reason: budget_reached. Событие session.usage всегда идёт непосредственно перед этим переходом в простой.

Последний запрос треда может одновременно превысить лимит и завершить ход треда. Тогда в собственном событии session.thread_status_idle тред сообщает end_turn, а сессия по-прежнему сообщает budget_reached. Чтобы обнаружить приостановку, ориентируйтесь на stop_reason уровня сессии.

Пока сессия находится на пределе бюджета, она принимает только события, которые завершают уже начатую работу: user.tool_confirmation, user.tool_result, user.custom_tool_result и user.interrupt. Любое событие, которое начало бы новую работу, включая user.message, отклоняется с ошибкой 400, в которой приведён этот список. Если в сессии одновременно есть тред, ожидающий ответа на запрос подтверждения инструмента, и тред, приостановленный на лимите, stop_reason уровня сессии равен requires_action, а не budget_reached. Ответ на такой запрос не запускает запрос к модели, поэтому отвечайте на него как обычно.

Никакое событие не возобновляет сессию, приостановленную на лимите. Вместо этого обновите бюджет сессии. Приостановленная работа возобновится автоматически, если вы:

  • измените лимит на любое значение выше израсходованной прейскурантной стоимости;
  • удалите бюджет, обновив сессию с "budget": null.

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

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

Отправьте событие system.message, чтобы передать агенту привилегированный контекст системного уровня. Он применяется к сопутствующему ходу и всем последующим ходам. Поле system в определении агента задаёт «system prompt» (системную подсказку) верхнего уровня. Содержимое system.message, напротив, не заменяет эту подсказку, а добавляется к системному контексту сессии как ход role: "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.",
                },
            ],
        },
    ],
)

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

Отслеживание использования

Объект сеанса включает поле usage с накопленными данными об использовании сеанса: количеством токенов, использованием серверных инструментов, активным временем и отслеживаемой «list cost» (стоимостью по прейскуранту). Получите сеанс после того, как он перейдёт в состояние ожидания, чтобы прочитать последние итоговые значения.

{
  "id": "sesn_01...",
  "status": "idle",
  "usage": {
    "input_tokens": 5000,
    "output_tokens": 3200,
    "cache_read_input_tokens": 20000,
    "cache_creation": {
      "ephemeral_5m_input_tokens": 2000,
      "ephemeral_1h_input_tokens": 0
    },
    "list_cost": {
      "amount": "187",
      "currency": "USD"
    },
    "active_seconds": 342.5,
    "server_tool_use": {
      "web_search_requests": 3,
      "web_fetch_requests": 0
    }
  }
}

input_tokens показывает некэшированные входные токены, а output_tokens — общее количество выходных токенов по всем вызовам модели в сеансе. Поле cache_read_input_tokens показывает токены, прочитанные из «prompt cache» (кэша подсказок), а объект cache_creation разбивает токены создания кэша по времени жизни кэша (ephemeral_5m_input_tokens и ephemeral_1h_input_tokens). По умолчанию записи кэша используют «time to live» (время жизни), или TTL, равное 5 минутам, поэтому последовательные ходы в пределах этого окна выигрывают от чтения из кэша, что снижает стоимость за токен.

list_cost — это накопленное потребление сеанса, рассчитанное по публичным прейскурантным ставкам, в виде целого числа центов в строке, с кодом валюты. active_seconds — это накопленное время, в течение которого в сеансе выполнялся хотя бы один поток; перекрывающаяся активность параллельных потоков учитывается один раз, в отличие от active_seconds в объекте stats сеанса, где суммируется собственное активное время каждого потока. Именно по этой дедуплицированной величине рассчитывается стоимость среды выполнения сеанса. server_tool_use подсчитывает запросы к инструментам, выполняемым на сервере, для целей тарификации: запросы веб-поиска включаются в стоимость по прейскуранту за каждый запрос, а запросы веб-загрузки не тарифицируются за запрос и не учитываются, поэтому web_fetch_requests показывает 0. Собственный объект usage каждого потока сеанса также содержит list_cost и active_seconds. Значения для отдельных потоков округляются независимо и не включают стоимость времени работы сеанса, поэтому их сумма не совпадает в точности с list_cost сеанса; определяющим является значение для сеанса.

Вам не нужно опрашивать сеанс, чтобы отслеживать эти итоговые значения. Событие session.usage содержит тот же накопленный снимок (объект usage, а также budget сеанса, который равен null, если бюджет для сеанса не задан) в потоке событий сеанса и в истории событий. Оно генерируется при переходах в состояние ожидания, а не по таймеру: сеанс генерирует одно такое событие непосредственно перед переходом в состояние ожидания, независимо от причины остановки, и одно — когда поток приостанавливается при достижении бюджета сеанса. Поэтому тот, кто читает поток событий, видит итоговую стоимость хода или работы, достигшей бюджета, без дополнительного запроса.

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

Наблюдаемость в Console

Claude Console включает «session viewer» (средство просмотра сеансов), позволяющее изучить, что сделал агент, без написания кода. На боковой панели Console в разделе Managed Agents выберите Sessions, чтобы увидеть все сеансы в рабочем пространстве с их статусом, агентом, использованием токенов, стоимостью и временем создания, затем выберите сеанс, чтобы открыть его. Средство просмотра сеансов доступно только пользователям с ролями Developer и Admin. Оно показывает:

  • Мини-карта временной шкалы: Масштабируемый обзор активности сеанса во времени, с отдельной дорожкой для каждого потока в многоагентных сеансах. Выберите дорожку, чтобы просмотреть этот поток, или выберите отметку, чтобы перейти к соответствующему событию.
  • Стенограмма: Диалог, сгруппированный по запросам к модели, включая размышления, вызовы инструментов с их входными данными и результатами, а также текст сообщений по мере потоковой передачи. Вы можете фильтровать события, а также копировать или скачивать их в формате JSON.
  • Инспектор: Боковая панель с изменяемым размером, содержащая сведения о сеансе, на пяти вкладках:
    • Session показывает сведения и метаданные сеанса, его накопленную стоимость во времени, а также расходы относительно бюджета сеанса, если он задан.
    • Events перечисляет все необработанные события текущего потока в том порядке, в котором их отправил сервер; выберите событие, чтобы увидеть его JSON. Для сообщения, которое передавалось потоком, пока страница была открыта, также доступно представление Deltas с его «event deltas» (дельтами событий).
    • Tools перечисляет инструменты, настроенные для агентов сеанса, вместе с количеством вызовов, сбоев и медианной длительностью; выберите инструмент, чтобы увидеть его вызовы и перейти к одному из них в стенограмме.
    • Resources перечисляет подключённые файлы, репозитории и хранилища памяти по их путям в контейнере, включая записи памяти в каждом хранилище и изменения, внесённые в них этим сеансом, а также файлы, которые агент записал в /mnt/session/outputs, и навыки, прикреплённые к агентам сеанса.
    • Threads перечисляет все потоки с их статусом, размером контекста и стоимостью. Выберите поток, чтобы просмотреть его сведения, такие как агент, модель, использование контекста и стоимость.

Добавьте ?event={event_id} к URL сеанса, чтобы открыть сеанс на определённом событии.

С помощью ant beta:sessions connect вы можете открыть то же средство просмотра из CLI ant или следить за сеансом в терминале. См. Подключение к сеансу Managed Agents из терминала.

Советы по отладке

  • Проверяйте события сеанса: Ошибки сеанса передаются через событие session.error
  • Просматривайте результаты инструментов: Сбои при выполнении инструментов часто объясняют неожиданное поведение агента
  • Отслеживайте использование токенов: Контролируйте расход токенов, чтобы оптимизировать подсказки и снизить затраты
  • Используйте системные подсказки: Добавьте в системную подсказку инструкции по ведению журнала, чтобы агент объяснял свои рассуждения
  • Устраняйте неполадки с предпросмотром: Если поток событий, в котором включены дельты событий, ведёт себя не так, как вы ожидаете, см. Устранение неполадок с предпросмотром

Was this page helpful?