Claude Platform Docs
AdministraciónHooks de inferencia

Desarrolla una integración de Inference hooks

Construye el servidor de seguridad de IA que recibe solicitudes firmadas de Inference hooks, las verifica y devuelve veredictos de permitir o denegar.

Una integración de Inference hooks es un "AI security server" (servidor de seguridad de IA): un servicio HTTPS al que Anthropic llama. Para cada solicitud gobernada, tu servidor recibe un POST firmado que lleva la transcripción de la conversación y responde con un veredicto de permitir o denegar. Esta página documenta el protocolo para construir ese servidor: los esquemas de solicitud y veredicto, la verificación de firmas y el contrato operativo.

Para activar los Inference hooks y apuntarlos a tu endpoint, consulta Configurar Inference hooks. Para aprender qué son los Inference hooks y cuándo usarlos, consulta la descripción general de Inference hooks.

Obtén un primer viaje de ida y vuelta de veredicto

La integración funcional más pequeña es un servidor que lee cada solicitud y la permite. Ejecuta uno de los siguientes servidores, expónlo en una URL pública https:// (por ejemplo, detrás de un proxy inverso con terminación TLS en un host que controles, no un servicio de túnel inverso; consulta Recibir una solicitud), y luego pide a tu administrador que lo establezca como el endpoint y pruebe la conexión: el resultado de Test connection informa el veredicto de permitir que devolvió tu servidor.

# Ejecuta con: python server.py
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer


class VerdictHandler(BaseHTTPRequestHandler):
    protocol_version = "HTTP/1.1"  # keep the connection open between verdicts

    def do_POST(self):
        # Drena el cuerpo; las transcripciones pueden ocupar megabytes.
        self.rfile.read(int(self.headers.get("Content-Length", 0)))
        verdict = b'{"action": "allow"}'
        self.send_response(200)
        self.send_header("Content-Type", "application/json")
        self.send_header("Content-Length", str(len(verdict)))
        self.end_headers()
        self.wfile.write(verdict)


ThreadingHTTPServer(("", 8000), VerdictHandler).serve_forever()

Recibir una solicitud

Anthropic envía un POST HTTPS a la URL que configura tu administrador. La URL configurada completa es el endpoint: no hay un sufijo de ruta fijo, así que elige cualquier ruta que se adapte a tu servidor.

Aloja tu servidor de seguridad de IA donde Anthropic pueda alcanzarlo: una URL https:// en el puerto 443, en un host enrutable públicamente (los rangos privados, de loopback y de NAT de nivel de operador se rechazan al conectar), con un certificado que se valide contra el almacén de confianza de CA públicas y que responda sin redirecciones. El host debe tener una dirección IPv4, que Anthropic usa incluso cuando el host también tiene direcciones IPv6; se rechaza una URL cuyo host sea localhost o una dirección IPv6. La URL configurada debe ser el destino final. Los hosts de túnel inverso (ngrok y servicios de túnel similares) no son compatibles: la política de red de Anthropic los bloquea. Aloja tu servidor en un dominio que controles. Configurar Inference hooks explica cómo tu administrador configura y prueba la URL.

Cada solicitud lleva estos encabezados fijos, junto con cualquier encabezado de solicitud personalizado que tu administrador haya configurado y, una vez que tu organización tenga un secreto de firma, los encabezados de firma webhook-* descritos en Verificar la firma:

EncabezadoValor
Content-Typeapplication/json
User-Agentanthropic-dlp/1
Accept-Encodingidentity

Hay dos eventos de hook, que se distinguen por el campo type de nivel superior. El "prompt frame" (marco de prompt) se envía una vez por cada solicitud de inferencia gobernada, antes de que comience la inferencia. El "tool call frame" (marco de llamada a herramienta) se envía cuando una respuesta del modelo contiene llamadas a herramientas, antes de que se ejecute cualquiera de ellas, en organizaciones que tienen activado Validar llamadas a herramientas. En ambos casos, Anthropic espera hasta que tu servidor de seguridad de IA responda o se agote el tiempo de espera del veredicto.

El marco de prompt

El cuerpo de la solicitud es un objeto JSON con estos campos:

