🎥 AI 시대 옵저버빌리티 전략 웨비나 | 무료 다시보기 (~4/9)
Top
도입문의
테크
2026-08-14

LLM API 비용이 급증하는 3가지 원인과 토큰 비용 절감 방법

LLM(대규모 언어 모델) API 요금은 서버를 빌릴 때처럼 시간 단위로 과금하지 않습니다. 모델이 글을 잘게 나눠 세는 단위인 토큰을 주고받은 양으로 계산합니다. 그래서 챗봇이나 요약 기능을 붙여 두면 사용자가 질문 하나를 보낼 때마다 요금이 쌓입니다.

사용자 수는 지난달과 비슷한데 금액만 두 배가 되는 일이 생깁니다. 호출 건수를 세어 보면 크게 늘지 않았습니다. 늘어난 쪽은 호출 하나에 담긴 토큰 수입니다.

LLM API의 기본 요금은 입력 토큰과 출력 토큰에 각각 단가를 곱해 계산합니다. 캐시 토큰, 이미지·음성 입력, 도구 사용처럼 별도 단가가 붙는 항목도 있지만, 텍스트 기반 서비스에서는 우선 입력과 출력 토큰을 나눠 보는 것이 출발점입니다. 별다른 배포나 트래픽 변화 없이 비용이 뛰었다면 호출 횟수보다 호출당 입력 토큰을 먼저 확인하는 편이 빠릅니다.

LLM API 비용이 급증하는 3가지 원인과 절감 방법

LLM API 비용은 크게 두 방향에서 늘어납니다. 호출 하나에 담긴 토큰이 많아지거나, 사용자 요청 하나가 여러 번의 API 호출로 번지는 경우입니다. 이 글에서는 대화 이력 누적, 캐시 적중률 하락, 재시도와 에이전트 루프라는 원인 3개로 나눠 살펴봅니다.

1. 대화 이력 누적으로 늘어나는 입력 토큰 (컨텍스트 윈도우 크리프)

일반적인 LLM API 호출은 이전 대화를 자동으로 기억하지 않습니다. 대화를 이어 가려면 애플리케이션이 지난 이력을 다시 보내거나, 제공사가 지원하는 대화 상태 관리 기능을 써야 합니다. 어느 방식을 쓰더라도 모델이 다시 읽는 대화 이력은 입력 토큰에 포함될 수 있습니다.

모델이 한 번에 처리할 수 있는 최대 입력 범위를 컨텍스트 윈도우(context window)라고 합니다. 대화가 길어지면 호출마다 다시 보내는 이력이 늘어나면서 이 범위를 점점 더 많이 차지합니다.

FinOps Foundation은 클라우드 비용 관리 표준을 만드는 리눅스 재단 산하 조직입니다. 2026년 5월 GenAI 토큰 가격 구조를 다룬 글에서 대화가 이어지며 입력이 조금씩 불어나는 현상을 컨텍스트 윈도우 크리프(context window creep)라고 부르고, "프로덕션 AI 애플리케이션에서 가장 큰 숨은 비용"이라고 밝혔습니다. FinOps Foundation은 대화가 길어지면 이력을 다시 보내는 비용이 실제로 생성한 답변의 비용을 넘어선다고 덧붙였습니다.

증가 폭은 계산으로 추정할 수 있습니다. 시스템 프롬프트(모델에 역할과 말투를 지정해 두는 고정 지시문)가 1,000 토큰, 사용자 질문 하나가 200 토큰이고, 한 턴이 끝날 때마다 대화 이력이 400 토큰씩 늘어나는 챗봇을 가정한 계산 예시입니다.

구분 이력 토큰 입력 토큰
첫 번째 호출 0 1,200
10번째 호출 3,600 4,800
20번째 호출 7,600 8,800
20턴 합계 76,000 100,000
대화 이력을 매번 전송하면 20턴 기준 입력 토큰이 4배 넘게 불어납니다. 2만 4천 토큰이 10만 토큰이 됩니다.

20턴을 주고받은 대화 하나의 입력 토큰 합계는 10만 토큰입니다. 이력을 빼고 시스템 프롬프트와 질문만 보냈다면 2만 4천 토큰입니다. 이력을 함께 보내면 같은 대화의 입력 토큰 합계가 4배 넘게 커집니다.

보내는 이력을 줄이면 입력 토큰 비용을 줄일 수 있습니다. 방법은 2개입니다.

  • 슬라이딩 윈도우: 최근 몇 턴만 보내고 그보다 앞선 대화는 제외합니다. 구현이 단순하고 효과가 바로 나타납니다.
  • 요약 압축: 오래된 대화는 원문 대신 짧은 요약으로 바꿔 보냅니다. 요약을 만들 때도 호출이 한 번 들어가므로 대화가 충분히 길 때만 이득입니다.

