Перехватчики агента

Хуки агента — это полноценная возможность платформы Agent Framework для применения политик управления и механизмов контроля во время выполнения в четко определенных точках исполнения агента. Он реализует контракт AGENT-HOOKS-0.1, не зависящий от фреймворка, поэтому механизмы политик, шлюзы согласования, ограничители бюджета, фильтры содержимого и средства контроля исходящего трафика могут использовать единую общую точку управления.

Это важно

Agent Hooks — это плоскость управления, а не плоскость телеметрии. Каждый перехватчик возвращает вердикт. В режиме enforce фреймворк действует в соответствии с этим вердиктом; в режиме evaluate_only он записывает вердикт, не изменяя ход выполнения. Используйте observability для пассивной трассировки, метрик и журналов.

Agent Hooks пока недоступны для .NET. Используйте промежуточное ПО агента, подтверждение инструментов и безопасность агента, чтобы добавить элементы управления во время выполнения агентам .NET.

Agent Hooks — экспериментальная возможность в Python. Фабрика генерирует ExperimentalWarning при первом использовании, и API фабрики может измениться до стадии общедоступности.

Когда использовать Agent Hooks

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

Capability Используйте его для
Перехватчики агента Стандартизированные политические решения, преобразования, согласования, бюджеты и контроль исходящего трафика на протяжении всего жизненного цикла агента.
Промежуточное ПО агента Сквозная функциональность, специфичная для приложения, не требующая ни контракта Agent Hooks, ни его основных гарантий среды выполнения.
Безопасность агента с помощью FIDES Детерминированные метки потока информации и политики для ненадежного или конфиденциального содержимого.
Утверждение инструмента Подтверждение человеком каждого отдельного вызова функций и инструментов.
Наблюдаемость Пассивная трассировка, метрики и журналы, которые не управляют выполнением.

Что обеспечивает фреймворк агентов

Когда вы добавляете хуки агента к агенту, Agent Framework применяет скоординированные ограничения для запусков агента, вызовов модели и вызовов инструментов. Среда выполнения предоставляет следующие гарантии:

  • Сбой закрытия: Запрет блокирует защищенное действие. Недопустимые контексты, недопустимые вердикты, ошибки перехватчика и сбои принудительного применения не обходят элементы управления автоматически.
  • Обратная запись преобразования: Преобразование изменяет исходные сообщения, аргументы инструмента, результаты инструмента или окончательный ответ, которые фактически используются при выполнении. Если преобразование невозможно применить, выполнение завершается сбоем.
  • Буферизованная потоковая передача: Обновления ответа не доходят до вызывающей стороны, пока полный ответ модели и окончательный вывод не пройдут через свои точки перехвата.
  • Сохранение, зависящее от вердикта: Сохранение ожидает вердикта, к которому оно относится. Стандартное сохранение после выполнения ожидает output; сохранение истории для каждого вызова службы ожидает каждый post_model_call.
  • Завершение установки пакета: Компоненты агента, чата и функции устанавливаются в одну единицу, поэтому не удается случайно настроить неполную границу принудительного применения.

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

Установка перехватчиков агента

Установите Agent Hooks SDK как прямую зависимость:

pip install agent-hooks-sdk

Если вы используете uv:

uv add agent-hooks-sdk

Зависимость agent-hooks-sdk импортируется лениво. Импортирование agent_framework не загружает SDK, если не создать пакет промежуточного ПО Agent Hooks.

Замечание

agent-framework-core не содержит дополнительного agent-hooks. Установите agent-hooks-sdk отдельно, прежде чем создавать пакет промежуточного ПО Agent Hooks.

Добавление перехватчика

Перехватчик получает agent_hooks.AgentContext (сопоставление контекста спецификации, а не agent_framework.AgentContext, используемое промежуточным ПО агента) и возвращает вердикт. Следующий перехватчик блокирует окончательные выходные данные, содержащие слово secret. В примере предполагается, что client клиент чата Agent Framework уже настроен.

from agent_framework import Agent, create_agent_hooks_middleware
from agent_hooks import ALLOW, AgentContext, InterceptionBlocked, Verdict