CampoTipoDescripción
typestringEl evento de hook: "prompt" o "tool_call" (consulta El marco de llamada a herramienta). En el futuro se introducirán otros tipos de eventos, así que maneja adecuadamente un valor no reconocido (consulta Compatibilidad hacia adelante).
request_idstringIdentificador opaco por marco para correlación. Es igual al encabezado webhook-id.
tenant_idstring o nullIdentificador opaco de la organización a la que pertenece la solicitud.
actorobjectEl principal al que se atribuye la solicitud, discriminado por type ("user" es el único valor enviado hoy): id (un identificador etiquetado, estable entre solicitudes para la misma cuenta) y email_address (cuando está disponible). Tanto id como email_address pueden ser null.
sourceobjectLa aplicación de origen: application (consulta Valores de source).
messagesarrayLa transcripción de la conversación hasta el punto de inferencia. Consulta Bloques de contenido.
session_idstring o nullIdentificador opaco de conversación, cuando existe uno. No lo analices. Para Claude Code es un identificador de sesión de mejor esfuerzo, afirmado por el cliente.
modelstring o nullIdentificador público del modelo para esta solicitud, cuando está disponible.
metadataobjectMapa de extensión reservado de claves string a valores string, enviado vacío hoy. No exijas nada de él, y tolera su ausencia, su presencia y cualquier clave que aparezca.

Un ejemplo de cuerpo de solicitud:

{
  "type": "prompt",
  "request_id": "req_abc123",
  "tenant_id": "11111111-1111-1111-1111-111111111111",
  "actor": {
    "type": "user",
    "id": "user_01AbCdEfGhIjKlMnOpQrStUv",
    "email_address": "alice@example.com"
  },
  "source": {
    "application": "claude-ai"
  },
  "session_id": "22222222-2222-2222-2222-222222222222",
  "model": "claude-sonnet-4-5",
  "messages": [
    {
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "Summarize the attached report."
        },
        {
          "type": "attachment",
          "file_name": "q2-report.pdf",
          "media_type": "application/pdf",
          "size_bytes": 48213,
          "text": "Q2 revenue grew 14% quarter over quarter..."
        }
      ]
    }
  ],
  "metadata": {}
}

Bloques de contenido

Cada entrada en messages tiene un role de user o assistant (los resultados de herramientas aparecen bajo el rol user, coincidiendo con el modelo de contenido público de la Messages API) y un array content de bloques discriminados por type:

type del bloqueCampos
texttext: el contenido de texto.
tool_useid: el identificador al que hace referencia el resultado de herramienta correspondiente. tool_name: el nombre de la herramienta. input: los argumentos que el modelo pasó a la herramienta. tool_info: solo en un marco de llamada a herramienta (se omite en los demás casos, nunca es null), un objeto que indica quién ejecuta o proporciona la herramienta; consulta El marco de llamada a herramienta.
tool_resultcontent: la salida de la herramienta como texto, con las partes unidas por saltos de línea; las partes binarias como imágenes se reemplazan por marcadores de posición, y nunca se envían bytes sin procesar. is_error: si la llamada a la herramienta falló. tool_name: el nombre de la herramienta, para que una política pueda condicionarse a la identidad de la herramienta sin hacer referencia cruzada a un bloque anterior. tool_use_id: el id del bloque tool_use correspondiente.
attachmentfile_name: el nombre o ruta original del archivo. media_type: el tipo de medio del adjunto. size_bytes: el tamaño del archivo original. text: el contenido de texto del adjunto cuando está disponible, como texto extraído de un documento, una transcripción de audio o metadatos de un enlace. Nunca se envían los bytes sin procesar del adjunto.

Aparte de type, el text de un bloque text, y el content y el is_error de un bloque tool_result, cualquiera de estos campos puede ser null cuando el valor no se conoce; por ejemplo, una imagen llega como un bloque attachment con file_name y text establecidos en null.

Un bloque cuyo type no reconozcas es una adición compatible hacia adelante. El único campo que garantiza es type; tu política puede inspeccionar cualquier otro campo presente, pero no debe rechazar la solicitud debido a un tipo no reconocido.

Qué contiene la transcripción