슬라이딩 윈도우와 요약 압축 모두 앞선 대화를 잘라 내므로 답변 품질과 맞바꾸는 선택입니다. 몇 턴까지 남길지는 문의 유형별 실제 대화 길이를 확인한 뒤 정합니다.

2. 프롬프트 변경으로 떨어지는 캐시 적중률

반복되는 프롬프트에 캐싱을 적용한 서비스에서도 배포나 프롬프트 변경 뒤 비용이 갑자기 오를 수 있습니다. 시스템 프롬프트 앞부분에 시각, 사용자 정보, 요청 번호처럼 매번 달라지는 값이 들어가면 이전과 같은 접두부로 인식되지 않아 캐시 적중률이 떨어지기 때문입니다.

호출마다 앞부분에 반복되는 내용이 있습니다. 역할과 말투를 정한 시스템 프롬프트, 출력 형식 예시, 모든 요청에 공통으로 붙이는 정책 문서입니다. 검색 증강 생성(RAG)으로 찾은 문서도 여러 요청에서 같은 순서로 반복된다면 캐싱 대상이 될 수 있습니다.

프롬프트 캐싱(prompt caching)은 요청 앞부분이 직전 요청과 똑같을 때 제공사가 앞부분을 다시 계산하지 않고 낮은 단가로 청구하는 기능입니다. 할인 폭이 큽니다. Anthropic 공식 문서에 따르면 캐시에 처음 써 넣을 때는 기본 입력 단가의 1.25배를 받고, 이후 캐시에서 읽은 입력 토큰은 0.1배로 청구합니다. 앞부분을 두 번 이상 보내는 상황이면 총액이 내려갑니다. 저장 기본 수명은 5분이고, 1시간으로 늘리면 쓰기 단가가 2배입니다.

프롬프트 캐싱을 적용하려면 조건을 맞춰야 합니다. OpenAI는 1,024 토큰 이상인 앞부분에만 캐싱이 적용되며 캐시 가능한 접두부가 이전 요청과 일치해야 한다고 안내합니다. Anthropic의 최소 길이는 모델에 따라 512 토큰에서 4,096 토큰까지 다릅니다. 조건을 충족하지 않아도 요청은 정상 처리될 수 있어, 설정 여부만으로는 할인 적용을 확인하기 어렵습니다.

단가와 조건은 제공사가 바꾸므로 적용 전에 현재 문서를 확인합니다. 이 글의 값은 2026년 8월 기준입니다.

캐싱 할인을 받으려면 세 곳을 손봅니다. 프롬프트 순서부터 바꿉니다.

  • 고정 내용을 앞으로: 지침·예시·참고 문서처럼 변하지 않는 내용을 프롬프트 맨 앞에 모으고, 사용자 이름이나 시각처럼 매번 달라지는 내용을 뒤로 보냅니다. OpenAI 문서가 권하는 순서입니다.
  • 앞부분 고정: 시스템 프롬프트에 현재 시각이나 요청 번호를 끼워 넣지 않습니다. 앞부분이 매번 달라지면 캐싱이 적용되지 않습니다.
  • 적중 여부 확인: 응답에 함께 오는 캐시 읽기 토큰 수를 기록해 실제로 할인을 받고 있는지 확인합니다. 캐시 수명이 짧으면 호출이 드문 기능에서 적중률이 낮습니다.

3. 중복 재시도와 에이전트 반복 루프

대화 이력 누적과 캐시 적중률 하락은 호출당 토큰을 늘립니다. 반면 재시도와 에이전트 루프(에이전트가 같은 동작을 되풀이하는 구간)는 호출 횟수 자체를 늘립니다.

재시도는 대개 라이브러리에서 자동으로 일어납니다. OpenAI 파이썬 SDK는 연결 오류, 408 요청 시간 초과, 409 충돌, 429 요청 한도 초과, 500 이상 서버 오류를 기본 2회까지 자동으로 다시 보냅니다. 재시도 2회는 최초 시도와 별개이므로, SDK 호출 하나가 실제로 보내는 전송은 최대 3회입니다. 애플리케이션 코드에서 같은 호출을 최초 시도까지 합쳐 3회 시도하도록 감싸 두었다면 요청 하나가 최대 9회 전송으로 늘어납니다. 재시도할 때마다 같은 프롬프트가 새 요청으로 전송됩니다. 제공사가 요청을 처리한 뒤 응답 전달 단계에서 실패했다면 해당 호출과 재시도 호출이 모두 사용량에 잡힐 수 있습니다. 그래서 전송 횟수와 실제 사용량을 함께 확인해야 합니다.

