Ganchos de agente

O Agent Hooks é uma funcionalidade de primeira classe do Agent Framework para aplicar controles de governança e runtime em pontos bem definidos na execução de um agente. Ele implementa o contrato AGENT-HOOKS-0.1 neutro da estrutura, de modo que mecanismos de política, gateways de aprovação, proteções orçamentárias, filtros de conteúdo e controles de saída podem ter como destino uma superfície de controle comum.

Important

Agent Hooks é um plano de controle, não um plano de telemetria. Cada interceptador retorna um veredicto. No enforce modo, a estrutura atua nesse veredito; no evaluate_only modo, registra o veredicto sem alterar a execução. Use a observabilidade para rastreamento passivo, métricas e logs.

O Agent Hooks ainda não está disponível para .NET. Use o middleware do agente, a aprovação da ferramenta e a segurança do agente para adicionar controles de runtime aos agentes de .NET.

Agent Hooks é experimental em Python. A fábrica emite um ExperimentalWarning quando usado pela primeira vez e sua API pode ser alterada antes da disponibilidade geral.

Quando usar ganchos de agente

Use os Ganchos do Agente quando os controles desenvolvidos independentemente precisarem de um contrato compartilhado e exequível na entrada do agente, chamadas de modelo, chamadas de ferramenta e saída final.

Capacidade Use-o para
Ganchos de agente Decisões de política padronizadas, transformações, aprovações, orçamentos e controles de saída em todo o ciclo de vida do agente.
Middleware do agente Comportamento de corte cruzado específico do aplicativo que não precisa do contrato do Agent Hooks ou de suas principais garantias de runtime.
Segurança do agente com o FIDES Políticas e rótulos determinísticos de fluxo de informações para conteúdo não confiável ou confidencial.
Aprovação da ferramenta Confirmação humana de chamadas individuais da ferramenta de função.
Observabilidade Rastreamentos passivos, métricas e logs que não controlam a execução.

O que o Agent Framework impõe

Quando você adiciona o Agent Hooks a um agente, o Agent Framework aplica um limite de imposição coordenado entre execuções de agente, chamadas de modelo e chamadas de ferramenta. O runtime fornece as seguintes garantias:

  • Falha ao fechar: Uma negação bloqueia a ação protegida. Contextos inválidos, veredictos inválidos, falhas de interceptador e falhas de imposição não ignoram silenciosamente os controles.
  • Transformar write-back: Uma transformação altera as mensagens nativas, os argumentos da ferramenta, os resultados da ferramenta ou a resposta final que a execução realmente usa. Se uma transformação não puder ser aplicada, a execução falhará.
  • Streaming em buffer: Nenhuma atualização de resposta atinge o chamador até que a resposta completa do modelo e a saída final passem seus pontos de interceptação.
  • Persistência fechada por veredicto: Persistência aguarda o veredicto que o cobre. A persistência de pós-execução padrão aguarda output; a persistência do histórico de chamadas por serviço espera por cada post_model_call.
  • Concluir a instalação do pacote: As partes de agente, chat e função são instaladas como uma unidade, portanto, um limite de imposição incompleto não pode ser configurado acidentalmente.

O contrato é cooperativo em vez de um limite de isolamento de processo. Interceptores são executados no processo de host e recebem o conteúdo necessário para tomar decisões. Registre apenas interceptores de sua confiança.

Instalar ganchos de agente

Instale o extra opcional agent-hooks para o pacote principal:

pip install "agent-framework-core[agent-hooks]"

Se você usar uv:

uv add "agent-framework-core[agent-hooks]"

A agent-hooks-sdk dependência é importada lentamente. A importação agent_framework não carrega o SDK, a menos que você crie um pacote de middleware do Agent Hooks.

Note

O agent-hooks extra intencionalmente não está incluído em agent-framework-core[all]. Instale-o explicitamente quando quiser habilitar essa superfície de controle experimental.

Adicionar um interceptor

Um interceptador recebe um agent_hooks.AgentContext (mapeamento de contexto da especificação, não o agent_framework.AgentContext usado pelo middleware do agente) e retorna um veredicto. O interceptador a seguir bloqueia a saída final que contém a palavra secret. O exemplo pressupõe client ser um cliente de chat do Agent Framework já configurado.

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}")

Passe o pacote como um elemento da lista do middleware agente. Instale exatamente um pacote do Agent Hooks em cada agente.

Pontos de interceptação

O Agent Framework emite automaticamente os pontos de interceptação aplicáveis:

Ponto de interceptação Quando ele é emitido Destino de transformação
agent_startup Antes da primeira entrada em uma sessão do Agent Hooks Não transformável
input Quando uma solicitação externa insere o agente Conteúdo e função de entrada
pre_model_call Antes de cada solicitação de modelo Mensagens enviadas para o modelo
post_model_call Após cada resposta completa do modelo Conteúdo da resposta, chamadas de ferramenta executadas pela estrutura e motivo de término
pre_tool_call Antes de cada invocação de ferramenta executada pela estrutura Argumentos da ferramenta
post_tool_call Depois que uma ferramenta for bem-sucedida ou falhar Resultado da ferramenta
output Antes que a resposta final chegue ao chamador Conteúdo da resposta final
agent_shutdown Quando a sessão do Agent Hooks for concluída, falhar ou for cancelada Não transformável

Uma execução que chama uma ferramenta normalmente emite:

agent_startup input → → pre_model_call → → post_model_callpre_tool_call → → post_tool_call → → post_model_callpre_model_call → → → outputagent_shutdown

Veredictos

O contrato tem três decisões: allow, denye transform. O SDK do Python também fornece auxiliares para avisos e negações liftable.

Resultado API de Python Behavior
Permitir ALLOW ou Verdict(decision=Decision.ALLOW) Continue com o destino inalterado.
Permitir com aviso Verdict.warn(...) Continue e inclua o aviso no registro de interceptação.
Negar Verdict.deny(...) Bloqueie a ação protegida.
Negar aprovação pendente Verdict.escalate(...) Bloqueie a menos que o resolvedor de aprovação configurado retorne um veredicto de licença.
Transformar Verdict(decision=Decision.TRANSFORM, transform=Transform(...)) Reescreva um valor em $target, em seguida, continue com o valor reescrito.

O nível de execução e o nível do modelo nega o aumento InterceptionBlocked e impede que o resultado protegido atinja o chamador ou o próximo estágio. Em uma costura de ferramenta, uma negação de política impede a ação da ferramenta ou descarta seu resultado e retorna um erro de controle que contém o motivo da política, sem a carga de destino negada, para o modelo. Isso permite que o loop do agente continue. Uma falha de host ou de imposição interrompe a execução.

Aplicar uma transformação

Um caminho de transformação deve começar em $target. Por exemplo, um interceptor pode substituir o conteúdo da resposta final:

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]",
            ),
        )

As transformações são aplicadas a valores do Agent Framework Content , preservando conteúdo avançado com suporte em vez de reduzir cada valor para texto sem formatação. Um caminho malformado ou uma substituição incompatível falha ao fechar em vez de continuar com o valor original.

Aprovação da ferramenta e transformações de argumento

A aprovação da ferramenta do Agent Framework e a costura de aprovação do Agent Hooks são mecanismos separados. Para uma ferramenta de função com approval_mode="always_require"o Agent Framework cria a solicitação de aprovação humana antes da execução do middleware de função. Uma pre_tool_call transformação pode, portanto, alterar argumentos depois que o usuário aprovou os valores originais.

Aviso

Não transforme argumentos em pre_tool_call ferramentas que usam approval_mode="always_require". Transforme a chamada de ferramenta para post_model_call que a solicitação de aprovação da estrutura contenha os valores transformados ou retorne Verdict.escalate(...)pre_tool_call e resolva a aprovação por meio dos Ganchos resolverdo Agente.

Streaming e persistência

O Agent Hooks mantém a API de streaming, mas usa semântica de saída em buffer. O Agent Framework monta a resposta completa do modelo, emite post_model_call, monta a resposta final do agente e emite output antes de liberar as atualizações. Se um dos pontos negar a resposta, o chamador não receberá atualizações parciais.

Esse comportamento negocia a latência token por token para a imposição de saída com fail closed. Uma transformação de saída também é refletida nas atualizações eventualmente liberadas para o chamador.

A persistência é fechada pelo ponto de interceptação que abrange a operação de persistência:

  • Por padrão, o histórico e outros trabalhos do provedor após a execução esperam pelo output veredicto. Uma saída negada não é mantida e uma transformação de saída é mantida após a transformação.
  • Quando você define require_per_service_call_history_persistence=True no Agent construtor ou client.as_agent(...), cada troca de modelo é mantida após o post_model_call veredicto permitir. Uma negação posterior output não reverte esse histórico já permitido.
  • Para persistência pós-execução padrão, as tentativas de repetição permanecem por trás da decisão final output . Em vez disso, o modo de chamada por serviço persiste cada resposta de modelo que passa post_model_call.

Important

Se o conteúdo do modelo não deve se tornar durável, imponha essa política quando post_model_callrequire_per_service_call_history_persistence=True. Uma política de saída somente saída protege o que atinge o chamador, mas não remove retroativamente as trocas de modelo já permitidas e persistidas em post_model_call.