La transcripción es la conversación tal como la ve el usuario final, hasta el punto de inferencia: texto de la transcripción, llamadas a herramientas y sus resultados, texto extraído de adjuntos y turnos anteriores. Nunca incluye indicaciones del sistema, definiciones de herramientas, contexto interno de Anthropic, el razonamiento oculto de Claude ni bytes sin procesar de archivos.

Un turno cuyos bloques están todos excluidos se omite por completo, así que no asumas una alternancia estricta entre usuario y asistente.

Las transcripciones se envían sin truncar, por lo que una conversación larga con adjuntos grandes produce un cuerpo de solicitud grande. En la práctica, la "context window" (ventana de contexto) del modelo mantiene los cuerpos por debajo de unos 10 MB, pero el protocolo permite hasta 64 MiB. Varios valores predeterminados comunes son mucho más pequeños, incluidos client_max_body_size de nginx con 1 MB y express.json() de Express con 100 kB, y un cuerpo rechazado cuenta como un fallo del webhook, por lo que con el manejo de fallos Allow the request, un prompt demasiado grande llegaría al modelo sin inspeccionar.

Valores de source

source.application es un string abierto, no un enum cerrado. Los valores comunes son claude-ai, claude-code y cowork; las pruebas de conexión y las comprobaciones de recuperación automáticas del circuit breaker usan config-test. Pueden aparecer valores nuevos, y tu servidor no debe rechazar una solicitud por uno que no reconozca.

Trata source.application como metadatos de enrutamiento orientativos, no como un límite de confianza: no bases una decisión de política crítica para la seguridad únicamente en él.

El marco de llamada a herramienta

Cuando Claude produce llamadas a herramientas, Anthropic envía un marco de llamada a herramienta que las enumera. Las llamadas a algunas de las herramientas propias de claude.ai pueden omitirse, y una respuesta cuyas únicas llamadas a herramientas se omiten no produce un marco de llamada a herramienta; consulta Disponibilidad. Un solo veredicto cubre todo el marco: no puedes permitir algunas llamadas a herramientas y denegar otras. El marco va al mismo endpoint que el marco de prompt, con los mismos encabezados, la misma firma y los mismos campos de nivel superior. Las llamadas a herramientas realizadas por código que Claude ejecuta en la herramienta de ejecución de código se envían de la misma manera, en marcos de llamada a herramienta separados, antes de ejecutarse.

Se diferencia del marco de prompt en tres aspectos:

  • type es "tool_call".
  • messages contiene solo el último mensaje, el mensaje assistant que Claude acaba de producir: cualquier bloque text y un bloque tool_use por cada llamada a herramienta que enumera el marco, en el orden en que el modelo las produjo. La conversación anterior se omite, porque el marco de prompt enviado antes de esa llamada al modelo ya la incluía. Lee la última entrada de messages, porque el protocolo podría agregar más adelante mensajes anteriores antes de ella.
  • Cada bloque tool_use lleva un objeto tool_info que indica quién ejecuta o proporciona la herramienta.

Cuando session_id está establecido, es el mismo en ambos marcos. El marco de llamada a herramienta tiene su propio request_id, que es opaco como el del marco de prompt.

tool_info indica quién ejecuta o proporciona la herramienta, no a qué puede acceder la herramienta. Es de uno de cuatro tipos, que se distinguen por su campo type, y cada tipo lleva sus propios campos. Anthropic envía el primero de los siguientes tipos que corresponda a la herramienta. Pueden aparecer tipos nuevos: acepta un type que no reconozcas y, para ese tipo, confía solo en type.

Un campo opcional que no aplica se omite, nunca es null, así que un tool_info puede ser simplemente {"type": "client"}. tool_name lo elige quien definió la herramienta, y el toolset_name de un servidor lo elige quien escribió la solicitud, así que no trates ninguno de los dos como un límite de confianza.

Herramientas de plataforma

Una herramienta de plataforma es aquella que la propia Claude API ejecuta mientras atiende la solicitud, como la búsqueda web o la ejecución de código.

CampoPresenteDescripción
typeSiempre"platform"
tool_typeSiempreEl tipo versionado de la herramienta, como web_search_20250305. Compáralo exactamente; no extraigas un nombre ni una fecha de él.
toolset_nameOpcionalEl grupo de herramientas al que pertenece.

Herramientas de aplicación

