Ganchos de agente

Agent Hooks es una funcionalidad de Marco de agente de primera clase para aplicar controles de gobernanza y tiempo de ejecución en puntos bien definidos en la ejecución de un agente. Implementa el contrato AGENT-HOOKS-0.1 neutral del marco, por lo que los motores de directivas, las puertas de enlace de aprobación, los guardias de presupuesto, los filtros de contenido y los controles de salida pueden tener como destino una superficie de control común.

Importante

Los enlaces del agente son un plano de control, no un plano de telemetría. Cada interceptor devuelve un veredicto. En enforce modo, el marco actúa sobre ese veredicto; en evaluate_only modo, registra el veredicto sin cambiar la ejecución. Use la observabilidad para el seguimiento pasivo, las métricas y los registros.

Los enlaces del agente aún no están disponibles para .NET. Use el middleware del agente, la aprobación de herramientas y la seguridad del agente para agregar controles en tiempo de ejecución a .NET agentes.

Agent Hooks es experimental en Python. El generador emite una ExperimentalWarning excepción cuando se usa por primera vez y su API puede cambiar antes de la disponibilidad general.

Cuándo usar enlaces de agente

Use enlaces de agente cuando los controles desarrollados de forma independiente necesiten un contrato compartido y ejecutable entre la entrada del agente, las llamadas de modelo, las llamadas a las herramientas y la salida final.

Capacidad Úselo para
Enlaces de agente Decisiones de directiva estandarizadas, transformaciones, aprobaciones, presupuestos y controles de salida en todo el ciclo de vida del agente.
Middleware del agente Comportamiento transversal específico de la aplicación que no necesita el contrato de enlaces del agente o sus garantías principales en tiempo de ejecución.
Seguridad del agente con FIDES Etiquetas y directivas de flujo de información deterministas para contenido que no es de confianza o confidencial.
Aprobación de herramientas Confirmación humana de llamadas individuales a las herramientas de función.
Observabilidad Seguimientos pasivos, métricas y registros que no controlan la ejecución.

¿Qué aplica Agent Framework?

Al agregar enlaces de agente a un agente, Agent Framework aplica un límite de cumplimiento coordinado entre las ejecuciones del agente, las llamadas de modelo y las llamadas a herramientas. El tiempo de ejecución proporciona las siguientes garantías:

  • Error cerrado: Una denegación bloquea la acción protegida. Los contextos no válidos, los veredictos no válidos, los errores de interceptor y los errores de cumplimiento no omiten de forma silenciosa los controles.
  • Transformar reescritura: Una transformación cambia los mensajes nativos, los argumentos de la herramienta, los resultados de la herramienta o la respuesta final que realmente usa la ejecución. Si no se puede aplicar una transformación, se produce un error en la ejecución.
  • Streaming almacenado en búfer: Ninguna actualización de respuesta llega al autor de la llamada hasta que la respuesta completa del modelo y la salida final pasan sus puntos de interceptación.
  • Persistencia por puerta de veredicto: La persistencia espera el veredicto que lo cubre. La persistencia estándar después de la ejecución espera ; outputla persistencia del historial de llamadas por servicio espera para cada post_model_call.
  • Instalación completa del lote: Los elementos de agente, chat y función se instalan como una unidad, por lo que no se puede configurar accidentalmente un límite de cumplimiento incompleto.

El contrato es cooperativo en lugar de un límite de aislamiento de proceso. Los interceptores se ejecutan en el proceso de host y reciben el contenido necesario para tomar decisiones. Registre solo interceptores de confianza.

Instalación de enlaces de agente

Instale el adicional opcional agent-hooks para el paquete principal:

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

Si usa uv:

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

La agent-hooks-sdk dependencia se importa diferida. La importación agent_framework no carga el SDK a menos que cree un conjunto de middleware de enlaces de agente.

Note

El agent-hooks adicional no se incluye intencionadamente en agent-framework-core[all]. Instálelo explícitamente cuando desee habilitar esta superficie de control experimental.

Adición de un interceptor

Un interceptor recibe una agent_hooks.AgentContext (asignación de contexto de la especificación, no la agent_framework.AgentContext usada por el middleware del agente) y devuelve un veredicto. El siguiente interceptor bloquea la salida final que contiene la palabra secret. En el ejemplo se supone que client es un cliente de chat de Agent Framework ya 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}")

Pase la agrupación como un elemento de la lista del middleware agente. Instale exactamente un paquete de enlaces del agente en cada agente.

Puntos de interceptación

Agent Framework emite automáticamente los puntos de interceptación aplicables:

