OpenCode에 커스텀 OpenAI 호환 프로바이더 추가하기.

Updated 2026-07-29

OpenCode는 opencode.json에서 커스텀 프로바이더를 바로 읽습니다. @ai-sdk/openai-compatible 패키지로 프로바이더 블록을 선언하고, options.baseURL을 https://api.apisrouter.com/v1로 지정하면, 나열한 모든 모델이 키 하나로 /models 피커에서 선택 가능해집니다.

빠른 답: opencode.json의 프로바이더 블록 하나.

OpenCode는 커스텀 OpenAI 호환 프로바이더를 네이티브로 지원합니다. opencode.json에 npm을 "@ai-sdk/openai-compatible"로 설정한 프로바이더 항목을 추가하고, options.baseURL을 https://api.apisrouter.com/v1로 설정하고, {env:...} 템플릿으로 환경 변수에서 키를 읽어오고, models 아래에 원하는 모델 id를 나열하세요. 그런 다음 최상위 model 필드를 "apisrouter/<model-id>"로 설정하면 OpenCode가 전체 에이전트 루프를 게이트웨이를 통해 라우팅합니다. 이는 래퍼나 포크가 아니라 OpenCode 문서에 나온 커스텀 프로바이더 경로입니다. 설정 파일은 프로젝트 루트(opencode.json)에 두거나 전역으로 ~/.config/opencode/opencode.json에 둘 수 있으며, 둘은 병합되므로 프로바이더 블록을 한 번만 선언해 모든 저장소에서 재사용할 수 있습니다.

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

OpenCode가 프로바이더와 모델을 해석하는 방법.

OpenCode(GitHub의 anomalyco, 약 18.6만 스타로 가장 많은 스타를 받은 터미널 코딩 에이전트 중 하나)는 Vercel AI SDK 위에 프로바이더 레이어를 구축합니다. 프로바이더 블록의 npm 필드는 OpenCode가 해당 프로바이더와 통신하기 위해 불러올 SDK 패키지를 지정합니다: "@ai-sdk/openai-compatible"은 표준 /v1/chat/completions 프로토콜로 말하고, "@ai-sdk/openai"는 OpenAI의 /v1/responses 프로토콜로 말합니다. 멀티 벤더 게이트웨이는 chat completions를 제공하므로 openai-compatible이 올바른 패키지입니다. chat-completions 엔드포인트에 "@ai-sdk/openai"를 선택하는 것이 이 설정이 깨지는 가장 흔한 원인입니다. 모델은 provider/model 쌍으로 지정됩니다. 프로바이더 id는 프로바이더 블록에서 여러분이 선택한 키(위 예시의 "apisrouter")이고, 모델 id는 models 맵 안의 키이므로, 기본 모델은 "apisrouter/claude-sonnet-4-6"이 됩니다. 선언한 모든 항목이 TUI 안의 /models 피커에 나타나며, 세션 중간에도 전환할 수 있습니다. 기억해 둘 만한 동작 하나: 커스텀 프로바이더의 경우 models 맵이 허용 목록(allowlist)입니다. 내장 프로바이더는 알려진 카탈로그를 함께 제공하지만, OpenCode는 커스텀 엔드포인트의 모델을 스스로 나열할 수 없으므로 명시적으로 선언한 id만 사용할 수 있습니다. baseURL 뒤의 엔드포인트가 Claude, GPT, DeepSeek, Kimi id를 나란히 제공한다면, 모델당 항목 하나씩 선언하는 것만으로 피커가 키 하나 뒤의 크로스 벤더 스위치보드가 됩니다.

전체 설정: 전역 설정, 프로젝트 설정, 모델별 한도.

깔끔한 구성은 ~/.config/opencode/opencode.json의 전역 설정에서 프로바이더를 한 번만 선언하고, 저장소별 선택(어떤 모델, 어떤 에이전트)만 각 프로젝트의 opencode.json에 남겨두는 것입니다. OpenCode는 설정 파일을 교체하지 않고 병합하므로, 프로젝트 파일은 작게 유지되고 프로바이더 블록이 중복되지 않습니다. {env:APISROUTER_API_KEY} 템플릿은 로드 시점에 환경 변수에서 해석되므로, 커밋될 수도 있는 어떤 파일에도 키가 남지 않습니다. 셸 프로필에서 export해 두면 OpenCode를 실행하는 모든 터미널 세션이 그 값을 볼 수 있습니다. 각 모델 항목은 컨텍스트와 출력 토큰 상한을 담은 limit 객체도 받을 수 있습니다. 이를 선언하는 것은 보기보다 중요합니다: OpenCode는 세션에 요약이 필요한 시점을 판단할 때 이 컨텍스트 수치를 사용하므로, 한도 없이 선언된 긴 컨텍스트 모델은 필요 이상으로 보수적으로 취급됩니다. limit.context를 모델이 실제로 지원하는 값으로 설정하면 긴 세션이 더 일찍이 아니라 더 늦게 압축됩니다.

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