Una herramienta de aplicación es aquella que proporciona la propia aplicación de Anthropic que realiza la solicitud, como las herramientas propias de claude.ai.

CampoPresenteDescripción
typeSiempre"application"
toolset_nameOpcionalEl grupo de herramientas al que pertenece.

Un bloque tool_use para una herramienta de búsqueda web que proporciona la propia claude.ai:

{
  "type": "tool_use",
  "id": "toolu_01LmNoPqRsTuVwXyZaBcDeFg",
  "tool_name": "web_search",
  "input": {
    "query": "comparable deals for unannounced 4.2B USD Acme Corp acquisition"
  },
  "tool_info": {
    "type": "application"
  }
}

claude.ai no siempre nombra esta herramienta web_search, así que no la identifiques solo por el nombre. input siempre incluye la consulta de búsqueda y puede contener otros campos.

Herramientas de terceros

Una herramienta de terceros es aquella que está en un servidor que Anthropic conoce, como un conector de claude.ai o un servidor MCP que la solicitud nombra en mcp_servers. Esto no significa que Anthropic haya evaluado el servidor.

CampoPresenteDescripción
typeSiempre"third_party"
toolset_nameOpcionalEl nombre que la solicitud le da al servidor.
originOpcionalEl esquema, el host y el puerto no predeterminado de la URL del servidor. Puede ser una dirección privada o local, incluido localhost. Un origin ausente significa desconocido, no seguro.
verified_originSiempre que origin lo estétrue solo cuando los servidores de Anthropic se conectan al servidor por sí mismos. Trata false como un origen que Anthropic no ha confirmado.

Un bloque tool_use para una herramienta en un servidor MCP que la solicitud nombra crm en mcp_servers:

{
  "type": "tool_use",
  "id": "toolu_01GhIjKlMnOpQrStUvWxYzAb",
  "tool_name": "crm_search",
  "input": {
    "query": "accounts renewing in Q4"
  },
  "tool_info": {
    "type": "third_party",
    "toolset_name": "crm",
    "origin": "https://mcp.crm.example.com",
    "verified_origin": true
  }
}

Herramientas de cliente

Una herramienta de cliente es cualquier otra herramienta, normalmente una que ejecuta la aplicación que llama a Claude. Una herramienta que Anthropic define pero que ejecuta la aplicación que llama, como bash o uso de computadora, también es una herramienta de cliente y lleva su tipo versionado en tool_type. Una llamada a una herramienta que la solicitud no declara también es "client".

Una herramienta en un servidor MCP al que Claude Code se conecta directamente desde la computadora del usuario, como un servidor MCP local, es una herramienta de cliente. Su tool_info es {"type": "client"}, y su tool_name es el nombre que Claude Code le da, con el formato mcp__<server>__<tool>.

Una denegación detiene la llamada antes de que Claude Code la ejecute. El intercambio entre Claude Code y un servidor local no pasa por Anthropic, así que tu servidor de seguridad de IA ve el resultado de la herramienta solo cuando Claude Code lo devuelve. Su texto aparece entonces en un bloque tool_result en el siguiente marco de prompt.

CampoPresenteDescripción
typeSiempre"client"
tool_typeOpcionalEl tipo versionado de la herramienta, como bash_20250124, cuando Anthropic define la herramienta. Compáralo exactamente; no extraigas un nombre ni una fecha de él.
toolset_nameOpcionalEl grupo de herramientas al que pertenece, como browser.

Un bloque tool_use para una herramienta que declara la aplicación que llama:

{
  "type": "tool_use",
  "id": "toolu_01AbCdEfGhIjKlMnOpQrStUv",
  "tool_name": "read_file",
  "input": {
    "path": "reports/q3.txt"
  },
  "tool_info": {
    "type": "client"
  }
}

Un bloque tool_use para bash, que Anthropic define y la aplicación que llama ejecuta:

{
  "type": "tool_use",
  "id": "toolu_01HiJkLmNoPqRsTuVwXyZaBc",
  "tool_name": "bash",
  "input": {
    "command": "ls -la reports/"
  },
  "tool_info": {
    "type": "client",
    "tool_type": "bash_20250124"
  }
}

Devolver un veredicto