Sessões e registros de auditoria

Por padrão, cada execução de agente cria uma sessão do Agent Hooks. agent_startup e colchete agent_shutdown da execução e os registros recebem uma ID de sessão com uma sequência de aumento monotonicamente.

Use record_sink para receber cada InterceptionRecordum:

records = []

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

Os registros de interceptação capturam a decisão, o motivo, o resumo do interceptor, o modo, a identidade e a sequência sem copiar a carga interceptada no registro de auditoria. O interceptor em si ainda recebe o contexto completo.

Abranger várias execuções com uma sessão

Use create_agent_hooks_middleware_from_emitter() quando o aplicativo possui uma sessão do Agent Hooks de vida mais longa, como uma conversa com um razão de aprovação:

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"))

Nesse formulário, o aplicativo configura o emissor e possui a inicialização, o desligamento e a limpeza de erros. O middleware emite os pontos por execução de input até output.

Configurar a imposição

create_agent_hooks_middleware() aceita os seguintes controles:

Parâmetro Purpose
interceptors Uma sequência de interceptadores ou um mapeamento de nome para interceptador. Pelo menos um é obrigatório.
resolver Resolve negações liftable por meio de um canal de aprovação. Sem um resolvedor, a negação permanece em vigor.
mode "enforce" aplica veredictos. "evaluate_only" registra o que aconteceria, mas permite todas as ações.
composition Seleciona como vários veredictos de interceptador são combinados.
identity_provider Produz identidades de contexto associadas ao conteúdo. O padrão é "jcs-sha256".
timeout Tempo limite por interceptador e resolvedor para chamadas aguardadas. O padrão é cinco segundos. Um interceptor ou resolvedor síncrono que bloqueia o loop de eventos não pode ser antecipado por esse tempo limite.
record_sink Recebe cada registro de interceptação sem carga.

A composição padrão é sequencial first_deny com aprovação configurada para interromper a dobra. Portanto, a ordem do interceptor é importante: coloque controles que sempre devem ser executados antes dos controles que podem solicitar aprovação. Consulte a lista de verificação de produção do Agent Hooks antes de selecionar outro perfil de composição.

Implantar com o modo somente avaliação

Use evaluate_only para medir o comportamento da política antes da imposição:

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

Nesse modo, os interceptores são executados e os registros incluem seus veredictos, mas nenhuma ação é bloqueada ou transformada. Não descreva uma implantação evaluate_only como governança imposta.

Regras de composição

Coloque o pacote primeiro na lista de middleware do agente para que ele forme o limite de imposição mais externo:

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

Siga estas regras:

  • Instale exatamente um pacote do Agent Hooks por agente. Os pacotes empilhados são rejeitados.
  • Mantenha o pacote intacto. Seu middleware de agente, chat e função não pode ser instalado separadamente.
  • Instale o pacote, Agentnão diretamente em um cliente de chat ou por meio de um provedor de contexto.
  • Middleware colocado antes que o pacote esteja fora do limite de imposição. Trate a posição externa como confiança externa.
  • Dê a cada agente aninhado seu próprio pacote quando seu modelo interno e atividade de ferramentas também precisarem de interceptação.

Limitações atuais

  • Python somente: os Ganchos do Agente ainda não foram implementados nos SDKs de .NET ou Go.
  • API experimental: As assinaturas de fábrica e o comportamento podem ser alterados antes da disponibilidade geral.
  • Streaming em buffer: As atualizações não são lançadas token por token porque a saída deve ser concluída antes de um veredito fechado por fail-closed.
  • Ferramentas hospedadas: As ferramentas executadas por um provedor de modelos não passam pela costura de invocação de função do Agent Framework. Suas chamadas e saídas são exibidas post_model_call, mas pre_tool_callpost_tool_call não podem bloquear a execução do lado do servidor do provedor.
  • Limite cooperativo: O Agent Hooks não protege interceptadores de área restrita ou contra um host hostil. Caminhos de código que ignoram o pipeline do agente protegido não são cobertos.
  • A disponibilidade do interceptor afeta a disponibilidade do agente: No modo de imposição, uma falha ou tempo limite do interceptor bloqueia a ação protegida por design.

Para obter distribuição de produção, motivos de falha e diretrizes de alerta, consulte o runbook de operações do Agent Hooks.

O Agent Hooks ainda não está disponível para o Go. Use o middleware do agente, a aprovação da ferramenta e a segurança do agente para adicionar controles de runtime aos agentes do Go.

Próximas Etapas