본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 18. 04:24

어떻게 토큰 100만 개당 $0.27로 문서 QA를 출시했는가 — 한 CTO의 일기

요약

문서 Q&A 서비스의 높은 운영 비용 문제를 해결하기 위해 CTO가 실행한 아키텍처 최적화 과정을 다룹니다. 특정 벤더 종속성을 탈피하고 OpenAI 호환 인터페이스를 통한 추상화 계층을 구축하여 비용을 획기적으로 절감한 사례를 공유합니다.

핵심 포인트

  • 특정 모델에 종속된 프롬프트와 에러 핸들링은 기술 부채가 됨
  • OpenAI 호환 인터페이스를 통한 추상화 계층 구축의 중요성
  • 설정 변경만으로 모델을 교체할 수 있는 유연한 아키텍처 설계
  • 비용 절감을 위한 모델별 토큰 단가 및 컨텍스트 분석 필요성

어떻게 토큰 100만 개당 $0.27로 문서 QA를 출시했는가 — 한 CTO의 일기

2025년 말, 재무 책임자로부터 받은 Slack 메시지를 여전히 기억합니다. 우리의 문서 Q&A 비용이 그달에 5자리를 넘어섰고, 비용 소모율 (burn rate)은 가속화되고 있었습니다. 솔직히 말해서, 그저 미화된 검색 파이프라인 (retrieval pipeline)에 불과한 것에 우리는 입력 토큰 100만 개당 $2.50, 출력 토큰 100만 개당 $10.00를 지불하고 있었습니다. 그때 저는 문제가 생겼음을 직감했고, 본격적인 아키텍처 작업이 시작되었습니다.

이것은 교과서적인 설명서가 아닙니다. 이것은 제가 실제로 무엇을 했는지, 무엇이 실패했는지, 그리고 우리의 문서 Q&A 인프라를 통제 불능의 비용 센터에서 이사회가 심장마비를 일으키지 않고도 Series A 전망치까지 확장 가능한 수준으로 만들기 위해 실행했던 정확한 수치들에 대한 기록입니다. 제가 이 글을 1인칭으로 쓰는 이유는 솔직히 시중에 나와 있는 문서들이 너무 깔끔하기 때문입니다. 실제 CTO의 삶은 훨씬 더 무질서합니다.

아무도 경고해주지 않는 벤더 종속 (Vendor Lock-In)의 함정

우리가 처음 문서 Q&A 기능을 구축했을 때, 우리는 대부분의 스타트업이 하는 방식을 따랐습니다. 명백한 기본 옵션을 선택하고, 모든 것을 단일 제공업체의 SDK를 통해 연결한 뒤, 프로덕션에 출시했습니다. 빠른 반복 (iteration)은 좋았습니다. 함정은 6개월 뒤, 사용량이 실제 규모가 되고 고객들이 비용을 지불하기 시작할 때, 갑자기 이해할 수 없는 청구서를 마주하게 될 때 나타납니다.

문제는 단지 비용만이 아닙니다. 제공업체를 교체하는 것을 몇 주간의 마이그레이션 작업으로 만들어버리는 가설들을 코드베이스에 박아 넣었다는 점입니다. 당신의 프롬프트 (prompts)는 특정 모델의 동작에 맞춰 튜닝되어 있습니다. 당신의 에러 핸들링 (error handling)은 특정 제공업체의 장애 모드 (failure modes)를 가정하고 있습니다. 당신의 전체 RAG 파이프라인은 특정 함수 호출 (function-calling) 의미론을 기대합니다. 벤더 종속 (Vendor lock-in)은 단순히 가격 문제가 아닙니다. 그것은 무시할 때마다 매 분기 악화되는 누적된 기술 부채 (technical debt)입니다.

제가 찾아낸 해결책은 개념적으로는 간단하지만 실행하기에는 번거로운 것이었습니다. 모든 것을 OpenAI 호환 인터페이스 (OpenAI-compatible interface)를 통해 라우팅하여, 기반이 되는 제공업체 (provider)가 리팩터링 (refactor) 대상이 아닌 설정 변경 (config change)만으로 바뀌도록 만드는 것이었습니다. 이것이 현재 제 전체 스택이 https://global-apis.com/v1을 가리키고 있는 이유입니다. 하나의 베이스 URL (base URL), 184개의 모델, 그리고 애플리케이션 코드를 전혀 건드리지 않고도 DeepSeek, Qwen, 그리고 다음 주 화요일에 출시될 새로운 모델 사이에서 A/B 테스트를 수행할 수 있습니다.

