Ganchos de agente

O Agent Hooks é uma funcionalidade de primeira classe do Agent Framework para aplicar governação e controlos de tempo de execução em pontos claramente definidos durante a execução de um agente. Implementa o contrato AGENT-HOOKS-0.1, independente do framework, pelo que motores de políticas, gateways de aprovação, controlos orçamentais, filtros de conteúdo e controlos de saída podem atuar sobre uma interface de controlo comum.

Importante

O Agente Hooks é um plano de controlo, não um plano de telemetria. Cada interceptor emite um veredicto. No enforce modo, o quadro atua com base nesse veredicto; no evaluate_only modo, regista o veredicto sem alterar a execução. Use observabilidade para rastreio passivo, métricas e logs.

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

O Agent Hooks é experimental em Python. A fábrica emite um ExperimentalWarning quando é usada pela primeira vez, e a sua API pode mudar antes da disponibilidade geral.

Quando usar Ganchos de Agente

Use Ganchos de Agente quando os controlos desenvolvidos de forma independente necessitam de um contrato partilhado e executável entre a entrada do agente, chamadas de modelo, chamadas de ferramentas e saída final.

Capability Usa-o para
Agente Hooks Decisões de política padronizadas, transformações, aprovações, orçamentos e controlos de saída ao longo do ciclo de vida do agente.
Middleware de agente Comportamento transversal específico da aplicação que não precisa do contrato Agent Hooks nem das suas garantias de execução principais.
Segurança de Agentes com FIDES Etiquetas e políticas determinísticas de fluxo de informação para conteúdo não confiável ou confidencial.
Aprovação de ferramentas Confirmação humana das chamadas de ferramentas funcionais individuais.
Observabilidade Rastreios passivos, métricas e registos que não controlam a execução.

O que o Agent Framework aplica

Quando adiciona Hooks do Agente a um agente, o Agent Framework aplica um limite de imposição coordenado em todas as execuções do agente, chamadas ao modelo e chamadas a ferramentas. O tempo de execução oferece as seguintes garantias:

  • Falha encerrada: Uma negação bloqueia a ação defensiva. Contextos inválidos, veredictos inválidos, falhas nos interceptores e falhas de imposição não contornam os controlos de forma silenciosa.
  • Reescrita da transformação: Uma transformação altera as mensagens nativas, os argumentos da ferramenta, os resultados da ferramenta ou a resposta final que a execução utiliza efetivamente. Se uma transformação não puder ser aplicada, a execução falha em modo fechado.
  • Transmissão em fluxo com buffer: Nenhuma atualização da resposta é transmitida ao chamador até que a resposta completa do modelo e a saída final passem pelos respetivos pontos de interceção.
  • Persistência condicionada ao veredicto: A persistência aguarda o veredito do qual depende. A persistência padrão após a execução aguarda output; a persistência do histórico por chamada de serviço aguarda cada post_model_call.
  • Instalação completa do pacote: O agente, o chat e as partes funcionais são instalados como uma só unidade, por isso não se pode configurar acidentalmente um limite de fiscalização incompleto.

O contrato é cooperativo e não um limite de isolamento de processos. Os interceptores correm no processo anfitrião e recebem o conteúdo necessário para tomar decisões. Regista apenas interceptores em quem confies.

Instalar extensões do agente

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

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

Caso utilize uv:

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

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

Observação

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

Adicionar um interceptor

Um intercetador recebe um agent_hooks.AgentContext (o mapeamento de contexto da especificação, e não o agent_framework.AgentContext utilizado pelo middleware do agente) e devolve um veredito. O interceptor seguinte bloqueia a saída final contendo a palavra secret. O exemplo assume client que é um cliente de chat 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 Agent Hooks em cada agente.

Pontos de interceção

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

Ponto de interceção Quando é emitido Alvo de transformação
agent_startup Antes da primeira entrada numa sessão de Agent Hooks Não transformável
input Quando uma solicitação externa chega ao agente Conteúdo de entrada e função
pre_model_call Antes de cada pedido de modelo Mensagens enviadas ao modelo
post_model_call Após cada resposta completa do modelo Conteúdo de resposta, chamadas de ferramentas executadas pelo framework e razão final
pre_tool_call Antes de cada invocação de ferramenta executada pelo framework Argumentos da ferramenta
post_tool_call Depois de uma ferramenta ter sucesso ou falhar Resultado da ferramenta
output Antes de a resposta final chegar ao interlocutor Conteúdo da resposta final
agent_shutdown Quando a sessão Agent Hooks termina, falha ou é cancelada Não transformável

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

