Dans cet article
Un assistant de développement peut recevoir une simple question de syntaxe, puis un problème de débogage complexe. Faire appel au même modèle pour toutes les requêtes est une approche simple, mais peut laisser de côté des compromis intéressants entre coût et qualité. Le nouvel Inference Router de DigitalOcean mérite une comparaison à petite échelle si votre application traite ce type de demandes variées.
Commencez par un modèle fixe de référence et des tâches synthétiques dont vous pouvez vérifier les réponses. Ne transférez qu’une part limitée du trafic, et seulement si le routage améliore les résultats qui comptent pour votre application. Conservez les appels directs aux modèles lorsque le choix exact du modèle, une validation reproductible ou les exigences de localisation des données priment sur la sélection automatique.
Ce guide de configuration et d’aide à la décision s’appuie sur la documentation, vérifiée le 13 octobre 2026. L’exemple a passé des essais locaux sans appel réseau, ainsi que des vérifications simulées de réussite, d’échec et de redirection ; il n’a pas été exécuté via l’API payante. Il ne présente aucun test en production, aucun benchmark d’inférence payant ni aucun résultat d’économies mesurées.
Ce qui a changé le 12 octobre
DigitalOcean a remplacé son mode principal de configuration du routeur par le nom de modèle inference-router et trois préférences définies pour chaque requête : balanced, budget et quality. Les anciennes listes de configurations prédéfinies et l’interface Create Router ont disparu, mais les routeurs personnalisés existants et les identifiants des configurations prédéfinies continuent de fonctionner. Aucune migration urgente n’est nécessaire. Note de version du 12 octobre
Le routeur général reste en préversion publique, accessible à tous les utilisateurs. Le routage n’entraîne aucun supplément pendant cette préversion ; l’utilisation du modèle sélectionné est facturée. Le même nom de routeur fonctionne avec Chat Completions, Responses et Messages. Il ne permet pas d’imposer un modèle précis pour traiter la requête. La préférence budget privilégie le coût sans garantir le choix le moins cher. Fonctionnement du routeur
Il faut distinguer ce produit de l’optimiseur Inference Router, que le communiqué officiel du 12 octobre présente comme étant en préversion privée. L’accès au routage classique ne donne pas nécessairement accès à cet optimiseur. Annonce officielle de disponibilité
Les performances de la préversion publique ne sont pas garanties pour les charges de production et ne donnent pas droit à des crédits au titre d’un SLA. DigitalOcean recommande d’utiliser des données simulées et d’éviter les traitements sensibles pendant la préversion. Intégrez cette restriction à votre décision de déploiement. Politique de cycle de vie des produits
Déterminer si l’expérience est adaptée
| Votre situation | Point de départ | Ce qui justifierait un changement |
|---|---|---|
| Un outil de développement reçoit des questions et des tâches de débogage variées | Une comparaison à petite échelle avec le routeur | Un meilleur coût par réponse acceptée, sans délais ni régressions inacceptables |
| Une tâche bien délimitée fonctionne déjà correctement | Le modèle fixe actuel | Une amélioration reproductible assez importante pour justifier la migration et la surveillance |
| Vous devez approuver chaque modèle susceptible d’être utilisé | Des appels directs aux modèles approuvés | Des contrôles explicitement vérifiés qui répondent à votre procédure d’approbation |
| Un routeur personnalisé possède déjà un ensemble de modèles ou une politique de repli importante | La configuration existante | La preuve que la solution de remplacement conserve le comportement requis |
| Un contrat impose un lieu de traitement précis | Régler d’abord la question de la résidence des données | Une confirmation écrite couvrant le parcours réel de l’inférence |
Ce tutoriel nécessite une API serverless, pas un Droplet GPU ni un déploiement d’inférence dédié. DigitalOcean décrit l’offre serverless comme un accès direct aux modèles, sans infrastructure d’inférence à gérer. Les déploiements dédiés relèvent d’un choix distinct en matière de capacité. Présentation de l’offre serverless
Vérifier les accès et les coûts avant d’envoyer un prompt
- Connectez-vous à l’équipe DigitalOcean concernée et vérifiez qu’elle a accès aux modèles dont vous avez besoin. Relevez l’ensemble actuel des modèles du routeur sur sa page Overview. Vérifiez-le à nouveau avant le déploiement, car il évolue dans le temps. Modèles actuellement disponibles dans le routeur
- Utilisez une clé d’accès aux modèles créée via la procédure de gestion des clés documentée. Conservez-la sur le serveur ou dans votre processus de test local. Ne la placez pas dans du code frontend, un dépôt, des captures d’écran ou un fichier d’évaluation partagé. Vérifiez que ses restrictions de modèles et de réseau sont compatibles avec le test prévu. N’élargissez pas les droits d’une clé de production uniquement pour faire fonctionner un test. Clés d’accès aux modèles
- Vérifiez les crédits et les soldes utilisables avant tout achat. L’inférence serverless fonctionne en prépaiement. L’accès s’arrête lorsque le crédit promotionnel et les soldes utilisables sont épuisés. Le Playground est lui aussi facturé aux tarifs serverless. Tarification actuelle
- Si vous décidez d’ajouter des fonds, examinez les paramètres de paiement : le rechargement automatique est activé par défaut dans la procédure documentée. Désactivez-le si vous souhaitez financer une expérience ponctuelle. Un dépôt prépayé ne correspond pas au prix d’une requête, et une préférence de routage ne constitue pas un plafond de dépenses en dollars. Paramètres de prépaiement
Le catalogue des modèles indique que la résidence des données dans l’Union européenne n’est pas disponible. Les instructions publiques du routeur ne proposent pas de sélecteur de région par requête. La région du Droplet de votre application ne prouve pas où l’inférence est traitée. Utilisez ici des données inventées ; clarifiez la résidence des données et les modalités de traitement propres à chaque fournisseur avant d’utiliser des données de clients. Disponibilité des modèles · Confidentialité des données
Les droits du compte restent importants : la page des limites de DigitalOcean exclut les modèles commerciaux d’Anthropic et d’OpenAI des niveaux 1 et 2, à l’exception de gpt-oss. Un format compatible avec OpenAI ne garantit pas non plus la prise en charge de chaque fonctionnalité propre à un fournisseur. Vérifiez précisément votre clé, votre point de terminaison, vos modèles, vos quotas et le comportement de votre SDK avant le déploiement. Limites d’accès et de compatibilité
Définir d’abord les critères d’acceptation
Pour une première comparaison destinée à un outil de développement, préparez six tâches courtes et inventées :
- Un bug d’une ligne sur une condition limite, avec une correction attendue précise
- Un petit test qui échoue, avec assez de contexte pour en déterminer la cause
- Un message d’erreur trompeur pour lequel la réponse doit distinguer les faits des suppositions
- Une question incomplète pour laquelle la bonne réponse demande le contexte manquant
- Une question en deux tours qui dépend d’une exigence fournie au premier tour
- Une instruction intégrée à un exemple de journal, qui doit être traitée comme une donnée
Pour chaque tâche, notez les faits attendus, les affirmations interdites et l’incertitude acceptable. Pour les suggestions de code, utilisez un environnement de test local jetable pour vérifier le comportement. Une personne doit juger si la réponse satisfait réellement la demande ; une explication fluide ne suffit pas.
Fixez un objectif de latence jusqu’à réception de la réponse complète et un budget maximal de test avant de lancer quoi que ce soit. Appuyez-vous sur les exigences de votre application, plutôt que sur un pourcentage choisi après avoir vu les résultats. Six cas constituent un test de bon fonctionnement initial. Élargissez cet ensemble pour représenter votre charge réelle avant toute décision de mise en production.
Exécuter une requête avec des limites explicites
Utilisez Python 3 et enregistrez le code suivant dans routing_probe.py. Il utilise la bibliothèque standard, écrit la requête synthétique dans un nouveau répertoire de sortie et n’effectue aucun appel réseau sans l’option --send. Lors d’un envoi, il demande la clé d’accès au modèle sans l’afficher et s’arrête si la saisie masquée dans le terminal est indisponible. Les redirections et les nouvelles tentatives automatiques sont désactivées. Les tentatives échouées conservent un horodatage et des métadonnées de diagnostic, sans enregistrer le contenu brut des réponses d’erreur ni les identifiants d’accès.
La requête utilise le point de terminaison Chat Completions documenté, des messages de conversation explicites et max_completion_tokens. Ce paramètre limite les tokens générés, pas le coût total en dollars. Les tours suivants doivent inclure l’historique pertinent de la conversation. Format des requêtes
import argparse
from datetime import datetime, timezone
import getpass
import hashlib
import http.client
import json
from pathlib import Path
import time
import urllib.error
import urllib.request
import warnings
parser = argparse.ArgumentParser()
parser.add_argument("--model", default="inference-router")
parser.add_argument("--preference", choices=["balanced", "budget", "quality"],
default="balanced")
parser.add_argument("--out", required=True)
parser.add_argument("--send", action="store_true")
args = parser.parse_args()
payload = {
"model": args.model,
"messages": [{
"role": "user",
"content": (
"A function should accept ages 18 and over. Its condition is "
"age > 18. Give the corrected condition and two boundary tests. "
"Do not claim to have executed tests."
),
}],
"max_completion_tokens": 512,
}
if args.model == "inference-router":
payload["routing_preference"] = args.preference
out = Path(args.out)
out.mkdir(parents=True, exist_ok=False)
def save(name, value):
(out / name).write_text(json.dumps(value, indent=2) + "\n", encoding="utf-8")
save("request.json", payload)
if not args.send:
print("Dry run only. Inspect request.json; no API request was sent.")
raise SystemExit(0)
try:
with warnings.catch_warnings():
warnings.simplefilter("error", getpass.GetPassWarning)
key = getpass.getpass("Model access key (hidden): ").strip()
except (getpass.GetPassWarning, EOFError):
raise SystemExit("Hidden input unavailable. Run in a terminal; no request sent.")
if not key:
raise SystemExit("No key supplied; no API request was sent.")
class NoRedirect(urllib.request.HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
return None
request = urllib.request.Request(
"https://inference.do-ai.run/v1/chat/completions",
data=json.dumps(payload).encode("utf-8"),
headers={"Authorization": "Bearer " + key, "Content-Type": "application/json"},
method="POST",
)
opener = urllib.request.build_opener(NoRedirect)
save("attempt.json", {
"started_at_utc": datetime.now(timezone.utc).isoformat(),
"cost_status": "unknown until response and billing are reconciled",
})
started = time.monotonic()
status, raw = None, b""
try:
with opener.open(request, timeout=90) as response:
status = response.status
raw = response.read()
elapsed = round(time.monotonic() - started, 3)
result = json.loads(raw)
if not isinstance(result, dict) or "error" in result:
raise ValueError("Unexpected response object")
choices = result.get("choices")
if not isinstance(choices, list) or not choices or not isinstance(choices[0], dict):
raise ValueError("Unexpected choices")
choice = choices[0]
if not isinstance(choice.get("message"), dict):
raise ValueError("Unexpected message")
except (OSError, http.client.HTTPException, ValueError, KeyboardInterrupt) as error:
if isinstance(error, urllib.error.HTTPError):
status = error.code
error.close() # Do not read or save HTTP error bodies.
if isinstance(error, http.client.IncompleteRead):
raw = error.partial
save("failure.json", {
"http_status": status,
"error_type": type(error).__name__,
"elapsed_seconds": round(time.monotonic() - started, 3),
"received_bytes": len(raw),
"response_sha256": hashlib.sha256(raw).hexdigest() if raw else None,
"cost_status": "unknown; reconcile billing before retry",
})
raise SystemExit("Request failed. Check failure.json; no automatic retry.")
save("response.json", result)
summary = {
"served_model": result.get("model"),
"finish_reason": choice.get("finish_reason"),
"usage": result.get("usage"),
"elapsed_seconds": elapsed,
"answer": choice["message"].get("content"),
"refusal": choice["message"].get("refusal"),
}
save("summary.json", summary)
print(json.dumps(summary, indent=2))
Commencez par exécuter uniquement la préparation locale :
python3 routing_probe.py --out probe-dry
Lisez probe-dry/request.json. Si les vérifications concernant le compte, les données et les dépenses sont satisfaisantes, cette commande distincte envoie une requête facturable :
python3 routing_probe.py --preference balanced --out probe-balanced --send
Critères d’évaluation attendus pour ce cas de test inventé : la réponse utilise age >= 18, refuse l’âge de 17 ans, accepte l’âge de 18 ans et n’invente aucune exécution de test. Il s’agit de critères d’acceptation, pas d’une réponse observée de l’API.
Examinez summary.json. Exigez un modèle ayant traité la requête, une réponse exploitable, un relevé d’utilisation et un motif de fin satisfaisant avant de considérer l’appel comme réussi. Une réponse vide, un refus ou un arrêt dû à la limite de tokens nécessite une analyse. Conservez toute tentative échouée dans votre relevé des coûts. Le champ model de la réponse identifie le modèle qui a réellement traité la requête. Champ du modèle utilisé
Pour établir une référence par appel direct, choisissez dans le catalogue un identifiant de modèle actuellement disponible et compatible avec Chat Completions. Passez cet identifiant avec --model ; le script omet la préférence de routage pour les appels directs. Utilisez un nouveau répertoire de sortie pour chaque tentative afin de ne pas écraser les éléments de preuve précédents. Remplacez le message synthétique dans le script pour chaque tâche supplémentaire, et gardez ce message identique entre les variantes comparées.
En cas d’erreur 401 ou 403, vérifiez la clé, les autorisations, les droits du compte et les éventuelles restrictions réseau. Pour une erreur 429, consultez le quota actuel et les consignes de nouvelle tentative avant de prévoir un autre essai. Une erreur 503 peut signaler une capacité limitée. Un délai d’attente dépassé ne prouve pas que le fournisseur n’a effectué aucun traitement ; vérifiez la facturation avant de réessayer.
Comparer le travail utile plutôt que le prix des tokens
Exécutez les mêmes tâches approuvées avec le modèle de référence et chaque préférence de routage que vous souhaitez étudier. Gardez autant que possible le même prompt, la même limite de sortie, la même grille d’évaluation et les mêmes conditions de trafic. Consignez les différences que vous ne pouvez pas contrôler. Alternez l’ordre des variantes au lieu de toujours commencer par la même. Pour les tâches à plusieurs tours, comparez les conversations complètes.
Pour chaque tentative, relevez ces informations :
| Champ | Utilité |
|---|---|
| Identifiant de la tâche et paramètres de la requête | Reconstituer la demande |
| Routage demandé et modèle ayant réellement traité la requête | Distinguer votre choix de celui du routeur |
| Réponse acceptée ou rejetée, avec le motif | Relier la dépense à un résultat utile |
| Utilisation en entrée, en sortie, en lecture et en écriture du cache, lorsque ces données sont présentes | Tenir compte des catégories réellement facturées |
| Durée jusqu’à réception de la réponse complète, erreurs et nouvelles tentatives | Inclure les traitements lents ou échoués |
| Coût estimé et date de la grille tarifaire | Rapprocher l’expérience de la facturation |
Utilisez la grille tarifaire actuelle correspondant au modèle réellement utilisé et au mode de traitement. Vérifiez les seuils de contexte long et les éventuels outils facturés séparément. Il n’existe pas de tarif unique fixe par token du routeur qui rendrait toutes les requêtes routées équivalentes en coût. Ne calculez pas un coût en multipliant tous les tokens par le seul tarif d’entrée. Tarifs actuels des modèles
La mise en cache exige sa propre vérification. Les modèles hébergés par DigitalOcean n’entraînent aucun supplément pour l’écriture en cache, tandis que les requêtes Anthropic éligibles peuvent générer des frais d’écriture en cache et bénéficier de lectures à tarif réduit. Un routage qui change de modèle peut empêcher une réutilisation utile du cache. Séparez les catégories de cache pour éviter de compter deux fois les tokens mis en cache. Documentation sur la mise en cache
Pour chaque variante, divisez le total des frais de modèle, y compris les tentatives infructueuses et les nouvelles tentatives, par le nombre de tâches ou de conversations terminées et acceptées. Si aucune n’est acceptée, considérez la variante comme un échec. À titre purement illustratif, 12 unités comptables dépensées pour 8 réponses acceptées donnent 1,5 unité par réponse acceptée. Dix unités pour seulement 5 réponses acceptées donnent 2 unités. La facture la plus faible aboutit au coût unitaire le plus élevé. Ces chiffres ne sont ni des tarifs DigitalOcean ni des résultats mesurés.
La vue Serverless Inference Live Usage de la facturation s’actualise toutes les dix minutes et couvre les trente derniers jours. Utilisez sa ventilation par modèle et par clé d’accès pour rapprocher les chiffres du test de ceux de la facturation ; les estimations excluent les crédits, les remises promotionnelles et les taxes. La facture reste la référence définitive. Un tableau de bord sans activité visible juste après une requête ne prouve pas l’absence de frais. Rapprochement avec la facturation
Migrer en prévoyant un retour en arrière
Gardez disponible la configuration actuelle du fournisseur ou du modèle. Pilotez la nouvelle sélection par un paramètre de l’application et commencez par ne lui confier qu’un ensemble de tâches à faible risque, explicitement choisi. Testez le comportement en cas d’échec : un délai d’attente dépassé ne doit pas déclencher une boucle de nouvelles tentatives sans limite ni un recours payant à une solution sans rapport avec le test.
Pour un routeur personnalisé existant, consignez sa configuration actuelle avant d’évaluer une solution de remplacement. DigitalOcean prend toujours en charge la gestion des routeurs personnalisés via l’API. Ne supposez pas que le routeur géré conserve votre ancienne liste de modèles autorisés, votre politique ou vos choix de repli. Prise en charge des routeurs personnalisés par l’API
Ne généralisez l’expérience que lorsqu’elle satisfait les exigences de qualité, de latence, de traitement des données et de coût définies au préalable. Relancez les vérifications représentatives après tout changement significatif de l’ensemble de modèles ou de l’application. Conservez assez de métadonnées pour repérer une évolution défavorable de la répartition des modèles utilisés, sans enregistrer inutilement des prompts privés.
Rétablissez le paramètre précédent de l’application si les échecs, les régressions de qualité ou le coût par tâche acceptée dépassent vos limites. Une réponse réussie du fournisseur ne garantit pas que le résultat de l’application soit correct. Conservez vos contrôles d’acceptation après le déploiement.
À la fin de l’expérience, révoquez toute clé créée uniquement pour ce test si vous n’en avez plus besoin. Conservez les résultats vérifiés et non sensibles, puis supprimez les copies temporaires inutiles. Vérifiez séparément le rechargement automatique du solde prépayé ; l’arrêt d’un script local ne modifie pas ce paramètre.
Un prochain achat raisonnable
Choisissez une expérience serverless limitée si vos tâches sont variées, si le traitement des données est acceptable et si quelqu’un peut évaluer les résultats. Financez uniquement le périmètre prévu et vérifiez le rechargement automatique avant de payer. Si le modèle de référence répond déjà à vos besoins, conservez-le jusqu’à ce que les résultats justifient un changement.
Découvrir DigitalOcean Serverless Inference (lien d’affiliation).
Pour les charges qui réutilisent le même contexte, poursuivez avec le guide de mesure des économies liées au cache de prompts, en anglais. Si votre outil de développement échoue avant de terminer une requête, commencez par le diagnostic du fournisseur en lecture seule.