이 글 전체에서 단 한 가지만 기억해야 한다면, 바로 이것입니다. 추상화 계층 (abstraction layer)은 당신이 내릴 수 있는 가장 중요한 아키텍처 결정입니다. 모델도, 벡터 데이터베이스 (vector database)도, 청킹 전략 (chunking strategy)도 아닙니다. 바로 추상화 계층입니다.

내가 전환하게 만든 수치들

단 하나의 요청을 옮기기 전에도 저는 제대로 된 비용 분석을 수행했습니다. 제가 2주 동안 계속해서 허점을 찾아내며 Notion에 기록해 두었던 표는 다음과 같습니다:

모델입력 ($/M)출력 ($/M)컨텍스트 (Context)
DeepSeek V4 Flash0.271.10128K
...

이 목록에서 가장 저렴한 옵션과 가장 비싼 옵션 사이의 가격 차이는 입력에서 약 9배, 출력에서 약 12.5배에 달합니다. 그리고 이들은 성능이 떨어지는 모델들이 아닙니다. DeepSeek V4 Pro는 200K의 컨텍스트를 제공하는데, 이는 우리가 프리미엄 가격을 지불하며 사용하던 것보다 유의미하게 더 큽니다. 입력 비용이 $0.20인 GLM-4 Plus는 순수하게 비용 관점에서 볼 때 정말 말도 안 되는 수준입니다.

대규모 문서 Q&A 워크로드 (workload)를 예측했을 때, 수치는 명확한 이야기를 들려주었습니다. GPT-4o에서 단순 조회용 DeepSeek V4 Flash와 복잡한 멀티홉 추론 (multi-hop reasoning) 질문용 DeepSeek V4 Pro의 혼합 구성으로 전환함으로써 40-65%의 비용 절감을 달성했습니다. 이는 이론적인 수치가 아니라, 60일간의 실제 사용 텔레메트리 (telemetry)를 바탕으로 예측된 결과입니다. 동일한 질문, 동일한 문서, 동일한 사용자 패턴을 유지하면서 오직 더 나은 라우팅 (routing)만 적용했을 뿐입니다.

품질 또한 급락하지 않았습니다. 우리는 이전 베이스라인 (baseline) 대비 혼합 구성에서 평균 84.6%의 벤치마크 점수를 유지했습니다. 시리즈 C 투자를 유치하지 못한 스타트업에게 이 정도의 트레이드오프 (tradeoff)는 명백한 선택지입니다.

나의 실제 프로덕션 스택 (Production Stack)

AI와 관련이 없는 아키텍처 부분으로 여러분을 지루하게 만들지는 않겠습니다. 하지만 구체적인 LLM 레이어(LLM layer)의 형태는 다음과 같습니다.

문서 인제스션 (Document ingestion): PDF, DOCX, HTML 파일이 들어옵니다. 우리는 200 토큰의 오버랩 (overlap)을 포함하여 800 토큰 단위로 청킹 (chunking)을 수행합니다. 임베딩 (Embeddings)은 벡터 스토어 (vector store)로 전송됩니다 (이 이야기의 흥미로운 부분은 아닙니다).

리트리벌 (Retrieval): 상위 10개의 시맨틱 검색 (semantic search) 결과를 가져온 뒤, 상위 4개로 리랭킹 (rerank)하여 컨텍스트 (context)로 입력합니다. 표준적인 방식입니다.

LLM 호출 (The LLM call): 아키텍처 결정이 실제로 중요한 지점입니다. 우리는 계층형 시스템 (tiered system)을 운영합니다. "4절의 취소 정책은 무엇인가요?"와 같은 단순한 사실 확인 (factual lookups)은 가장 저렴하고 실행 가능한 모델로 보냅니다. 다중 문서 합성 (Multi-document synthesis) 및 추론 (reasoning) 작업은 더 무거운 모델로 라우팅 (route)합니다. 분류 (Classification) 및 추출 (extraction) 작업은 가장 빠른 모델로 보냅니다. 단일 모델이 모든 것을 처리하지는 않는데, 그럴 필요가 없기 때문입니다.

핵심 요소: 모든 모델 호출은 동일한 OpenAI 호환 인터페이스 (OpenAI-compatible interface)를 거칩니다. 동일한 클라이언트 라이브러리 (client library)를 사용하고, 동일한 함수 시그니처 (function signature)를 사용합니다. 바뀌는 유일한 것은 설정 파일 (config file) 내의 문자열뿐입니다.

코드: 내가 실제로 작성한 것

