잘 만든 AI 기능도 비용을 이기지 못하면 오래가지 못한다
AI 기능을 처음 붙일 때는 대부분 품질에 집중합니다. 답변이 자연스러운가, 사용자의 질문을 잘 이해하는가, RAG가 근거를 잘 찾아오는가, 에이전트가 도구를 제대로 호출하는가. 여기까지는 앞 장들에서 충분히 다뤘습니다.
그런데 제품으로 운영하기 시작하면 전혀 다른 질문이 찾아옵니다.
'이 기능을 사용자가 매일 써도 회사가 버틸 수 있을까?'
LLM API는 마법 상자가 아닙니다. 호출할 때마다 비용이 발생합니다. 사용자가 한 명일 때는 몇 원처럼 보이던 비용이, 사용자가 천 명, 만 명으로 늘어나면 서버비보다 더 큰 항목이 될 수 있습니다. 특히 챗봇, 문서 요약기, 고객지원 봇, 에이전트처럼 여러 번 모델을 호출하는 기능은 비용이 조용히, 그러나 빠르게 불어납니다.
이 장의 핵심은 단순합니다. AI 기능은 잘 만드는 것만큼 지속 가능한 비용 구조로 운영하는 것이 중요합니다. 비용 최적화는 '싸구려 모델을 쓰자'가 아닙니다. 같은 품질을 더 적은 토큰, 더 적절한 모델, 더 적은 중복 호출로 만드는 운영 설계입니다.