model과 small_model 선택하기.

실용적인 작업 흐름은 main 슬롯을 신뢰하는 편집용 모델로 고정해 두고, 벤치마크가 아니라 실제 세션을 통해 후보들을 돌려보는 것입니다: 여러분의 코드베이스에서 실제 diff를 만드는 오후 한 나절이 리더보드보다 더 많은 것을 알려줍니다. 엔드포인트 하나로 라우팅하면 각 후보는 한 줄 변경이면 되고, 키별 사용량 뷰가 각 실험이 실제로 얼마나 들었는지 보여줍니다.

  • model은 메인 에이전트 루프를 구동합니다: 파일 읽기, 수정 계획, diff 작성, 툴 실행. 이 슬롯은 가장 긴 컨텍스트를 받고 실제 엔지니어링을 수행하므로, 프론티어 코딩 모델(claude-sonnet-4-6, claude-opus-4-7, gpt-5.5)이 여기에 적합합니다.
  • small_model은 세션 제목 생성 같은 가벼운 작업을 처리합니다. 자주 호출되지만 코딩 작업은 전혀 담당하지 않으므로, 빠르고 저렴한 id가 적합합니다. 제목 하나 짓는 데 프론티어 토큰을 태울 이유가 없습니다.
  • gpt-5.6-sol이나 kimi-k2.7-code 같은 코딩 특화 id는 기본값이 아니더라도 선언해 둘 가치가 있습니다: 리팩터링 위주 세션에서 이들로 전환하는 것은 설정 수정이 아니라 /models 선택 한 번이면 됩니다.
  • 두 슬롯 모두 같은 프로바이더 블록에 대해 provider/model 문자열을 받으므로, 같은 세션에서 main 슬롯과 small 슬롯이 서로 다른 벤더의 것일 수 있습니다 — 단일 벤더 키로는 불가능한 조합입니다.

사용한 만큼 지불 · 공식 요금보다 저렴

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

모델공식 요금저희 요금
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

OpenCode 커스텀 프로바이더 특유의 실패 패턴.

잘못된 SDK 패키지. "@ai-sdk/openai"는 /v1/responses에 요청을 보내는데, chat-completions 게이트웨이는 그 경로에 오류로 응답합니다. 첫 요청이 인증 오류가 아니라 프로토콜이나 경로 형태의 오류로 실패한다면, npm 필드가 정확히 "@ai-sdk/openai-compatible"인지 확인하세요. 피커에 모델이 없음. 커스텀 프로바이더 모델은 선언된 것만 존재합니다. models 키의 오타나, 있다고 짐작했지만 실제로 추가하지 않은 id는 그냥 /models에 나타나지 않습니다. id는 버전 접미사까지 포함한 정확한 문자열이며, 게이트웨이의 /v1/models 목록이 그대로 복사해 올 수 있는 정답입니다. 해석되지 않는 {env:...}. 이 템플릿은 OpenCode를 실행한 프로세스의 환경에서 해석됩니다. 한 터미널에서 export한 키는 다른 터미널이나, 프로필을 한 번도 불러오지 않은 데스크톱 런처에서 실행한 OpenCode 인스턴스에는 전달되지 않습니다. 일회성 세션이 아니라 셸 프로필에 export를 넣으세요. 설정 병합으로 인한 뜻밖의 결과. 전역 설정과 프로젝트 설정이 병합되므로, 다른 프로바이더로 model을 설정한 프로젝트 opencode.json이 전역 기본값을 조용히 덮어쓸 수 있고, 오래된 프로젝트에 남은 프로바이더 블록이 예상을 뒤흔들 수 있습니다. 라우팅이 이상해 보이면, 게이트웨이가 오작동한다고 단정하기 전에 두 파일을 모두 확인하세요. /v1 없는 baseURL. SDK는 여러분이 준 베이스에 /chat/completions 같은 경로를 덧붙이므로, https://api.apisrouter.com/v1이 올바르며 호스트만 있는 값은 그렇지 않습니다. 다른 부분은 다 맞는 설정에서 연결 오류나 404 형태의 실패가 난다면 거의 항상 이 문제입니다.