요청 1건이 최대 9회 전송으로 늘어나는 흐름을 왼쪽에서 오른쪽으로 그린 도식. 왼쪽은 실패 시 최대 3회 시도하는 애플리케이션으로 1차 시도, 2차 시도, 3차 시도가 놓여 있다. 가운데는 SDK 자동 재시도로, 각 시도마다 SDK 1, SDK 2, SDK 3까지 최대 3회를 전송한다. 오른쪽은 같은 요청을 반복해서 받는 LLM API이고 3 곱하기 3으로 최대 9회 전송이 된다. 애플리케이션 시도 3회는 가정한 값이다
재시도를 SDK와 애플리케이션 두 곳에서 하면 전송 횟수가 곱으로 늘어납니다. SDK 재시도 2회는 기본값, 애플리케이션 시도 3회(최초 포함)는 가정한 값입니다.

모델이 도구를 직접 골라 쓰며 여러 단계를 스스로 진행하는 AI 에이전트에서는 증가 폭이 더 큽니다. 에이전트는 도구를 부르고 결과를 읽고 다음 행동을 정하는 동작을 반복합니다. 이 한 단위를 스텝이라고 부르고, 스텝마다 LLM을 새로 호출합니다. 지금까지의 도구 호출 기록이 스텝마다 입력에 쌓이므로 컨텍스트 윈도우 누적과 겹칩니다. 종료 조건을 잘못 정하면 같은 도구를 계속 부르며 멈추지 않습니다.

에이전트 실행 단위로 호출 수와 누적 토큰 상한을 둡니다. 상한을 숫자로 정해 두면 최악의 경우를 막을 수 있습니다.

  • 스텝 상한: 에이전트 프레임워크는 대개 반복 횟수 상한을 제공합니다. OpenAI Agents SDK에서는 반복 횟수가 max_turns 값을 넘으면 MaxTurnsExceeded 예외가 발생하고 실행이 멈춥니다. 상한을 끄는 옵션도 있으므로 운영 환경에서 켜 둔 상태인지 확인합니다.
  • 요청당 토큰 상한: 요청 하나가 쓸 수 있는 누적 토큰 수를 정하고 넘으면 중단합니다. 멈추지 않는 반복을 그대로 두는 것보다 요청 몇 건을 중단시키는 편이 손실이 작습니다.
  • 재시도 규칙 정리: 재시도는 한 곳에서만 하고, 429 응답은 즉시 다시 보내지 않고 1초, 2초, 4초처럼 대기 시간을 배로 늘려 가며 보냅니다(지수 백오프). 400·401·404처럼 요청 자체가 잘못돼 다시 보내도 결과가 같은 실패는 재시도 대상에서 제외합니다.

비용 급증에 대비해 기록해야 할 5가지

청구서만 보면 챗봇과 요약 기능 가운데 어느 쪽이 얼마를 썼는지 구분하기 어렵습니다. 청구서만으로 확인하면 원인 파악 시점도 늦습니다. 호출할 때 직접 남겨 두지 않으면 나중에 확인할 방법이 없습니다. 호출마다 다음 다섯 묶음의 값을 남깁니다.

  • 입력 토큰 수와 출력 토큰 수: 응답에 사용량이 함께 오므로 그대로 남깁니다. 둘을 합치지 않고 나눠 남겨야 어느 쪽이 늘었는지 알 수 있습니다.
  • 캐시에서 읽은 토큰 수: 할인을 실제로 받고 있는지 확인하는 값입니다.
  • 모델 이름과 기능 구분: 챗봇·요약·분류처럼 기능을 태그로 남기면 비용을 기능별로 나눠 볼 수 있습니다.
  • 대화 또는 요청 식별자: 호출 하나가 아니라 대화 하나가 쓴 누적 토큰을 세려면 필요합니다.
  • 재시도 횟수와 에이전트 스텝 수: 호출 수가 늘어난 원인을 구분합니다.

기록한 값을 전부 매일 볼 필요는 없습니다. 추이로 볼 값만 골라 둡니다.

  • 호출당 입력 토큰 중앙값: 중앙값은 값을 크기 순으로 줄 세웠을 때 가운데 오는 값입니다. 평균은 아주 긴 호출 몇 건에 끌려가므로 중앙값을 씁니다.
  • 대화당 누적 토큰 95번째 백분위수(p95): 대화 100개를 토큰이 적은 순으로 줄 세웠을 때 95번째 대화가 쓴 토큰입니다. 중앙값은 그대로인데 95번째 백분위수만 오르면 긴 대화 몇 건에서 비용이 늘고 있습니다.
  • 캐시 읽기 토큰 비율: 전체 입력 토큰 가운데 캐시에서 읽은 토큰의 비율입니다. 캐싱을 적용했는데 비율이 낮으면 프롬프트 앞부분이 매번 달라지고 있습니다.

