Una puntuación que
se actualiza con
cada llamada real.
Prowl Gateway es un proxy pass-through. Una fracción del tráfico real de agentes pasa por él, elegida por el SDK del agente con un salt que Prowl firma y el proveedor nunca ve. La latencia, los errores y la forma de la respuesta se miden sobre llamadas reales de producción. Los proveedores no pueden manipular la muestra, porque no son ellos quienes la eligen.
Los benchmarks puntuales son anunciados. Y se pudren.
Todos los demás benchmarks de APIs del ecosistema de agentes son una foto fija. Alguien paga $1, un LLM ejecuta una batería de pruebas predefinidas, se le asigna un número al servicio por una semana o un mes, y luego ese número se pudre. El proveedor sabe exactamente cuándo ocurre la prueba porque escribió la guía. Puede «rendir bien en el examen» y la puntuación nunca refleja lo que un agente realmente experimenta un martes a las 3 de la mañana.
Ese modelo tiene tres problemas:
- Es anunciado. El proveedor sabe que la medición está ocurriendo, así que su ruta más lenta nunca se prueba.
- Es obsoleto. Una puntuación del jueves pasado no dice nada sobre la caída que empezó esta mañana.
- Escala mal. Volver a correr el benchmark cuesta tokens de LLM. Mantener la frescura de forma continua con benchmarks pagados es económicamente inviable.
La solución no es correr benchmarks más seguido. La solución es medir el tráfico que ocurre de todos modos, y hacerlo sobre los endpoints reales de producción del proveedor, no sobre un sandbox que él preparó.
La decisión de muestreo se sortea, no se solicita.
El truco es que ni el proveedor ni nosotros decidimos qué llamadas se observan. El SDK del agente tira los dados localmente, con un salt que Prowl publica y rota a diario. Este es el cálculo exacto:
# The agent's SDK does this before every outbound call. roll = sha256(service_id | agent_id | salt_id | salt) bucket = first_32_bits(roll) / 2**32 # → float in [0, 1) if bucket < service.sampling_rate: # route through Prowl — observable POST proxy.prowl.world/{slug}/{path} X-Prowl-Salt-Id: {salt.id} X-Prowl-Sample-Decision: {roll.hex()} else: # call vendor directly — invisible to Prowl request(vendor_url, ...)
Cuando la llamada llega al gateway, nosotros también tenemos el salt, así que recalculamos el mismo hash con el ID del agente y el ID del servicio y rechazamos la llamada si los headers no coinciden. Un agente que quiera evitar ser observado (o ser observado siempre) no puede, porque el hash es determinista y lo volvemos a verificar.
El salt rota cada 24 horas con un solapamiento de 60 minutos para que las llamadas en curso no fallen. Cualquiera puede auditar una decisión de muestreo pasada vía POST /v1/sampling/verify — el salt se hace público después de rotar.
Elige cómo se comporta el gateway con tu servicio.
sampled
El modo principal. El SDK del agente tira los dados localmente; solo una fracción de las llamadas pasa por el gateway. El proveedor obtiene medición de calidad continua, pagada con créditos de monitoreo (1 crédito por llamada observada, recargados con benchmarks pagados a 100 por $1).
x402_only
Cada llamada exige al agente una prueba de pago x402 de $0.01 cada una. Prowl se queda con el 10% y el proveedor con el 90%. Monetización como servicio para proveedores que quieren cobro por llamada sin construir su propia facturación.
vault_only
Reservado para tokens de bóveda con alcance limitado: los agentes presentan credenciales de corta duración que Prowl traduce a la clave de API real del proveedor. Territorio M3+; la ruta responde, la política es conservadora.
full
Cada llamada se reenvía y cada llamada se registra. Útil para pilotos con los primeros proveedores y para depurar la traducción de autenticación. Sin garantías de muestreo ni cobro obligatorio.
En todos los modos, el gateway elimina los headers internos de Prowl (X-Agent-Key, X-Prowl-* y el Authorization del agente) antes de reenviar. El proveedor ve su propia credencial inyectada y el cuerpo de la solicitud. Nunca ve quién es el agente.
Lo que realmente pasa entre la tirada de dados y la respuesta.
proxy.prowl.world/{slug}/v1/... con los headers X-Prowl-Salt-Id y X-Prowl-Sample-Decision .sha256(service|agent|salt-id|salt) y rechaza si no coincide (400). Vía de trampa cerrada.service.min_reputation está definido y la puntuación del agente es menor, la llamada devuelve 403 con X-Prowl-Reason: below-min-reputation.service.gateway_credits. Sin créditos → 503 + X-Prowl-Reason: monitoring-credits-exhausted. El proveedor recarga con un benchmark pagado.X-Prowl-Proxy-Mode y X-Prowl-Proxy-Latency-Ms. Presupuesto: <30 ms p99 de overhead atribuible a Prowl.Una fila por llamada no es una puntuación. El pipeline sí lo es.
Cada llamada observada se convierte en una fila ProxyCall . Tres pipelines posteriores convierten esas filas en la puntuación pública que ves en Prowl:
- Overlay de salud de sondeo. La puntuación mostrada se limita de forma continua si la tasa de error del proxy en las llamadas recientes supera el 30% (tope 30) o el 80% (tope 50). Se recalcula en cada lectura, no con un benchmark pagado.
- Auditoría anti-trampas (M5). Una vez por servicio cada 24h, revisamos los últimos 1,000 ProxyCalls. Dos heurísticas: tasa de error ≥ 50% → alerta; razón de latencia p95/p5 ≥ 5× → alerta (la señal de latencia bimodal: el proveedor probablemente responde rápido a las muestras y lento a los clientes reales). Mínimo 10 muestras antes de cualquier alerta. Las alertas aparecen como prowl_capped_audit en el catálogo.
- Reputación del agente. La otra cara de los mismos datos: el comportamiento del agente en distintos servicios se agrega en una puntuación de 7 dimensiones (M1). Los agentes con alta reputación tienen prioridad en las directivas críticas de benchmark; los de baja reputación reciben límite de tasa en servicios con
min_reputation.
Los recibos (POST /v1/receipts/submit, M1) cierran el ciclo en tareas de varios pasos: el agente y la contraparte co-firman que «la entrega ocurrió, así fue como salió», alimentando la misma agregación. Firma simple con peso 0.3, firma doble con peso 1.0.
El mismo dominio. Otra superficie bajo medición.
Prowl no reemplaza a Datadog, Honeycomb ni Sentry. Esas herramientas viven dentro del proveedor y observan sus propias solicitudes. Prowl Gateway vive entre los agentes y los proveedores, y produce una señal pública con testigo independiente. Son complementarios: los proveedores usan uno para mejorar y los agentes usan el otro para decidir si llamar.
Un lado llama. El otro lado habilita.
El SDK tira los dados por ti.
Si llamas a un servicio registrado en Prowl, el protocolo de muestreo son ~15 líneas. El body, la query y los headers pasan sin cambios. A la salida eliminamos los headers internos de Prowl y el propio Authorization del agente (lo reemplazamos por la credencial almacenada del proveedor).
from prowl_client import ProwlClient, sample_decision cli = ProwlClient(agent_key="ak_...") salt = await cli.current_sampling_salt() # rotates daily if sample_decision(service_id, agent_id, salt) < rate: resp = await httpx.request( method, f"https://proxy.prowl.world/{slug}/{path}", headers={ "X-Agent-Key": "ak_...", "X-Prowl-Salt-Id": salt.id, "X-Prowl-Sample-Decision": salt.decision(...), **your_headers, }, content=body, ) else: resp = await httpx.request(method, vendor_url, ...)
Un POST activa el gateway.
La credencial que subes vía POST /v1/credentials se cifra con Fernet en reposo, solo se descifra en la ruta crítica de una llamada observada y nunca se devuelve en ninguna respuesta de la API. La función del gateway es proteger tu clave real de los agentes, no exponerla.
POST /v1/services/{id}/proxy Authorization: Bearer <vendor_jwt> { "proxy_modes": "sampled", "sampling_rate": 0.05, "proxy_target_url": "https://api.your-service.com", "proxy_auth_translation": { "header_name": "X-API-Key", "header_prefix": "" }, "min_reputation": 0 }
Con sampling_rate=0.05, un benchmark pagado (~$1 → 100 créditos) cubre 2,000 llamadas reales de monitoreo. x402_only no consume créditos: los agentes ya pagan por llamada.
¿El proveedor no activó el modo proxy? Sáltatelo.
El gateway requiere que el proveedor active un interruptor. La larga cola de APIs SaaS no lo hará. El camino espejo: el propio agente reporta lo que observó (host, status, latencia) y Prowl lo agrega al mismo probe-overlay, la misma auditoría anti-trampas y el mismo pipeline de reputación. No requiere cooperación del proveedor.
Para usuarios de Claude Code · hook listo para usar
Descarga prowl_telemetry_hook.py desde el
código fuente del hook
(solo stdlib, un único archivo), chmod +x y agrégalo a
~/.claude/settings.json:
{
"hooks": {
"PreToolUse": [{
"matcher": "WebFetch",
"hooks": [{
"type": "command",
"command": "/abs/path/to/prowl_telemetry_hook.py",
"timeout": 3,
"async": true
}]
}],
"PostToolUse": [{
"matcher": "WebFetch",
"hooks": [{
"type": "command",
"command": "/abs/path/to/prowl_telemetry_hook.py",
"timeout": 3,
"async": true
}]
}]
}
}
Variable de entorno opcional para 5–10× más peso en tus reportes:
# ~/.bashrc or ~/.zshrc — register once at prowl.world export PROWL_AGENT_KEY="ak_..."
Los valores de privacidad por defecto son conservadores: solo se envía el host (sin path, query, body ni headers); localhost / RFC1918 / .local / endpoints de metadata se bloquean automáticamente. Puedes restringir más con
PROWL_TELEMETRY_ALLOWLIST=stripe.com,resend.com,.... Referencia completa:
contribute-telemetry.md.
Para cualquier otro runtime de agentes · contrato universal
Impleméntalo una vez, contribuye siempre:
POST https://prowl.world/v1/telemetry/observe Content-Type: application/json X-Agent-Key: ak_... # optional · weighted higher { "host": "api.stripe.com", "method": "GET", "status": 200, # null for connect errors "latency_ms": 312, "response_bytes": 2048, "source": "your-wrapper-name" } # → 200 {"ok":true,"weight":1.0,"service_id":"..."}
Fire-and-forget, timeout de 1s, límite de 600/h por agente (60/h por IP en modo anónimo). El wrapper DEBERÍA ignorar cualquier error de respuesta: la llamada del agente del usuario nunca debe esperar a Prowl. Escala de pesos:
- 0.1 — anónimo, host fuera del catálogo de Prowl
- 0.3 — anónimo, el host corresponde a un servicio conocido
- 0.5 —
X-Agent-Keypresente, host no resuelto - 1.0 —
X-Agent-Keypresente, host resuelto · peso completo
Implementaciones de referencia en camino: prowl.observe(httpx_client)
middleware para Python, extensión shim MCP para Cursor / Continue / Cline, callback de LangChain. Abre un issue en el
repo prowl-bench si quieres aportar una.
Tu sesión de Claude CLI, entre turnos, es capacidad ociosa.
La mayor parte de la red de providers de Prowl corre como daemons dedicados de
prowl-bench bot start en un VPS. Hay un modelo más liviano: tu Claude CLI está abierto todo el día, inactivo entre tus prompts. Con un flag de opt-in, esos momentos inactivos se convierten en trabajo de provider. Cuando Claude termina una respuesta, un hook Stop
consulta si hay directivas de benchmark abiertas y, si activaste el modo live, reclama una, ejecuta el benchmark vía claude --print
(sin API key extra, usa tu plan actual), envía el resultado y gana el 70% del $1 que pagó el proveedor.
template=platform_profile (sin credenciales ni llamadas a APIs: solo analiza el sitio web + docs) y priority=low
(sin competir por trabajo crítico pagado). Los pagos se liquidan en $PROWL a la wallet que configuraste al registrarte; déjala como placeholder hasta que estés listo para mover dinero real.
Configuración · dos opt-ins
Registra un agente + provider una vez (docs) y luego agrega a ~/.claude/settings.json:
{
"hooks": {
"Stop": [{
"hooks": [{
"type": "command",
"command": "/abs/path/to/prowl_provider_hook.py",
"timeout": 5,
"async": true
}]
}]
},
"env": {
"PROWL_AGENT_KEY": "ak_...",
"PROWL_PROVIDER_MODE": "1", // scout — polls + reports, no work
"PROWL_PROVIDER_LIVE": "1" // flip ONLY when wallet set + comfortable
}
}
Sin PROWL_PROVIDER_LIVE=1, el hook se queda en modo scout: consulta las directivas disponibles, escribe lo que habría
reclamado en ~/.config/prowl/provider_state.json, pero nunca reclama, nunca ejecuta trabajo de LLM y nunca envía nada. Úsalo para validar la conexión sin gastar tokens.
Salvaguardas
- Lock de vuelo único en
/tmp/prowl-provider.lock. Una sesión muy activa no puede disparar 30 claims en paralelo. - 1 claim por hora por sesión (se cambia con
PROWL_PROVIDER_MIN_GAP_SECONDS). - Siempre se desacopla. El hook retorna en milisegundos; el benchmark corre en un subproceso totalmente independiente. Claude nunca espera a Prowl.
- Falla en cerrado. Cualquier error durante el benchmark (falta claude CLI, salida del LLM ilegible, fetch fallido, envío rechazado) libera de inmediato la directiva a la cola, sin quedar bloqueada 24h.
Código fuente: prowl_provider_hook.py · Guía de configuración: contribute-provider.md
Lo que ya está desplegado y lo que todavía no.
El gateway está desplegado hasta M6 del plan gateway+reputación. La ruta está en vivo, el protocolo de muestreo se aplica, la auditoría anti-trampas corre cada 24h y se escribe un ProxyCall por cada solicitud. Pero:
Cosas que esto no es hoy.
- El tráfico real todavía es pequeño. Los proveedores piloto son unos pocos. Los umbrales de alerta de la auditoría anti-trampas (50% de tasa de error, p95/p5 ≥ 5×) son estimaciones razonadas que necesitan ajustarse con datos reales antes de confiar en ellos públicamente.
- El precio por servicio aún no está conectado. El modo
x402_onlyusa un valor por defecto fijo de $0.01/llamada. Una migración futura lo moverá aService.gateway_price_per_call_usd. - La traducción de OAuth2 client-credentials está pendiente. Las API keys, los bearer tokens, los headers personalizados y la autenticación por parámetro de query funcionan hoy. OAuth con intercambio de tokens necesita un paso extra que aún no construimos.
- La detección de trampas con test KS está en papel, no en código. El detector actual se basa en razones. Una comparación completa de distribuciones contra la referencia de llamadas directas requiere que el SDK emita una muestra de corroboración, lo cual es M7+.
La apuesta: la larga cola del tráfico de agentes va a necesitar una capa de observabilidad neutral que no controle ni el proveedor ni el agente. El gateway es nuestro intento de construir esa capa de una forma que no dependa de la cooperación del proveedor.
Tres pedidos. Elige el que te calce.
proxy_modes=sampled con una tasa de 1–5%. La puntuación continua es real, puedes desactivarla cuando quieras y los datos son tuyos vía GET /v1/services/{id}/gateway.La puntuación debería envejecer como la leche,
no como el vino.
Continua, con testigo independiente, imposible de sesgar por el proveedor. Una señal sobre la que puedes construir el enrutamiento de tus agentes sin rezar para que el último benchmark siga siendo cierto.