다음은 우리 LLM 통합 코드의 약 90%를 차지하게 된 파이썬 (Python) 스니펫 (snippet)입니다. 대략적인 전체 모습은 다음과 같습니다:

import openai
import os

...

이것이 전부입니다. 이것이 통합의 전체 과정입니다. OpenAI 호환 방식을 채택했기 때문에 SDK는 표준을 따르고, 호출 시그니처도 표준이며, 모델을 마이그레이션 (migrating)하는 것은 말 그대로 문자열 하나를 바꾸는 일입니다. 추론 계층 (reasoning tier)에서 DeepSeek V4 Pro와 GLM-4 Plus를 A/B 테스트하고 싶을 때, 그것은 설정 플래그 (config flag) 하나로 해결됩니다. 새로운 모델이 출시되면 한 시간 이내에 프로덕션 (production) 환경에 적용할 수 있습니다.

비용 효율적인 (cost-aware) 버전은 다음과 같습니다:

def route_question(question: str, context_chunks: list[str]) -> str:
    is_simple = len(question) < 80 and not requires_synthesis(question)

...

실제로 우리 트래픽의 약 60%는 Flash 티어(tier)로 향하게 됩니다. 그것만으로도 엔지니어링 시간을 투자할 가치가 충분했습니다. 우리 정도의 규모에서는, 요청의 60%를 $2.50/$10.00 모델 대신 $0.27 입력 / $1.10 출력 모델로 라우팅(routing)하는 것만으로도 연간 수십만 달러의 차이를 만들어냅니다. 계산 결과는 매우 명확합니다.

실제 비용 최적화 플레이북 (Playbook)

영향력이 큰 순서대로, 실제로 우리에게 유의미한 변화를 가져다준 요소들은 다음과 같습니다:

1. 공격적인 캐싱 (Caching). 안정적인 상태에서 우리의 캐시 히트율(cache hit rate)은 약 40%를 유지하고 있습니다. 문서들은 반복적으로 쿼리(query)됩니다. 사람들은 자신의 계약서, 인사(HR) 문서, 온보딩 가이드에 대해 똑같은 질문을 던집니다. (document_id, question_embedding)의 해시(hash)를 키(key)로 사용하는 간단한 Redis 캐시는 하룻밤 사이에 LLM 호출의 5분의 2를 제거했습니다. 우리 규모에서 캐싱의 ROI(투자 대비 수익)는 항상 양수입니다. 언제나 말이죠.

2. 모든 것을 스트리밍 (Streaming) 하기. 한 번은 주니어 엔지니어가 이것이 복잡성을 더한다며 반대했던 적이 있습니다. 저는 그들에게 실제 지연 시간(latency)보다 체감 지연 시간이 더 중요하다는 점을 상기시켜 주어야 했습니다. 사용자들은 로딩 스피너(spinner)가 돌아가는 것을 기다리는 것을 싫어합니다. 하지만 텍스트가 단어 하나하나씩 나타나는 것은 참아줍니다. 스트리밍은 실제 지연 시간은 거의 변하지 않았음에도 불구하고 체감 지연 시간을 약 60% 감소시켰습니다. UX(사용자 경험)는 단순한 다듬기 작업이 아니라 ROI를 높이는 레버(lever)입니다.

3. 계층형 모델 라우팅 (Tiered model routing). 위에서 이미 다루었지만, 반복할 가치가 있습니다. 작업을 처리할 수 있는 가장 저렴한 모델을 사용하세요. 우리는 트래픽의 60%를 입력당 $0.27인 DeepSeek V4 Flash로 라우팅하며, 정말로 어려운 작업들만 Pro 티어(tier)로 보냅니다. 만약 모든 요청을 가장 비싼 모델로 보내고 있다면, 당신은 아키텍처(architecture)를 고민하는 것이 아니라 그냥 수표를 써 내려가고 있는 것입니다.

4. 출력 토큰 규율 (Output token discipline). 사람들이 끊임없이 놓치는 부분입니다. 모든 출력 토큰은 비용을 발생시킵니다. 우리는 "상세히 설명해 주세요"라고 적힌 프롬프트를 사용했는데, 이로 인해 200개 토큰이면 충분했을 답변이 1,500개 토큰으로 부풀어 올랐습니다. 시스템 프롬프트(system prompt)에 "별도의 요청이 없는 한 2~3문장으로 답변하세요"라는 문구를 추가하자 평균 출력 토큰이 거의 절반으로 줄었습니다. 품질은 동일하면서 비용은 절반이 된 것입니다. 시스템 프롬프트는 제품의 표면적(product surface area)입니다.

