# \[프로젝트 소개\] APIGOTO: OpenAI Python SDK에서 base\_url만 바꿔 여러 모델을 같은 코드로 비교하기

**URL:** <https://discuss.pytorch.kr/t/apigoto-openai-python-sdk-base-url/12241>\
**Category:** 읽을거리&정보공유\
**Created:** [10월 19, 2026, 7:04오전 UTC](https://discuss.pytorch.kr/t/apigoto-openai-python-sdk-base-url/12241 "2026-10-19T07:04:40Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![apigoto](https://discuss.pytorch.kr/letter_avatar_proxy/v4/letter/a/e9c0ed/32.png) [@apigoto](https://discuss.pytorch.kr/u/apigoto)\
**Post date:** [10월 19, 2026, 7:04오전 UTC](https://discuss.pytorch.kr/t/apigoto-openai-python-sdk-base-url/12241/1 "2026-10-19T07:04:40Z")

</div>

먼저 밝힙니다. 저는 APIGOTO 팀에서 일합니다. APIGOTO는 OpenAI 호환 API 게이트웨이이고, OpenAI·Anthropic·Google과는 관계없는 독립 서비스입니다. 아래 방법은 vLLM, Ollama 같은 다른 OpenAI 호환 서버에도 그대로 쓸 수 있습니다.

## 1. 연결 확인

```bash
export APIGOTO_API_KEY=...
curl https://api.china-aiapi.com/v1/models -H "Authorization: Bearer $APIGOTO_API_KEY"

```

JSON 모델 목록이 나오면 주소와 키는 정상입니다. 여기서 정확한 모델 ID를 복사해 둡니다(아래 `MODEL_ID_*`).

## 2. SDK에서 바꿀 곳은 두 줄

```python
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.china-aiapi.com/v1",
                api_key=os.environ["APIGOTO_API_KEY"])

```

코드를 고치기 싫다면 `OPENAI_BASE_URL`, `OPENAI_API_KEY` 환경변수만 설정해도 SDK가 읽습니다.

## 3. 같은 프롬프트로 여러 모델 비교

```python
import os, time
from openai import OpenAI

client = OpenAI(base_url="https://api.china-aiapi.com/v1",
                api_key=os.environ["APIGOTO_API_KEY"],
                max_retries=0, timeout=60)

MODELS = ["MODEL_ID_A", "MODEL_ID_B", "MODEL_ID_C"] # /models 결과에서 복사
PROMPT = "PyTorch에서 model.eval()과 torch.no_grad()의 차이를 세 문장으로 설명해 주세요."

for m in MODELS:
    t0 = time.perf_counter()
    try:
        r = client.chat.completions.create(
            model=m, temperature=0, max_tokens=300,
            messages=[{"role": "user", "content": PROMPT}])
    except Exception as e:
        print(f"[{m}] 실패: {e}")
        continue
    dt = time.perf_counter() - t0
    u = r.usage
    print(f"=== {m} | {dt:.2f}s | in={getattr(u,'prompt_tokens','-')} out={getattr(u,'completion_tokens','-')}")
    print(r.choices[0].message.content.strip(), "\n")

```

설계 메모:

- 코드 비교에는 `max_retries=0`을 씁니다. SDK 재시도가 시간 측정에 섞이지 않게 하려는 것입니다.
- 게이트웨이 쪽에서도 업스트림 실패 시 다른 경로로 재시도합니다(최대 3회). 한 모델만 유난히 느리면 요청 로그에서 재시도가 있었는지 먼저 확인하세요.
- 한 번 돌린 결과는 벤치마크가 아닙니다. 여러 번 반복해서 중앙값을 보세요. `temperature=0`이어도 매번 같은 출력이 나오지는 않을 수 있습니다.

## 4. 문제 해결

- 404: `base_url`은 `/v1`까지만 씁니다. `/chat/completions`를 붙이면 경로가 중복됩니다.
- `model not found`: ID는 대소문자와 접미사까지 `/models` 결과와 같아야 합니다.
- 401: 키 앞뒤 공백, 또는 다른 서비스의 키를 넣은 경우.
- `max_tokens` 관련 오류: 일부 모델은 `max_completion_tokens`를 요구합니다.
- `usage`가 비어 있음: 업스트림에 따라 다릅니다. 위 스크립트는 비스트리밍 기준입니다.

제가 쓴 게이트웨이는 base\_url 하나로 여러 모델 계열을 부르고, 요청별 로그를 남기며, 종량제와 BYOK를 지원합니다: [www.china-aiapi.com](https://www.china-aiapi.com/grokbot)

여러 모델을 비교할 때 어떤 프롬프트 세트를 쓰시는지 궁금합니다. 한국어 평가용으로 괜찮은 게 있으면 공유 부탁드립니다.
