Tambahkan provider OpenAI-compatible kustom ke OpenCode.

Updated 2026-07-29

OpenCode membaca provider kustom langsung dari opencode.json. Deklarasikan blok provider dengan paket @ai-sdk/openai-compatible, arahkan options.baseURL ke https://api.apisrouter.com/v1, dan setiap model yang Anda daftar menjadi bisa dipilih di picker /models di bawah satu key.

Jawaban singkat: satu blok provider di opencode.json.

OpenCode mendukung provider OpenAI-compatible kustom secara native. Tambahkan entri provider ke opencode.json dengan npm diatur ke "@ai-sdk/openai-compatible", atur options.baseURL ke https://api.apisrouter.com/v1, baca key dari environment variable dengan template {env:...}, dan daftarkan id model yang Anda inginkan di bawah models. Lalu atur field model tingkat atas ke "apisrouter/<model-id>" dan OpenCode merutekan seluruh loop agent melalui gateway. Ini adalah jalur provider-kustom terdokumentasi di dokumentasi OpenCode, bukan wrapper atau fork. File konfigurasinya berada baik di root proyek Anda (opencode.json) atau secara global di ~/.config/opencode/opencode.json, dan keduanya digabung, jadi blok provider bisa dideklarasikan sekali dan dipakai ulang di setiap repo.

{
  "$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"
}

Bagaimana OpenCode me-resolve provider dan model.

OpenCode (anomalyco di GitHub, salah satu agent coding terminal paling berbintang dengan sekitar 186K bintang) membangun lapisan providernya di atas Vercel AI SDK. Field npm di blok provider menamai paket SDK mana yang dimuat OpenCode untuk berbicara dengan provider itu: "@ai-sdk/openai-compatible" berbicara protokol /v1/chat/completions standar, sementara "@ai-sdk/openai" berbicara protokol /v1/responses milik OpenAI. Gateway multi-vendor melayani chat completions, jadi openai-compatible adalah paket yang benar; memilih "@ai-sdk/openai" terhadap endpoint chat-completions adalah cara paling umum setup ini rusak. Model dialamatkan sebagai pasangan provider/model. Id provider adalah key apa pun yang Anda pilih di blok provider ("apisrouter" di atas), dan id model adalah key di dalam map models, jadi model default menjadi "apisrouter/claude-sonnet-4-6". Semua yang Anda deklarasikan muncul di picker /models di dalam TUI, bisa ditukar di tengah sesi. Satu perilaku yang layak diinternalisasi: untuk provider kustom, map models adalah allowlist. Provider bawaan hadir dengan katalog yang dikenal, tapi OpenCode tidak bisa mengenumerasi model endpoint kustom sendiri, jadi hanya id yang Anda deklarasikan secara eksplisit yang bisa dialamatkan. Saat endpoint di balik baseURL melayani id Claude, GPT, DeepSeek, dan Kimi berdampingan, mendeklarasikan satu entri per model mengubah picker menjadi switchboard lintas-vendor di balik satu key.

Setup lengkap: konfigurasi global, konfigurasi proyek, batas per model.

Susunan yang bersih adalah mendeklarasikan provider sekali di konfigurasi global di ~/.config/opencode/opencode.json dan menyimpan hanya pilihan per-repo (model mana, agent mana) di opencode.json setiap proyek. OpenCode menggabung file konfigurasi alih-alih menggantinya, jadi file proyek tetap kecil dan blok provider tidak pernah terduplikasi. Template {env:APISROUTER_API_KEY} di-resolve saat load time dari environment, yang menjaga key keluar dari file mana pun yang mungkin ter-commit. Export dari shell profile Anda agar setiap sesi terminal yang meluncurkan OpenCode bisa melihatnya. Setiap entri model juga menerima objek limit dengan batas token context dan output. Mendeklarasikannya penting lebih dari kelihatannya: OpenCode menggunakan angka context untuk memutuskan kapan sesi butuh summarization, jadi model long-context yang dideklarasikan tanpa limit diperlakukan lebih konservatif dari seharusnya. Atur limit.context ke apa yang benar-benar didukung model dan sesi panjang berkompaksi lebih belakangan, bukan lebih awal.