class SecretEgressGuard:
    def intercept(self, context: AgentContext) -> Verdict:
        if (
            context["interception_point"] == "output"
            and "secret" in str(context["target"]).lower()
        ):
            return Verdict.deny(
                reason="secret_in_output",
                message="The final response contains restricted content.",
            )
        return ALLOW


hooks = create_agent_hooks_middleware(
    {"secret-egress": SecretEgressGuard()},
)

agent = Agent(
    client=client,
    instructions="You are a helpful assistant.",
    middleware=[hooks],
)

try:
    response = await agent.run("Summarize the account details.")
except InterceptionBlocked as exc:
    print(f"Blocked: {exc.result.verdict.reason}")

Передайте пакет как один элемент списка агента middleware . Установите только один пакет Agent Hooks на каждый агент.

Точки перехвата

Agent Framework автоматически выдает применимые точки перехвата:

Точка перехвата При генерации Целевой объект преобразования
agent_startup Перед первым вводом в сеансе Agent Hooks Не преобразуемый
input Когда в агент поступает внешний запрос Входное содержимое и роль
pre_model_call Перед каждым запросом модели Сообщения, отправленные в модель
post_model_call После каждого полного ответа модели Содержимое ответа, вызовы инструментов, выполняемые фреймворком, и причина завершения
pre_tool_call Перед вызовом каждого выполняемого платформой средства Аргументы инструментов
post_tool_call После успешного завершения или сбоя инструмента Результат работы инструмента
output Прежде чем окончательный ответ достигнет вызывающего абонента Окончательное содержимое ответа
agent_shutdown Когда сеанс Agent Hooks завершается, завершается сбоем или отменяется Не преобразуемый

agent_startup.tools_registered — это снимок инструмента запуска. Каждый payload pre_model_call включает инструменты, фактически используемые для этого вызова модели, в необязательном поле tools. Сюда входят инструменты, добавленные в ходе работы поставщиками контекста, подключёнными серверами MCP или в результате постепенного раскрытия информации. Поле опущено, если вызов не имеет средств или набор инструментов не может быть проецирован.

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

agent_startupinputpost_tool_callpre_model_callpre_tool_callpre_model_callpost_model_callpost_model_calloutputagent_shutdown

Вердикты

Контракт имеет три решения: allow, denyи transform. Python SDK также предоставляет вспомогательные функции для предупреждений и снимаемых запретов.

Результат API Python Behavior
Позволить ALLOW или Verdict(decision=Decision.ALLOW) Продолжайте использовать целевой объект без изменений.
Разрешить с предупреждением Verdict.warn(...) Продолжить и включить предупреждение в запись перехвата.
Отрицать Verdict.deny(...) Заблокируйте защищённое действие.
Отклонение ожидающего утверждения Verdict.escalate(...) Блокировать, если настроенный модуль согласования не возвращает решение о разрешении.
Transform Verdict(decision=Decision.TRANSFORM, transform=Transform(...)) Измените значение под $target, затем продолжайте с изменённым значением.

Уровень выполнения и уровень модели отрицает InterceptionBlocked и запрещает защищенный результат достичь вызывающего или следующего этапа. На стыке с инструментом запрет по политике предотвращает выполнение инструмента или отбрасывает его результат и возвращает модели управляющую ошибку с причиной срабатывания политики, без полезной нагрузки запрещённого целевого объекта. Это позволяет продолжить цикл агента. Сбой узла или механизма принудительного применения останавливает выполнение.

Прервать выполнение из промежуточного ПО функций

Импорт MiddlewareFailure из agent_framework. ПО промежуточного слоя функций обычно преобразует обычное исключение в результат ошибки средства, а затем позволяет циклу агента продолжаться. Если промежуточное ПО функции не может безопасно продолжить выполнение, вызовите MiddlewareFailure на основе исходного исключения. Среда выполнения прерывает выполнение и передаёт сбой вызывающей стороне, вместо того чтобы преобразовывать его в результат инструмента.

Не перехватывайте MiddlewareFailure в промежуточном ПО. Его перехват позволяет циклу продолжить выполнение и меняет поведение с безопасного отказа (fail-closed) на отказ с сохранением работоспособности (fail-open). Agent Hooks использует этот сигнал внутри системы, когда его слой принудительного применения промежуточного ПО для функций дает сбой. Передайте пользовательское промежуточное ПО с закрытием при сбое в последовательности, например middleware=[policy_middleware].

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