Responde con HTTP 200 y un cuerpo JSON de veredicto para ambos resultados; el campo action discrimina. Para permitir la solicitud:

{
  "action": "allow"
}

Para denegarla:

{
  "action": "deny",
  "deny_reason": "This prompt appears to contain customer payment card data, which your organization's policy does not allow.",
  "reference_id": "scan_01HXPT4R9V"
}
CampoRestriccionesSemántica
action"allow" o "deny"; obligatorioallow permite que la inferencia continúe; deny la rechaza.
deny_reasonstring o null; como máximo 500 caracteres, los valores más largos se truncanSe muestra al usuario final cuando action es deny; se ignora en allow.
reference_idstring o null; como máximo 50 caracteres de [A-Za-z0-9._:/-]Tu propio identificador para esta evaluación. Se registra en la actividad de cumplimiento inference_hooks_request_denied de la denegación y nunca se muestra al usuario final. Mantenlo opaco: sin contenido de la solicitud ni datos personales.

Una denegación nunca se descarta por un problema de formato: un deny_reason demasiado grande se trunca, un reference_id mal formado se descarta silenciosamente, y el action se sigue respetando.

Lo contrario no se cumple. Cualquier cosa que no sea HTTP 200 con un veredicto analizable es un fallo de webhook, y se aplica el manejo de fallos de tu organización en lugar de un veredicto. En particular:

  • No señales una denegación con un estado de error. Una respuesta distinta de 200 es un fallo, no una denegación.
  • Cualquier valor de action distinto de allow o deny se trata como un fallo de webhook.

Anthropic lee como máximo 64 KiB del cuerpo de la respuesta, y el cuerpo debe estar sin comprimir. No se siguen las redirecciones y se ignoran las cookies. Los campos desconocidos en el cuerpo del veredicto se ignoran, por lo que puedes devolver un objeto más rico junto con los campos documentados aquí.

Un marco de llamada a herramienta acepta el mismo cuerpo de veredicto, y todas las reglas de esta sección se le aplican sin cambios. allow permite que se ejecuten las llamadas a herramientas y la respuesta continúa; deny las detiene todas y termina la respuesta con el mismo error que un prompt denegado, incluido tu deny_reason. El texto entregado antes de la primera llamada a herramienta no se retira.

Verificar la firma

Las solicitudes se firman según la especificación Standard Webhooks, usando tres encabezados. Anthropic envía los nombres de los encabezados en minúsculas, y los proxies son libres de cambiar su capitalización, así que búscalos sin distinguir mayúsculas de minúsculas.

EncabezadoContenido
webhook-idIdentificador único para esta entrega. Es igual al request_id del cuerpo. Úsalo como clave de idempotencia y como el primer componente de la carga firmada.
webhook-timestampTiempo Unix en segundos, como string decimal, del momento en que se firmó la solicitud. Rechaza una marca de tiempo que difiera más de cinco minutos del reloj de tu servidor, en cualquier dirección.
webhook-signatureUno o más valores v1,<base64> separados por espacios, cada uno un HMAC-SHA256 sobre {webhook-id}.{webhook-timestamp}.{raw body bytes}. Acepta la solicitud si algún valor coincide con el tuyo, usando una comparación de tiempo constante.

Dos detalles causan la mayoría de los errores de verificación:

  • Verifica los bytes sin procesar. Calcula el HMAC sobre el cuerpo exactamente como se recibió, antes de cualquier análisis JSON o recodificación.
  • Decodifica el secreto con un decodificador base64 estándar. El secreto de firma es el valor después del prefijo whsec_, codificado con el alfabeto base64 estándar (+ y /), al igual que la firma en el encabezado. Un decodificador seguro para URL deriva los bytes de clave incorrectos siempre que el secreto contenga + o /, lo cual ocurre la mayoría de las veces.

Una vez que tu organización tiene un secreto de firma, todas las solicitudes que envía Anthropic están firmadas, incluida la prueba de conexión, porque el flujo de configuración genera el secreto antes de la primera prueba. Habilitar Inference hooks requiere un secreto, así que rechaza cualquier solicitud que llegue sin firmar. Una excepción: una organización que habilitó Inference hooks antes de que se exigiera el secreto sigue enviando solicitudes sin firmar hasta que su administrador genere uno. Acepta solicitudes sin firmar solo hasta que tu administrador confirme que el secreto existe y, después, recházalas.