어떤 사람들이 게이트웨이를 통해 OpenCode를 쓰는가.

  • 하루 종일 TUI에서 지내며, 벤더마다 별도의 프로바이더 자격 증명을 유지하는 대신 Claude, GPT, Kimi를 하나의 /models 피커에 두고 싶은 개발자.
  • 실제 작업에서 코딩 모델을 비교하는 엔지니어. 각 후보는 선언한 항목 하나와 피커 선택 한 번이면 되며, 세션별 비교에 새 계정이 필요 없습니다.
  • 시크릿 하나로 표준화하는 팀. 온보딩 문서의 APISROUTER_API_KEY 하나가 벤더별 키 체크리스트를 대체하며, 키별 사용량이 누가 무엇을 쓰는지 보여줍니다.
  • 프론티어 main 모델과 다른 벤더의 저렴한 small_model을 조합하는 사용자 — 단일 벤더 설정으로는 표현할 수 없는 조합입니다.
  • 특정 벤더의 결제 수단에 접근할 수 없는 개발자. 카드 없이 충전만으로 접근할 수 있어 프로바이더별 가입 의존성이 사라집니다.

엔드포인트 검증 및 첫 세션 디버깅.

세션을 시작하기 전에 게이트웨이가 제공하는 모델을 조회하세요. /v1/models가 반환하는 id가 바로 models 맵의 키가 일치해야 하는 정확한 문자열입니다. 첫 세션의 실패는 일관된 패턴을 보입니다. 401은 OpenCode 프로세스에 APISROUTER_API_KEY가 보이지 않는다는 뜻입니다. 실행하는 그 터미널에서 변수를 echo로 확인하세요. 게이트웨이에서 나오는 model-not-found 오류는 선언한 키가 버전 접미사를 포함해 제공되는 id와 일치하지 않는다는 뜻입니다. 프로바이더가 아예 나타나지 않는다면 JSON을 검증하세요 — 후행 쉼표나 잘못된 위치의 중괄호는 파일 전체를 읽을 수 없게 만들고, 그러면 OpenCode가 기본값으로 폴백합니다. 요청이 순조롭게 흐르면, APIsRouter 콘솔이 요청별 모델, 토큰 수, 지출을 보여줍니다. 코딩 에이전트는 컨텍스트가 길고 턴이 많은 작업이므로, 어떤 세션과 어떤 모델이 토큰을 소모하는지 보는 것이 main 슬롯이 값어치를 하는지 판단하는 방법입니다.

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

자주 묻는 질문

OpenCode에서 커스텀 프로바이더 하나로 Claude, GPT, Kimi 모델을 쓸 수 있나요?

네. 커스텀 프로바이더는 그저 baseURL과 models 허용 목록일 뿐입니다. 엔드포인트가 여러 벤더를 제공한다면 id마다 항목을 하나씩 선언하세요. 선언한 모든 모델이 같은 프로바이더와 키 아래 /models 피커에 나타나며, 세션 중간에도 전환할 수 있습니다.

opencode.json에서 API 키는 어디에 넣나요?

환경 변수 템플릿을 사용해 options.apiKey에 넣습니다. 예: "{env:APISROUTER_API_KEY}". 이 템플릿은 로드 시점에 해석되므로 실제 키 값이 설정 파일에 그대로 남지 않습니다. 셸 프로필에서 변수를 export해 두면 OpenCode를 실행하는 모든 터미널이 이를 상속받습니다.

프로바이더 블록은 전역 설정과 프로젝트 설정 중 어디에 둬야 하나요?

전역, 즉 ~/.config/opencode/opencode.json입니다. OpenCode는 설정 파일을 병합하므로, 프로바이더를 전역에서 한 번만 선언하고 프로젝트마다 모델 선택만 설정하면 저장소에 자격 증명 관련 코드가 끼어들지 않고, 중복된 블록이 서로 어긋나는 것도 피할 수 있습니다.

모델이 /models 피커에 나타나지 않는 이유는?

커스텀 프로바이더 모델은 명시적으로 선언해야 합니다. OpenCode는 커스텀 엔드포인트를 스스로 나열할 수 없습니다. models 맵에 버전 접미사까지 포함한 정확한 id 문자열이 있는지 확인하고, 기억으로 입력하는 대신 게이트웨이의 /v1/models 응답에서 id를 복사하세요.

여기서 @ai-sdk/openai-compatible과 @ai-sdk/openai의 차이는 무엇인가요?

@ai-sdk/openai-compatible은 멀티 벤더 게이트웨이가 제공하는 프로토콜인 /v1/chat/completions로 말합니다. @ai-sdk/openai는 OpenAI의 /v1/responses 프로토콜로 말합니다. APIsRouter에는 @ai-sdk/openai-compatible을 사용하세요. 다른 패키지는 이 용도로 게이트웨이가 제공하지 않는 경로에 요청을 보냅니다.

선언한 컨텍스트 한도가 실제로 중요한가요?

네. OpenCode는 세션에 압축이 필요한 시점을 판단할 때 limit.context를 사용합니다. 긴 컨텍스트 모델에 한도를 선언하지 않으면 세션이 필요 이상으로 일찍 요약됩니다. limit.context와 limit.output을 모델이 실제로 지원하는 값으로 설정하세요.