Ajoutez un fournisseur compatible OpenAI personnalisé à OpenCode.
Updated 2026-07-29
OpenCode lit les fournisseurs personnalisés directement depuis opencode.json. Déclarez un bloc provider avec le package @ai-sdk/openai-compatible, pointez options.baseURL vers https://api.apisrouter.com/v1, et chaque modèle que vous listez devient sélectionnable dans le sélecteur /models, sous une seule clé.
Réponse rapide : un bloc provider dans opencode.json.
OpenCode prend en charge nativement les fournisseurs compatibles OpenAI personnalisés. Ajoutez une entrée provider à opencode.json avec npm réglé sur « @ai-sdk/openai-compatible », définissez options.baseURL sur https://api.apisrouter.com/v1, lisez la clé depuis une variable d'environnement avec le template {env:...}, et listez les id de modèles que vous voulez sous models. Réglez ensuite le champ model de premier niveau sur « apisrouter/<model-id> » et OpenCode route toute la boucle de l'agent via la passerelle. C'est le chemin de fournisseur personnalisé documenté dans la doc d'OpenCode, pas un wrapper ni un fork. Le fichier de config vit soit à la racine de votre projet (opencode.json), soit globalement à ~/.config/opencode/opencode.json, et les deux sont fusionnés, donc le bloc provider peut être déclaré une seule fois et réutilisé dans chaque dépôt.
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"apisrouter": {
"npm": "@ai-sdk/openai-compatible",
"name": "APIsRouter",
"options": {
"baseURL": "https://api.apisrouter.com/v1",
"apiKey": "{env:APISROUTER_API_KEY}"
},
"models": {
"claude-sonnet-4-6": { "name": "Claude Sonnet 4.6" }
}
}
},
"model": "apisrouter/claude-sonnet-4-6"
}Comment OpenCode résout les fournisseurs et les modèles.
OpenCode (anomalyco sur GitHub, l'un des agents de codage terminal les plus étoilés avec environ 186 000 étoiles) construit sa couche de fournisseurs sur le Vercel AI SDK. Le champ npm d'un bloc provider nomme le package SDK qu'OpenCode charge pour parler à ce fournisseur : « @ai-sdk/openai-compatible » parle le protocole /v1/chat/completions standard, tandis que « @ai-sdk/openai » parle le protocole /v1/responses d'OpenAI. Une passerelle multi-fournisseurs sert des chat completions, donc openai-compatible est le bon package ; choisir « @ai-sdk/openai » contre un endpoint chat-completions est la façon la plus courante dont cette configuration casse. Les modèles sont adressés comme des paires fournisseur/modèle. L'id du fournisseur est la clé que vous avez choisie dans le bloc provider (« apisrouter » ci-dessus), et l'id du modèle est la clé dans la map models, donc le modèle par défaut devient « apisrouter/claude-sonnet-4-6 ». Tout ce que vous déclarez apparaît dans le sélecteur /models de la TUI, modifiable en cours de session. Un comportement à bien intégrer : pour les fournisseurs personnalisés, la map models est une liste d'autorisation. Les fournisseurs intégrés viennent avec un catalogue connu, mais OpenCode ne peut pas énumérer seul les modèles d'un endpoint personnalisé, donc seuls les id que vous déclarez explicitement sont adressables. Quand l'endpoint derrière baseURL sert côte à côte des id Claude, GPT, DeepSeek et Kimi, déclarer une entrée par modèle transforme le sélecteur en un standard multi-fournisseurs derrière une seule clé.
Configuration complète : config globale, config de projet, limites par modèle.
La disposition propre consiste à déclarer le fournisseur une seule fois dans la config globale à ~/.config/opencode/opencode.json, et à ne garder que les choix propres à chaque dépôt (quel modèle, quels agents) dans l'opencode.json de chaque projet. OpenCode fusionne les fichiers de config plutôt que de les remplacer, donc le fichier de projet reste minuscule et le bloc provider ne se duplique jamais. Le template {env:APISROUTER_API_KEY} se résout au chargement depuis l'environnement, ce qui garde la clé hors de tout fichier susceptible d'être commité. Exportez-la depuis votre profil shell afin que chaque session de terminal qui lance OpenCode puisse la voir. Chaque entrée de modèle accepte aussi un objet limit avec des plafonds de tokens de contexte et de sortie. Les déclarer compte plus qu'il n'y paraît : OpenCode utilise le chiffre de contexte pour décider quand une session a besoin d'être résumée, donc un modèle à long contexte déclaré sans limites est traité plus prudemment qu'il ne le devrait. Réglez limit.context sur ce que le modèle prend réellement en charge, et les longues sessions se compactent plus tard plutôt que plus tôt.
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"apisrouter": {
"npm": "@ai-sdk/openai-compatible",
"name": "APIsRouter",
"options": {
"baseURL": "https://api.apisrouter.com/v1",
"apiKey": "{env:APISROUTER_API_KEY}"
},
"models": {
"claude-opus-4-7": { "name": "Claude Opus 4.7", "limit": { "context": 200000, "output": 32000 } },
"claude-sonnet-4-6": { "name": "Claude Sonnet 4.6", "limit": { "context": 200000, "output": 64000 } },
"gpt-5.5": { "name": "GPT-5.5" },
"gpt-5.6-sol": { "name": "GPT-5.6 Sol" },
"kimi-k2.7-code": { "name": "Kimi K2.7 Code" }
}
}
},
"model": "apisrouter/claude-sonnet-4-6",
"small_model": "apisrouter/kimi-k2.7-code"
}Choisir model et small_model.
Le workflow pratique consiste à garder l'emplacement main sur le modèle en qui vous avez confiance pour les éditions, et à faire tourner des candidats via de vraies sessions plutôt que des benchmarks : un après-midi de vrais diffs sur votre propre base de code vous en dit plus qu'un classement. Router via un seul endpoint fait de chaque candidat un changement d'une ligne, et la vue d'usage par clé montre ce que chaque expérience a réellement coûté.
- model pilote la boucle principale de l'agent : lire les fichiers, planifier les éditions, écrire les diffs, exécuter les outils. Cet emplacement voit les contextes les plus longs et fait le véritable travail d'ingénierie, donc un modèle de codage frontier (claude-sonnet-4-6, claude-opus-4-7, gpt-5.5) a sa place ici.
- small_model gère des tâches légères comme la génération de titre de session. Il se déclenche souvent mais ne porte jamais le travail de codage, donc un id rapide et bon marché est la bonne forme ; il n'y a aucune raison de brûler des tokens frontier pour des titres.
- Les id calibrés pour le code comme gpt-5.6-sol et kimi-k2.7-code valent la peine d'être déclarés même s'ils ne sont pas votre défaut : basculer vers eux pour une session à forte dose de refactorisation n'est qu'une sélection dans /models, pas une modification de config.
- Comme les deux emplacements prennent des chaînes provider/model contre le même bloc provider, les emplacements main et small peuvent venir de fournisseurs différents dans la même session, ce qu'aucune clé mono-fournisseur ne permet.
Paiement à l'usage · en dessous du tarif officiel
Selected models are priced below official list prices. Exact input, output, cache, and per-request prices are shown for each model.
| Modèle | Prix officiel | Notre prix |
|---|---|---|
| Claude Sonnet 4.6 | $3.00 / $15.00 per M | $2.40 / $12.00 per M |
| Claude Opus 4.7 | $5.00 / $25.00 per M | $4.00 / $20.00 per M |
| GPT-5.5 | $5.00 / $30.00 per M | $4.00 / $24.00 per M |
| GPT-5.6 Sol | $5.00 / $30.00 per M | $4.00 / $24.00 per M |
| Kimi K2.7 Code | $0.95 / $4.00 per M | $1.00 / $4.00 per M |
Les modes d'échec spécifiques aux fournisseurs personnalisés d'OpenCode.
Mauvais package SDK. « @ai-sdk/openai » poste vers /v1/responses ; une passerelle chat-completions répond à cette route par une erreur. Si votre première requête échoue avec une erreur de forme protocole ou route plutôt qu'une erreur d'authentification, vérifiez que le champ npm indique exactement « @ai-sdk/openai-compatible ». Modèle absent du sélecteur. Les modèles d'un fournisseur personnalisé n'existent que s'ils sont déclarés ; une faute de frappe dans une clé models, ou un id que vous pensiez avoir ajouté mais qui ne l'a jamais été, n'apparaît tout simplement pas dans /models. Les id sont des chaînes exactes, suffixes de version inclus, et le listing /v1/models de la passerelle est la source de vérité à copier. {env:...} non résolu. Le template se résout depuis l'environnement du processus qui a lancé OpenCode. Une clé exportée dans un terminal n'atteint pas une instance d'OpenCode lancée depuis un autre terminal ou depuis un lanceur de bureau qui n'a jamais chargé votre profil. Placez l'export dans le profil shell, pas dans une session ponctuelle. Surprises de fusion de config. Comme les configs globale et de projet fusionnent, un opencode.json de projet qui règle model sur un autre fournisseur écrase silencieusement votre défaut global, et un bloc provider oublié dans un vieux projet peut contredire vos attentes. Quand le routage semble faux, lisez les deux fichiers avant de supposer que la passerelle se comporte mal. baseURL sans /v1. Le SDK ajoute des chemins de route comme /chat/completions à la base que vous lui donnez, donc https://api.apisrouter.com/v1 est correct et l'hôte nu ne l'est pas. Un échec de connexion ou de forme 404 sur une config par ailleurs correcte vient presque toujours de là.
Qui route OpenCode via une passerelle.
- Les développeurs qui vivent dans la TUI toute la journée et veulent Claude, GPT et Kimi dans un seul sélecteur /models plutôt que de maintenir des identifiants de fournisseur séparés par fournisseur.
- Les ingénieurs qui comparent des modèles de codage sur du vrai travail. Chaque candidat n'est qu'une entrée déclarée et une sélection dans le sélecteur ; la comparaison session par session ne nécessite aucun nouveau compte.
- Les équipes qui standardisent un seul secret. Un unique APISROUTER_API_KEY dans la doc d'onboarding remplace une checklist de clés par fournisseur, et l'usage par clé montre qui dépense quoi.
- Les utilisateurs qui associent un modèle main frontier à un small_model bon marché d'un fournisseur différent, ce qu'aucune configuration mono-fournisseur ne permet d'exprimer.
- Les développeurs sans accès à la facturation d'un fournisseur donné. Un accès basé sur la recharge, sans exigence de carte, supprime la dépendance à une inscription par fournisseur.
Vérifiez l'endpoint et déboguez la première session.
Avant de démarrer une session, listez ce que sert la passerelle. Les id renvoyés par /v1/models sont exactement les chaînes que les clés de votre map models doivent correspondre. Les échecs de première session sont cohérents. Un 401 signifie qu'APISROUTER_API_KEY n'était pas visible du processus OpenCode ; faites echo de la variable dans le même terminal depuis lequel vous lancez. Une erreur de modèle introuvable venant de la passerelle signifie que la clé déclarée ne correspond à aucun id servi, suffixes de version inclus. Si le fournisseur n'apparaît pas du tout, validez le JSON, car une virgule finale ou une accolade mal placée rend tout le fichier illisible et OpenCode retombe sur les valeurs par défaut. Une fois que les requêtes circulent, la console APIsRouter affiche le modèle par requête, le nombre de tokens et la dépense. Les agents de codage sont des charges de travail à long contexte et à nombreux tours, et voir quelles sessions et quels modèles consomment les tokens est ce qui vous permet de décider si l'emplacement main justifie son prix.
curl -s https://api.apisrouter.com/v1/models \
-H "Authorization: Bearer $APISROUTER_API_KEY" | head -50Questions fréquentes
OpenCode peut-il utiliser des modèles Claude, GPT et Kimi via un seul fournisseur personnalisé ?
Oui. Un fournisseur personnalisé n'est qu'une baseURL plus une liste d'autorisation de modèles. Quand l'endpoint sert plusieurs fournisseurs, déclarez une entrée par id et chaque modèle déclaré apparaît dans le sélecteur /models sous le même fournisseur et la même clé, modifiable en cours de session.
Où va la clé API dans opencode.json ?
Dans options.apiKey, via le template d'environnement, par exemple « {env:APISROUTER_API_KEY} ». Le template se résout au chargement, donc la clé littérale ne réside jamais dans le fichier de config. Exportez la variable depuis votre profil shell afin que chaque terminal qui lance OpenCode en hérite.
Le bloc provider doit-il vivre dans la config globale ou de projet ?
Globale, à ~/.config/opencode/opencode.json. OpenCode fusionne les fichiers de config, donc déclarer le fournisseur une seule fois globalement et ne régler que le choix de modèle par projet garde les dépôts libres de tuyauterie d'identifiants et évite que des blocs dupliqués ne divergent.
Pourquoi mon modèle n'apparaît-il pas dans le sélecteur /models ?
Les modèles d'un fournisseur personnalisé doivent être déclarés explicitement ; OpenCode ne peut pas énumérer un endpoint personnalisé. Vérifiez que la map models contient la chaîne d'id exacte, suffixes de version inclus, et copiez les id depuis la réponse /v1/models de la passerelle plutôt que de les taper de mémoire.
Quelle est la différence entre @ai-sdk/openai-compatible et @ai-sdk/openai ici ?
@ai-sdk/openai-compatible parle /v1/chat/completions, le protocole que servent les passerelles multi-fournisseurs. @ai-sdk/openai parle le protocole /v1/responses d'OpenAI. Pour APIsRouter, utilisez @ai-sdk/openai-compatible ; l'autre package postera vers une route que la passerelle ne sert pas à cet effet.
Les limites de contexte déclarées comptent-elles réellement ?
Oui. OpenCode utilise limit.context pour décider quand une session a besoin d'être compactée. Laisser les limites non déclarées sur un modèle à long contexte signifie que les sessions sont résumées plus tôt que nécessaire, donc réglez limit.context et limit.output sur ce que le modèle prend réellement en charge.