Rotar el secreto es un cambio inmediato, pero las solicitudes firmadas con el secreto anterior aún pueden llegar durante aproximadamente un minuto después, más cualquier cosa que ya esté en tránsito. Haz que tu servidor de seguridad de IA acepte firmas de ambos secretos durante el cambio para que esas solicitudes rezagadas no sean rechazadas.

Los siguientes ejemplos son implementaciones de servidor, por lo que no hay pestaña de shell: un servidor de seguridad de IA es un servicio HTTPS de larga duración en lugar de una solicitud única. Cada ejemplo usa solo la biblioteca estándar del lenguaje; el proyecto Standard Webhooks también publica bibliotecas de verificación para la mayoría de los lenguajes.

import base64
import hashlib
import hmac
import time

TOLERANCE_SECONDS = 300


def verify(secret: str, headers: dict[str, str], body: bytes) -> bool:
    """Return True if the body was signed by Anthropic for this organization.

    Anthropic sends header names in lowercase, but proxies are free to
    re-case them, so normalize the lookup to lowercase.
    """
    lowercased = {name.lower(): value for name, value in headers.items()}
    try:
        message_id = lowercased["webhook-id"]
        timestamp = lowercased["webhook-timestamp"]
        signatures = lowercased["webhook-signature"]
    except KeyError:
        return False  # unsigned request: not from Anthropic

    try:
        signed_at = int(timestamp)
    except ValueError:
        return False
    if abs(time.time() - signed_at) > TOLERANCE_SECONDS:
        return False  # replayed, or the clocks disagree

    try:
        key = base64.b64decode(secret.removeprefix("whsec_"), validate=True)
    except ValueError:
        return False  # misconfigured secret: reject rather than crash

    payload = f"{message_id}.{timestamp}.".encode() + body
    expected = b"v1," + base64.b64encode(
        hmac.new(key, payload, hashlib.sha256).digest()
    )

    # Compara bytes: compare_digest con str lanza error ante entrada no ASCII.
    return any(
        hmac.compare_digest(expected, candidate.encode())
        for candidate in signatures.split()
    )

Semántica operativa

Tiempo de espera y reintento

Tu administrador establece un tiempo de espera del veredicto entre 1 y 10,000 ms (5,000 ms de forma predeterminada). El presupuesto cubre todo el intercambio: conexión, handshake de TLS, solicitud y respuesta. El mismo tiempo de espera se aplica a los marcos de llamada a herramienta.

Anthropic reintenta exactamente una vez, después de un retraso de 100 ms, y solo cuando el intento de conexión falla. El reintento comparte el mismo presupuesto de tiempo de espera y lleva el mismo webhook-id y la misma firma. Una vez que tu servidor de seguridad de IA ha respondido, el intercambio nunca se reintenta.

Fallos de webhook

Los tiempos de espera agotados, los estados distintos de 200 (incluidas las redirecciones), los cuerpos de respuesta no analizables o demasiado grandes y los endpoints inalcanzables son todos fallos de webhook. Un fallo de webhook nunca se convierte en una denegación; en su lugar, la configuración de manejo de fallos de tu organización decide si la solicitud afectada se bloquea o continúa sin inspección.

Circuit breaker

Los fallos de webhook sostenidos atribuibles a tu servidor de seguridad de IA activan un "circuit breaker" (disyuntor) que detiene la aplicación de políticas: Anthropic deja de contactar a tu servidor, y el manejo de fallos se aplica a cada solicitud.

A partir de 10 minutos después de la activación, Anthropic comprueba si tu servidor se ha recuperado: como máximo aproximadamente una vez por minuto, envía a tu servidor la misma solicitud de prueba sintética que envía Test connection (source.application es config-test), firmada como cualquier otra solicitud y sin contenido de usuario. Respóndela normalmente. Un veredicto válido, de permitir o denegar, restablece el circuit breaker y se reanuda la aplicación de políticas; un fallo del webhook deja el circuit breaker activado y las comprobaciones continúan. Un administrador también puede restablecer el circuit breaker en cualquier momento, y los cambios de configuración del administrador detienen las comprobaciones automáticas; consulta Circuit breaker.