Punto de interceptación Cuando se emite Destino de transformación
agent_startup Antes de la primera entrada en una sesión de enlaces del agente No transformable
input Cuando una solicitud externa entra en el agente Contenido y rol de entrada
pre_model_call Antes de cada solicitud de modelo Mensajes enviados al modelo
post_model_call Después de cada respuesta completa del modelo Contenido de respuesta, llamadas a herramientas ejecutadas por marco y motivo de finalización
pre_tool_call Antes de cada invocación de herramienta ejecutada por el marco Argumentos de la herramienta
post_tool_call Después de que una herramienta se realice correctamente o se produzca un error Resultado de la herramienta
output Antes de que la respuesta final llegue al autor de la llamada Contenido final de la respuesta
agent_shutdown Cuando se completa la sesión de enlaces del agente, se produce un error o se cancela No transformable

Una ejecución que llama a una herramienta normalmente emite:

agent_startup input → → → post_model_callpre_model_callpre_tool_callpost_tool_call → → pre_model_callpost_model_call → → → outputagent_shutdown

Veredictos

El contrato tiene tres decisiones: allow, denyy transform. El SDK de Python también proporciona asistentes para advertencias y denegaciones de elevación.

Result API de Python Comportamiento
Permitir ALLOW o Verdict(decision=Decision.ALLOW) Continúe con el destino sin cambios.
Permitir con advertencia Verdict.warn(...) Continúe e incluya la advertencia en el registro de interceptación.
Denegar Verdict.deny(...) Bloquear la acción protegida.
Denegación de aprobación pendiente Verdict.escalate(...) Bloquear a menos que el solucionador de aprobación configurado devuelva un veredicto de permiso.
Transformación Verdict(decision=Decision.TRANSFORM, transform=Transform(...)) Vuelva a escribir un valor en $targety, a continuación, continúe con el valor reescrito.

El nivel de ejecución y el nivel de modelo deniegan InterceptionBlocked y impiden que el resultado protegido llegue al autor de la llamada o a la siguiente fase. En una costura de herramienta, una denegación de directiva impide la acción de la herramienta o descarta su resultado y devuelve un error de control que contiene el motivo de la directiva, sin la carga de destino denegada, al modelo. Esto permite que el bucle del agente continúe. Un host o un error de cumplimiento detiene la ejecución.

Aplicación de una transformación

Una ruta de acceso de transformación debe iniciarse en $target. Por ejemplo, un interceptor puede reemplazar el contenido final de la respuesta:

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

Las transformaciones se aplican a los valores de Agent Framework Content , conservando el contenido enriquecido admitido en lugar de reducir cada valor a texto sin formato. Se produce un error en una ruta de acceso con formato incorrecto o un reemplazo incompatible en lugar de continuar con el valor original.

Transformaciones de argumento y aprobación de herramientas

La aprobación de la herramienta Agent Framework y la costura de aprobación de enlaces del agente son mecanismos independientes. Para una herramienta de función con approval_mode="always_require", Agent Framework crea la solicitud de aprobación humana antes de que se ejecute el middleware de función. Por lo tanto, una pre_tool_call transformación puede cambiar los argumentos después de que el usuario haya aprobado los valores originales.

Warning

No transforme argumentos en pre_tool_call para las herramientas que usan approval_mode="always_require". Transforme la llamada a la herramienta en post_model_call para que la solicitud de aprobación del marco contenga los valores transformadosresolver, o bien devuelva Verdict.escalate(...)pre_tool_call y resuelva la aprobación mediante los enlaces del agente .

Streaming y persistencia

Los enlaces del agente mantienen la API de streaming, pero usan la semántica de salida almacenada en búfer. Agent Framework ensambla la respuesta completa del modelo, emite post_model_call, ensambla la respuesta final del agente y emite output antes de liberar las actualizaciones. Si alguno de los puntos deniega la respuesta, el autor de la llamada no recibe actualizaciones parciales.

Este comportamiento negocia la latencia de token por token para la aplicación de salida con error cerrada. Una transformación de salida también se refleja en las actualizaciones publicadas finalmente en el autor de la llamada.

La persistencia está controlada por el punto de interceptación que cubre la operación de persistencia:

  • De forma predeterminada, el historial y otros trabajos del proveedor posterior a la ejecución esperan el output veredicto. Una salida denegada no se conserva y se conserva una transformación de salida después de la transformación.
  • Cuando se establece require_per_service_call_history_persistence=True en el Agent constructor o client.as_agent(...), cada intercambio de modelos se conserva después de que su post_model_call veredicto lo permita. Una denegación posterior output no revierte el historial ya permitido.
  • Para la persistencia después de la ejecución predeterminada, los reintentos permanecen detrás de la decisión final output . En su lugar, el modo de llamada por servicio conserva cada respuesta del modelo que pasa post_model_call.

Importante

Si el contenido del modelo no debe ser duradero, aplique esa directiva en post_model_call cuando require_per_service_call_history_persistence=True. Una directiva de salida de solo salida protege lo que llega al autor de la llamada, pero no quita retroactivamente los intercambios de modelos ya permitidos y guardados en post_model_call.

