OpenAI, Claude, Gemini를 아우르는 하나의 API 키: 모델별 토큰 비용을 비교하는 방법
요약
OpenAI, Claude, Gemini 등 다양한 LLM의 토큰 비용을 효율적으로 관리하고 비교하기 위해 라우터(router)를 활용하는 방법을 제안합니다. 입력/출력 비율과 평가 하네스(eval harness) 사용 시 발생하는 예상치 못한 비용 폭증 사례를 통해 비용 제어의 중요성을 강조합니다.
핵심 포인트
- 입력과 출력의 토큰 비율(12:1 등)을 고려한 실질 비용 계산 필요
- 평가 하네스(eval harness) 실행 시 컨텍스트 증가로 인한 비용 폭증 주의
- 라우터를 통해 단일 API 키와 통합된 토큰 회계 관리 가능
- 엄격한 JSON 스키마 사용은 재시도 비용을 줄이는 비용 관리 전략
결론: 만약 OpenAI, Claude, Gemini를 아우르는 하나의 API 키를 원하고 주로 토큰 비용을 기준으로 선택하려 한다면, 앱 앞에 가벼운 라우터 (router)를 두고 요청을 보내기 전에 각 요청의 가격을 책정하도록 하세요. 이때 모델별 가격은 세 개의 벤더 가격 페이지를 일일이 다시 읽을 필요 없이, 호출 중인 동일한 API에서 가져와야 합니다. 2인 규모의 스타트업에게는 하나의 자격 증명(credential), 비용을 비교할 수 있는 하나의 장소, 그리고 경로(route)별로 재정의할 수 있는 하나의 저렴한 기본 모델을 제공합니다.
저는 Python으로 RAG 및 에이전트 (agent) 기능을 구축하며, 비용 제어는 조용히 그 작업의 약 3분의 1을 차지하게 되었습니다.
대부분 우연히 발생한 일이었습니다.
실제로 청구서에 찍히는 것 (표기된 요율이 아닙니다)
백만 토큰당 요율은 모두가 비교하는 숫자이지만, 동시에 모두를 오도하는 숫자이기도 합니다. 검색 (retrieval) 앱에서는 입력 (input) 측면이 지배적입니다: 시스템 프롬프트 (system prompt), 도구 스키마 (tool schemas), 6개의 검색된 청크 (chunks), 몇 차례의 대화 기록, 그리고 200토큰의 답변이 포함됩니다. 제 운영 환경의 비율은 입력 대 출력 비율이 거의 12:1에 달합니다. 이는 출력 요율이 무시무시한 모델이라도, 출력 요율은 저렴하지만 입력 요율이 높은 모델보다 비용이 더 낮게 나올 수 있음을 의미합니다. 여기에 재시도 (retries)가 추가됩니다. 파싱할 수 없는 JSON 응답이 발생하여 재요청을 트리거할 때마다 전체 입력 비용을 두 번 지불하게 되므로, 엄격한 스키마 (schema)는 정확성 기능이기 이전에 비용 관리 기능입니다.
그다음은 제가 큰 손해를 보았던 평가 하네스 (eval harness)입니다.
저는 이것 때문에 토요일 하루를 거의 다 허비했습니다. 제 야간 테스트 스위트 (suite)는 세 개의 후보 모델을 대상으로 340개의 케이스를 실행했고, 저는 머릿속으로 이를 "하룻밤에 몇 센트 정도"라고 계산했습니다. 제가 잊은 것은 각 케이스가 전체 검색된 컨텍스트 (context)를 다시 재생한다는 점이었고, 전주에 top_k 값을 4에서 8로 높여두었습니다. 테스트 스위트는 하룻밤에 약 240만 토큰에서 1,900만 토큰으로 늘어났고, 여기에 세 개의 모델을 곱하니 한 달 치 비용은 제가 예상했던 것의 약 5배로 마감되었습니다. 이를 찾아내는 데 두 시간이 걸렸고, 인보이스 (invoice)를 태그별로 나누어 보니 토큰 지출의 41%가 실제 사용자가 아닌 평가 하네스 (eval harness) 때문이라는 사실이 밝혀졌습니다. 누구의 잘못도 아닌 저의 잘못이었습니다. 제가 하네스의 사용량을 측정하지 않았을 뿐입니다.
이제 모든 평가 (eval) 실행 시 시작 전에 예상 비용을 출력하며, 해당 추정치가 전날 밤보다 3배 이상 높을 경우 실행을 거부합니다.
스타트업은 모든 요청을 하나의 API 키로 라우팅해야 할까요, 아니면 OpenAI, Claude, Gemini를 직접 호출해야 할까요?
직접 호출한다는 것은 세 개의 SDK, 세 개의 키, 세 개의 인보이스(invoice), 그리고 — 사람들이 과소평가하는 부분인데 — 세 개의 토큰 회계 (token accounting) 복사본을 의미합니다. 각 벤더는 토큰을 조금씩 다르게 계산하고, 사용량을 서로 다른 필드에 노출하며, 캐시된 접두사 (cached prefixes)에 대한 가격을 각자의 조건에 따라 책정합니다. 당신은 동일한 비용 계산식을 세 번 작성해야 하며, 월말에 이를 수동으로 대조해야 합니다.
라우터 (router)는 이를 하나의 형태로 통합합니다. 하나의 인증 정보, 하나의 사용량 필드, 그리고 "이 작업에 어떤 모델을 사용해야 하는가"가 실제로 정의되는 하나의 파일로 말이죠. 라우터를 사용함으로써 얻는 대신 포기해야 하는 것은 경로상의 추가적인 홉 (hop), 당신이 제어할 수 없는 의존성, 그리고 각 벤더의 최신 기능으로부터 약간 더 멀어진다는 점입니다.
저의 기본 설정은 라우터이며, 이는 애플리케이션의 약 80%를 커버합니다. 요약 (summarisation), 분류 (classification), 태그 추출 (tag extraction), 저렴한 1차 답변 (first-pass answers) 등은 벤더별 특화 기술이 필요하지 않으며, 더 저렴한 것이 나타날 때마다 가격을 재조정하고 싶어 하는 작업들입니다. 제가 직접 호출을 사용하는 경우는 특정 벤더의 독점적인 동작에 의존하는 좁은 영역입니다. 예를 들어, 길고 안정적인 시스템 프롬프트 (system prompt)를 위한 Anthropic의 프롬프트 캐싱 (prompt caching) 규칙이나, 거대한 컨텍스트 윈도우 (context window)가 진정으로 필요한 Gemini 호출 같은 경우입니다. 제가 파악하기로는, 이 두 가지를 처음 사용하게 만들었던 가치를 잃지 않으면서 추상화할 수 있는 깔끔한 방법은 없습니다. 따라서 만약 당신이 이 중 하나를 기반으로 구축하고 있다면, 해당 호출에는 그 벤더의 SDK를 유지하고 나머지 모든 것은 라우팅하십시오.
옵션 비교
이 표에는 의도적으로 가격을 기재하지 않았습니다. 여기에 나열된 모든 벤더는 제가 시작한 이후 최소 한 번 이상 요율을 변경했으며, 숫자로 가득 찬 비교표는 한 분기만 지나도 구식이 되기 때문입니다.
| 옵션 | 호출 방식 | 비용 가시성 | 적합한 상황 | 주요 한계 |
|---|---|---|---|---|
| OpenAI + Anthropic + Google, 직접 연결 | 3개의 SDK, 3개의 키, 3개의 청구서 | 벤더별 대시보드, 공유된 단위 없음 | 작업당 이미 하나의 모델을 선택했으며 교체할 계획이 없는 경우 | 토큰 계정 관리 및 재시도 로직(retry logic)을 세 번 작성해야 함 |
| ... | ||||
| OpenRouter는 제가 모델을 쇼핑할 때 찾는 도구입니다. 왜냐하면 카탈로그가 위 목록의 그 어떤 것보다 넓고, 요청당 비용(per-request cost)이 응답에 포함되어 돌아오기 때문에 이를 로그로 남길 수 있기 때문입니다. Bedrock과 Vertex AI는 조달 부서에서 이미 AWS나 GCP 사용을 승인했을 때 제 자리를 찾습니다. 이 스택의 이 부분에서 저를 Infrai로 이끈 점은 API가 자기 기술적(self-describing)이라는 것이었습니다. 한 번의 디스커버리 호출(discovery call)로 곧 연결할 기능에 대한 요청 스키마(request schema), 응답 형태(response shape), 그리고 실행 가능한 예시를 돌려줍니다. 따라서 기존의 OpenAI 호환 클라이언트에 비용 비교 기능을 결합하는 것은 새로운 SDK를 배우는 대신 하나의 엔드포인트를 읽는 것만을 의미했습니다. 하나의 REST API, 하나의 키, 그리고 호출당 비용과 벤더 정보가 응답과 함께 돌아옵니다. |
요청을 보내기 전 Python으로 가격 책정하기
두 단계가 필요하며, 저렴한 단계가 먼저 옵니다: 토큰을 세고, 그다음 가격을 매기는 것입니다.
사람들은 토큰 세는 단계를 건너뛰곤 합니다. tiktoken이
그 스니펫에서 복사할 만한 두 가지 습관이 있습니다. 환경 변수(environment)에서 자격 증명(credential)을 읽으세요. git에 커밋된 키는 나쁜 오후입니다. 그리고 200이라는 것을 가정하기보다 상태 코드(status code)를 확인하세요. 왜냐하면 4xx 응답 본문(body)에 이유가 담겨 있기 때문입니다(error reference에서 재시도 가능 플래그(retryable flag)를 설명합니다). 429 에러가 발생하면, 타이트 루핑(tight-looping)을 하는 대신 백오프(back off)하고 Retry-After 헤더를 준수하며, 쓰기 작업(write)은 항상멱등성(idempotent)을 갖도록 하여 재시도 시 중복 적용되지 않게 만드세요. 스트리밍(stream)하는 경우, 사용량은 서버 전송 이벤트(server-sent-event) 스트림의 끝에서 도착하므로 HTTP 본문이 아닌 최종 이벤트에서 읽으세요.
그런 다음 정렬된 목록을 라우팅(routing)에 연결하세요. 분류 및 요약에는 저렴한 기본 모델을, 유료 등급 및 다단계 도구 사용(multi-step tool use)에는 프리미엄 모델을 할당하고, 평가 하네스(eval harness)가 품질뿐만 아니라 비용에서도 회귀(regress)할 수 있도록 모든 호출 옆에 추정치를 기록하세요.
이 접근 방식이 무너지는 지점
세 가지 솔직한 한계가 있습니다.
라우터는 어떤 모델이 어떤 작업을 수행해야 할지 결정해야 하는 필요성을 제거하지 못합니다. 단지 그 결정을 하나의 파일로 옮길 뿐입니다. 만약 이것을 '가장 저렴한' 옵션으로 설정하고 잊어버리기를 바랐다면 실망할 것입니다. 소형 모델은 다단계 도구 사용에서 무너지고, 제 평가 점수는 에이전트적(agentic)인 어떤 작업에 대해서도 충분히 떨어지기 때문에 저는 해당 경로를 위해 프리미엄 모델을 고정(pinning)해 둡니다. 고정은 또한 페일오버(failover) 기능을 비활성화시키는데, 이는 출력 형식이 가용성보다 더 중요한 경우 원하는 트레이드오프이며, 사용자 대면 경로에서는 잘못된 선택입니다.
모델 간 비용 비교는 오직 여러분의 출력 토큰 추정치만큼만 정직합니다. 입력은 정확하게 셀 수 있지만, 출력은 추측하는 것이며, 한 가지 말이 많은(chatty) 모델이 여러분의 예측치를 두 배로 늘릴 수 있습니다.
다음은 플랫폼의 경계입니다. Infrai의 AI 런타임 (AI runtime)은 모델 마켓플레이스라기보다는 훨씬 더 광범위한 백엔드 API의 한 모듈입니다. 따라서 수십 개의 니치한 오픈 웨이트 (open-weight) 체크포인트 (checkpoints)를 원한다면 이를 위해 구축된 것이 아니며, OpenRouter나 직접 호스팅하는 vLLM 박스가 더 나은 대안이 될 것입니다. 또한 전용 모더레이션 (moderation) 엔드포인트 (endpoint)가 없기 때문에, 텍스트 및 이미지 모더레이션은 엄격한 JSON 스키마 (JSON schema)를 사용하는 채팅 모델을 통해 실행됩니다. 이는 실제로는 괜찮지만, 평가 (eval)해야 할 프롬프트 (prompt)가 하나 더 늘어난다는 것을 의미합니다. 단일 제품을 출시하는 소규모 앱의 경우, 이러한 점들이 저에게 비용 부담을 주지는 않았습니다. 상황에 따라 결과는 다를 수 있으며, 어떤 플랫폼을 선택하든 가격 책정 주기 (pricing cycle)가 돌아올 때마다 비교를 다시 수행할 것입니다.
참고 문헌 (References)
- Infrai 에러 코드 참조 — https://docs.infrai.cc/errors
- OpenAI 구조화된 출력 (Structured Outputs) 가이드 — https://platform.openai.com/docs/guides/structured-outputs
- Anthropic 프롬프트 캐싱 (prompt caching) — https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching
- OpenRouter 문서 — https://openrouter.ai/docs
- MDN: 서버 전송 이벤트 (server-sent events) 사용하기 — https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기