Los marcos de prompt y los marcos de llamada a herramienta comparten un solo circuit breaker, y los fallos en cualquiera de ellos cuentan para él.

Cada activación se registra como una actividad inference_hooks_circuit_breaker_tripped en el Activity Feed, una actividad por activación. Mientras el disyuntor está activado, no se registran actividades de Inference hooks por solicitud, por lo que la actividad de activación es el único registro en el feed de la ventana de activación.

Latencia

La aplicación de la política agrega el tiempo de ida y vuelta de tu servidor de seguridad de IA a la "latency" (latencia) de cada solicitud gobernada en tu organización. Con Validar llamadas a herramientas activado, una respuesta que produce un marco de llamada a herramienta también espera su veredicto, incluso en "shadow mode" (modo sombra). Mantén el veredicto rápido y realiza pruebas de carga de tu servidor antes de implementarlo en una organización grande.

Direcciones IP de origen

Las solicitudes a tu servidor de seguridad de IA se originan desde 160.79.106.0/24, parte de los rangos de IP de salida publicados por Anthropic. Agrega ese bloque a tu lista de permitidos, no los rangos de entrada de la misma página, que no lo cubren. La lista de permitidos reduce la exposición de tu servidor, pero no sustituye la verificación de firmas: el bloque transporta tráfico de salida de Anthropic más allá de los Inference hooks.

Compatibilidad hacia adelante

El protocolo crece sin romper los servidores escritos correctamente. Tu servidor debe ignorar:

  • Campos de nivel superior desconocidos en cualquiera de los dos marcos.
  • Claves desconocidas en metadata.
  • Nuevos valores de source.application.
  • Nuevos valores de actor.type. actor es una unión discriminada por type, y "user" es el único tipo enviado hoy; un tipo futuro garantiza solo que type esté presente.
  • Bloques de contenido con un type no reconocido.
  • Mensajes con un role distinto de user o assistant, que una revisión posterior podría agregar.

Nunca rechaces una solicitud debido a un tipo de bloque o campo no reconocido; lee los campos que conoces y omite el resto.

En el futuro se introducirán otros tipos de eventos de hook. Un nuevo tipo de evento es una adición que tu servidor no puede manejar omitiendo un campo: la solicitud aún necesita un veredicto. Cuando el type de nivel superior sea un valor que no reconozcas, devuelve un veredicto de permitir en lugar de un estado de error; una respuesta de error es un fallo de webhook, y los fallos sostenidos activan el circuit breaker.

Diseña tu integración

Un servidor de seguridad de IA de producción toma algunas decisiones de diseño más allá del protocolo de comunicación.

Deduplica por webhook-id. El encabezado webhook-id es único por entrega y es igual al request_id del cuerpo, y un reintento por fallo de conexión lo reutiliza, por lo que funciona como clave de idempotencia. Si registras veredictos, usa ese valor como clave de los registros.

Registra veredictos y une denegaciones. Almacena cada veredicto que devuelvas junto con su reference_id. Cada denegación se registra como una actividad de cumplimiento inference_hooks_request_denied que lleva el reference_id que devolvió tu servidor, por lo que puedes unir las denegaciones en el Activity Feed con los registros correspondientes en tu propio sistema.

Archiva con un servidor que siempre permite. Para capturar transcripciones en tiempo real sin vigilarlas, devuelve {"action": "allow"} incondicionalmente y persiste el marco después de responder. Esta es una alternativa basada en push al sondeo de la Compliance API, y responder antes de persistir mantiene tu viaje de ida y vuelta fuera de la ruta crítica del usuario.

Escribe deny_reason para el usuario final. El texto que devuelves es lo que el usuario ve cuando su solicitud es bloqueada, truncado a 500 caracteres. Dile qué cambiar, como qué tipo de contenido eliminar, en lugar de emitir un código de escáner que solo tu equipo pueda interpretar.

Próximos pasos

Habilita Inference hooks, conecta y prueba tu endpoint, y controla la aplicación de políticas, el manejo de fallos y el despliegue.

Qué son los Inference hooks, cómo funciona el viaje de ida y vuelta del veredicto y cuándo usarlos.

Was this page helpful?