Integración con AI Gateway
El AI Gateway de Beak expone un endpoint /chat/completions compatible con OpenAI. Las aplicaciones externas apuntan cualquier cliente compatible con OpenAI al Gateway, pasan una clave virtual como token bearer y reciben una respuesta del proveedor subyacente que las reglas de enrutamiento del equipo hayan seleccionado — sin que la aplicación necesite saber qué proveedor se utilizó.
Esta página cubre el contrato de solicitud y respuesta, autenticación, manejo de errores, streaming y ejemplos de clientes en Python y TypeScript.
Endpoint
POST {base_url}/chat/completions
Donde {base_url} es la URL específica del entorno indicada en Agentes Externos — Descripción General.
La ruta es compatible con OpenAI. El Gateway acepta el mismo cuerpo de solicitud que /v1/chat/completions de OpenAI y devuelve la misma estructura de respuesta.
Autenticación
Pase la clave virtual como token bearer:
Authorization: Bearer sk-<vkey>
El Gateway también acepta la clave en el encabezado x-api-key, pero se prefiere Authorization: Bearer porque todos los clientes compatibles con OpenAI lo establecen automáticamente.
El Gateway resuelve la clave, aplica el presupuesto del equipo, el límite de velocidad, la lista de modelos permitidos, la política de Seguridad y el indicador de Observabilidad, y luego enruta la solicitud. Ninguno de estos parámetros es enviado por el cliente — se almacenan en el equipo asociado a la clave.
Solicitud
{
"model": "gpt-4o-mini",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Summarize the changes in last week's commits."}
],
"temperature": 0.2,
"max_tokens": 500,
"stream": false
}
Campos
model— El nombre de visualización del modelo tal como está registrado en el Gateway bajo Models. No el id del modelo del proveedor subyacente. Debe estar en la lista de permitidos del equipo.messages— Array estándar de OpenAI conrole/content. Roles:system,user,assistant,tool.temperature,top_p,max_tokens,n,stop,presence_penalty,frequency_penalty— Se reenvían al proveedor tal cual.stream—truepara streaming SSE (véase Streaming).tools,tool_choice— Formato de llamada a herramientas de OpenAI. Se reenvía a los proveedores que lo soportan.response_format— Se reenvía para los proveedores que soportan salidas estructuradas.
Encabezados opcionales para vinculación de trazas
Cuando el equipo tiene Observabilidad habilitada, el Gateway emite una traza y un span automáticamente. Si su aplicación gestiona una traza padre, proporcione estos encabezados para que la llamada LLM aparezca anidada bajo ella:
| Encabezado | Descripción |
|---|---|
x-beak-trace-id | El id de traza de su aplicación. El Gateway lo usa como id de traza para esta llamada y no emite una fila de traza padre — solo emite spans. |
x-beak-span-id | El id de span para esta llamada LLM. Opcional — se genera automáticamente si se omite. |
x-beak-parent-span-id | El id del span padre en su traza. Se usa para posicionar este span en el árbol. |
x-beak-agent-id | El slug de su agente. Aparece en la vista Agents de Observabilidad. |
x-beak-agent-name | Etiqueta legible del agente. |
x-beak-user-id | El id del usuario final en cuyo nombre se realiza esta llamada. |
x-beak-session-id | Id de conversación o sesión para agrupación. |
Sin estos encabezados, el Gateway genera su propia traza y la llamada LLM aparece como una traza de un solo span en Observabilidad.
Respuesta
Una respuesta exitosa sin streaming tiene la estructura estándar de completions de OpenAI:
{
"id": "chatcmpl-...",
"object": "chat.completion",
"created": 1730800000,
"model": "gpt-4o-mini",
"choices": [
{
"index": 0,
"message": {"role": "assistant", "content": "..."},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 42,
"completion_tokens": 128,
"total_tokens": 170
}
}
usage impulsa el seguimiento del gasto — cada respuesta exitosa se carga contra los presupuestos de la clave, el equipo y el proyecto en segundo plano.
Contrato de Errores
| HTTP | Causa | Respuesta |
|---|---|---|
401 | Clave virtual ausente o inválida | {"detail": "Missing API key"} o {"detail": "Invalid API key"} |
401 | Presupuesto excedido (clave, equipo o proyecto) | {"detail": "<level> budget exceeded: spend=$X.XX, limit=$Y.YY"} |
403 | Modelo no está en la lista de permitidos del equipo | {"detail": "Model '<name>' not allowed for team"} |
403 | La moderación bloqueó la solicitud | Envelope de Beak: {"module_code": "SECURITY_ERR002", "message": "Request blocked by Beak AI Security. Action: <action>, Risk Score: <score>/100. Triggered by: <validators>", "data": {"action", "legacy_action", "risk_score", "violations", "event_id"}} |
400 | El modelo existe pero está desactivado | {"detail": "Model '<name>' is not currently active"} |
429 | Límite de velocidad RPM alcanzado | {"detail": "RPM limit exceeded: <n>/<limit>"} |
429 | Límite de solicitudes paralelas alcanzado | {"detail": "Parallel request limit exceeded"} |
500 | Error del proveedor o fallo interno | {"detail": "Internal error: <reason>"} |
Nota: Los rechazos por moderación devuelven un envelope de respuesta de Beak, no el formato de error de OpenAI. El campo
data.event_idenlaza con la entrada en el Registro de Auditoria para revisión forense. Trate un403conmodule_codeque comience porSECURITY_como una decisión de política, no como un error transitorio — reintentar con el mismo contenido será bloqueado nuevamente.
Streaming
Establezca stream: true para recibir una respuesta SSE:
data: {"id":"...","choices":[{"delta":{"content":"Hello"}}]}
data: {"id":"...","choices":[{"delta":{"content":" world"}}]}
data: [DONE]
El fragmento final es la cadena literal data: [DONE]. El streaming sigue el formato SSE de OpenAI byte a byte; cualquier cliente de streaming compatible con OpenAI funciona sin cambios.
El gasto y el conteo de tokens se almacenan en búfer al final del stream a partir del campo usage del proveedor en el fragmento final. Si el proveedor no incluye usage en los fragmentos del stream, el seguimiento del gasto recurre a una estimación de costo de mejor esfuerzo basada en los conteos de tokens de prompt y completion.
Ejemplos
Python — OpenAI SDK
from openai import OpenAI
client = OpenAI(
base_url="https://<tenant>.beakops.com/api",
api_key="sk-<your-virtual-key>",
)
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Hello"}],
extra_headers={
"x-beak-trace-id": "trace-abc123",
"x-beak-agent-id": "support-agent-v2",
},
)
print(response.choices[0].message.content)
Python — LangChain
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="gpt-4o-mini",
base_url="https://<tenant>.beakops.com/api",
api_key="sk-<your-virtual-key>",
default_headers={"x-beak-agent-id": "support-agent-v2"},
)
result = llm.invoke("Hello")
TypeScript — OpenAI SDK
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://<tenant>.beakops.com/api",
apiKey: process.env.BEAK_VIRTUAL_KEY,
defaultHeaders: {
"x-beak-agent-id": "support-agent-v2",
},
});
const response = await client.chat.completions.create({
model: "gpt-4o-mini",
messages: [{ role: "user", content: "Hello" }],
});
cURL
curl -X POST "https://<tenant>.beakops.com/api/chat/completions" \
-H "Authorization: Bearer sk-<your-virtual-key>" \
-H "Content-Type: application/json" \
-H "x-beak-agent-id: support-agent-v2" \
-d '{
"model": "gpt-4o-mini",
"messages": [{"role": "user", "content": "Hello"}]
}'
Webhooks para Eventos de Presupuesto y Límite de Velocidad
Configure webhooks en AI Gateway > Alerting para recibir notificaciones cuando se active un evento de presupuesto o límite de velocidad. Útil para enrutar notificaciones a Slack, PagerDuty o un manejador personalizado.
| Evento | Se activa cuando |
|---|---|
Budget Exceeded | Un equipo o clave virtual supera su presupuesto flexible o estricto |
Rate Limited | Un equipo o clave virtual alcanza su límite TPM o RPM |
Error | Un proveedor upstream devuelve un error |
Cada webhook publica un payload JSON que describe la entidad, el límite y el valor observado. Véase Alerting.
Buenas Prácticas
- Establezca el
base_urldel cliente OpenAI una sola vez al inicio del proceso. No lo reconstruya por solicitud — el SDK de OpenAI agrupa conexiones y la sobrecarga por solicitud se desperdicia. - Siempre establezca
x-beak-agent-idsi su equipo ejecuta más de una aplicación contra la misma clave. El encabezado es lo que hace significativos los resúmenes por agente en Observabilidad. - Trate
403 SECURITY_ERR002como un veredicto definitivo. No reintente — la política bloqueará el mismo contenido nuevamente, y cada reintento crea una entrada en el registro de auditoría. - Trate
429como una señal de espera. El limitador de velocidad se restablece cada 60 segundos; un retroceso exponencial de 1–2s suele ser suficiente. - Muestre el
event_idde una respuestaSECURITY_ERR002en la interfaz de errores de su aplicación — su equipo de seguridad lo usa para buscar la interacción infractora en el Explorador Forense. - Para agentes con su propio razonamiento de múltiples pasos, envíe
x-beak-trace-idy emita sus propios spans no LLM directamente a/aiobservability/ingest/spanspara que Observabilidad muestre la traza completa, no solo las llamadas LLM. Véase Seguridad IA y Observabilidad — API Directa.