Применение преобразования

Путь преобразования должен начинаться с $target. Например, перехватчик может заменить окончательное содержимое ответа:

from agent_hooks import ALLOW, AgentContext, Decision, Transform, Verdict


class OutputRedactor:
    def intercept(self, context: AgentContext) -> Verdict:
        if context["interception_point"] != "output":
            return ALLOW

        return Verdict(
            decision=Decision.TRANSFORM,
            reason="redacted_output",
            transform=Transform(
                path="$target.content",
                value="[Response removed by policy]",
            ),
        )

Преобразования применяются к значениям Agent Framework Content, сохраняя поддерживаемое форматированное содержимое вместо преобразования каждого значения в обычный текст. Неправильный путь или несовместимая замена завершается сбоем вместо продолжения исходного значения.

Подтверждение инструмента и преобразования аргументов

Подтверждение инструмента Agent Framework и точка подтверждения Agent Hooks — это отдельные механизмы. Для инструмента функции с approval_mode="always_require" Agent Framework создает запрос на одобрение пользователем до запуска промежуточного ПО функции. Поэтому pre_tool_call преобразование может изменять аргументы после утверждения пользователем исходных значений.

Предупреждение

Не преобразуйте аргументы в pre_tool_call для инструментов, использующих approval_mode="always_require". Преобразуйте вызов инструмента в post_model_call так, чтобы запрос на утверждение фреймворка содержал преобразованные значения, или верните Verdict.escalate(...) в pre_tool_call и выполните утверждение через перехватчики агента resolver.

Потоковая передача и сохраняемость

Agent Hooks сохраняет потоковый API, но использует семантику буферизованного вывода. Agent Framework собирает полный ответ модели, выводит post_model_call, собирает окончательный ответ агента и выводит output перед отправкой каких-либо обновлений. Если любая из двух точек отклоняет ответ, вызывающая сторона не получает частичных обновлений.

Это поведение является компромиссом между задержкой при генерации токен за токеном и жёстким обеспечением режима fail-closed для вывода. Преобразование выходных данных также отражается в обновлениях, которые в конечном итоге передаются вызывающей стороне.

Сохранение данных контролируется точкой перехвата, которая охватывает операцию сохранения:

  • По умолчанию история и другая работа поставщиков, выполняемая после запуска, ожидают решения output. Отклоненные выходные данные не сохраняются, и после преобразования выходные данные сохраняются.
  • Когда вы задаёте require_per_service_call_history_persistence=True в конструкторе client.as_agent(...) или Agent, каждый обмен с моделью сохраняется после того, как это разрешит вердикт post_model_call. Более поздний output запрет не отменяет уже разрешённую историю.
  • Для сохраняемости состояния после выполнения по умолчанию повторные попытки остаются после окончательного решения output. Вместо этого режим для каждого вызова сервиса сохраняет каждый ответ модели, прошедший через post_model_call.

Это важно

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

Сеансы и записи аудита

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

Используйте record_sink, чтобы получать каждый InterceptionRecord:

records = []

hooks = create_agent_hooks_middleware(
    {"secret-egress": SecretEgressGuard()},
    record_sink=records.append,
)

Записи перехвата фиксируют решение, причину, сводные сведения о перехватчике, режим, идентификатор и последовательность без копирования перехваченных полезных данных в запись аудита. Сам перехватчик по-прежнему получает полный контекст.

Один сеанс для нескольких запусков

Используйте create_agent_hooks_middleware_from_emitter(), когда приложение поддерживает более длительный сеанс Agent Hooks, например разговор с одним журналом утверждений:

from agent_framework import Agent, create_agent_hooks_middleware_from_emitter
from agent_hooks import AgentContextBuilder, InterceptionEmitter


emitter = InterceptionEmitter().register(SecretEgressGuard())
builder = AgentContextBuilder(
    agent_id="support-agent",
    framework="agent-framework",
    session_id="conversation-42",
)

hooks = create_agent_hooks_middleware_from_emitter(emitter, builder)
agent = Agent(client=client, middleware=[hooks])