Sesiones y registros de auditoría

De forma predeterminada, cada ejecución del agente crea una sesión de enlaces de agente. agent_startup y agent_shutdown corchete la ejecución, y los registros reciben un identificador de sesión con una secuencia que aumenta de forma monotónica.

Use record_sink para recibir cada InterceptionRecord:

records = []

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

Los registros de interceptación capturan la decisión, el motivo, el resumen del interceptor, el modo, la identidad y la secuencia sin copiar la carga interceptada en el registro de auditoría. El interceptor en sí mismo sigue recibiendo el contexto completo.

Intervalo de varias ejecuciones con una sesión

Use create_agent_hooks_middleware_from_emitter() cuando la aplicación posee una sesión de enlaces de agente de larga duración, como una conversación con un libro de contabilidad de aprobación:

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

En este formulario, la aplicación configura el emisor y posee la limpieza de inicio, apagado y error. El middleware emite los puntos por ejecución desde input hasta output.

Configuración de la aplicación

create_agent_hooks_middleware() acepta los siguientes controles:

Parámetro Purpose
interceptors Secuencia de interceptores o una asignación de nombre a interceptor. Al menos uno es obligatorio.
resolver Resuelve las denegaciones liftables a través de un canal de aprobación. Sin un solucionador, la denegación permanece en vigor.
mode "enforce" aplica veredictos. "evaluate_only" registra lo que sucedería, pero permite cada acción.
composition Selecciona cómo se combinan varios veredictos de interceptor.
identity_provider Genera identidades de contexto enlazadas al contenido. El valor predeterminado es "jcs-sha256".
timeout Tiempo de espera por interceptor y resolución para las llamadas que se pueden esperar. El valor predeterminado es de cinco segundos. Este tiempo de espera no puede reemplazar un interceptor sincrónico o solucionador que bloquee el bucle de eventos.
record_sink Recibe cada registro de interceptación sin carga útil.

La composición predeterminada es secuencial first_deny con la aprobación configurada para detener el plegado. Por lo tanto, el orden del interceptor es importante: colocar controles que siempre deben ejecutarse antes de que los controles que puedan solicitar aprobación. Consulte la lista de comprobación de producción de enlaces del agente antes de seleccionar otro perfil de composición.

Implementación con el modo de solo evaluación

Use evaluate_only para medir el comportamiento de la directiva antes de la aplicación:

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

En este modo, los interceptores ejecutan y registran sus veredictos, pero no se bloquea ni transforma ninguna acción. No describa una evaluate_only implementación como gobernanza aplicada.

Reglas de composición

Coloque primero la agrupación en la lista de middleware del agente para que forma el límite de cumplimiento más externo:

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

Siga estas reglas:

  • Instale exactamente un paquete de enlaces del agente por agente. Se rechazan los paquetes apilados.
  • Mantenga intacto el lote. Su middleware de agente, chat y función no se puede instalar por separado.
  • Instale la agrupación en Agent, no directamente en un cliente de chat o a través de un proveedor de contexto.
  • Middleware colocado antes de que la agrupación esté fuera del límite de cumplimiento. Trate la posición externa como confianza externa.
  • Asigne a cada agente anidado su propio lote cuando su actividad interna de modelo y herramienta también necesite interceptación.

Limitaciones actuales

  • solo Python: los enlaces del agente aún no se implementan en los SDK de .NET o Go.
  • API experimental: Las firmas y el comportamiento de fábrica pueden cambiar antes de la disponibilidad general.
  • Streaming almacenado en búfer: Las actualizaciones no se liberan por token porque la salida debe completarse antes de un veredicto de error cerrado.
  • Herramientas hospedadas: Las herramientas ejecutadas por un proveedor de modelos no pasan a través de la costura de invocación de funciones de Agent Framework. Sus llamadas y salidas se muestran en post_model_call, pero pre_tool_call y post_tool_call no pueden bloquear la ejecución del lado servidor del proveedor.
  • Límite cooperativo: Los enlaces del agente no protegen a los interceptores de espacio aislado ni protegen contra un host hostil. Las rutas de acceso de código que omiten la canalización del agente protegido no están cubiertas.
  • La disponibilidad del interceptor afecta a la disponibilidad del agente: En el modo de aplicación, un error de interceptor o tiempo de espera bloquea la acción protegida por diseño.

Para ver la implementación de producción, los motivos de error y las instrucciones de alertas, consulte el runbook de operaciones de enlaces de agente.

Los enlaces del agente aún no están disponibles para Go. Use el middleware del agente, la aprobación de herramientas y la seguridad del agente para agregar controles en tiempo de ejecución a los agentes de Go.

Pasos siguientes