Unité 4.4 : AI Model Hub Intégration
Introduction
Vous ajoutez une fonctionnalité d'intelligence artificielle à TaskBoard : lorsque l'utilisateur soumet une description de tâche longue, le API appelle un grand modèle de langage pour produire un résumé d'une ligne, puis stocke ce résumé dans le PostgreSQL. Le AI Model Hub expose des modèles hébergés derrière une interface REST compatible OpenAI API, vous n'avez donc pas besoin d'exécuter de GPU et vous n'avez pas besoin de gérer les poids de modèle. Vous envoyez une invite à un point de terminaison d'inférence, vous obtenez des jetons en retour, et vous payez par jeton.
Cette unité commence à l'appel HTTP. Vous verrez les formes exactes de la demande et de la réponse, les connecterez en Python à la fois avec requests et le client OpenAI, ajouterez la logique de réessai et de temporisation nécessaire à l'inférence de production, puis connecterez la fonctionnalité à la REST de TaskBoard via des appels synchrones et un chemin asynchrone mis en file d'attente Kafka. Chaque bloc de code cible le point de terminaison IONOS réel et les identificateurs de modèle réels, vous pouvez donc copier, définir votre jeton et exécuter.
1. Le point de terminaison d'inférence et l'authentification
AI Model Hub propose deux options d'authentification API : une authentification native AI Model Hub API et une authentification compatible OpenAI API. L'authentification compatible OpenAI reflète la structure de requête et de réponse d'OpenAI, ce qui vous permet de réutiliser les outils et les SDK existants d'OpenAI en ne changeant que l'URL de base et les informations d'identification. Pour l'intégration d'applications, c'est le chemin que vous souhaitez emprunter, car les formes de requête et de réponse sont déjà familières et les bibliothèques clientes officielles d'OpenAI fonctionnent sans modification.
L'URL de base compatible OpenAI est https://openai.inference.de-txl.ionos.com/v1. L'authentification utilise un jeton Bearer, qui est un jeton Web JSON (JWT) avec une date d'expiration. Les didacticiels de AI Model Hub supposent que le jeton est stocké dans la variable d'environnement IONOS_API_TOKEN. Puisque le jeton est un JWT avec une revendication exp, une requête qui renvoie soudainement une erreur d'authentification signifie généralement que le jeton a expiré, et non que l'appel est incorrect. Vérifiez la revendication exp et régénérez le jeton s'il a expiré.
1.1 Premier appel avec curl
Envoyez une completion de chat pour confirmer votre jeton et votre connectivité avant d'écrire le code de l'application. Le point de terminaison est POST /v1/chat/completions et le corps de la requête contient un identifiant model et un tableau 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 réponse est un objet de completion de style OpenAI. Le texte généré est dans choices[0].message.content, et usage signale prompt_tokens, completion_tokens, et total_tokens, qui sont nécessaires pour la surveillance des coûts.
{
"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 Liste des modèles disponibles
L'authentification compatible OpenAI expose un point de terminaison de modèles pour récupérer la liste des modèles disponibles et leurs détails. Utilisez-le pour découvrir les chaînes d'identifiant de modèle exactes plutôt que de les deviner, puisque l'identifiant est ce que le champ model exige.
curl -s https://openai.inference.de-txl.ionos.com/v1/models \
-H "Authorization: Bearer ${IONOS_API_TOKEN}" | python3 -m json.tool
L'identifiant de modèle que vous passez doit correspondre exactement au catalogue. Pour les modèles de chat utilisés dans cette unité, les identifiants sont meta-llama/Llama-3.3-70B-Instruct, openai/gpt-oss-120b, et mistralai/Mistral-Small-24B-Instruct. Une faute d'orthographe dans l'identifiant est l'une des erreurs de premier appel les plus courantes.
2. Appel de Model Hub à partir du code d'application
Dans le service API de TaskBoard, vous appelez l'inférence à partir de Python. Vous avez deux options propres : piloter directement le HTTP API avec requests, ou utiliser le client officiel openai pointé vers l'URL de base d'IONOS. Les deux frappent le même point de terminaison. Le chemin requests garde les dépendances minimales ; le client OpenAI vous donne des aides typées, des itérateurs de diffusion et des crochets de réessai gratuitement.
2.1 Inférence directe HTTP avec des requêtes
Il s'agit de l'intégration à la dépendance la plus faible. C'est également la façon la plus claire de voir exactement ce qui traverse le fil, ce qui aide lors de la débogage.
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()
Définissez toujours une durée d'attente explicite timeout. La latence de l'inférence varie en fonction de la longueur de la invite et de la taille du modèle, et une prise de socket bloquée sans délai va bloquer un thread de travail dans votre API.
2.2 Le client OpenAI pointé vers IONOS
Puisque le API est compatible OpenAI, le package Python officiel openai fonctionne lorsque vous remplacez base_url et api_key. Il s'agit de l'option la plus ergonomique pour le code d'application.
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 Réponses de diffusion
Pour une interface utilisateur interactive, vous pouvez diffuser des jetons à mesure qu'ils sont générés en définissant stream sur vrai. Lors de la diffusion, les statistiques d'utilisation ne sont pas incluses par défaut. Pour obtenir l'utilisation dans le dernier bloc, vous devez définir explicitement stream_options avec include_usage activé.
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 diffusion se termine par une ligne de données finale contenant usage suivie d'un marqueur [DONE]. Si vous omettez stream_options, vous perdez les comptes de jetons dont vous avez besoin pour la comptabilité des coûts.
3. Choix d'un modèle : fenêtre de contexte et prix
La sélection d'un modèle est une décision de code dictée par deux chiffres : le nombre de jetons que le modèle accepte (fenêtre de contexte) et le coût de chaque million de jetons. Les résumés de TaskBoard sont courts, donc le modèle le moins cher capable est le paramètre par défaut correct ; réservez les modèles plus grands pour les tâches qui en ont vraiment besoin.
Le tableau suivant compare les modèles de chat utilisés dans cette unité. Les prix sont en EUR par million de jetons.
| Identifiant de modèle | Fenêtre de contexte (jetons) | Prix d'entrée (EUR / 1M) | Prix de sortie (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 |
Comme le montre le tableau ci-dessus, les trois modèles acceptent une fenêtre de contexte de 128000 jetons, donc pour une invite de résumé courte, le facteur décisif est le prix. mistralai/Mistral-Small-24B-Instruct est le moins cher pour les entrées et les sorties et constitue un paramètre par défaut solide pour les résumés de TaskBoard. N'utilisez un modèle plus grand que lorsque la qualité du résumé sur des descriptions de tâches réelles est nettement meilleure et vaut la peine du prix premium par jeton.
3.1 Configuration de modèle tenant compte du coût
Faites du modèle une valeur de configuration, et non un élément littéral réparti dans le code, afin que vous puissiez basculer entre les environnements sans redéployer la logique.
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 Incorporations pour les fonctionnalités sémantiques
Lorsque TaskBoard nécessite une recherche sémantique sur les tâches, vous générez des vecteurs avec un modèle d'incorporation plutôt qu'un modèle de chat. Le point de terminaison est POST /v1/embeddings. Le modèle BAAI/bge-m3 renvoie des vecteurs de 1024 dimensions et est facturé à 0,02 EUR par million de jetons.
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
Stockez les vecteurs résultants à l'endroit où vit votre couche de recherche. L'incorporation est déterministe pour une entrée et un modèle donnés, donc le même texte produit toujours le même vecteur, ce qui fait des incorporations un candidat fort pour la mise en cache.
4. Gestion des erreurs de production
Les appels d'inférence échouent de manière que vos points de terminaison CRUD ne le font pas : le modèle est limité en taux, le temps de requête expire sous charge, ou la réponse est bien formée JSON mais le contenu est vide ou mal formaté. Le code de production doit gérer les trois. Le plus important sur IONOS est la limite de taux.
4.1 Limites de taux et recul 429
La limite de taux générale API est de 5 requêtes par seconde (base) avec une tolérance de 10. Lorsque vous dépassez la limite, le service renvoie HTTP 429 Trop de requêtes. Traitez 429 comme un signal pour reculer et réessayer, et non comme une erreur définitive. Utilisez un recul exponentiel afin qu'une poussée d'activité TaskBoard ne frappe pas sans cesse le point de terminaison.
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")
Respectez l'en-tête Retry-After lorsque le service le fournit, et revenez à votre propre retard exponentiel lorsqu'il ne le fait pas. Limitez le nombre de tentatives afin qu'une panne prolongée se manifeste comme une erreur au lieu d'une boucle infinie.
4.2 Temps d'attente et validation de réponse
Une réponse 200 n'est pas une garantie de contenu utilisable. Le modèle peut renvoyer une chaîne vide ou du texte qui brise vos hypothèses en aval. Validez avant de stocker.
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
Pour l'extraction structurée, les complétions de chat API prennent en charge un response_format avec un schéma JSON et strict activé, ce qui contraint le modèle à émettre des JSON valides correspondant à votre schéma. C'est la méthode fiable pour obtenir une sortie analysable par machine au lieu d'un texte libre que vous devez analyser de manière défensive.
5. Modèles d'intégration et contrôle des coûts
Vous pouvez appeler l'inférence de deux manières à l'intérieur de TaskBoard. L'inférence synchrone s'exécute à l'intérieur de la requête qui nécessite le résultat. L'inférence asynchrone met en file d'attente le travail et le traite en dehors de la bande. Le choix approprié dépend de savoir si l'utilisateur attend la réponse.
5.1 Synchrone : résumer lors de la création
Lorsque l'utilisateur soumet une tâche et attend la synthèse immédiatement, appelez l'inférence à l'intérieur du gestionnaire de requête et écrivez la synthèse dans PostgreSQL dans la même transaction.
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]
Gardez le chemin synchrone derrière un délai d'attente et un budget de réessai afin qu'un modèle lent ne bloque pas indéfiniment la requête orientée utilisateur.
5.2 Asynchrone : mettre en file d'attente l'inférence via Kafka
Lorsque la synthèse n'est pas nécessaire instantanément, découpez-la. Le API écrit la tâche immédiatement et produit un événement de modification de tâche à Kafka (voir Unité 4.3) ; un worker consomme l'événement, appelle l'inférence et met à jour la ligne. Cela maintient la requête de création rapide et isole la latence et les limites de taux de l'inférence de la voie utilisateur.
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()
Le modèle asynchrone lisse également les pics : la limite de 5 requêtes par seconde est beaucoup plus facile à respecter lorsqu'un seul consommateur draine une file d'attente à un rythme contrôlé que lorsqu'il y a de nombreux workers Web qui appellent l'inférence de manière concurrente.
5.3 Mise en cache des résultats dans Redis
L'inférence est l'appel le plus coûteux de cette fonctionnalité, ne payez donc pas deux fois. Mettez en cache par un hachage du modèle plus l'entrée. Les descriptions identiques ne coûtent alors rien après le premier appel. Cela s'associe naturellement au cache existant de TaskBoard In-Memory DB (Redis) à partir de l'Unité 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
Puisque l'inférence est sans état et que les invites et les sorties sont supprimées à la fin de chaque session, le seul enregistrement durable d'un résultat est celui que vous choisissez de conserver. La mise en cache est donc à la fois un levier de coût et votre magasin de résultats calculés.
5.4 Résidence des données et confidentialité
AI Model Hub fonctionne comme un service sans état : les invites et les sorties sont supprimées à la fin de chaque session, ne sont pas enregistrées ou enregistrées, et ne sont pas réutilisées pour la formation de modèles. Les données des clients ne sont pas utilisées pour la formation dans aucune circonstance. Tous les services AI Model Hub, y compris les points de terminaison d'inférence de modèles et les bases de données vectorielles gérées, sont hébergés dans des centres de données certifiés ISO 27001 en Allemagne, et le traitement est entièrement conforme à GDPR. Pour TaskBoard, cela signifie que les descriptions de tâches envoyées pour la synthèse restent dans les limites du centre de données allemand et n'entrent jamais dans un ensemble de formation.
5.5 Accès agentic en lecture seule avec le IONOS CLOUD MCP Server
Lorsque l'intégration dont vous avez besoin n'est pas « appeler un modèle » mais « laisser un agent IA inspecter votre infrastructure IONOS », le IONOS CLOUD MCP Server est le chemin orienté développeur. Il s'agit d'un binaire local qui met en œuvre le protocole de contexte de modèle (MCP), en parlant JSON-RPC sur stdio à un client ou un agent autonome IA. Il donne à ce client un accès en lecture seule à plus de 100 outils à travers six produits : Compute Engine, Object Storage, Cloud DNS, Certificate Manager, Facturation et Journal d'activité. Les outils sont conçus pour être d'inspection uniquement, donc le binaire ne peut créer, mettre à jour ou supprimer aucune ressource.
Le serveur MCP est une alternative pour connecter vos propres appels directs API ou SDK pour les scénarios d'inspection et d'automatisation agentic. Au lieu d'écrire du code client contre chaque produit API, vous exécutez le binaire comme sous-processeur local ; le client IA découvre les outils et les appelle dans une boucle agentic, et le binaire appelle directement les appels API d'IONOS Cloud via HTTPS en utilisant votre jeton API. Pour des flux de travail pleinement souverains, il s'associe à AI Model Hub, donc à la fois l'étape d'inférence et l'étape d'inspection de l'infrastructure restent à l'intérieur du périmètre d'IONOS. Traitez les sorties d'outils comme des données qui quittent ce périmètre une fois que le client IA les a lues.
API Référence Quick Card
Points de terminaison clés API pour l'intégration AI Model Hub :
| Méthode | Point de terminaison | Description |
|---|---|---|
GET |
/v1/models |
Liste les modèles disponibles et leurs détails |
POST |
/v1/chat/completions |
Générer une complétion de chat (définir stream pour le streaming) |
POST |
/v1/embeddings |
Générer des vecteurs d'intégration pour le texte de saisie |
POST |
/v1/images/generations |
Générer des images à partir d'une invite de texte |
URL de base (compatible OpenAI) : https://openai.inference.de-txl.ionos.com/v1
Documents natifs API : https://api.ionos.com/docs/inference-modelhub/v1
Authentification : Authorization: Bearer <IONOS_API_TOKEN> (JWT avec réclamation exp)
Laboratoire de code
Objectif : Ajouter une synthèse par intelligence artificielle à TaskBoard. Appelez AI Model Hub pour synthétiser une description de tâche, gérer un 429 avec un délai d'attente, et mettre en cache le résultat dans Redis afin qu'une synthèse répétée ne coûte aucun jeton.
Prérequis :
- Compte IONOS Cloud avec un jeton API (JWT) dans
IONOS_API_TOKEN - Python 3.10+ avec
pip install openai requests redis - Une instance Redis accessible (ou une instance locale
redispour le laboratoire)
Étape 1 : Exporter votre jeton et confirmer la connectivité
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
Sortie attendue :
{
"object": "list",
"data": [
{ "id": "meta-llama/Llama-3.3-70B-Instruct", ... }
Étape 2 : Effectuer un premier appel de synthèse
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)
Sortie attendue :
The deployment failed because the container registry token had expired.
tokens: 41
Étape 3 : Ajouter une nouvelle tentative en cas de 429 avec un délai d'attente exponentiel
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")
Sortie attendue : pas d'erreur lors d'un appel normal ; un 429 déclenche une attente et une nouvelle tentative au lieu d'une erreur.
Étape 4 : Valider la réponse avant de l'utiliser
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."))
Sortie attendue :
The CI job failed during the embeddings step.
Étape 5 : Mettre en cache les résultats dans 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
Étape 6 : Vérifier que le cache élimine le coût de la deuxième appel
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))
Sortie attendue :
miss 0.9
hit 0.0
Étape 7 : Générer une intégration pour la recherche sémantique
e=client.embeddings.create(model="BAAI/bge-m3", input="Fix the expired registry token")
print(len(e.data[0].embedding))
Sortie attendue :
1024
Liste de validation :
- [ ]
/v1/modelsrenvoie une liste de modèles avec votre jeton - [ ] Une completion de chat renvoie du contenu et un décompte de jetons
usage - [ ] Un 429 déclenche un délai d'attente et une nouvelle tentative plutôt qu'une exception
- [ ] Une synthèse répétée est servie à partir de Redis sans coût de jeton
- [ ]
BAAI/bge-m3renvoie un vecteur de 1024 dimensions
Nettoyage :
redis-cli --scan --pattern 'sum:*' | xargs -r redis-cli del
Erreurs courantes
Erreurs de développement à éviter avec l'intégration de AI Model Hub :
-
Traiter un 429 comme une erreur fatale
- Problème : Un afflux d'activité TaskBoard renvoie
HTTP 429 Too Many Requestset votre gestionnaire renvoie une erreur, ce qui entraîne l'échec des requêtes utilisateur. - Pourquoi cela se produit-il : La limite de taux générale de API est de 5 requêtes par seconde (base) avec un afflux de 10 ; les workers web concurrents dépassent facilement cette limite.
- Correction : Intercepter 429, respecter
Retry-After, et réessayer avec un délai exponentiel. Pousser l'inférence sur un worker Kafka pour contrôler la concurrence.
- Problème : Un afflux d'activité TaskBoard renvoie
-
Jeton JWT expiré confondu avec une erreur de code
- Problème : Les appels qui fonctionnaient hier renvoient une erreur d'authentification aujourd'hui, et vous commencez à déboguer les en-têtes et les charges utiles.
- Pourquoi cela se produit-il : Le jeton Bearer est un JWT avec une revendication
expet une date d'expiration fixe. Lorsqu'il expire, chaque appel échoue l'authentification. - Correction : Décodez la revendication
expdu jeton et régénérez le jeton lorsqu'il expire. Traitez les échecs d'authentification comme un contrôle de cycle de vie du jeton en premier, et non comme une erreur de format de requête.
-
Appel d'inférence de manière synchrone et paiement pour des doublons
- Problème : Les pics de latence lors de la création de tâches et la facture de jetons augmente parce que les descriptions identiques sont résumées à plusieurs reprises.
- Pourquoi cela se produit-il : L'inférence s'exécute à l'intérieur du chemin de requête sans mise en cache, donc la même entrée coûte des jetons chaque fois.
- Correction : Mettez en cache par un hachage de modèle plus d'entrée dans Redis avec un TTL, et déplacez les résumés non urgents vers un worker Kafka asynchrone afin que la requête de création reste rapide.
Résumé
Vous pouvez maintenant intégrer AI Model Hub dans le code d'application. Vous appelez le point de terminaison compatible OpenAI à https://openai.inference.de-txl.ionos.com/v1 avec un jeton Bearer JWT, le pilotez à partir de requests ou du client officiel OpenAI, le diffusez lorsque l'interface utilisateur en a besoin, et générez des embeddings avec BAAI/bge-m3. Vous sélectionnez des modèles en fonction de la fenêtre de contexte et du prix par jeton, et vous enveloppez chaque appel dans une temporisation, un recul 429 et une validation de réponse. Vous avez connecté la fonctionnalité à TaskBoard à la fois de manière synchrone et via un travailleur Kafka-file d'attente, et vous mettez en cache les résultats dans Redis afin que les entrées répétées ne coûtent rien.
Points clés :
- Le point de terminaison compatible OpenAI API à
/v1/chat/completions,/v1/embeddings,/v1/models, et/v1/images/generationspermet au client officiel OpenAI de fonctionner en remplaçantbase_urletapi_key - L'authentification est un jeton Bearer JWT dans
IONOS_API_TOKEN; une revendicationexpexpirée est la cause la plus courante d'échecs d'authentification soudains - La limite de débit générale est de 5 requêtes par seconde de base, 10 burst ; la dépasser renvoie HTTP 429, que vous gérez avec
Retry-Afteret un recul exponentiel - Le choix du modèle est une décision de coût : les trois modèles de chat partagent une fenêtre de contexte de 128000 jetons, donc le prix les sépare, avec
mistralai/Mistral-Small-24B-Instructle moins cher - Le service est sans état et hébergé en Allemagne ; les invites et les sorties sont supprimées par session et ne sont jamais utilisées pour la formation, donc la mise en cache Redis est à la fois votre levier de coût et votre seul magasin durable de résultats
- Le IONOS CLOUD MCP Server est un binaire local donnant aux agents IA un accès en lecture seule à plus de 100 outils à travers Compute Engine, Object Storage, Cloud DNS, Certificate Manager, Facturation, et Journal d'activité sur MCP (JSON-RPC sur stdio) ; il est une alternative aux appels directs API ou SDK pour les scénarios de lecture agentic et s'associe avec AI Model Hub pour les flux de travail souverains
Terminologie importante :
- Point de terminaison compatible OpenAI API : Un point de terminaison qui reflète la structure de requête et de réponse d'OpenAI, permettant aux SDK OpenAI de fonctionner contre IONOS en changeant l'URL de base et la clé
- Fenêtre de contexte : Le nombre maximum de jetons (invite plus complétion) qu'un modèle accepte en une requête ; 128000 pour les modèles de chat dans cette unité
- Prix basé sur les jetons : Coût facturé par million de jetons d'entrée et de sortie ; suivi via l'objet
usagedans chaque réponse - Recul exponentiel : Une stratégie de réessai qui double l'attente entre les tentatives après un 429, empêchant une tempête de réessai
- Inférence sans état : Chaque requête se tient seule ; AI Model Hub supprime les invites et les sorties à la fin de la session et ne les enregistre, ne les stocke ni ne les forme pas
- IONOS CLOUD MCP Server : Un binaire local mettant en œuvre le protocole de contexte de modèle (JSON-RPC sur stdio) qui expose des outils d'inspection en lecture seule à travers six produits IONOS à un client IA, en appelant directement le point de terminaison IONOS Cloud API sans fournisseur de IA tiers dans le chemin des données
Prochaines étapes
Continuer l'apprentissage : Unité 4.5 : Vérification des connaissances - Intégration de service
Sujets connexes :