Ce que signifie l'expression
Les gens utilisent « LLM local API OpenAI » pour deux choses liées. La première est un modèle de langage que vous exécutez vous-même, sur un portable ou un serveur domestique, qui écoute sur un port local et utilise le format de chat OpenAI. La seconde est l'habitude d'écrire votre application contre ce format afin que le modèle derrière puisse être remplacé.
Le format est un contrat simple. Votre application envoie un corps JSON avec un model nom et une liste de messages, chacun ayant un rôle de system, user ou assistant. Le serveur répond par un objet JSON contenant le message généré, ou par un flux de petits fragments si vous demandez du streaming. Les SDK officiels pour Python et JavaScript enveloppent cela, et ils vous permettent de remplacer l’URL de base, ce qui est toute l’astuce.
De nombreux outils locaux exposent ce contrat. Ollama, LM Studio, le serveur llama.cpp et vLLM offrent chacun un endpoint de style OpenAI. Les services hébergés font de même, c’est pourquoi les mêmes vingt lignes de code client peuvent parler à l’un ou à l’autre. L’endpoint de ce site est de type hébergé. Il accepte POST /v1/chat/completions et GET /v1/models, et il est accessible à https://api.onekeyllmapi.com/v1.
Local versus hébergé en un coup d'œil
Aucun n'est meilleur en général. Ils échangent le contrôle contre l'effort. Le tableau se concentre sur les différences qui s'appliquent à la catégorie, pas à un produit particulier.
| Question | Exécuteur local | API de style OpenAI hébergée |
|---|---|---|
| Où vont les prompts | Restez sur votre machine | Connectez-vous au fournisseur via HTTPS |
| Matériel | Vous fournissez le GPU ou le CPU et la mémoire | Aucun de votre côté |
| Taille du modèle | Limité par votre mémoire | Ce que le fournisseur sert |
| Modèle de coût | Matériel et énergie | Par token, depuis le crédit prépayé ici |
| Disponibilité | Tant que votre machine est allumée | Serveur toujours actif, limites partagées |
| Installation | Installer, télécharger les poids, ajuster | Créer une clé, définir l'URL de base |
Si vos données ne doivent jamais quitter une machine que vous contrôlez, le local gagne et l'hébergé est le mauvais outil. Si vous avez besoin d'un modèle plus grand que ce que votre matériel permet, ou d'un bot qui reste accessible depuis de nombreux endroits, l'hébergé gagne. Une configuration courante conserve les deux et choisit par tâche.
Passage d'un client du local à l'hébergé
Si votre code parle déjà à un exécuteur local, le déplacement se fait en trois valeurs. Tout le reste, y compris la façon dont vous construisez les messages et lisez les chunks en streaming, reste identique.
- URL de base. Utilisez
https://api.onekeyllmapi.com/v1au lieu de votre adresse locale. - Clé API. Les serveurs locaux ignorent souvent la clé. Un hébergé l'exige en tant que
Authorization: Bearer <key>, et le SDK l'envoie pour vous. - ID du modèle. Les noms locaux sont ce que vous avez tiré. Ici, l'ID est
uncensored.
Une façon propre de garder cela flexible est de lire les trois depuis des variables d'environnement, afin qu'un seul fichier fonctionne aux deux endroits.
import os
from openai import OpenAI
client = OpenAI(
base_url=os.environ.get("LLM_BASE_URL", "https://api.onekeyllmapi.com/v1"),
api_key=os.environ.get("LLM_API_KEY", "YOUR_KEY"),
)
MODEL = os.environ.get("LLM_MODEL", "uncensored")
models = client.models.list()
print([m.id for m in models.data])
resp = client.chat.completions.create(
model=MODEL,
messages=[
{"role": "system", "content": "Answer in two sentences."},
{"role": "user", "content": "Why do OpenAI-style endpoints make switching models easy?"},
],
temperature=0.5,
)
print(resp.choices[0].message.content)
La même appel depuis la ligne de commande, utile pour un test rapide :
curl https://api.onekeyllmapi.com/v1/chat/completions \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "uncensored", "messages": [{"role": "user", "content": "ping"}], "max_tokens": 20}'
Avec Node, le modèle est identique :
import OpenAI from "openai";
const client = new OpenAI({
baseURL: process.env.LLM_BASE_URL ?? "https://api.onekeyllmapi.com/v1",
apiKey: process.env.LLM_API_KEY,
});
const res = await client.chat.completions.create({
model: process.env.LLM_MODEL ?? "uncensored",
messages: [{ role: "user", content: "Name three uses for JSON mode." }],
});
console.log(res.choices[0].message.content);
Ce que couvre ou non la compatibilité OpenAI
Compatible signifie que le format de transport correspond. Cela ne promet pas que chaque fonctionnalité que le service original offre est présente. Avant de migrer une application réelle, vérifiez chacune de ces fonctionnalités par rapport à la cible.
Ce que cette API prend en charge
- Complétions de chat à
POST /v1/chat/completionset liste de modèles àGET /v1/models. - Streaming via les événements envoyés par le serveur avec
stream: true, avec l'utilisation rapportée à la fin du flux. - Appel de fonctions via
toolsettool_choice, streaming destool_calls, et les résultats envoyés en tant que messagesrole: "tool". - Mode JSON via
response_format: {"type": "json_object"}. - Contrôles d'échantillonnage : temperature, top_p, stop, seed et les paramètres de pénalité sont transmis.
Ce qu'il ne fait pas
- Pas de génération d'images, d'audio ou de vidéo. Il s'agit uniquement de texte.
- Pas d'endpoint d'embedding et pas de fine-tuning. Si votre application construit un index vectoriel, vous avez besoin d'une source d'embedding séparée.
- Un seul modèle. Le modèle est un modèle à poids ouverts exécuté par un fournisseur indépendant. Ce n'est pas l'API officielle d'un grand vendeur, et ce n'est pas un routeur entre vendeurs, donc vous ne pouvez pas choisir entre des familles de modèles en changeant l'ID.
Les exécuteurs locaux diffèrent parfois dans l'autre sens : un serveur local peut offrir une route d'embedding ou vous permettre de charger plusieurs modèles, et la taille du contexte est ce que vous configurez. Lisez la documentation de la cible pour chacun, et gardez une courte liste des fonctionnalités que votre application utilise vraiment. Les docs de démarrage rapide montrent les champs de requête en entier.
Contexte, limites et différences de coût
Trois nombres changent lorsque vous quittez un serveur local. Le premier est la fenêtre. La longueur de contexte d'un exécuteur local est un paramètre lié à votre mémoire. Ici, elle est fixée à 100 000 tokens, partagée par le prompt et la complétion, et max_tokens est optionnel. Le second est la concurrence. Votre propre machine peut être mise en file d'attente aussi profondément que vous le souhaitez, mais une clé complète ici permet 8 requêtes simultanées et 300 par minute, et une clé d'essai 2 et 60. Le troisième est la facture.
L'utilisation hébergée coûte $0,15 par 1M de tokens d'entrée et $0,50 par 1M de tokens de sortie, en paiement à l'usage depuis le crédit prépayé. Prenez un travail quotidien comme exemple : un résumateur traite 400 documents par jour, chacun avec 3 000 tokens d'entrée et 300 tokens de sortie. L'entrée est 400 x 3 000 = 1 200 000 tokens, ce qui coûte 1,2 x $0,15 = $0,18. La sortie est 400 x 300 = 120 000 tokens, ce qui coûte 0,12 x $0,50 = $0,06. Le total de la journée est $0,24, et un mois de 30 jours est $7,20. Comparez cela avec le coût de maintien d'un GPU alimenté et de la carte elle-même avant de décider.
Lorsque vous dépassez une limite, l'API répond HTTP 429 avec le code rate_limited ou concurrency. Pour une surcharge brève, il ajoute Retry-After: 5. Gardez la logique de retry qui attend et réessaie. Les requêtes qui échouent ou sont refusées ne sont pas facturées. Le crédit n'expire jamais, donc un mois d'inactivité ne coûte rien.
Une requête streamée conserve son slot de concurrence jusqu'à la fin du flux, donc fermez les flux lorsque vous arrêtez de lire. Les recharges commencent à $20 ; les paliers et les bonus sont sur la page de tarification.
Débogage en cas de problème de bascule
La plupart des migrations échouées s’expliquent par quelques causes. Parcourez-les dans cet ordre.
- Erreurs 404 ou de connexion. L’URL de base manque probablement du suffixe
/v1ou contient un chemin supplémentaire. Utilisez-le exactement commehttps://api.onekeyllmapi.com/v1. - Erreurs d’authentification. La clé est manquante ou envoyée dans le mauvais en-tête. Le format est
Authorization: Bearer <key>. Les utilisateurs de SDK doivent confirmer que la variable d’environnement a bien été chargée en réalité. - Modèle introuvable. L’ancien nom du modèle local est encore dans votre configuration. Appelez
GET /v1/modelset utilisez l’ID qu’il liste, qui estuncensored. - 429 sous charge. Vous dépassez 8 requêtes simultanées ou 300 par minute avec une clé complète. Ajoutez une file d’attente ou un sémaphore.
- Un paramètre semble ignoré. Vérifiez qu’il figure parmi les champs transmis listés ci-dessus, et comparez le comportement avec un
seedfixe et une température faible.
Chaque réponse inclut un en-tête X-Request-Id. Enregistrez-le à côté de votre propre ID de requête afin qu’une mauvaise réponse puisse être tracée plus tard. Si vous gérez du trafic de production et souhaitez mesurer la qualité au fil du temps, l’article du site LLM Observability: Myths vs Facts constitue une bonne lecture suivante. Les en-têtes de réponse X-Balance-USD, X-RateLimit-Limit-Requests et X-RateLimit-Limit-Concurrency méritent également d’être capturés.
L'essayer sans engagement
La méthode la plus économique pour tester si votre code s’adapte sans problème est de l’exécuter une fois. Créez un compte avec Google ou par e-mail et mot de passe, puis réclamez le crédit d’essai de 0,50 $ depuis la page de clé. Cela prend un clic, ne nécessite aucune carte, est limité à une personne et reste valable 7 jours. Obtenez votre clé à la page de clé API, définissez les trois variables d’environnement mentionnées ci-dessus et exécutez votre suite de tests existante.
Si les tests réussissent et que l’utilisation s’inscrit dans votre budget, rechargez à partir de 20 $, par carte (Visa, Mastercard, Apple Pay, Google Pay) ou crypto (USDT sur TRC20, USDC sur Base). Les prompts ne sont pas utilisés pour l’entraînement. Le modèle est ajusté pour répondre sans refus de contenu pour une utilisation adulte légale, avec une règle fixe : aucun contenu sexuel impliquant des mineurs.