{
  "$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"
}

Memilih model dan small_model.

Alur kerja praktisnya adalah menahan slot main pada model yang Anda percaya untuk edit dan merotasi kandidat melalui sesi nyata alih-alih benchmark: satu sore diff sesungguhnya melawan codebase Anda sendiri memberi tahu Anda lebih banyak daripada leaderboard. Merutekan melalui satu endpoint membuat setiap kandidat perubahan satu baris, dan tampilan penggunaan per-key menunjukkan berapa biaya setiap eksperimen sesungguhnya.

  • model menjalankan loop agent utama: membaca file, merencanakan edit, menulis diff, menjalankan tool. Slot ini melihat context terpanjang dan melakukan engineering sesungguhnya, jadi model coding frontier (claude-sonnet-4-6, claude-opus-4-7, gpt-5.5) tergolong di sini.
  • small_model menangani tugas ringan seperti pembuatan judul sesi. Ia menembak sering tapi tidak pernah mengangkut kerja coding, jadi id yang cepat dan murah adalah bentuk yang tepat; tidak ada alasan membakar token frontier untuk judul.
  • Id yang disetel untuk coding seperti gpt-5.6-sol dan kimi-k2.7-code layak dideklarasikan meski bukan default Anda: beralih ke situ untuk sesi refactor-heavy adalah satu pilihan /models, bukan edit konfigurasi.
  • Karena kedua slot menerima string provider/model terhadap blok provider yang sama, slot main dan small bisa berasal dari vendor berbeda dalam sesi yang sama, sesuatu yang tidak diizinkan key vendor tunggal mana pun.

Bayar sesuai pemakaian · di bawah harga resmi

Selected models are priced below official list prices. Exact input, output, cache, and per-request prices are shown for each model.

ModelHarga ResmiHarga Kami
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

Mode kegagalan spesifik provider kustom OpenCode.

Paket SDK yang salah. "@ai-sdk/openai" mengirim ke /v1/responses; gateway chat-completions menjawab route itu dengan error. Jika request pertama Anda gagal dengan error berbentuk protokol atau route alih-alih error auth, cek field npm mengatakan "@ai-sdk/openai-compatible" persis. Model tidak ada di picker. Model provider kustom hanya ada jika dideklarasikan; salah ketik di key models, atau id yang Anda asumsikan tapi tidak pernah ditambahkan, sederhananya tidak muncul di /models. Id adalah string persis termasuk suffix versi, dan listing /v1/models gateway adalah sumber kebenaran untuk disalin. {env:...} yang tidak ter-resolve. Template ini di-resolve dari environment proses yang meluncurkan OpenCode. Key yang di-export di satu terminal tidak menjangkau instance OpenCode yang diluncurkan dari terminal lain atau dari launcher desktop yang tidak pernah men-source profile Anda. Taruh export di shell profile, bukan sesi sekali pakai. Kejutan config-merge. Karena konfigurasi global dan proyek digabung, opencode.json proyek yang mengatur model ke provider berbeda diam-diam menimpa default global Anda, dan blok provider tersisa di proyek lama bisa membayangi ekspektasi. Saat routing terlihat salah, baca kedua file sebelum menyalahkan gateway. baseURL tanpa /v1. SDK menambahkan path route seperti /chat/completions ke base apa pun yang Anda berikan, jadi https://api.apisrouter.com/v1 benar dan host telanjang tidak. Kegagalan koneksi atau berbentuk-404 pada konfigurasi yang sebaliknya benar hampir selalu ini.