await emitter.emit(builder.agent_startup(tools_registered=[]))
await agent.run("First turn")
await agent.run("Second turn")
await emitter.emit(builder.agent_shutdown(reason="completed"))

В этой форме приложение настраивает эмитатор и владеет запуском, завершением работы и очисткой ошибок. Промежуточное ПО передает точки для каждого запуска в диапазоне от input до output.

Настройка принудительного применения

create_agent_hooks_middleware() принимает следующие элементы управления:

Parameter Purpose
interceptors Последовательность перехватчиков или сопоставление имени с перехватчиком. Необходимо указать хотя бы один атрибут.
resolver Устраняет снимаемые запреты через канал согласования. Без сопоставителя запрет остается в силе.
mode "enforce" применяет вердикты. "evaluate_only" записывает то, что произойдет, но разрешает каждое действие.
composition Определяет, как объединяются несколько вердиктов перехватчика.
identity_provider Создает идентификаторы контекста, привязанные к содержимому. Значение по умолчанию — "jcs-sha256".
timeout Время ожидания перехватчика и сопоставителя для ожидаемых вызовов. Значение по умолчанию — пять секунд. Синхронный перехватчик или резолвер, блокирующий цикл событий, не может быть прерван этим тайм-аутом.
record_sink Получает каждую запись о перехвате без полезных данных.

По умолчанию композиция является последовательной first_deny с утверждением, настроенным для остановки свертывания. Таким образом, порядок перехватчика имеет значение: помещайте элементы управления, которые всегда должны выполняться перед элементами управления, которые могут запрашивать утверждение. Перед выбором другого профиля композиции ознакомьтесь с контрольным списком для production Agent Hooks.

Развертывание в режиме только оценки

Используйте evaluate_only, чтобы оценить поведение политики до принудительного применения:

hooks = create_agent_hooks_middleware(
    {"secret-egress": SecretEgressGuard()},
    mode="evaluate_only",
    record_sink=records.append,
)

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

Правила композиции

Поместите этот модуль первым в списке middleware агента, чтобы он образовывал самый внешний рубеж принудительного применения:

agent = Agent(
    client=client,
    middleware=[
        create_agent_hooks_middleware([SecretEgressGuard()]),
        application_middleware,
    ],
)

Следуйте этим правилам:

  • Установите ровно один пакет Agent Hooks на каждого агента. Связки, сложенные в стопку, отклоняются.
  • Сохраните пакет нетронутым. Промежуточное ПО для агентов, чата и функций нельзя устанавливать по отдельности.
  • Установите пакет в Agent, а не напрямую в клиент чата или через провайдер контекста.
  • Промежуточное ПО, размещённое перед пакетом, находится вне границы принудительного применения. Рассматривайте внешнее положение как внешнее доверие.
  • Назначьте каждому вложенному агенту собственный пакет, если его внутренняя модель и активность инструментов также нуждаются в перехвате.

Текущие ограничения

  • Только для Python: Agent Hooks ещё не реализованы в SDK для .NET и Go.
  • Экспериментальный API: Сигнатуры и поведение фабрики могут изменяться до общедоступной доступности.
  • Буферизованная потоковая передача: Обновления не выдаются по токену, поскольку вывод должен быть полностью сформирован до вынесения решения по принципу fail-closed.
  • Размещенные инструменты: Инструменты, которые выполняются поставщиком модели, не проходят через механизм вызова функций Agent Framework. Их вызовы и выходные данные отображаются в post_model_call, но post_tool_call и pre_tool_call не могут блокировать выполнение на стороне сервера поставщика.
  • Граница доверия: Agent Hooks не изолирует перехватчики в песочнице и не защищает от враждебного хоста. Пути кода, которые обходят защищенный конвейер агента, не охватываются.
  • Доступность перехватчика влияет на доступность агента: В режиме принудительного выполнения при сбое перехватчика или тайм-ауте защищённое действие блокируется — это предусмотрено архитектурой.

Сведения о развертывании в рабочей среде, причинах сбоев и рекомендациях по оповещениям см. в руководстве по эксплуатации хуков агента.

Agent Hooks пока недоступен для Go. Используйте промежуточное ПО агента, одобрение инструментов и безопасность агента, чтобы добавить средства контроля во время выполнения для агентов Go.

Дальнейшие действия