22 min de lectura

Objetivos de aprendizaje

Al final de este módulo, podrás:

  • Autenticar contra el punto de inferencia de AI Model Hub con un token Bearer y llamar a completaciones de chat desde Python y curl
  • Integrar AI Model Hub en el código de la aplicación utilizando el API compatible con OpenAI y el cliente de Python de OpenAI oficial apuntando a la URL base de IONOS
  • Generar incrustaciones con `BAAI/bge-m3` y seleccionar el modelo adecuado según la ventana de contexto y el precio por token
  • Implementar control de errores de producción para los límites de tasa 429 de HTTP, tiempos de espera y respuestas mal formadas con retroceso exponencial
  • Construir un patrón de inferencia síncrono y asíncrono (en cola de Kafka) y almacenar los resultados en Redis para controlar el costo de tokens

Unidad 4.4: AI Model Hub Integración

Introducción

Está agregando una característica de inteligencia artificial a TaskBoard: cuando un usuario envía una descripción de tarea larga, el API llama a un modelo de lenguaje grande para producir un resumen de una línea, luego almacena ese resumen en PostgreSQL. El AI Model Hub expone modelos alojados detrás de una REST compatible con OpenAI API, por lo que no ejecuta ningún GPU y no administra pesos de modelo. Envía una solicitud a un punto de inferencia, obtiene tokens de vuelta y paga por token.

Esta unidad comienza en la llamada a HTTP. Verá las formas exactas de la solicitud y la respuesta, las conectará a Python con requests y el cliente de OpenAI, agregará la lógica de reintento y tiempo de espera que la inferencia de producción necesita, y luego conectará la característica al REST de TaskBoard a través de llamadas sincrónicas y una ruta asíncrona en cola Kafka. Cada bloque de código tiene como objetivo el punto de conexión real de IONOS y los identificadores de modelo reales, por lo que puede copiar, establecer su token y ejecutar.

1. El Punto de Inferencia y Autenticación

AI Model Hub proporciona dos opciones de API: una autenticación nativa de AI Model Hub y una autenticación compatible con OpenAI. La autenticación compatible con OpenAI refleja la estructura de solicitud y respuesta de OpenAI, lo que le permite reutilizar herramientas y SDK de OpenAI existentes cambiando solo la URL base y las credenciales. Para la integración de aplicaciones, este es el camino que desea seguir, porque las formas de solicitud y respuesta ya son familiares y las bibliotecas de cliente de OpenAI funcionan sin modificaciones.

La URL base compatible con OpenAI es https://openai.inference.de-txl.ionos.com/v1. La autenticación utiliza un token Bearer, que es un token Web de JSON (JWT) con una fecha de caducidad. Los tutoriales de AI Model Hub suponen que el token se almacena en la variable de entorno IONOS_API_TOKEN. Debido a que el token es un JWT con una reclamación exp, una solicitud que de repente devuelve un error de autenticación generalmente significa que el token ha caducado, no que la llamada esté incorrecta. Verifique la reclamación exp y regenere el token si ha caducado.

1.1 Primera llamada con curl

Envíe una solicitud de finalización de chat para confirmar su token y conectividad antes de escribir cualquier código de aplicación. El punto de conexión es POST /v1/chat/completions y el cuerpo de la solicitud lleva un identificador model y una matriz messages.

export IONOS_API_TOKEN="your-jwt-token"

curl -s https://openai.inference.de-txl.ionos.com/v1/chat/completions \
  -H "Authorization: Bearer ${IONOS_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "meta-llama/Llama-3.3-70B-Instruct",
    "messages": [
      {"role": "user", "content": "Summarize in one sentence: the deploy pipeline failed because the registry token expired."}
    ],
    "temperature": 0.2,
    "max_tokens": 60
  }'

La respuesta es un objeto de finalización de estilo OpenAI. El texto generado está en choices[0].message.content, y usage informa prompt_tokens, completion_tokens, y total_tokens, que necesita para realizar un seguimiento de los costos.

{
  "id": "chatcmpl-123",
  "object": "chat.completion",
  "model": "meta-llama/Llama-3.3-70B-Instruct",
  "choices": [
    {
      "index": 0,
      "message": {"role": "assistant", "content": "The deploy pipeline failed because the container registry token had expired."},
      "finish_reason": "stop"
    }
  ],
  "usage": {"prompt_tokens": 28, "completion_tokens": 14, "total_tokens": 42}
}