agent_startupinputpre_model_callpost_model_callpre_tool_callpost_tool_callpre_model_callpost_model_calloutputagent_shutdown

Vereditos

O contrato tem três decisões: allow, deny, e transform. O SDK Python também fornece ajudantes para avisos e recusas levantáveis.

Result API Python Comportamento
Permitir ALLOW ou Verdict(decision=Decision.ALLOW) Continue com o alvo inalterado.
Permitir com aviso Verdict.warn(...) Continue e inclua o aviso no registo de interceção.
Negar Verdict.deny(...) Bloquear a ação protegida.
Negar aguardando aprovação Verdict.escalate(...) Bloquear a menos que o resolvedor de aprovação configurado devolva um veredicto de licença.
Transform Verdict(decision=Decision.TRANSFORM, transform=Transform(...)) Reescreva um valor sob $target, e continue com o valor reescrito.

As recusas ao nível da execução e ao nível do modelo geram InterceptionBlocked e impedem que o resultado protegido chegue ao chamador ou à fase seguinte. Num ponto de integração da ferramenta, uma política de negação impede a ação da ferramenta ou descarta o respetivo resultado e devolve ao modelo um erro de controlo que contém o motivo da política, sem a carga útil do alvo negado. Isto permite que o ciclo de agentes continue. Uma falha do anfitrião 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 aos valores do Agent Framework Content , preservando o conteúdo rico suportado em vez de reduzir todos os valores a texto simples. Um caminho malformado ou substituição incompatível falha ao fechar em vez de continuar com o valor original.

Aprovação de ferramentas e transformações de argumentos

A aprovação da ferramenta Agent Framework e o ponto de integração de aprovação do Agent Hooks são mecanismos distintos. Para uma ferramenta de função com approval_mode="always_require", o Agent Framework cria o pedido de aprovação humana antes da execução do middleware da função. Uma pre_tool_call transformação pode, portanto, alterar argumentos depois de o utilizador aprovar os valores originais.

Warning

Não transforme argumentos em pre_tool_call para ferramentas que usam approval_mode="always_require". Transforme a chamada à ferramenta em post_model_call de modo que o pedido de aprovação do framework contenha os valores transformados, ou devolva Verdict.escalate(...) em pre_tool_call e resolva a aprovação através dos ganchos do agente resolver.

Transmissão e persistência

O Agent Hooks mantém a API de streaming mas utiliza 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 lançar quaisquer atualizações. Se qualquer um dos pontos negar a resposta, o chamador não recebe atualizações parciais.

Este comportamento sacrifica a latência por token em troca da imposição de uma saída em modo de falha fechada. Uma transformação de saída também se reflete nas atualizações eventualmente lançadas ao chamador.

A persistência é limitada pelo ponto de interceção que cobre a operação de persistência:

  • Por defeito, o histórico e outras tarefas do fornecedor pós-execução aguardam o veredito output. Uma saída recusada não é armazenada, e uma transformação de saída é armazenada após a transformação.
  • Quando se define require_per_service_call_history_persistence=True no construtor Agent ou em client.as_agent(...), cada intercâmbio de modelos é persistido depois de o veredito de post_model_call o permitir. Uma negação posterior output não anula esse histórico já autorizado.
  • Para a persistência predefinida após a execução, as tentativas de repetição permanecem dependentes da output decisão final. O modo por chamada de serviço, em vez disso, persiste cada resposta do modelo que passa post_model_call.

Importante

Se o conteúdo do modelo não se deve tornar persistente, aplique essa política em post_model_call quando require_per_service_call_history_persistence=True. Uma política de saída apenas protege o que chega ao chamador, mas não remove retroativamente interações com o modelo já permitidas e persistidas em post_model_call.

Sessões e registos de auditoria

