Build a Tenant-Aware /v1/models Catalog for a Multi-Model API Gateway
Trate el descubrimiento de modelos como un contrato de autorización y preparación de ruta. Cree un catálogo /v1/models compatible con los inquilinos que enumere solo los modelos que cada clave API puede usar en cada superficie API admitida.
Una puerta de enlace no debe devolver todos los modelos conocidos por todos los proveedores conectados desde GET /v1/models. Debería devolver los modelos a los que la clave autenticada API está autorizada y operativamente puede llamar.
Esta distinción es importante cuando una clave API proporciona acceso a varios proveedores de LLM. Una unión sin formato de catálogos ascendentes puede incluir modelos que están prohibidos por la política del equipo, que no están disponibles según el plan del inquilino, que carecen de una credencial en buen estado, que son incompatibles con el número solicitado API o que no están implementados en la región requerida. Esas entradas producen selectores de modelos defectuosos y errores de tiempo de ejecución que el descubrimiento debería haber evitado.
El contrato práctico es más sólido: cada modelo anunciado debe pasar los mismos controles de admisión que se aplicarían a una solicitud real.
Defina qué significa "disponible"
La existencia del proveedor es solo una entrada. Un modelo debe aparecer en el catálogo predeterminado de una clave solo cuando todas las condiciones requeridas sean verdaderas:
- La puerta de enlace tiene un producto público configurado para el modelo.
- El inquilino, el equipo y la clave API tienen derecho a ese producto.
- El plan comercial aplicable permite su uso.
- La política permite el modelo, proveedor, región y modo de manejo de datos.
- Existe al menos una implementación o ruta ascendente compatible.
- Hay una credencial de proveedor utilizable disponible para esa ruta.
- La ruta admite al menos una API superficie anunciada en el catálogo.
- La ruta está operativamente lista según la política de salud de la puerta de enlace.
Expresado como una operación establecida:
visible_models(key) =
configured_products
∩ tenant_entitlements
∩ team_grants
∩ key_grants
∩ commercial_rights
∩ policy_eligible_routes
∩ compatible_deployments
∩ operationally_ready_routes
Esta es una recomendación, no una afirmación sobre el esquema OpenAI. El esquema estándar no define todos estos controles específicos de la puerta de enlace. Pertenecen al plano de control de la puerta de enlace y al compilador del catálogo.
Normalizar el descubrimiento de proveedores sin utilizar proxy
Hecho: las API de descubrimiento de proveedores exponen conceptos diferentes. La lista de modelos de OpenAI proporciona identificadores y metadatos básicos, pero no una matriz de capacidades completa para cada superficie de API. Anthropic distingue los estados del ciclo de vida y puede devolver información de capacidad más rica cuando se recupera un modelo o alias. Gemini expone campos como límites de tokens y métodos de generación admitidos. Microsoft Foundry puede requerir un nombre de implementación en el campo model y una implementación puede ser incompatible con un API en particular incluso cuando el modelo subyacente existe.
En consecuencia, reenviar las respuestas del proveedor directamente no es un diseño duradero. Trate a cada proveedor API como una fuente de conciliación. Convierta sus observaciones en un registro interno y luego combínelas con la configuración de la puerta de enlace y la política del inquilino.
Usar un registro de catálogo canónico
Un registro interno útil separa el contrato público de la implementación ascendente:
{
"catalog_revision": "cat_2026_11_05_0182",
"public_model_id": "reasoning-large",
"lifecycle": "active",
"api_surfaces": ["chat.completions", "responses"],
"input_modalities": ["text", "image"],
"output_modalities": ["text"],
"limits": {
"context_tokens": 200000,
"max_output_tokens": 32000
},
"capabilities": {
"tools": true,
"structured_output": true,
"batch": false
},
"entitlement_profile": "advanced-reasoning",
"routes": [
{
"provider": "provider-a",
"target_type": "deployment",
"target_id": "prod-reasoning-east",
"region": "us-east",
"state": "ready"
}
]
}
No exponga target_id, referencias de credenciales ni el estado de enrutamiento interno a través del punto final público estándar. Esos campos son datos del plano de control. Manténgalos disponibles para enrutar la admisión, las herramientas de soporte y la atribución de uso.
ID, alias e implementaciones independientes
Un ID de modelo público es un contrato de cliente. Un ID de modelo de proveedor identifica una familia o versión de modelo ascendente. Un nombre de implementación identifica un recurso de servicio creado por el operador. No son intercambiables.
Resolver un alias público en una revisión de catálogo inmutable antes del enrutamiento. Registre tanto el ID solicitado como el objetivo resuelto en el evento de uso. Si el alias cambia más adelante, el personal de soporte aún puede reconstruir qué implementación manejó una llamada anterior.
Compilar el catálogo de la clave autenticada
El compilador del catálogo debe recibir un principal autenticado, no simplemente un ID de inquilino. El mismo inquilino puede tener claves de producción, claves de desarrollo, claves de cliente restringidas y cuentas de servicio con diferentes modelos de concesión.
Una secuencia de compilación determinista es:
- Cargue la revisión del catálogo base inmutable.
- Resolver la membresía de inquilinos, la membresía de equipos y las concesiones específicas de claves.
- Aplicar restricciones de plan, geografía, residencia de datos y proveedores.
- Eliminar rutas sin credenciales válidas o implementaciones compatibles.
- Evaluar la preparación de la ruta utilizando la instantánea de estado actual.
- Agregar rutas supervivientes en registros de modelo públicos.
- Devuelve solo API superficies soportadas por al menos una ruta sobreviviente.
Utilice la semántica de intersección cuando existan concesiones clave y de equipo. Una clave asignada a un equipo restringido no debería recuperar un acceso más amplio simplemente porque el inquilino posee un plan más amplio. Esto hace que el control de acceso al modelo de IA para equipos de software sea predecible y reduce la divulgación accidental.
Mantener la lista y recuperar el comportamiento idéntico
GET /v1/models/{model} debe ejecutar el mismo predicado de autorización que la operación de lista. De lo contrario, un atacante puede enumerar identificadores ocultos comparando respuestas exitosas, prohibidas y no encontradas.
Para un modelo que la clave no puede ver, devuelve el mismo error público utilizado para un modelo desconocido. No revele si otro inquilino puede usarlo, qué proveedor lo aloja o qué derecho lo desbloquearía. Las API administrativas pueden exponer motivos más detallados a los operadores autorizados.
Representa API la compatibilidad explícitamente
La existencia de un modelo no implica compatibilidad con todos los puntos finales. Las finalizaciones de chat, las respuestas, las incrustaciones, la generación de imágenes, los mensajes en tiempo real, por lotes y Anthropic tienen diferentes contratos de solicitud y transmisión.
Por lo tanto, la admisión de ruta debe aceptar tanto un modelo como una API superficie:
admit(key, public_model_id, api_surface, request_features)
El resultado debe identificar una revisión del catálogo compatible y una o más rutas elegibles. Por ejemplo, un modelo puede admitir chat.completions pero no responses, o admitir Respuestas solo cuando no hay herramientas integradas. Un solo valor booleano como supports_responses puede ser insuficiente cuando la compatibilidad depende de las funciones solicitadas.
Recomendación: publicar capacidades conservadoras. Anuncie una función solo cuando la puerta de enlace pueda aplicarla en todo el conjunto de rutas elegibles o pueda seleccionar una ruta que la admita de manera determinista. No infieras entradas de imágenes, llamadas a herramientas ni salidas estructuradas a partir del nombre de una familia de proveedores.
Conservar SDK la compatibilidad al agregar metadatos
Mantener estables los campos estándar esperados por los clientes compatibles con OpenAI:
{
"id": "reasoning-large",
"object": "model",
"created": 1793836800,
"owned_by": "gateway",
"x_gateway": {
"catalog_revision": "cat_2026_11_05_0182",
"lifecycle": "active",
"api_surfaces": ["chat.completions", "responses"],
"input_modalities": ["text", "image"],
"availability": "available"
}
}Una extensión con espacio de nombres reduce el riesgo de colisión, pero algunos clientes descartan campos desconocidos. Si las aplicaciones necesitan datos de selección detallados, proporcione un punto final de información de modelo autenticado por separado con un esquema versionado. Mantenga /v1/models lo suficientemente pequeño para SDK, herramientas de línea de comandos y selectores de modelos.
Elija listados estables o filtrados de salud
Existen dos políticas de disponibilidad razonables.
Catálogo filtrado en estado: oculta un modelo cuando ninguna ruta está actualmente en buen estado. Esto minimiza las llamadas fallidas, pero los catálogos pueden fluctuar durante incidentes e invalidar las selecciones del lado del cliente.
Catálogo estable: continúa enumerando productos titulados mientras informas availability: temporarily_unavailable. Esto es más fácil para las herramientas de automatización y migración, pero los clientes aún pueden intentar realizar llamadas a menos que comprendan la extensión.
Un valor predeterminado práctico es ocultar los modelos que no están implementados, prohibidos, retirados o no elegibles para credenciales, y al mismo tiempo conservar los modelos que no están disponibles temporalmente con un estado explícito para clientes confiables. El punto final de compatibilidad mínima puede omitir entradas no disponibles si los clientes existentes no pueden interpretar los metadatos de estado.
Predicción: los clientes de selección de modelos más ricos dependerán cada vez más de los metadatos de capacidad y disponibilidad. Hasta que ese comportamiento sea ampliamente confiable, la admisión de rutas del lado del servidor debe seguir siendo autorizada.
Caché de catálogos compilados sin ofrecer subvenciones obsoletas
Compile catálogos fuera de la ruta de solicitud siempre que sea posible. Una clave de caché debe incluir al menos:
(tenant_id, key_id, entitlement_version, catalog_revision, policy_revision)
Invalide las entradas afectadas cuando cambie la membresía del equipo, las subvenciones de modelos, los planes de precios, las credenciales del proveedor, el estado de implementación o la política de enrutamiento. Los valores de tiempo de vida cortos no sustituyen a los eventos de revocación: incluso una breve ventana obsoleta puede exponer un modelo recientemente prohibido.
La conciliación de proveedores puede ser asíncrona. Durante una interrupción del plano de control del proveedor, conserve el último catálogo conocido, registre su tiempo de observación y evite que rutas recientemente inciertas se vuelvan elegibles. Esto mantiene la capacidad de respuesta del listado sin tratar el descubrimiento obsoleto como prueba de que se puede utilizar una nueva ruta.
Prueba el catálogo como contrato de admisión
La propiedad de conformidad más sólida es simple: para cada modelo y API superficie devuelta a una clave, la admisión de ruta debe realizarse correctamente bajo el mismo catálogo y revisión de estado.
Agregar pruebas automatizadas para:
- Una clave permitida para ver y recuperar sus modelos asignados.
- Una clave prohibida que no ve entradas de lista ni metadatos recuperables.
- Las restricciones del equipo reducen, en lugar de ampliar, el acceso a las claves.
- Una implementación de solo chat que no se anuncia para respuestas.
- Una credencial deshabilitada que elimina sus rutas dependientes.
- Un alias que se resuelve en la revisión del catálogo inmutable esperada.
- Un modelo retirado que desaparece del catálogo predeterminado.
- Invalidación de la caché después de cambios en concesiones, membresías o políticas.
- ID de modelo desconocidos y ocultos que producen errores públicos indistinguibles.
- Cada capacidad anunciada tiene al menos una ruta elegible.
Las sondas sintéticas pueden aportar pruebas de que una ruta funciona, pero consumen cuota, pueden costar dinero y no pueden cubrir todas las combinaciones de funciones. Úselos para clases de rutas representativas y combínelos con el estado de implementación, verificaciones de credenciales y el estado real del tráfico.
Registre evidencia suficiente para explicar las decisiones
Para cada solicitud aceptada o rechazada, registre la revisión del catálogo, el ID del modelo público solicitado, la superficie API, la ruta resuelta, el contrato de capacidad, la revisión de la política y un motivo de admisión estructurado. Evite almacenar contenido emergente únicamente para este propósito.
La secuencia de implementación es sencilla: definir el registro canónico, crear reconciliadores de proveedores, compilar vistas por clave, hacer una lista y recuperar un predicado de autorización compartido, conectar la admisión de rutas a la misma revisión y agregar pruebas negativas antes de habilitar las cachés. Una vez que estas piezas están en su lugar, /v1/models se convierte en una respuesta confiable a "¿qué puede llamar esta clave?" en lugar de un inventario poco filtrado.