1.2 Enumeración de modelos disponibles

La autenticación compatible con OpenAI expone un punto de conexión de modelos para recuperar la lista de modelos disponibles y sus detalles. Úselo para descubrir las cadenas de identificador de modelo exactas en lugar de codificar una suposición, ya que el identificador es lo que el campo model requiere.

curl -s https://openai.inference.de-txl.ionos.com/v1/models \
  -H "Authorization: Bearer ${IONOS_API_TOKEN}" | python3 -m json.tool

El identificador de modelo que pasa debe coincidir con el catálogo exactamente. Para los modelos de chat utilizados en esta unidad, los identificadores son meta-llama/Llama-3.3-70B-Instruct, openai/gpt-oss-120b, y mistralai/Mistral-Small-24B-Instruct. Un error tipográfico en el identificador es uno de los fallos de llamada más comunes.

2. Llamada a Model Hub desde el código de la aplicación

En el servicio API de TaskBoard, usted llama a la inferencia desde Python. Usted tiene dos opciones limpias: conducir el HTTP API directamente con requests, o utilizar el cliente oficial openai apuntando a la URL base de IONOS. Ambas opciones golpean el mismo punto de conexión. El camino requests mantiene las dependencias mínimas; el cliente de OpenAI le da ayudantes tipados, iteradores de transmisión y ganchos de reintento de forma gratuita.

2.1 Inferencia directa con solicitudes

Esta es la integración con la menor dependencia. También es la forma más clara de ver exactamente qué cruza el cable, lo que ayuda cuando usted depura.

import os
import requests

BASE_URL = "https://openai.inference.de-txl.ionos.com/v1"
TOKEN = os.environ["IONOS_API_TOKEN"]

def summarize(description: str) -> str:
    resp = requests.post(
        f"{BASE_URL}/chat/completions",
        headers={"Authorization": f"Bearer {TOKEN}"},
        json={
            "model": "meta-llama/Llama-3.3-70B-Instruct",
            "messages": [
                {"role": "system", "content": "You write one-sentence task summaries."},
                {"role": "user", "content": description},
            ],
            "temperature": 0.2,
            "max_tokens": 60,
        },
        timeout=30,
    )
    resp.raise_for_status()
    return resp.json()["choices"][0]["message"]["content"].strip()

Siempre establezca un timeout explícito. La latencia de inferencia varía con la longitud de la solicitud y el tamaño del modelo, y un socket colgado sin tiempo de espera puede bloquear un hilo de trabajo en su API.

2.2 El cliente de OpenAI apuntando a IONOS

Dado que el API es compatible con OpenAI, el paquete de Python oficial openai funciona cuando usted anula base_url y api_key. Esta es la opción más ergonómica para el código de la aplicación.

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://openai.inference.de-txl.ionos.com/v1",
    api_key=os.environ["IONOS_API_TOKEN"],
)

def summarize(description: str) -> str:
    completion = client.chat.completions.create(
        model="meta-llama/Llama-3.3-70B-Instruct",
        messages=[
            {"role": "system", "content": "You write one-sentence task summaries."},
            {"role": "user", "content": description},
        ],
        temperature=0.2,
        max_tokens=60,
    )
    return completion.choices[0].message.content.strip()

2.3 Respuestas de transmisión

Para interfaces de usuario interactivas, usted puede transmitir tokens a medida que son generados estableciendo stream en true. Cuando se transmite, las estadísticas de uso no se incluyen por defecto. Para obtener el uso en el último fragmento, usted debe establecer explícitamente stream_options con include_usage habilitado.