Siapa yang merutekan OpenCode melalui gateway.

  • Developer yang hidup di TUI sepanjang hari dan ingin Claude, GPT, dan Kimi di satu picker /models alih-alih memelihara kredensial provider terpisah per vendor.
  • Engineer yang membandingkan model coding pada kerja nyata. Setiap kandidat adalah satu entri terdeklarasi dan satu pilihan picker; perbandingan sesi-demi-sesi tidak butuh akun baru.
  • Tim yang menstandarkan satu secret. Satu APISROUTER_API_KEY di dokumen onboarding menggantikan checklist key per vendor, dan penggunaan per-key menunjukkan siapa membelanjakan apa.
  • Pengguna yang memasangkan model main frontier dengan small_model murah dari vendor berbeda, yang tidak bisa diekspresikan konfigurasi vendor tunggal.
  • Developer tanpa akses ke billing vendor tertentu. Akses berbasis top-up tanpa syarat kartu menghilangkan ketergantungan sign-up per provider.

Verifikasi endpoint dan debug sesi pertama.

Sebelum memulai sesi, daftar apa yang dilayani gateway. Id yang dikembalikan /v1/models adalah persis string yang harus dicocokkan key map models Anda. Kegagalan sesi pertama konsisten. 401 berarti APISROUTER_API_KEY tidak terlihat oleh proses OpenCode; echo variabel di terminal yang sama tempat Anda meluncurkannya. Error model-not-found dari gateway berarti key yang dideklarasikan tidak cocok dengan id yang dilayani, termasuk suffix versi. Jika provider tidak muncul sama sekali, validasi JSON-nya, karena koma tersisa atau kurung kurawal salah tempat membuat seluruh file tidak terbaca dan OpenCode jatuh ke default. Setelah request mengalir, konsol APIsRouter menunjukkan model per request, hitungan token, dan pengeluaran. Agent coding adalah beban kerja context-panjang, banyak-giliran, dan melihat sesi mana dan model mana yang menghabiskan token adalah cara Anda memutuskan apakah slot main sepadan dengan harganya.

curl -s https://api.apisrouter.com/v1/models \
  -H "Authorization: Bearer $APISROUTER_API_KEY" | head -50

Pertanyaan umum

Bisakah OpenCode menggunakan model Claude, GPT, dan Kimi melalui satu provider kustom?

Ya. Provider kustom hanyalah baseURL plus allowlist models. Saat endpoint melayani beberapa vendor, deklarasikan satu entri per id dan setiap model terdeklarasi muncul di picker /models di bawah provider dan key yang sama, bisa ditukar di tengah sesi.

Di mana API key ditaruh di opencode.json?

Di options.apiKey menggunakan template environment, misalnya "{env:APISROUTER_API_KEY}". Template di-resolve saat load time sehingga key literal tidak pernah duduk di file konfigurasi. Export variabelnya dari shell profile Anda agar setiap terminal yang meluncurkan OpenCode mewarisinya.

Haruskah blok provider berada di konfigurasi global atau proyek?

Global, di ~/.config/opencode/opencode.json. OpenCode menggabung file konfigurasi, jadi mendeklarasikan provider sekali secara global dan hanya mengatur pilihan model per proyek menjaga repo bebas dari plumbing kredensial dan menghindari blok terduplikasi yang saling menyimpang.

Mengapa model saya tidak muncul di picker /models?

Model provider kustom harus dideklarasikan secara eksplisit; OpenCode tidak bisa mengenumerasi endpoint kustom. Cek map models berisi string id yang persis, termasuk suffix versi, dan salin id dari respons /v1/models gateway alih-alih mengetiknya dari ingatan.

Apa perbedaan @ai-sdk/openai-compatible dan @ai-sdk/openai di sini?

@ai-sdk/openai-compatible berbicara /v1/chat/completions, protokol yang dilayani gateway multi-vendor. @ai-sdk/openai berbicara protokol /v1/responses OpenAI. Untuk APIsRouter, gunakan @ai-sdk/openai-compatible; paket lainnya akan mengirim ke route yang tidak dilayani gateway untuk tujuan ini.

Apakah batas context yang dideklarasikan benar-benar penting?

Ya. OpenCode menggunakan limit.context untuk memutuskan kapan sesi butuh kompaksi. Membiarkan limit tidak dideklarasikan pada model long-context berarti sesi diringkas lebih awal dari seharusnya, jadi atur limit.context dan limit.output ke apa yang benar-benar didukung model.