알림 기준을 절대 토큰 수로 고정하면 트래픽이 늘 때마다 울립니다. 호출당 입력 토큰 중앙값과 대화당 누적 토큰 95번째 백분위수를 각각 지난 2주 기준선과 견줍니다. 중앙값이 오르면 전반적인 입력이 길어진 것이고, 95번째 백분위수만 오르면 일부 긴 대화나 에이전트 실행에서 비용이 커진 것입니다.

기록할 값의 이름은 직접 정하지 않아도 됩니다. OpenTelemetry는 관측 데이터의 항목 이름을 표준으로 정해 둔 시맨틱 컨벤션(semantic conventions)을 두고 있고, 여기에 LLM 호출용 토큰 항목이 있습니다.

호출 하나하나의 기록에는 gen_ai.usage.input_tokensgen_ai.usage.output_tokens를 씁니다. 캐시에서 읽은 토큰은 gen_ai.usage.cache_read.input_tokens입니다. 합계를 집계하는 값은 gen_ai.client.token.usage 하나만 두고, gen_ai.token.typeinputoutput을 넣어 입력과 출력을 구분합니다. 아직 개발 단계(development) 규격이지만 이름을 맞춰 두면 나중에 도구를 바꿀 때 데이터를 다시 만들지 않아도 됩니다.

자주 묻는 질문

컨텍스트 윈도우가 큰 모델로 바꾸면 해결되나요?

오히려 늘어날 수 있습니다. 윈도우가 커지면 더 많은 이력과 문서를 넣게 되고, 넣은 만큼 입력 토큰으로 청구됩니다. 윈도우 크기는 넣을 수 있는 상한이고, 얼마를 넣을지는 애플리케이션이 정합니다.

더 저렴한 모델로 바꾸면 비용이 그만큼 줄어드나요?

토큰 단가만 보면 줄어듭니다. 다만 작은 모델이 형식을 틀려 재시도가 늘거나 답을 길게 늘여 출력 토큰이 늘면 총액은 오히려 오를 수 있습니다. FinOps Foundation도 토큰 단가만 보지 말고 성공적으로 끝난 작업을 기준으로 판단하라고 권합니다. 분류나 항목 추출처럼 단순한 작업만 작은 모델로 보내고 나머지는 기존 모델에 두는 방식이 안전합니다.

타임아웃으로 끊어진 호출에도 토큰 비용이 나가나요?

자동 재시도로 다시 보낸 호출은 새 호출로 집계되므로 비용이 발생합니다. 클라이언트가 응답을 기다리다 포기한 첫 호출까지 과금되는지는 제공사 문서에 일률적으로 정해져 있지 않습니다. 오류로 끝난 호출과 그때의 재시도 횟수를 남겨 두면 사용량 기록과 청구 내역을 맞춰 보며 확인할 수 있습니다.

RAG를 쓰면 비용이 어디에서 늘어나나요?

검색해서 프롬프트에 붙인 문서가 전부 입력 토큰으로 들어갑니다. 문서 5개를 붙이던 것을 3개로 줄이거나 문서 한 개의 길이를 줄이면 곧바로 비용이 내려갑니다. 질문을 벡터(의미를 숫자 목록으로 바꾼 값)로 변환하는 임베딩 호출은 생성 호출과 별도 단가로 청구되니 함께 세어야 합니다.

스트리밍으로 받으면 비용이 줄어드나요?

줄지 않습니다. 스트리밍은 생성한 토큰을 조금씩 먼저 보여 주는 전달 방식이라 토큰 수 자체는 같습니다. 답이 빨리 보이기 시작해 체감 속도는 좋아지지만 요금 계산은 달라지지 않습니다.

비동기 배치로 보내면 요금이 달라지나요?

즉시 응답이 필요 없는 작업은 결과를 바로 받지 않고 나중에 모아 받는 방식으로 보내면 할인을 받습니다. FinOps Foundation은 제공사들이 비동기 처리에 흔히 50% 이상 할인을 준다고 정리했습니다. 리포트 생성이나 대량 분류처럼 몇 시간 뒤에 결과를 받아도 되는 작업이 대상입니다.

마치며

호출 건수가 비슷한데 토큰 비용이 올랐다면, 호출 하나에 담긴 입력 토큰이 늘었는지 먼저 확인합니다. 대화 이력을 얼마나 보낼지 정하고, 프롬프트 앞부분을 고정해 캐시 적중률을 지키고, 재시도와 에이전트 스텝에 상한을 두면 금액이 갑자기 뛰는 일을 대부분 막을 수 있습니다. 호출마다 토큰 수를 남겨 두어야 다음에 금액이 움직일 때 어느 기능이 얼마를 쓰는지 확인할 수 있습니다.

기능별로 토큰이 어디에서 늘었는지 모델과 함께 나눠 보려면 와탭 LLM Observability를 참고하실 수 있습니다.

더 읽을거리

와탭 모니터링을 무료로 체험해보세요!