stream = client.chat.completions.create(
    model="openai/gpt-oss-120b",
    messages=[{"role": "user", "content": "Explain what a poison message is."}],
    stream=True,
    stream_options={"include_usage": True},
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

La transmisión termina con una línea de datos final que contiene usage seguido de un marcador [DONE]. Si usted omite stream_options, pierde los recuentos de tokens que necesita para la contabilidad de costes.

3. Selección de un modelo: Ventana de contexto y precio

La selección de modelo es una decisión de código impulsada por dos números: cuántos tokens acepta el modelo (ventana de contexto) y cuánto cuesta cada millón de tokens. Los resúmenes de TaskBoard son breves, por lo que el modelo más barato capaz es el valor predeterminado correcto; reserve los modelos más grandes para las tareas que realmente los necesitan.

La siguiente tabla compara los modelos de chat utilizados en esta unidad. Los precios están en EUR por millón de tokens.

Identificador de modelo Ventana de contexto (tokens) Precio de entrada (EUR / 1M) Precio de salida (EUR / 1M)
mistralai/Mistral-Small-24B-Instruct 128000 0,10 0,30
openai/gpt-oss-120b 128000 0,15 0,65
meta-llama/Llama-3.3-70B-Instruct 128000 0,65 0,65

Como se muestra arriba, los tres aceptan una ventana de contexto de 128000 tokens, por lo que para un prompt de resumen breve, el factor decisivo es el precio. mistralai/Mistral-Small-24B-Instruct es el más barato tanto en entrada como en salida y es un valor predeterminado sólido para los resúmenes de TaskBoard. Pase a un modelo más grande solo cuando la calidad del resumen en descripciones de tareas reales sea demostrablemente mejor y valga la pena el premio por token.

3.1 Configuración de modelo con conciencia de costos

Haga que el modelo sea un valor de configuración, no un literal disperso por el código, para que pueda cambiar por entorno sin volver a implementar la lógica.

import os

SUMMARY_MODEL = os.environ.get("SUMMARY_MODEL", "mistralai/Mistral-Small-24B-Instruct")

def estimate_cost_eur(prompt_tokens: int, completion_tokens: int,
                      in_price: float, out_price: float) -> float:
    return (prompt_tokens / 1_000_000) * in_price + (completion_tokens / 1_000_000) * out_price

print(estimate_cost_eur(28, 14, 0.10, 0.30))  # 28 prompt + 14 completion tokens, Mistral-Small pricing

3.2 Incrustaciones para características semánticas

Cuando TaskBoard necesita búsqueda semántica sobre tareas, genera vectores con un modelo de incrustación en lugar de un modelo de chat. El punto de conexión es POST /v1/embeddings. El modelo BAAI/bge-m3 devuelve vectores de 1024 dimensiones y tiene un precio de 0,02 EUR por millón de tokens.

def embed(text: str) -> list[float]:
    resp = client.embeddings.create(model="BAAI/bge-m3", input=text)
    return resp.data[0].embedding  # 1024 floats

vec = embed("Fix the expired registry token in the deploy pipeline")
assert len(vec) == 1024

Almacene los vectores resultantes en cualquier lugar donde viva su capa de búsqueda. La incrustación es determinista para una entrada y modelo determinados, por lo que el texto idéntico siempre produce el mismo vector, lo que hace que las incrustaciones sean una sólida candidata a caché.

4. Manejo de errores de producción

Las llamadas de inferencia fallan de maneras que sus puntos de conexión CRUD no: el modelo tiene un límite de velocidad, el tiempo de solicitud se agota bajo carga o la respuesta está bien formada JSON pero el contenido es vacío o tiene un formato incorrecto. El código de producción debe manejar los tres. El más importante en IONOS es el límite de velocidad.

4.1 Límites de velocidad y retroceso 429

El límite de velocidad general API es de 5 solicitudes por segundo (base) con un permiso de ráfaga de 10. Cuando excede el límite, el servicio devuelve HTTP 429 Demasiadas solicitudes. Trate el 429 como una señal de retroceso y reintento, no como un fallo duro. Utilice un retroceso exponencial para que una ráfaga de actividad de TaskBoard no golpee el punto de conexión.

import time
import requests

def chat_with_retry(payload: dict, max_attempts: int = 5) -> dict:
    delay = 1.0
    for attempt in range(max_attempts):
        resp = requests.post(
            f"{BASE_URL}/chat/completions",
            headers={"Authorization": f"Bearer {TOKEN}"},
            json=payload,
            timeout=30,
        )
        if resp.status_code == 429:
            retry_after = float(resp.headers.get("Retry-After", delay))
            time.sleep(retry_after)
            delay *= 2
            continue
        resp.raise_for_status()
        return resp.json()
    raise RuntimeError("inference rate-limited after retries")

Respete el encabezado Retry-After cuando el servicio lo proporciona, y vuelva a su propio retraso exponencial cuando no lo hace. Limite el número de intentos para que una interrupción sostenida se presente como un error en lugar de un bucle infinito.

4.2 Tiempos de espera y validación de respuestas

Una respuesta 200 no es una garantía de contenido utilizable. El modelo puede devolver una cadena vacía o texto que rompe sus suposiciones posteriores. Valide antes de almacenar.

def safe_summary(description: str) -> str:
    payload = {
        "model": SUMMARY_MODEL,
        "messages": [
            {"role": "system", "content": "Reply with exactly one sentence."},
            {"role": "user", "content": description},
        ],
        "max_tokens": 60,
    }
    data = chat_with_retry(payload)
    choices = data.get("choices") or []
    if not choices:
        raise ValueError("no choices in inference response")
    content = (choices[0]["message"]["content"] or "").strip()
    if not content:
        raise ValueError("empty summary returned")
    return content

Para la extracción estructurada, los complementos de chat API admiten un response_format con un esquema JSON y strict habilitado, lo que limita el modelo a emitir JSON válidos que coinciden con su esquema. Esa es la forma confiable de obtener salida analizable por máquina en lugar de texto libre que debe analizar de forma defensiva.

5. Patrones de integración y control de costes

Puede llamar a la inferencia de dos maneras dentro de TaskBoard. La inferencia síncrona se ejecuta dentro de la solicitud que necesita el resultado. La inferencia asíncrona coloca el trabajo en una cola y lo procesa fuera de banda. La elección correcta depende de si el usuario está esperando la respuesta.

5.1 Síncrona: resumir al crear

Cuando el usuario envía una tarea y espera el resumen de inmediato, llame a la inferencia dentro del controlador de solicitudes y escriba el resumen en PostgreSQL en la misma transacción.

def create_task(db, description: str) -> int:
    summary = safe_summary(description)
    row = db.execute(
        "INSERT INTO tasks (description, summary) VALUES (%s, %s) RETURNING id",
        (description, summary),
    ).fetchone()
    db.commit()
    return row[0]

Mantenga el camino síncrono detrás de un temporizador y un presupuesto de reintento para que un modelo lento no bloquee la solicitud que enfrenta al usuario de manera indefinida.

5.2 Asíncrona: cola de inferencia a través de Kafka

Cuando el resumen no es necesario de inmediato, desacoplelo. El API escribe la tarea de inmediato y produce un evento de cambio de tarea a Kafka (ver Unidad 4.3); un trabajador consume el evento, llama a la inferencia y actualiza la fila. Esto mantiene la solicitud de creación rápida y aísla la latencia de inferencia y los límites de tasa de la ruta del usuario.

def handle_event(event: dict, db):  # worker side: consume task event, summarize, persist
    task_id = event["task_id"]
    description = event["description"]
    try:
        summary = safe_summary(description)
    except (ValueError, RuntimeError):
        # route to a dead-letter topic; do not block the consumer group
        produce_dead_letter(event)
        return
    db.execute("UPDATE tasks SET summary = %s WHERE id = %s", (summary, task_id))
    db.commit()

El patrón asíncrono también suaviza los picos: el límite de 5 solicitudes por segundo es mucho más fácil de cumplir cuando un solo consumidor drena una cola a una tasa controlada que cuando muchos trabajadores web llaman a la inferencia de forma concurrente.

5.3 Almacenamiento en caché de resultados en Redis

La inferencia es la llamada más costosa en esta función, así que no pague por ella dos veces. Almacene en caché por un hash del modelo más la entrada. Las descripciones idénticas no cuestan nada después de la primera llamada. Esto se combina naturalmente con la caché existente de TaskBoard In-Memory DB (Redis) desde la Unidad 4.1.

import hashlib
import redis

r = redis.Redis(host="taskboard-redis", port=6379, ssl=True)

def cached_summary(description: str) -> str:
    key = "sum:" + hashlib.sha256(
        (SUMMARY_MODEL + "|" + description).encode()
    ).hexdigest()
    hit = r.get(key)
    if hit:
        return hit.decode()
    summary = safe_summary(description)
    r.set(key, summary, ex=86400)  # 24h TTL
    return summary

Dado que la inferencia es sin estado y las solicitudes y salidas se descartan al final de cada sesión, el único registro duradero de un resultado es el que usted elige mantener. El almacenamiento en caché es, por lo tanto, tanto un control de costes como su almacén de resultados calculados.

5.4 Residencia de datos y privacidad

AI Model Hub opera como un servicio sin estado: las solicitudes y salidas se descartan al final de cada sesión, no se registran ni se graban, y no se reutilizan para el entrenamiento del modelo. Los datos del cliente no se utilizan para el entrenamiento bajo ninguna circunstancia. Todos los servicios AI Model Hub, incluidos los puntos de inferencia del modelo y las bases de datos de vectores administradas, se alojan en centros de datos certificados por ISO 27001 en Alemania, y el procesamiento es completamente conforme al GDPR. Para TaskBoard, esto significa que las descripciones de tareas enviadas para resumir se mantienen dentro del límite del centro de datos alemán y nunca entran en un conjunto de entrenamiento.

5.5 Acceso de agente de solo lectura con el IONOS CLOUD MCP Server

Cuando la integración que necesita no es "llamar a un modelo" sino "permitir que un agente de inteligencia artificial inspeccione su infraestructura de IONOS", el IONOS CLOUD MCP Server es la ruta para desarrolladores. Es un binario local que implementa el Protocolo de Contexto de Modelo (MCP), que habla JSON-RPC sobre stdio a un cliente de inteligencia artificial o agente autónomo. Proporciona a ese cliente acceso de solo lectura a más de 100 herramientas en seis productos: Compute Engine, Object Storage, Cloud DNS, Certificate Manager, Facturación y Registro de Actividades. Las herramientas están diseñadas para ser de solo inspección, por lo que el binario no puede crear, actualizar ni eliminar ningún recurso.

El servidor MCP es una alternativa a conectar sus propias llamadas directas API o SDK para escenarios de lectura de agente y automatización. En lugar de escribir código de cliente contra cada producto API, ejecuta el binario como un subproceso local; el cliente de inteligencia artificial descubre las herramientas y las llama en un bucle de agente, y el binario llama al API de IONOS Cloud directamente sobre HTTPS utilizando su token API. Para flujos de trabajo completamente soberanos, se combina con AI Model Hub, por lo que tanto el paso de inferencia como el paso de inspección de infraestructura se mantienen dentro del perímetro de IONOS. Trate las salidas de las herramientas como datos que dejan ese perímetro una vez que el cliente de inteligencia artificial las lee.

API Tarjeta de referencia rápida

Puntos de conexión clave de API para la integración con AI Model Hub:

Método Punto de conexión Descripción
GET /v1/models Lista los modelos disponibles y sus detalles
POST /v1/chat/completions Genera una finalización de chat (establezca stream para transmisión)
POST /v1/embeddings Genera vectores de incrustación para texto de entrada
POST /v1/images/generations Genera imágenes a partir de una llamada de texto

URL base (compatible con OpenAI): https://openai.inference.de-txl.ionos.com/v1 Documentos nativos de API: https://api.ionos.com/docs/inference-modelhub/v1 Autenticación: Authorization: Bearer <IONOS_API_TOKEN> (JWT con reclamo exp)

Laboratorio de código

Objetivo: Agregar resumen de inteligencia artificial a TaskBoard. Llame a AI Model Hub para resumir una descripción de tarea, maneje un 429 con retroceso y almacene el resultado en Redis para que un resumen repetido no cueste tokens.

Requisitos previos:

  • Cuenta de IONOS Cloud con un token API (JWT) en IONOS_API_TOKEN
  • Python 3.10+ con pip install openai requests redis
  • Una instancia Redis accesible (o local redis para el laboratorio)

Paso 1: Exporte su token y confirme la conectividad

export IONOS_API_TOKEN="your-jwt-token"
curl -s https://openai.inference.de-txl.ionos.com/v1/models \
  -H "Authorization: Bearer ${IONOS_API_TOKEN}" | python3 -m json.tool | head

Salida esperada:

{
    "object": "list",
    "data": [
        { "id": "meta-llama/Llama-3.3-70B-Instruct", ... }

Paso 2: Realice una primera llamada de resumen

from openai import OpenAI
import os
client = OpenAI(base_url="https://openai.inference.de-txl.ionos.com/v1",
                api_key=os.environ["IONOS_API_TOKEN"])
c = client.chat.completions.create(
    model="mistralai/Mistral-Small-24B-Instruct",
    messages=[{"role": "user", "content": "Summarize in one sentence: registry token expired so the deploy failed."}],
    max_tokens=60, temperature=0.2)
print(c.choices[0].message.content)
print("tokens:", c.usage.total_tokens)

Salida esperada:

The deployment failed because the container registry token had expired.
tokens: 41

Paso 3: Agregue reintento con retroceso exponencial en caso de 429

import time, requests, os
BASE="https://openai.inference.de-txl.ionos.com/v1"
def call(payload, attempts=5):
    delay=1.0
    for _ in range(attempts):
        r=requests.post(f"{BASE}/chat/completions",
            headers={"Authorization":f"Bearer {os.environ['IONOS_API_TOKEN']}"},
            json=payload, timeout=30)
        if r.status_code==429:
            time.sleep(float(r.headers.get("Retry-After", delay))); delay*=2; continue
        r.raise_for_status(); return r.json()
    raise RuntimeError("rate-limited")

Salida esperada: no hay error en una llamada normal; un 429 desencadena una espera y reintento en lugar de una falla.

Paso 4: Valide la respuesta antes de utilizarla

def summary(text):
    data=call({"model":"mistralai/Mistral-Small-24B-Instruct",
               "messages":[{"role":"user","content":text}],"max_tokens":60})
    out=(data["choices"][0]["message"]["content"] or "").strip()
    if not out: raise ValueError("empty summary")
    return out
print(summary("The CI job failed on the embeddings step."))

Salida esperada:

The CI job failed during the embeddings step.

Paso 5: Almacene los resultados en Redis

import hashlib, redis
r=redis.Redis(host="localhost", port=6379)
MODEL="mistralai/Mistral-Small-24B-Instruct"
def cached(text):
    k="sum:"+hashlib.sha256((MODEL+"|"+text).encode()).hexdigest()
    hit=r.get(k)
    if hit: return hit.decode()
    s=summary(text); r.set(k, s, ex=86400); return s

Paso 6: Verifique que la caché elimina el costo de la segunda llamada

import time
t=time.time(); cached("Same description here."); print("miss", round(time.time()-t,2))
t=time.time(); cached("Same description here."); print("hit ", round(time.time()-t,2))

Salida esperada:

miss 0.9
hit  0.0

Paso 7: Genere un incrustado para búsqueda semántica

e=client.embeddings.create(model="BAAI/bge-m3", input="Fix the expired registry token")
print(len(e.data[0].embedding))

Salida esperada:

1024

Lista de verificación:

  • [ ] /v1/models devuelve una lista de modelos con su token
  • [ ] Un completado de chat devuelve contenido y un recuento de tokens usage
  • [ ] Un 429 desencadena un retroceso y reintento en lugar de una excepción
  • [ ] Un resumen repetido se sirve desde Redis sin costo de tokens
  • [ ] BAAI/bge-m3 devuelve un vector de 1024 dimensiones

Limpieza:

redis-cli --scan --pattern 'sum:*' | xargs -r redis-cli del

Errores comunes

Errores de los desarrolladores que deben evitarse con la integración de AI Model Hub:

  1. Tratar un 429 como un error fatal

    • Problema: Una ráfaga de actividad de TaskBoard devuelve HTTP 429 Too Many Requests y su controlador se eleva, fallando las solicitudes de los usuarios.
    • Por qué sucede: El límite de velocidad general de API es de 5 solicitudes por segundo (base) con un estallido de 10; los trabajadores web concurrentes lo superan fácilmente.
    • Solución: Capturar 429, honrar Retry-After y volver a intentarlo con un retardo exponencial. Empujar la inferencia a un trabajador drenado por Kafka para controlar la concurrencia.
  2. JWT expirado confundido con un error de código

    • Problema: Las llamadas que funcionaban ayer devuelven un error de autenticación hoy, y usted comienza a depurar encabezados y cargas útiles.
    • Por qué sucede: El token Bearer es un JWT con una reclamación exp y una fecha de expiración fija. Cuando pasa, todas las llamadas fallan la autenticación.
    • Solución: Decodificar la reclamación exp del token y regenerar el token cuando expire. Tratar los fallos de autenticación como una comprobación del ciclo de vida del token primero, no como un error de formato de solicitud.
  3. Llamar a la inferencia de forma sincrónica y pagar por duplicados

    • Problema: Los picos de latencia en la creación de tareas y la factura de tokens aumenta porque las descripciones idénticas se resumen repetidamente.
    • Por qué sucede: La inferencia se ejecuta dentro del camino de la solicitud sin caché, por lo que el mismo entrada cuesta tokens cada vez.
    • Solución: Almacenar en caché por un hash del modelo más la entrada en Redis con un TTL, y mover las resúmenes no urgentes a un trabajador asíncrono Kafka para que la solicitud de creación se mantenga rápida.

Resumen

Ahora puede integrar AI Model Hub en el código de la aplicación. Llama al endpoint compatible con OpenAI en https://openai.inference.de-txl.ionos.com/v1 con un Bearer JWT, lo impulsa desde requests o el cliente oficial de OpenAI, transmite cuando la interfaz de usuario lo necesita y genera incrustaciones con BAAI/bge-m3. Seleccione modelos por ventana de contexto y precio por token, y envuelva cada llamada en tiempo de espera, retroceso 429 y validación de respuesta. Conectó la función a TaskBoard de forma síncrona y a través de un trabajador en cola de Kafka, y almacena los resultados en Redis para que las entradas repetidas no cuesten nada.

Puntos clave:

  • El endpoint compatible con OpenAI API en /v1/chat/completions, /v1/embeddings, /v1/models y /v1/images/generations permite que el cliente oficial de OpenAI funcione sobrescribiendo base_url y api_key
  • La autenticación es un Bearer JWT en IONOS_API_TOKEN; una reclamación expirada exp es la causa más común de fallos de autenticación repentinos
  • El límite de velocidad general es 5 solicitudes por segundo base, 10 de explosión; excederlo devuelve HTTP 429, que se maneja con Retry-After y retroceso exponencial
  • La elección del modelo es una decisión de costo: los tres modelos de chat comparten una ventana de contexto de 128000 tokens, por lo que el precio los separa, con mistralai/Mistral-Small-24B-Instruct el más barato
  • El servicio es estatal y alojado en Alemania; los prompts y salidas se descartan por sesión y nunca se utilizan para entrenar, por lo que la memoria caché de Redis es tanto su palanca de costo como su única tienda de resultados duraderos
  • El IONOS CLOUD MCP Server es un binario local que da a los agentes de inteligencia artificial acceso de solo lectura a más de 100 herramientas en Compute Engine, Object Storage, Cloud DNS, Certificate Manager, Facturación y Registro de actividades a través de MCP (JSON-RPC en stdio); es una alternativa a las llamadas directas a API o SDK para escenarios de lectura de agentes y se empareja con AI Model Hub para flujos de trabajo soberanos

Terminología importante:

  • Endpoint compatible con OpenAI API: Un endpoint que refleja la estructura de solicitud y respuesta de OpenAI, lo que permite que los SDK de OpenAI funcionen con IONOS cambiando la URL base y la clave
  • Ventana de contexto: La cantidad máxima de tokens (prompt más finalización) que un modelo acepta en una solicitud; 128000 para los modelos de chat en esta unidad
  • Precios basados en tokens: Costo cobrado por millón de tokens de entrada y salida; rastreado a través del objeto usage en cada respuesta
  • Retroceso exponencial: Una estrategia de reintento que duplica la espera entre intentos después de un 429, evitando una tormenta de reintento de manada
  • Inferencia estatal: Cada solicitud está sola; AI Model Hub descarta los prompts y salidas al final de la sesión y no los registra, almacena ni entrena
  • IONOS CLOUD MCP Server: Un binario local que implementa el Protocolo de Contexto de Modelo (JSON-RPC sobre stdio) que expone herramientas de inspección de solo lectura en seis productos de IONOS a un cliente de inteligencia artificial, llamando al endpoint de API de IONOS Cloud directamente sin ningún proveedor de inteligencia artificial de terceros en la ruta de datos

Próximos pasos

Continúe aprendiendo: Unidad 4.5: Verificación de conocimientos - Integración de servicios

Temas relacionados: