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, que é independente de framework, permitindo que mecanismos de política, gateways de aprovação, mecanismos de controle orçamentário, filtros de conteúdo e controles de saída operem sobre 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 observabilidade para rastreamento passivo, métricas e logs.

O Agent Hooks ainda não está disponível para .NET. Use middleware de agente, aprovação de ferramentas e segurança de agentes para adicionar controles de tempo de execução a agentes .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 Agent Hooks

Use os Agent Hooks quando controles desenvolvidos de forma independente precisarem compartilhar um contrato único, compartilhado e aplicável em toda a entrada do agente, as chamadas ao modelo, as chamadas a ferramentas e a 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 transversal específico da aplicação que não precisa do contrato do Agent Hooks nem de suas garantias centrais de execução.
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 de ferramentas de função.
Observabilidade Rastros passivos, métricas e logs que não controlam a execução.

O que o Agent Framework impõe

Ao adicionar Ganchos de agente a um agente, o Agent Framework aplica um limite de imposição coordenado que abrange as execuções do agente, as chamadas de modelo e as chamadas de ferramenta. O runtime fornece as seguintes garantias:

  • Falha ao fechar: uma negação bloqueia a ação protegida. Contextos inválidos, decisões inválidas, falhas no interceptor e falhas de aplicação não contornam os controles silenciosamente.
  • 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 efetivamente utiliza. Se uma transformação não puder ser aplicada, a execução falha fechada.
  • Streaming com buffer: nenhuma atualização de resposta chega ao solicitante até que a resposta completa do modelo e a saída final passem por seus pontos de intercepção.
  • Persistência condicionada ao veredicto: A persistência aguarda o veredicto que a abrange. A persistência padrão após a execução aguarda por output; a persistência do histórico por chamada de serviço aguarda 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, e não uma barreira de isolamento entre processos. Os interceptadores são executados no processo hospedeiro 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 dependência de agent-hooks-sdk é 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 extra agent-hooks não está incluído intencionalmente 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 (o mapeamento de contexto definido pela especificação, e não o agent_framework.AgentContext usado pelo middleware do agente) e retorna um veredito. 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 middleware do 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 é emitido Transformar alvo
agent_startup Antes da primeira entrada de dados em uma sessão do Agent Hooks Não transformável
input Quando uma solicitação externa entra no 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 pelo framework e razão de término
pre_tool_call Antes de cada invocação de ferramenta executada pelo framework Argumentos da ferramenta
post_tool_call Após uma ferramenta ter sucesso 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 é concluída, falha ou é 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 recursos auxiliares para avisos e negações passíveis de suspensão.

Resultado API de Python Behavior
Permitir ALLOW ou Verdict(decision=Decision.ALLOW) Continue com o alvo 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.

Negações em nível de execução e de modelo geram InterceptionBlocked e impedem que o resultado protegido chegue ao chamador ou à próxima etapa. Em um ponto de integração de ferramenta, uma negação de política impede a ação da ferramenta ou descarta seu resultado e retorna ao modelo um erro de controle contendo o motivo da política — sem o payload do alvo negado. Isso permite que o loop do agente continue. Uma falha no host ou na aplicaçã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 aos valores do Agent Framework Content, preservando o conteúdo avançado compatível em vez de reduzir cada valor a texto sem formatação. Um caminho malformado ou uma substituição incompatível resulta em falha fechada, em vez de prosseguir com o valor original.

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

A aprovação da ferramenta Agent Framework e o ponto de extensão para aprovação dos Ganchos de agente são mecanismos distintos. 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 de ferramentas que usam approval_mode="always_require". Transforme a chamada da ferramenta em post_model_call para que a solicitação de aprovação do framework contenha os valores transformados, ou retorne Verdict.escalate(...) em pre_tool_call e resolva a aprovação por meio de Agent Hooks resolver.

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 troca a latência token a token pela imposição de saída com falha fechada. Uma transformação de saída também se reflete nas atualizações liberadas ao chamador posteriormente.

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

  • Por padrão, o histórico e outras tarefas do provedor realizadas após a execução aguardam o veredito output. Uma saída negada não é persistida, e uma transformação de saída é persistida após a transformação.
  • Ao definir o construtor require_per_service_call_history_persistence=True on the Agent ou client.as_agent(...), cada troca de modelo é persistida após o seu veredito post_model_call a autorizar. Uma recusa posterior output não anula esse histórico já autorizado.
  • Para persistência pós-execução padrão, as tentativas de repetição permanecem após a decisão final output. Já o modo por chamada de serviço persiste cada resposta do modelo que passa post_model_call.

Important

Se o conteúdo do modelo não puder se tornar permanente, aplique essa política em post_model_call quando require_per_service_call_history_persistence=True. Uma política de saída somente para dados protege o que chega ao chamador, mas não remove retroativamente as trocas de modelos 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 agent_shutdown delimitam a execução, e os registros recebem um ID de sessão com uma sequência monotonicamente crescente.

Use record_sink para receber cada InterceptionRecord:

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 interceptador, o modo, a identidade e a sequência, sem copiar a payload interceptada para o registro de auditoria. O interceptor em si ainda recebe o contexto completo.

Cobrir várias execuções em uma única sessão

Use create_agent_hooks_middleware_from_emitter() quando a aplicação mantém uma sessão de Ganchos de agente de maior duração, como uma conversa com um registro 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"))

Nessa forma, o aplicativo configura o emissor e é responsável pela inicialização, pelo encerramento e pela limpeza em caso de erro. 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 passíveis de reversão por meio de um canal de aprovação. Sem quem a resolva, 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 vereditos do 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 por resolver para chamadas aguardáveis. O padrão é cinco segundos. Um interceptador ou resolvedor síncrono que bloqueia o loop de eventos não pode ser interrompido por esse tempo limite.
record_sink Recebe cada registro de interceptação sem payload.

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.

Implementar com o modo somente de 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 em primeiro lugar na lista de middleware do agente, de modo 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 para agente, chat e funções não pode ser instalado separadamente.
  • Instale o pacote em Agent, não diretamente em um cliente de chat nem por meio de um provedor de contexto.
  • O middleware posicionado antes do bundle está fora da fronteira de aplicação. Trate a posição externa como confiança externa.
  • Atribua a cada agente aninhado seu próprio pacote quando a atividade de seu modelo interno e de suas ferramentas também exigir 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 com buffer: as atualizações não são liberadas token a token, pois a saída precisa estar completa antes de um veredito de falha fechada.
  • Ferramentas hospedadas: As ferramentas executadas por um provedor de modelos não passam pela interface de invocação de funções do Agent Framework. Suas chamadas e saídas são apresentadas em post_model_call, mas pre_tool_call e post_tool_call não podem bloquear a execução no servidor do provedor.
  • Limite cooperativo: os ganchos de agente não isolam interceptadores nem protege contra um host hostil. Caminhos de código que contornam o pipeline de agente protegido não são cobertos.
  • A disponibilidade do interceptador afeta a disponibilidade do agente: no modo de imposição, uma falha ou um tempo limite do interceptador bloqueia a ação protegida, conforme projetado.

Para informações sobre implantação em produção, causas de falha e orientações sobre alertas, consulte o runbook operacional do Agent Hooks.

O Agent Hooks ainda não está disponível para o Go. Use middleware de agente, aprovação de ferramentas e segurança de agentes para adicionar controles de tempo de execução a agentes Go.

Próximas Etapas