Por qué las llamadas pasan por una pasarela
Una pasarela LLM es un servicio único por el que pasan todas las llamadas al modelo. Guarda las claves del proveedor, aplica límites, registra la llamada y elige el modelo. Importa porque cada producto que llama directamente al proveedor necesita su propia copia de cada regla.
Una empresa tiene tres productos que llaman a un modelo. Uno filtra una clave en el registro de una compilación. Otro no tiene límite y gasta el presupuesto de un mes en una noche. Una pasarela convierte las dos cosas en un solo arreglo.
Al final de esta lección
Nota
Puedo explicar para qué sirve una pasarela delante de las llamadas al modelo.
Palabras clave
| Palabra | Qué significa |
|---|---|
| Pasarela | un servicio por el que pasan todas las llamadas al modelo |
| Clave de cliente | una clave que un equipo usa para llegar a la pasarela |
| Límite de ritmo | un tope de peticiones en un periodo |
| Enrutado | elegir qué modelo atiende una petición |
| Registro de peticiones | un rastro de cada llamada, sin su texto |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Una pasarela hace cuatro trabajos
Cada trabajo es una regla que se aplica antes o después de la llamada. Claves: quien llama tiene una clave de cliente, y solo la pasarela tiene la del proveedor. Límites: una cuenta por equipo y minuto. Enrutado: una regla elige el modelo. Registro: una huella por llamada.
Como todas las llamadas pasan por una función, cambiar una regla es cambiar un solo sitio.
Ejemplo resuelto: cinco peticiones, límite dos
| Petición | Clave | Palabras | Resultado |
|---|---|---|---|
| 1 | key-madrid | 40 | ok, modelo-pequeno |
| 2 | key-madrid | 500 | ok, modelo-grande |
| 3 | key-madrid | 20 | limitada: Madrid ya tiene dos |
| 4 | key-zzz | 10 | rechazada: esa clave no existe |
| 5 | key-sevilla | 80 | ok, modelo-pequeno |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Qué puede registrar una pasarela
Registra el id, el equipo, el estado, el modelo, el tamaño y la hora. No registres el texto del prompt. Los prompts contienen datos personales, y un registro lo lee más gente que la propia función.
La pasarela es también un punto único de fallo y un salto más. Dale un tiempo máximo, ejecuta varias copias y mantén sus reglas pequeñas.
Un error frecuente
Advertencia
Mucha gente cree que una pasarela hace seguras las llamadas porque comprueba claves. Comprueba quién llama, no qué se pide. Una clave válida puede enviar un prompt dañino. Los límites y los registros acotan el daño; no juzgan el texto.
Escribe el ayudante del modelo, parte 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const base = process.env.AI_URL || \"http://ai:4000\";' 'async function ask(messages, sample, max) {' ' try {' ' const res = await fetch(base + \"/v1/chat/completions\", {' ' method: \"POST\",' ' headers: { \"content-type\": \"application/json\", authorization: \"Bearer lab\" },' ' body: JSON.stringify({ model: \"lab\", messages: messages, max_tokens: max || 200 }),' ' signal: AbortSignal.timeout(30000),' ' });' ' if (res.ok === false) throw new Error(\"estado \" + res.status);' ' return (await res.json()).choices[0].message.content;' > model.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe el ayudante del modelo, parte 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' ' } catch (error) {' ' console.log(\"Muestra grabada: ningún modelo respondió (\" + error.message + \").\");' ' const list = [].concat(sample);' ' const turn = messages.filter(function (m) { return m.role === \"assistant\"; }).length;' ' return list[Math.min(turn, list.length - 1)];' ' }' '}' 'module.exports = { ask };' >> model.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe la pasarela, parte 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' 'const KEYS = { \"key-madrid\": \"madrid\", \"key-sevilla\": \"sevilla\" }; // claves inventadas' 'const LIMIT = 2; // peticiones aceptadas por equipo' 'const counts = {};' 'const log = [];' > gateway.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe la pasarela, parte 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function choose(request) {' ' return request.words > 300 ? \"modelo-grande\" : \"modelo-pequeno\";' '}' 'function gateway(request) {' ' const team = KEYS[request.key];' ' let status = \"ok\";' ' if (team === undefined) status = \"rechazada\";' ' else if ((counts[team] || 0) >= LIMIT) status = \"limitada\";' ' if (status === \"ok\") counts[team] = (counts[team] || 0) + 1;' ' const model = status === \"ok\" ? choose(request) : \"ninguno\";' ' log.push({ id: request.id, team: team || \"desconocido\", status: status, model: model });' '}' >> gateway.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe la pasarela, parte 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const requests = [' ' { id: 1, key: \"key-madrid\", words: 40 },' ' { id: 2, key: \"key-madrid\", words: 500 },' ' { id: 3, key: \"key-madrid\", words: 20 },' ' { id: 4, key: \"key-zzz\", words: 10 },' ' { id: 5, key: \"key-sevilla\", words: 80 },' '];' 'requests.forEach(function (r) { gateway(r); });' 'log.forEach(function (row) { console.log(row.id, row.team, row.status, row.model); });' >> gateway.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe la pasarela, parte 4
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' const sample = \"Una pasarela guarda claves, límites y registro en un solo sitio.\";' ' const messages = [{ role: \"user\", content: \"En una frase corta: ¿por qué poner una pasarela delante de las llamadas al modelo?\" }];' ' console.log(\"Llamada real de la petición 1:\", await ask(messages, sample, 40));' '}' 'main();' >> gateway.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Ejecuta la pasarela
docker exec -w /home/node/project agent node gateway.jsSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Un sustituto, no una pasarela real
Esta pasarela es una función sobre una lista. El laboratorio no tiene una red de servicios, así que el límite vive en una variable. Una pasarela real es un servicio con almacenamiento compartido para sus cuentas, para que cada copia vea los mismos números.
Aquí la plataforma ya hace ese papel: añade tu token y elige el modelo para la única llamada real.
Una salida posible
| Línea | Qué muestra |
|---|---|
| 1 madrid ok modelo-pequeno | Aceptada y enviada al modelo pequeño |
| 3 madrid limitada ninguno | Rechazada, no se envía nada a un modelo |
| 4 desconocido rechazada ninguno | Rechazada, el equipo no se conoce |
| Llamada real | Una frase corta de un modelo, o una Muestra grabada con su etiqueta |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.