LLM API 비용은 어디서 생기는가
대부분의 LLM API 요금은 토큰 단위로 계산됩니다. 입력 토큰은 우리가 모델에게 보내는 프롬프트, 시스템 지시문, 대화 이력, RAG 검색 결과입니다. 출력 토큰은 모델이 생성해서 돌려주는 답변입니다. 제공사마다 가격표는 다르지만, 일반적으로 입력과 출력의 단가를 따로 책정하며 공식 가격표에서도 모델별 입력, 출력, 캐시 입력, 배치 처리 같은 항목을 구분해 제공합니다.1
기본 공식은 다음처럼 생각할 수 있습니다.
요청 1회의 비용 = 입력 토큰 수 × 입력 토큰 단가 + 출력 토큰 수 × 출력 토큰 단가
월 비용 = 요청 1회의 평균 비용 × 월 요청 수예를 들어 어떤 모델의 가격이 입력 100만 토큰당 1달러, 출력 100만 토큰당 5달러라고 해 봅시다. 한 요청에서 입력 800토큰, 출력 300토큰을 사용하고, 한 달에 10,000번 호출한다면 비용은 이렇게 계산됩니다.
요청 1회 입력 비용 = 800 / 1,000,000 × 1달러 = 0.0008달러
요청 1회 출력 비용 = 300 / 1,000,000 × 5달러 = 0.0015달러
요청 1회 총비용 = 0.0023달러
월 비용 = 0.0023 × 10,000 = 23달러눈여겨볼 부분은 출력입니다. 입력은 800토큰이고 출력은 300토큰인데, 비용은 출력 쪽이 더 큽니다. 많은 제공사에서 출력 토큰 단가가 입력보다 높습니다. 모델이 답변을 생성할 때는 토큰을 하나씩 만들어야 하기 때문입니다. 즉, 비용 최적화에서 '짧게 입력하기'만큼이나 '필요한 만큼만 출력하게 하기'가 중요합니다. 여러 가격 비교 자료도 제공사와 모델에 따라 토큰 단가 차이가 매우 크며, 출력 토큰이 입력보다 비싼 경우가 흔하다고 설명합니다.2
운영자가 가장 먼저 봐야 할 숫자는 세 가지입니다.
요청당 평균 입력 토큰 수
요청당 평균 출력 토큰 수
하루 또는 한 달 요청 수
이 셋을 모르면 비용을 줄일 수 없습니다. 반대로 이 셋을 정확히 알면 어느 지점에서 비용이 새고 있는지 보이기 시작합니다.
프롬프트 길이는 곧 청구서 길이다
LLM 서비스의 첫 번째 비용 누수는 프롬프트입니다. 개발 단계에서는 시스템 프롬프트에 온갖 지시를 넣기 쉽습니다. '친절하게 답하라', '정확하게 답하라', '전문가처럼 답하라', '절대 거짓말하지 말라', '다음 형식을 지켜라', '아래 예시를 참고하라' 같은 문장이 계속 붙습니다.
문제는 시스템 프롬프트가 보통 모든 요청에 반복해서 포함된다는 점입니다. 1,500토큰짜리 시스템 프롬프트가 있고 하루 10,000번 호출된다면, 하루에 1,500만 입력 토큰이 시스템 프롬프트만으로 발생합니다. 사용자의 실제 질문과 무관하게 매번 내는 '토큰 세금'입니다.
프롬프트를 줄일 때는 무작정 짧게 만들면 안 됩니다. 모델의 행동을 바꾸는 지시와 그냥 멋있어 보이는 문장을 구분해야 합니다. 예를 들어 다음 문장은 길지만 정보가 중복되어 있습니다.
당신은 고객에게 친절하고 정중하며 전문적으로 답변하는 고객지원 상담원입니다.
사용자의 감정을 고려하고, 공손한 말투를 유지하며, 가능한 한 정확하고 도움이 되는 답변을 제공해야 합니다.
모르는 내용은 지어내지 말고 모른다고 말해야 하며, 추가로 도와줄 것이 있는지 마지막에 물어보세요.운영용 프롬프트에서는 이렇게 줄일 수 있습니다.
고객지원 상담원. 정중하고 정확하게 답하라. 모르면 모른다고 말하라. 마지막에 추가 도움이 필요한지 묻는다.의미는 거의 유지하면서 토큰은 줄어듭니다. 물론 모든 프롬프트를 이렇게 압축할 수 있는 것은 아닙니다. 법률, 의료, 보안처럼 규칙이 중요한 분야에서는 필요한 제한 조건을 남겨야 합니다. 하지만 많은 서비스에서는 장황한 설명보다 간결한 계약이 더 안정적으로 작동합니다.
프롬프트 최적화에서 특히 효과적인 방법은 다음과 같습니다.
반복되는 배경 설명을 줄이고, 요청마다 달라지는 정보만 남긴다.
few-shot 예시는 꼭 필요한 개수만 넣는다.
출력 형식을 말로 길게 설명하지 말고 JSON Schema나 구조화 출력으로 강제한다.
대화 이력 전체를 매번 보내지 말고 요약 메모리와 최근 메시지만 보낸다.
답변 길이를 프롬프트와
max_output_tokens양쪽에서 제한한다.
여기서 중요한 것은 비용 절감과 품질 평가를 함께 해야 한다는 점입니다. 프롬프트를 줄였더니 답변 품질이 떨어지고 재시도가 늘어난다면 오히려 더 비싸질 수 있습니다. 좋은 비용 최적화는 한 번에 성공하는 짧은 요청을 만드는 일입니다.
출력 토큰을 통제하라
입력보다 더 위험한 것은 출력입니다. 사용자가 'Docker가 뭐야?'라고 물었는데 모델이 역사, 내부 구조, 장점, 단점, 설치법, 예시 명령어까지 줄줄이 답하면 사용자는 고마울 수도 있지만 운영자는 비용을 냅니다.
출력 토큰을 줄이는 가장 간단한 방법은 답변 길이를 명시하는 것입니다.
나쁜 예:
Docker가 무엇인지 설명해 줘.
좋은 예:
Docker를 처음 듣는 개발자에게 3문장 이내로 설명해 줘.분류나 추출 작업에서는 자연어 답변을 요구하지 않는 편이 좋습니다. 예를 들어 사용자의 문의가 결제 문제인지, 배송 문제인지, 환불 문제인지 분류하는 기능이라면 긴 설명은 필요 없습니다.
{
"category": "refund",
"confidence": 0.86
}이런 구조화 출력은 두 가지 장점이 있습니다. 첫째, 출력 토큰이 줄어듭니다. 둘째, 후속 코드가 안정적으로 처리할 수 있습니다. 앞에서 배운 구조화 출력과 Function Calling은 품질을 위한 기술이면서 동시에 비용 절감 기술이기도 합니다.
API 호출에서도 출력 한도를 반드시 설정해야 합니다. 이름은 제공사마다 max_tokens, max_output_tokens처럼 조금씩 다르지만 의미는 비슷합니다. 모델이 생성할 수 있는 최대 길이를 제한하는 장치입니다.
def call_llm(client, messages):
return client.responses.create(
model='low-cost-model',
input=messages,
max_output_tokens=300,
temperature=0.2,
)출력 한도는 너무 낮아도 문제입니다. 답변이 중간에 끊기면 사용자가 다시 요청하고, 결국 한 번 더 비용을 냅니다. 따라서 기능별로 적절한 출력 한도를 정해야 합니다. 상품 리뷰 감성 분석은 50토큰이면 충분할 수 있고, PDF 요약은 800토큰이 필요할 수 있습니다. 모든 기능에 같은 한도를 적용하는 것은 좋은 운영이 아닙니다.
모든 요청을 최고 성능 모델에 보내지 않는다
비용 최적화에서 가장 큰 지렛대는 모델 선택입니다. LLM API 가격은 모델과 제공사에 따라 크게 다릅니다. 어떤 모델은 빠르고 저렴하지만 복잡한 추론에는 약하고, 어떤 모델은 깊은 사고와 코딩에 강하지만 단가가 높습니다. 따라서 '가장 좋은 모델 하나'를 고르는 방식보다 '작업에 맞는 모델을 고르는 방식'이 더 현실적입니다.
이를 모델 라우팅이라고 합니다. 애플리케이션이 요청의 종류나 난이도를 보고 적절한 모델로 보내는 구조입니다.
| 작업 유형 | 예시 | 추천 전략 |
|---|---|---|
| 단순 분류 | 감성 분석, 카테고리 분류, 스팸 판단 | 저비용 모델 |
| 형식 변환 | 자연어를 JSON으로 변환, 날짜 형식 정리 | 저비용 모델 |
| 짧은 요약 | 고객 문의 3줄 요약 | 저비용 또는 중간 모델 |
| 문서 기반 답변 | 사내 문서 Q&A, 정책 안내 | 중간 모델 + RAG |
| 복잡한 추론 | 여러 조건 비교, 법률·계약 검토 보조 | 고성능 모델 |
| 코딩·에이전트 | 코드 수정, 다단계 도구 사용 | 고성능 모델 또는 단계별 라우팅 |
중요한 원칙은 '비싼 모델을 쓰지 말자'가 아닙니다. 비싼 모델이 필요한 요청에만 비싼 모델을 쓰자는 것입니다. 간단한 JSON 변환을 최고급 모델에 맡기는 것은 스포츠카로 편의점 심부름을 가는 것과 비슷합니다.
아주 단순한 라우터는 다음처럼 만들 수 있습니다.
def choose_model(task_type: str, user_tier: str) -> str:
if task_type in ['classification', 'extraction', 'formatting']:
return 'cheap-model'
if task_type in ['summary', 'support_chat']:
return 'balanced-model'
if task_type in ['complex_reasoning', 'coding_agent', 'legal_review']:
if user_tier == 'paid':
return 'strong-model'
return 'balanced-model'
return 'balanced-model'조금 더 발전시키면 저비용 모델이 먼저 난이도를 판정하게 할 수 있습니다.
def route_request(client, user_message: str):
label = client.responses.create(
model='cheap-model',
input=f'Classify as simple or complex only: {user_message}',
max_output_tokens=10,
temperature=0,
).output_text.strip().lower()
model = 'strong-model' if 'complex' in label else 'cheap-model'
return client.responses.create(
model=model,
input=user_message,
max_output_tokens=500,
)실제 제품에서는 이보다 더 정교해야 합니다. 기능별 평가 데이터셋을 만들고, 각 모델이 어느 정도 품질을 내는지 비교해야 합니다. 특정 모델이 10배 싸더라도 오류율이 2배 높아져 고객지원 티켓이 늘어난다면 싼 것이 아닙니다. 반대로 품질 차이가 거의 없는 작업이라면 고성능 모델을 계속 쓰는 것이 낭비입니다.
모델 라우팅은 비용뿐 아니라 제품 정책과도 연결됩니다. 무료 사용자는 저비용 모델과 짧은 컨텍스트를 사용하고, 유료 사용자는 더 긴 문맥과 고성능 모델을 사용할 수 있습니다. 이렇게 하면 비용이 매출 구조와 맞물립니다.
캐싱: 같은 비용을 두 번 내지 않기
비용 최적화에서 캐싱은 가장 직관적인 전략입니다. 이미 계산한 답을 다시 계산하지 않는 것입니다.
일반적인 웹 서비스에서도 캐시는 중요하지만, LLM에서는 더 중요합니다. 한 번의 API 호출이 데이터베이스 조회보다 훨씬 비쌀 수 있기 때문입니다. FAQ 챗봇에서 '비밀번호를 잊어버렸어요'와 '비밀번호 재설정은 어떻게 하나요?'는 표현만 다를 뿐 같은 질문입니다. 매번 LLM을 호출하지 않아도 됩니다.
캐싱은 크게 세 단계로 생각할 수 있습니다.
첫째, 정확히 같은 요청을 캐싱합니다. 프롬프트와 모델, 온도 같은 설정이 같고 deterministic한 작업이라면 응답을 저장해 둘 수 있습니다. 분류, 추출, 형식 변환 같은 작업에 잘 맞습니다.
import hashlib
import json
cache = {}
def cache_key(model: str, messages: list, temperature: float) -> str:
raw = json.dumps({
'model': model,
'messages': messages,
'temperature': temperature,
}, sort_keys=True, ensure_ascii=False)
return hashlib.sha256(raw.encode('utf-8')).hexdigest()
def cached_call(client, model, messages, temperature=0):
key = cache_key(model, messages, temperature)
if key in cache:
return cache[key]
response = client.responses.create(
model=model,
input=messages,
temperature=temperature,
)
cache[key] = response.output_text
return response.output_text둘째, 의미가 비슷한 요청을 캐싱합니다. 이를 semantic caching이라고 부릅니다. 사용자의 질문을 임베딩으로 바꾼 뒤, 이전 질문과 의미적으로 충분히 가까우면 기존 답변을 재사용합니다. 고객지원, 도움말, 정책 안내처럼 반복 질문이 많은 서비스에서 효과적입니다. 여러 운영 자료에서도 semantic caching과 모델 라우팅을 비용과 지연 시간을 함께 낮추는 주요 전략으로 설명합니다.3
셋째, 제공사 수준의 프롬프트 캐싱을 활용합니다. 일부 API는 반복되는 프롬프트 prefix, 즉 앞부분이 같은 입력에 대해 캐시된 입력 단가를 적용합니다. 이때 중요한 요령은 변하지 않는 내용을 앞에 두는 것입니다. 시스템 프롬프트, 도구 설명, 고정 예시, 공통 정책 문서를 앞에 두고, 사용자마다 달라지는 질문은 뒤에 둡니다.
좋은 순서:
1. 고정 시스템 프롬프트
2. 고정 도구 설명
3. 고정 예시
4. 사용자별 질문
나쁜 순서:
1. 사용자별 ID와 현재 시각
2. 고정 시스템 프롬프트
3. 고정 예시
4. 사용자 질문앞부분에 매번 바뀌는 값이 들어가면 캐시가 잘 맞지 않을 수 있습니다. 현재 시각, 요청 ID, 사용자별 랜덤 문자열은 꼭 필요한 경우가 아니라면 프롬프트 앞부분에 넣지 않는 편이 좋습니다.
대화 이력은 계속 들고 다니면 비싸진다
챗봇은 대화가 길어질수록 비용이 커집니다. 사용자가 20번 대화하면 20번째 요청에는 앞의 19번 대화가 함께 들어갈 수 있습니다. 첫 번째 메시지는 한 번만 보낸 것 같지만 실제로는 이후 모든 요청에 반복되어 다시 청구됩니다.
이 문제를 해결하는 가장 단순한 방법은 최근 대화만 남기는 것입니다.
def trim_messages(messages, keep_last=8):
return messages[-keep_last:]하지만 이 방식은 오래된 중요한 정보를 잃습니다. 사용자가 대화 초반에 '나는 채식주의자야'라고 말했는데 나중에 식당 추천을 요청하면, 해당 정보가 잘려 나가 잘못된 답을 할 수 있습니다.
더 나은 방식은 요약 메모리입니다. 오래된 대화는 그대로 버리지 말고, 사용자 선호와 결정된 사실만 짧은 메모리로 압축합니다.
대화 메모리:
- 사용자는 채식 위주의 식단을 선호한다.
- 예산은 1인당 2만 원 이하를 원한다.
- 강남역 근처 식당을 찾고 있다.그 다음 요청에는 전체 대화 대신 요약 메모리와 최근 메시지만 보냅니다.
시스템 지시문
+ 대화 메모리
+ 최근 4~8개 메시지
+ 현재 사용자 질문이 구조는 비용과 품질의 균형이 좋습니다. 다만 요약 메모리도 잘못 만들면 오류가 누적됩니다. 따라서 중요한 사실, 사용자의 명시적 선호, 결정된 작업 상태를 중심으로 저장하고, 모델의 추측은 메모리에 넣지 않는 것이 좋습니다.
RAG 비용은 LLM 호출 비용만이 아니다
RAG는 환각을 줄이고 최신 문서를 활용하기 위한 강력한 구조입니다. 하지만 비용 관점에서는 새로운 비용 항목이 생깁니다. RAG 비용은 크게 세 주머니로 나뉩니다.
첫 번째는 임베딩 생성 비용입니다. 문서를 청크로 나누고 각 청크를 벡터로 바꿀 때 비용이 듭니다. 문서가 자주 바뀌지 않는다면 한 번 임베딩한 결과를 저장하고 재사용해야 합니다. 같은 문서를 매번 다시 임베딩하는 것은 대표적인 낭비입니다.
두 번째는 벡터 데이터베이스 비용입니다. 벡터를 저장하는 공간, 인덱스, 검색 요청, 백업과 운영 비용이 발생합니다. 벡터 개수가 많아질수록 저장 비용과 검색 비용도 늘어납니다.
세 번째는 검색된 청크가 프롬프트에 추가되며 생기는 입력 토큰 비용입니다. 실제 운영에서는 이 세 번째 비용이 특히 중요합니다. RAG가 검색한 청크 10개를 모두 프롬프트에 넣으면 답변 품질이 좋아질 것 같지만, 비용과 지연 시간은 늘고 오히려 모델이 핵심 근거를 놓칠 수도 있습니다.
RAG 비용을 줄이는 핵심 파라미터는 다음과 같습니다.
청크 크기: 너무 작으면 맥락이 잘리고, 너무 크면 불필요한 토큰이 늘어난다.
overlap: 문맥 보존에는 도움이 되지만 벡터 개수와 중복 토큰을 늘린다.
top-k: 많이 가져올수록 근거 후보는 늘지만 프롬프트 비용도 증가한다.
재랭킹 여부: 후보를 많이 찾은 뒤 더 정확히 추려 LLM에 적게 보낼 수 있다.
문서 갱신 주기: 변경된 문서만 다시 임베딩해야 한다.
예를 들어 top_k=10으로 청크 10개를 모두 LLM에 넣는 대신, 먼저 30개 후보를 빠르게 검색하고 재랭커가 상위 4개만 고르게 할 수 있습니다. 재랭킹 비용과 지연 시간이 추가되지만, LLM에 들어가는 토큰이 줄어 전체 비용이 낮아질 수 있습니다. RAG 운영 자료에서도 LLM 생성 비용이 전체 비용의 큰 비중을 차지하는 경우가 많고, 더 적고 정확한 청크를 넘기는 전략이 비용에 직접 영향을 준다고 설명합니다.4
RAG의 비용 최적화는 '무조건 적게 검색하기'가 아닙니다. 정확한 근거를 적게 넣는 것입니다. 근거가 부족해 모델이 헛소리를 하고, 사용자가 다시 질문하고, 사람이 검수해야 한다면 그 비용도 결국 제품 비용입니다.
배치 처리는 기다릴 수 있는 일을 싸게 처리한다
모든 LLM 요청이 즉시 답해야 하는 것은 아닙니다. 사용자가 화면에서 기다리는 채팅 답변은 빠르게 처리해야 하지만, 밤에 10,000개 상품 설명을 생성하거나, 지난달 고객 문의를 분류하거나, 문서 요약을 미리 만들어 두는 작업은 몇 시간 기다려도 됩니다.
이런 작업에는 배치 처리가 적합합니다. 일부 제공사는 비동기 배치 API에 할인된 요금을 제공합니다. 공식 가격표에서도 표준 처리 외에 배치나 캐시 입력 같은 별도 가격 항목을 제공하는 경우가 있습니다.1
배치 처리에 어울리는 작업은 다음과 같습니다.
대량 문서 요약
로그 분류와 라벨링
상품 설명 생성
평가 데이터셋 자동 채점
매일 밤 생성하는 리포트
반대로 실시간 고객지원 답변, 결제 직전의 상품 추천, 사용자가 기다리는 코드 생성에는 배치 처리가 맞지 않습니다. 비용 최적화는 사용자 경험을 망치지 않는 선에서 해야 합니다. 기다릴 수 있는 일은 싸게, 즉시 필요한 일은 빠르게 처리하는 식으로 작업을 나누는 것이 좋습니다.
비용을 모르면 최적화할 수 없다
많은 팀이 비용 최적화를 늦게 시작합니다. 월말 청구서를 보고 놀란 뒤에야 로그를 뒤집니다. 하지만 그때는 이미 돈이 나간 뒤입니다.
운영 단계에서는 LLM 호출 로그를 반드시 남겨야 합니다. 로그에는 최소한 다음 정보가 있어야 합니다.
사용자 ID 또는 조직 ID
기능 이름
모델 이름
입력 토큰 수
출력 토큰 수
총 비용 추정치
응답 시간
캐시 적중 여부
RAG 검색 청크 수
오류와 재시도 횟수
이 정보가 있으면 기능별 비용을 볼 수 있습니다. 블로그 글 생성기가 비싼지, PDF 요약기가 비싼지, 고객지원 챗봇이 비싼지 알 수 있습니다. 사용자별 비용도 볼 수 있습니다. 무료 사용자가 유료 사용자보다 더 많은 API 비용을 쓰고 있다면 플랜 정책을 조정해야 합니다.
간단한 비용 계산 함수는 다음처럼 만들 수 있습니다.
MODEL_PRICES = {
'cheap-model': {'input': 0.2, 'output': 1.0},
'balanced-model': {'input': 1.0, 'output': 5.0},
'strong-model': {'input': 3.0, 'output': 15.0},
}
def estimate_cost(model: str, input_tokens: int, output_tokens: int) -> float:
price = MODEL_PRICES[model]
return (
input_tokens / 1_000_000 * price['input']
+ output_tokens / 1_000_000 * price['output']
)실제 운영에서는 가격표를 코드에 하드코딩하기보다 설정 파일이나 데이터베이스로 관리하는 편이 좋습니다. 모델 가격은 바뀝니다. 제공사도 바뀔 수 있습니다. 가격표가 바뀌었는데 코드가 예전 단가로 비용을 추정하면 대시보드는 예쁜 거짓말을 보여 줍니다.
대시보드에는 적어도 다음 그래프가 있어야 합니다.
일별 총비용
모델별 비용
기능별 비용
사용자 또는 조직별 비용
평균 입력·출력 토큰 수
캐시 적중률
RAG top-k와 평균 검색 청크 수
오류율과 재시도 비용
이 지표를 매일 보면 비용 폭증을 빨리 발견할 수 있습니다. 특정 기능 배포 이후 출력 토큰이 두 배가 되었는지, 캐시 적중률이 갑자기 떨어졌는지, 특정 사용자가 자동화 스크립트로 무료 플랜을 과도하게 쓰고 있는지 보입니다.
무료 플랜은 무제한이 아니다
AI 기능을 제품에 넣을 때 가장 위험한 말은 '무료로 마음껏 사용해 보세요'입니다. 일반 SaaS 기능에서는 무료 사용자의 추가 비용이 작을 수 있지만, LLM 기능은 사용량만큼 직접 비용이 발생합니다.
따라서 플랜별 사용량 정책이 필요합니다.
| 플랜 | 가능한 정책 예시 |
|---|---|
| 무료 | 월 50회, 짧은 답변, 저비용 모델, 파일 업로드 제한 |
| 개인 유료 | 월 1,000회, 중간 모델, RAG 사용 가능 |
| 팀 | 조직별 공유 한도, 긴 문서 처리, 우선 처리 |
| 엔터프라이즈 | 별도 계약, 전용 한도, 감사 로그, 비용 리포트 |
사용량 제한은 단순히 돈을 아끼기 위한 장치가 아닙니다. 서비스 안정성을 지키는 장치입니다. 한 사용자의 무한 루프나 악성 요청이 전체 서비스 비용과 속도에 영향을 주면 안 됩니다.
예산 알림도 필요합니다. 월 예산의 50%, 80%, 100%에 도달했을 때 알림을 보내고, 100%를 넘으면 자동으로 저비용 모델로 전환하거나 일부 기능을 제한할 수 있습니다.
def enforce_budget(user, estimated_cost):
if user.monthly_spend + estimated_cost > user.monthly_budget:
raise Exception('Monthly AI budget exceeded')
if user.monthly_spend > user.monthly_budget * 0.8:
return 'cheap-model'
return 'balanced-model'이런 정책은 처음부터 제품 설계에 포함해야 합니다. 나중에 갑자기 제한을 걸면 사용자는 기능이 나빠졌다고 느낍니다. 처음부터 '이번 달 AI 사용량'과 '남은 크레딧'을 보여 주면 사용자는 비용 구조를 이해합니다.
비용과 품질은 함께 최적화해야 한다
비용 최적화의 함정은 숫자만 보는 것입니다. 입력 토큰을 70% 줄였다고 해서 성공이 아닙니다. 답변 정확도가 떨어져 사용자가 같은 질문을 세 번 하게 된다면 실패입니다. 저비용 모델로 바꿨는데 상담원이 다시 확인해야 하는 티켓이 늘었다면 전체 비용은 증가합니다.
좋은 운영팀은 비용과 품질을 함께 봅니다. RAG 시스템에서도 마찬가지입니다. LLM 모델, 임베딩 모델, 재랭커, 청크 크기, top-k, 프롬프트 길이, 출력 한도는 서로 영향을 줍니다. 최근 연구에서도 LLM과 RAG 시스템의 비용, 지연 시간, 안전성, 정렬성을 함께 최적화하는 다목적 접근이 필요하다고 설명합니다.5
실무에서는 다음 순서로 접근하는 것이 안전합니다.
현재 비용을 측정한다. 기능별, 모델별, 사용자별 토큰 사용량을 확인한다.
품질 기준을 정한다. 정확도, 근거 일치율, 사용자 만족도, 재시도율을 함께 본다.
가장 큰 비용 항목부터 줄인다. 보통 출력 길이, 긴 대화 이력, 과도한 RAG 청크, 최고급 모델 남용이 먼저 보인다.
작은 비율로 A/B 테스트한다. 전체 트래픽을 한 번에 바꾸지 않는다.
비용과 품질을 함께 비교한다. 비용은 줄었지만 품질이 무너졌다면 롤백한다.
비용 최적화는 한 번 하고 끝나는 일이 아닙니다. 모델 가격은 바뀌고, 새 모델이 나오고, 사용자의 행동도 바뀝니다. 처음에는 블로그 글 생성기가 가장 비쌌다가, 나중에는 고객지원 챗봇의 사용량이 폭증할 수 있습니다. 운영 단계의 LLM 서비스는 계속 측정하고, 계속 조정해야 합니다.
비용 최적화 체크리스트
마지막으로 지금까지의 내용을 실무 체크리스트로 정리해 보겠습니다.
모든 API 호출에서 입력 토큰, 출력 토큰, 모델, 비용을 로그로 남긴다.
출력 토큰이 비싸다는 점을 전제로
max_output_tokens를 기능별로 설정한다.단순 분류, 추출, 형식 변환은 저비용 모델부터 평가한다.
복잡한 추론, 코딩, 다단계 에이전트 작업만 고성능 모델로 라우팅한다.
시스템 프롬프트를 정기적으로 감사하고 중복 문장을 줄인다.
대화 이력 전체를 보내지 말고 요약 메모리와 최근 메시지를 조합한다.
동일 요청은 정확 캐시로, 유사 질문은 semantic cache로 처리한다.
RAG에서는 청크 크기, overlap, top-k, 재랭킹 여부를 비용과 품질 기준으로 조정한다.
문서 임베딩은 변경된 문서만 다시 생성한다.
비실시간 대량 작업은 배치 처리로 돌린다.
무료/유료 플랜별 사용량 제한과 예산 알림을 둔다.
비용 절감 실험은 반드시 품질 평가와 함께 진행한다.
LLM 비용 최적화는 하나의 기술이 아닙니다. 모델 선택, 프롬프트 압축, 출력 제한, 캐싱, RAG 검색량 조절, 배치 처리, 모니터링, 플랜 설계가 함께 움직이는 운영 설계입니다.
처음 LLM을 배울 때 우리는 모델이 어떻게 다음 토큰을 예측하는지 배웠습니다. 이제 제품을 운영하는 입장에서는 다른 질문을 해야 합니다.
'이 다음 토큰은 정말 돈을 낼 만큼 필요한가?'
이 질문을 습관처럼 던질 수 있다면, 여러분의 AI 서비스는 더 오래 버틸 수 있습니다. 다음 장에서는 비용과 함께 운영의 또 다른 축인 응답 속도를 다룹니다. 사용자는 좋은 답변을 원하지만, 너무 오래 기다리지는 않습니다.
참고
2LLM API Pricing Comparison 2026: The Complete Cost Optimization Guide for Developers
3Reduce LLM Cost and Latency: A Comprehensive Guide for 2026
4RAG in Production 2026: Chunking Strategies, Embedding Costs, and What Actually Works at Scale
5Faster, Cheaper, Better: Multi-Objective Hyperparameter Optimization for LLM and RAG Systems
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.