Por predefinição, cada execução do agente cria uma sessão de Agent Hooks. agent_startup e agent_shutdown colocam a execução entre parênteses, e os registos recebem um ID de sessão com uma sequência monotonamente crescente.

Use record_sink para receber cada InterceptionRecord:

records = []

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

Os registos de interceção capturam a decisão, o motivo, o resumo do intercetador, o modo, a identidade e a sequência, sem copiar a carga útil intercetada para o registo de auditoria. O próprio interceptor continua a receber todo o contexto.

Abrange várias corridas numa só sessão

Utilize create_agent_hooks_middleware_from_emitter() quando a aplicação mantém uma sessão do Agent Hooks de longa duração, como uma conversa com um registo de aprovações:

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

Nesta forma, a aplicação configura o emissor e é responsável pelo arranque, desligamento e 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 controlos:

Parameter Purpose
interceptors Uma sequência de interceptores ou um mapeamento nome-para-interceptor. Pelo menos um é necessário.
resolver Resolve negações passíveis de levantamento por meio de um canal de aprovação. Na ausência de resolução, a recusa mantém-se em vigor.
mode "enforce" aplica veredictos. "evaluate_only" regista o que aconteceria, mas permite todas as ações.
composition Seleciona como os veredictos de múltiplos interceptores são combinados.
identity_provider Produz identidades contextuais ligadas ao conteúdo. A predefinição é "jcs-sha256".
timeout Tempo limite por interceptor e resolver para chamadas passíveis de espera. O padrão é cinco segundos. Um interceptor ou resolver síncrono que bloqueia o ciclo de eventos não pode ser preemptado por este timeout.
record_sink Recebe cada registo de interceção sem carga útil.

A composição padrão é sequencial first_deny, com a aprovação configurada para interromper o fold. A ordem dos intercetores é, por isso, importante: coloque os controlos que devem ser sempre executados antes dos controlos 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.

Implemente o modo apenas de avaliação

Utilização evaluate_only para medir o comportamento das políticas antes da aplicação:

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

Neste modo, os interceptores correm e os registos incluem os seus veredictos, mas nenhuma ação é bloqueada ou transformada. Não descreva uma implementação de evaluate_only como governação obrigatória.

Regras de composição

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

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

Siga estas regras:

  • Instale exatamente um pacote Agent Hooks por agente. Os pacotes empilhados são rejeitados.
  • Mantém o embrulho intacto. O seu agente, chat e middleware de funções não podem ser instalados separadamente.
  • Instale o pacote em Agent, não diretamente num cliente de chat nem através de um fornecedor de contexto.
  • O middleware colocado antes do pacote está fora do limite de fiscalização. Trate a posição externa como confiança externa.
  • Dê a cada agente aninhado o seu próprio pacote quando a atividade interna do modelo e das ferramentas também tiver de ser intercetada.

Limitações atuais

  • Apenas Python: O Agent Hooks ainda não está implementado nos SDKs .NET ou Go.
  • API Experimental: As assinaturas e comportamentos da fábrica podem mudar antes da disponibilidade geral.
  • Streaming em buffer: As atualizações não são disponibilizadas token a token porque o resultado tem de estar completo antes de uma decisão de falha em modo fechado.
  • Ferramentas hospedadas: As ferramentas executadas por um fornecedor de modelos não passam pela interface de invocação de funções da Agent Framework. As suas chamadas e resultados são apresentados em post_model_call, mas pre_tool_call e post_tool_call não podem bloquear a execução no lado do servidor do fornecedor.
  • Limite cooperativo: O Agent Hooks não isola os interceptores em sandbox nem protege contra um anfitrião malicioso. Os caminhos de código que contornam o pipeline protegido do agente não estão abrangidos.
  • A disponibilidade dos interceptores afeta a disponibilidade dos agentes: No modo de aplicação, uma falha ou um tempo limite do interceptor bloqueia, por definição, a ação protegida.

Para lançamento em produção, razões de falha e orientações de alerta, consulte o manual de operações do Agent Hooks.

O Agente Hooks ainda não está disponível para o Go. Utilize middleware de agentes, aprovação de ferramentas e segurança de agentes para adicionar controlos em tempo de execução aos agentes Go.

Passos seguintes