5. 모니터링 및 피드백 루프 (Monitoring and feedback loops). 우리는 모든 응답에 있는 따봉/역따봉(thumbs-up/thumbs-down) 버튼을 통해 사용자 만족도를 추적합니다. 환각 (hallucinations) 현상은 별도의 평가 파이프라인 (eval pipeline)을 통해 추적합니다. 질문당 비용은 대시보드에서 추적합니다. 측정 없이는 추측만 할 뿐이며, 대규모 환경에서의 추측은 돈을 빠르게 태워버립니다.

6. 속도 제한 시의 우아한 성능 저하 (Graceful degradation on rate limits). 모든 제공업체는 결국 당신에게 속도 제한 (rate-limit)을 걸 것입니다. 우리는 지수 백오프 (exponential backoff)를 사용하여 재시도하고, 그다음에는 캐시된 응답 (cached response)으로 전환하며, 마지막에는 "죄송합니다, 다시 시도해 주세요"라는 메시지로 전환하는 폴백 로직 (fallback logic)을 갖추고 있습니다. 사용자는 절대 500 에러를 보지 못합니다. 그것이 데모가 아닌, 프로덕션급 (production-ready) 시스템입니다.

처리량과 지연 시간: 실제 프로덕션의 모습

우리의 일반적인 문서 질문에 대한 평균 엔드 투 엔드 (end-to-end) 지연 시간 (latency)은 약 1.2초 내외입니다. 여기에는 검색 (retrieval), 재순위화 (reranking), 그리고 LLM 호출이 포함됩니다. 처리량 (throughput)은 Flash 티어의 경우 초당 약 320개 토큰을 기록하며, 이는 우리의 사용 사례에 충분하고도 남는 수준입니다. Pro 티어는 더 느리지만, 그쪽으로 보내는 요청은 적습니다.

이 수치들은 마법이 아닙니다. 과도한 엔지니어링 (overengineering)을 멈추고 측정을 시작할 때 얻게 되는 결과물입니다. 가장 빠른 아키텍처 (architecture)는 불필요한 단계가 가장 적은 아키텍처입니다. 복잡성 비용 (complexity cost)을 정당화하지 못하는 모든 추상화 (abstraction)는 삭제되어야 합니다.

솔직히 말씀드리면, 우리 시스템의 첫 번째 버전은 지연 시간이 약 40% 더 높았습니다. 우리는 중복된 임베딩 (embedding) 호출을 하고 있었고, 재순위화 (re-ranking)를 두 번 수행했으며, 너무 많은 청크 (chunks)를 가져오고 있었습니다. 저는 일주일 동안 이를 깎아내는 데 시간을 보냈고, 지연 시간은 2.1초에서 1.2초로 떨어졌습니다. 교훈은 제가 계속해서 배우고 있는 것과 같습니다. 규모가 커질수록 단순함이 승리합니다.

벤더 종속(Vendor Lock-In) 방지: 장기적인 관점

저는 벤더 종속(Vendor Lock-in) 문제로 다시 돌아가고 싶습니다. 왜냐하면 이것이 CTO로서 제가 가장 많이 고민하는 부분이기 때문입니다. 모델은 계속해서 변할 것입니다. 새로운 제공업체가 등장할 것이고, 가격은 변동될 것이며, 기능 또한 계속해서 바뀔 것입니다. 향후 3년을 살아남는 스타트업은 제품을 새로 다시 쓰지 않고도 이러한 변화에 적응할 수 있는 스타트업입니다.

OpenAI 호환 엔드포인트(endpoint) 계층을 사용하는 것은 우리가 단 하나의 모델 제공업체에 회사의 운명을 걸지 않는다는 것을 의미합니다. 만약 DeepSeek가 가격을 올린다면, 우리는 Qwen으로 이동합니다. 만약 OpenAI가 획기적으로 더 나은 무언가를 출시한다면, 우리는 그쪽으로 경로를 라우팅(route)합니다. 만약 내일 완전히 새로운 모델이 출시되고 벤치마크(benchmark) 결과가 경이롭다면, 우리는 이번 주 말까지 그것을 프로덕션(production)에 적용할 수 있습니다.

이것은 편집증이 아닙니다. 그저 훌륭한 아키텍처(architecture)일 뿐입니다. 추상화 계층(abstraction layer)을 구축하는 비용은 아마도 일주일 정도의 엔지니어링 시간일 것입니다. 하지만 이것을 갖추지 않았을 때의 비용은 선택권(optionality)을 포기하는 것이며, 선택권은 가장...

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0