LLM 출력 토큰 비용 줄이기: 실제로 효과 있는 9가지 기법
시리즈: toksum.dev 가이드 · 공식 공급자 가격 페이지 기준 검증
청구서의 대부분은 출력이다 — 토큰당 단가 격차가 그 이유다
요즘 거의 모든 API에서 출력 토큰 단가는 입력 토큰의 5~6배다. GPT-5.4는 100만 토큰당 입력 2.50 / 출력 15.00으로 정확히 6배다. Claude Sonnet 4.6은 3.00 / 15.00으로 정확히 5배. GPT-5.5는 5.00 / 30.00으로 역시 6배다. 이 비율은 우연이 아니다. 생성은 자기회귀(autoregressive)적이고 순차적으로 일어나기 때문에, 모델이 병렬로 처리하는 프리필(prefill) 토큰보다 출력 토큰 하나를 만들어내는 비용이 더 크다. 가격은 그 연산량을 그대로 반영한 것이다.
현실적인 채팅 한 턴을 따져보자. 고객 지원 어시스턴트가 1,000토큰짜리 프롬프트(시스템 지시문 + 사용자 메시지)를 보내고 모델이 600토큰으로 답한다. GPT-5.4 기준 입력은 1000 / 1,000,000 x 2.50 = $0.0025, 출력은 600 / 1,000,000 x 15.00 = $0.0090이다. 모델이 읽은 양보다 적게 출력했는데도, 출력이 한 턴 비용 $0.0115의 78%를 차지한다.
코드 생성은 편향이 더 심하다. 리팩터링 에이전트가 4,000토큰의 컨텍스트를 읽고 Claude Sonnet 4.6에서 3,000토큰짜리 diff를 출력한다고 해보자. 입력은 4000 x 3.00 / 1e6 = $0.012, 출력은 3000 x 15.00 / 1e6 = $0.045다. 비용의 79%가 바로 당신이 가장 직접적으로 통제할 수 있는 부분 — 모델이 얼마나 쓰느냐 — 에 몰려 있다. 생성 토큰을 줄이거나 더 싼 미터로 옮기는 작업은 곧바로 이 지배적인 비용 항목을 때리는 셈이다.
시작 전에 솔직한 단서 하나. 매 호출마다 거대한 문서를 컨텍스트에 욱여넣고 짧은 답만 받는다면, 청구서는 오히려 입력 위주일 수 있다. 최적화에 들어가기 전에 로그에서 실제 요청별 입력/출력 비율부터 뽑아보라. 아래 기법들은 출력이 지배적인 일반적인 경우를 전제로 한다. 당신 워크로드가 그렇지 않다면 먼저 프롬프트 캐싱 ROI부터 보는 게 낫다.
가장 손쉽고 즉효: max_tokens와 정지 시퀀스로 출력에 상한 걸기
가장 효과 대비 노력이 좋은 변경은 모든 호출에 max_tokens 하드 상한을 거는 것이다. 상한이 없으면 모델이 쓰기로 결정한 만큼 그대로 청구되고, 병적인 폭주 — 루프에 빠지거나, 같은 설명을 반복하거나, 멈추라는 신호가 없어서 리스트를 65,536토큰까지 늘리는 — 에 그대로 노출된다. 여기 나오는 모든 모델은 큰 최대 출력 예산을 갖고 있고(GPT-5.4와 Sonnet 4.6 모두 65,536 허용), 그 예산은 제약을 걸지 않는 한 당신 편이 아니라 당신의 부채다.
상한은 모델 최댓값이 아니라 실제 P99 답변 길이에 여유를 더한 값으로 잡아라. 답변의 99%가 500토큰 안에 들어간다면, 800토큰 상한은 정상적인 응답을 거의 잘라내지 않으면서 폭주는 막아준다. 상한에 얼마나 자주 걸리는지 로깅하라. 절단(truncation) 비율이 높다면 상한이 너무 빡빡하거나 작업이 정말로 더 많은 여유를 필요로 하는 것이니, 기본값으로 방치하지 말고 의도적으로 올려라.
정지 시퀀스(stop sequence)는 외과 수술 같은 정밀 버전이다. 출력 계약이 알려진 구분자로 끝난다면 — 닫는 ``` 펜스, 태그, END 같은 센티넬 — 그것을 정지 시퀀스로 넘겨라. 그러면 쓸모 있는 페이로드가 끝나는 순간 생성이 멈추고, 뒤에 붙는 군말 문단에는 과금되지 않는다. 정작 요청한 것 다음에 친절한 요약을 덧붙이길 좋아하는 모델과 특히 궁합이 좋다.
주의: 절단된 응답이 다운스트림 파싱을 망가뜨린다면 비싼 응답보다 더 나쁠 수 있다. 절단은 시끄럽게 실패해야 한다(finish_reason이 length/max_tokens인지 감지). 그리고 더 높은 상한으로 재시도하거나 에러를 노출해야지, JSON 객체를 반 토막 낸 채로 조용히 내보내선 절대 안 된다.
- 라우트별
max_tokens는 모델 기본값이 아니라 관측된 P99 길이를 기준으로 설정하라. - 결정론적 종료자가 있는 출력에는 정지 시퀀스를 추가하라.
- 절단 비율에 알림을 걸고, 급증은 노이즈가 아니라 회귀(regression)로 다뤄라.
- 절단된 구조화 응답이 검사 없이 파서에 도달하게 두지 마라.
산문이 아니라 데이터를 출력하게 하라: 구조화·스키마 제약 출력
가장 싼 토큰은 모델이 아예 쓰지 않는 토큰이다. 출력량의 상당 부분은 대화용 장식이다 — "물론이죠! 요청하신 정보는 다음과 같습니다:", 질문 재진술, 번호 매긴 서론, 그리고 끝에 붙는 "더 도와드릴까요?". 그 어느 것도 당신 DB로 들어가지 않지만, 전부 출력 단가 그대로 과금된다.
여기서 두 레버가 곱셈으로 작동한다. 첫째, 프롬프트에서 장황함을 낮추라: "서론이나 설명 없이 JSON 객체만 응답하라." 이것만으로도 추출형 작업에서 토큰의 20~40%를 흔히 줄인다. 둘째, 그리고 더 안정적으로, 제공자가 지원한다면 구조화 출력 / JSON 스키마 제약 디코딩을 써라. 모델이 스키마에 맞는 토큰만 출력하도록 강제되면 물리적으로 산문으로 새어나갈 수 없고, 패딩이 들어갈 표면적이 당신이 정의한 필드로 줄어든다.
스키마 설계 자체가 비용 레버다. {"sentiment":"pos"}를 반환하는 스키마는 {"sentiment":"positive","confidence":"high","explanation":"The customer expressed..."}를 반환하는 스키마의 몇 분의 일 비용이다. explanation 필드를 소비하지 않을 거면 요청하지 마라. enum이 자유 텍스트보다 낫다. 짧고 안정적인 필드명이 장황한 이름보다 낫다 — 모든 키는 모든 레코드마다 출력되므로, 100만 행 배치에서 6글자 키와 16글자 키의 차이는 실제 돈이다.
주의: 스키마 제약은 정말로 추론 여지가 필요한 작업에서는 품질을 떨어뜨릴 수 있다. 사고 연쇄(chain-of-thought) 필드를 억제하면 어려운 항목에서 정확도가 내려갈 수 있다. 해법은 모델이 추론을 쏟아낸 뒤 버릴 스크래치 필드를 두거나, 별도의 추론 단계를 쓰는 것이다 — 단, 측정하라. 스키마를 조일 때마다 평가셋(eval set)을 다시 돌려라. 싸다고 공짜라고 가정하지 마라.
스트리밍으로, 답이 완성되는 순간 끊어라
스트리밍은 토큰당 가격을 바꾸지 않지만, 과금을 언제 멈출 수 있는지를 바꾼다. 토큰을 도착하는 대로 소비하면, 애플리케이션이 답이 완성됐음을 감지하고 — JSON 객체의 닫는 중괄호, 첫 번째 유효한 코드 블록의 끝, 세 개로 제한한 리스트의 세 번째 불릿 — 연결을 닫을 수 있다. 끊기 전까지 생성된 토큰에만 과금된다.
이게 가장 중요해지는 건 모델이 쓸모 있는 페이로드를 넘어 계속 이어가는 습관이 있을 때다: 답하고, 그 답을 설명하고, 후속 제안까지 한다. 비스트리밍 호출이면 그 꼬리 전부에 돈을 낸다. 스트리밍 + 조기 종료면 당신이 읽은 부분만 낸다. 실무에서 이건 정지 시퀀스와 겹치는데, 결정론적 종료자가 있을 때는 정지 시퀀스가 더 깔끔하다 — 하지만 고정 토큰이 아니라 애플리케이션 로직에서 "끝"을 판단해야 하는 더 모호한 경우는 스트리밍 종료가 처리한다.
무엇을 절약하는지 정확히 하라. 스트림 중간에 끊는 것은 아직 생성되지 않은 토큰의 과금을 막을 뿐, 이미 만들어진 토큰에는 아무 효과가 없다. 그래서 스트리밍은 장황함 제어의 대체재가 아니라 보완재다. 응답이 오버슈팅했을 때 피해를 제한해주지만, 더 큰 승리는 애초에 응답을 짧게 만드는 것이다.
가장 큰 단일 레버: 출력 무거운 단계를 더 싼 티어로 라우팅
출력이 비싼 미터이기 때문에, 토큰을 가장 많이 생성하는 단계가 바로 모델 티어를 낮췄을 때 가장 큰 이득이 나는 지점이다. 앞의 3,000토큰 코드 생성 출력을 보자. Claude Sonnet 4.6에서는 $0.045다. Claude Haiku 4.5(1.00 / 5.00)에서 같은 3,000토큰은 $0.015 — 3분의 1이다. Gemini 2.5 Flash(0.30 / 2.50)에서는 $0.0075로 출력 항목이 6배 감소한다. GPT-5.4 mini(0.75 / 4.50)에서는 $0.0135다.
함정은 파이프라인 전체를 mini 티어로 보내고 품질 절벽을 떠안는 것이다. 규율은 단계별로 라우팅하는 것이다. 출력이 무겁고 기계적으로 모양이 정해진 단계 — 포매팅, 추출, 템플릿으로의 요약, 명확한 스펙에서 보일러플레이트 코드 생성 — 가 바로 작은 모델이 잘 버티고 토큰 물량이 몰려 있는 곳이다. 판단이 필요한 단계에는 프런티어 모델을 남겨두면, 위험의 대부분 없이 절감의 대부분을 챙길 수 있다.
더 싼 모델은 리더보드가 아니라 당신 작업의 실제 모양에 따라 고르라. 워크로드별 트레이드오프는 워크로드별 가장 싼 LLM에서 다루고, 구체적인 소형 모델 선택은 Haiku vs GPT mini에 있다. 위에서 든 정확히 그 두 모델의 1:1 비교는 Haiku 4.5 vs GPT-5.4 mini를 보라.
엔지니어들이 놓치는 주의점: 토큰 수는 제공자 간에 그대로 옮겨지지 않는다. Claude는 영어를 GPT 토큰 수의 대략 0.8배로 토큰화하므로, 토큰당으로는 약간 비싸 보이는 모델이 작업당으로는 더 쌀 수 있고 그 반대도 성립한다. 당신 트래픽에서 완료된 요청당 비용으로 비교하라 — 토큰 카운터와 마이그레이션 시뮬레이터가 바로 이걸 위해 있다.
2패스: 싼 모델이 초안을, 프런티어 모델은 수정만
더 공격적인 라우팅 패턴: 싼 모델이 출력의 대부분을 생성하고, 그것을 프런티어 모델에 넘겨 검토·교정만 하게 하는 것이다. 경제적 베팅은 비싼 모델의 출력은 작고 — 짧은 수정 목록, 패치, 승인 — 분량 많은 첫 초안은 싼 티어로 과금된다는 데 있다.
구체적으로: Gemini 2.5 Flash에서 3,000토큰 문서를 초안으로 쓰고(3000 x 2.50 / 1e6 = $0.0075), GPT-5.4가 400토큰짜리 교정 diff를 출력하게 한다(400 x 15.00 / 1e6 = $0.006) — 여기에 초안을 읽는 입력 비용이 더해진다. 총 출력 지출은 GPT-5.4에서 3,000토큰 전부를 생성하는 것($0.045)보다 한참 아래로 떨어지면서, 최종 결과에는 프런티어급 판단을 유지한다.
이건 두 가지 구체적인 방식으로 역효과를 낸다. 첫째, 프런티어 모델이 초안을 살릴 수 없다고 판단해 통째로 다시 쓰면, 싼 초안 비용에 더해 풀 프런티어 생성 비용을 내게 된다 — 좋은 모델 하나만 쓰는 것보다 명백히 나쁘다. 에디터의 출력에 상한을 걸고 작은 diff 예산을 얼마나 자주 초과하는지 계측하라. 재작성 비율이 높다면 초안 모델이 그 작업에 너무 약한 것이다. 둘째, 이제 2패스에서 초안을 입력으로 다시 먹이는 비용을 내야 하므로, 수정 출력이 초안 대비 정말로 작을 때만 계산이 맞는다. 2패스는 검토형 작업에는 진짜 이득이고, 생성형 작업에는 함정이다.
같은 답에 두 번 돈 내지 마라: 응답 캐싱과 중복 제거
두 요청이 같은 출력을 만들어낼 거라면, 두 번 생성하는 것은 순수한 낭비다. 애플리케이션 계층 응답 캐시 — 정규화한 프롬프트 해시를 키로 쓰고 완성된 응답을 저장 — 는 반복 질문을 LLM 미터에서 비용 0인 조회로 바꾼다. 이것은 반복되는 입력 접두부를 할인해주는 제공자 프롬프트 캐싱과는 다르다. 여기서는 캐시 히트 시 출력 생성 자체를 통째로 없애는 것이다.
이게 진가를 발휘하는 곳: FAQ형 어시스턴트, 반복 입력 분류, 자동완성, 인기 쿼리의 상위권이 반복되는 모든 표면. 해싱 전에 정규화하라(소문자화, 트림, 변동 필드 제거, 타임스탬프 반올림). 그래야 의미상 동일한 요청이 하나의 키로 합쳐진다. 그리고 정답이 얼마나 빨리 바뀌는지에 맞춰 TTL을 설정하라. 시맨틱 캐시(임베딩 기반 최근접 이웃)는 문자열 해시가 놓치는 유사 중복까지 잡지만, 임베딩 조회 비용과 미묘하게 틀린 캐시 답을 내놓을 실질적 위험이 따른다.
뼈아픈 주의점: 개인화·시간 민감·안전 관련 출력은 TTL과 무효화 전략 없이 절대 캐싱하지 마라. 그리고 정말로 매번 달라지길 원하는 비결정론적 응답은 절대 캐싱하지 마라. 자축하기 전에 히트율을 측정하라 — 히트율 3%짜리 캐시는 인프라와 복잡성만 더하고 절감은 거의 없으니, 차라리 출력을 짧게 만드는 게 낫다.
출력 계약 자체를 줄여라: 객체 대신 ID, 문서 대신 델타
때로는 가장 싼 해법이, 이미 갖고 있는 데이터를 모델더러 되풀이하게 하는 짓을 그만두는 것이다. 모델에 제품 목록을 건네고 세 개를 고르라고 할 때, 전체 제품 객체를 다시 받지 마라 — ID 세 개만 반환하게 하고 코드에서 다시 채워라(rehydrate). 모델은 약 300토큰 대신 약 10토큰을 출력했고, 당신은 그 10토큰에만 출력 단가를 냈다.
같은 원리가 문서로 확장된다. 모델이 무언가를 편집하거나 확장할 때, 전체 수정본이 아니라 델타를 요청하라 — diff, 패치, 바뀐 필드와 그 새 값의 목록. 3,000토큰 문서에서 모델이 두 문단을 바꿨다면 델타는 200토큰일 수 있다. Sonnet 4.6 출력 단가로 그건 전부를 다시 생성하는 $0.045 대신 $0.003, 그 호출에서 15배 절감이다. 전체 문서 재생성이 조용한 기본값이 되어 슬그머니 청구서를 지배하는 에이전트·문서 편집 워크로드에서, 이건 가장 큰 이득을 주는 패턴 중 하나다.
이걸 참조 전반에 적용하라: 전체 인용문 대신 인용 키, 전체 행 대신 행 ID, 호출자가 이미 소스를 갖고 있다면 전체 본문 대신 함수 이름. 규율은 출력의 모든 필드에 대해 "이걸 내가 이미 갖고 있나?"를 묻는 것이다. 그렇다면 재현하게 하지 말고 가리키게 하라.
주의: 델타는 애플리케이션 복잡성을 더한다(패치를 정확히 적용해야 하고 잘못된 패치도 처리해야 한다). 그리고 모델이 생각하는 기준 문서가 당신 것과 어긋나면 혼란스럽게 실패할 수 있다. 패치가 깨끗하게 적용되는지 검증하고, 실패하면 전체 재생성으로 폴백하라. 절감폭이 충분히 커서 배관 작업을 감수할 가치가 있지만, 그 배관은 실재한다.
이 가이드가 일부러 뺀 것, 그리고 모든 걸 묶는 규칙
위의 모든 것은 출력 미터를 겨냥한다. 입력 쪽 — 제공자 프롬프트 캐싱, 검색 결과 다듬기, 컨텍스트 가지치기, 시스템 프롬프트 압축 — 은 자체적인 손익분기 계산을 가진 별개의 레버이고, 둘을 뒤섞으면 엉뚱한 숫자를 최적화하게 된다. 로그가 입력 위주 비율을 보인다면 곧장 프롬프트 캐싱 ROI와 RAG 비용 아키텍처로 가라. 그쪽이 입력 지출을 다스린다. 배치 API(두 미터 모두 50% 할인, 최대 24시간 비동기)도 직교적인 레버이고, 비대화형 작업이라면 이 기법들 대부분과 겹쳐 쌓인다.
아홉 가지를 묶는 규칙 하나: 모든 변경 후에 품질을 재평가하라. 상한·스키마 제약·티어 다운·2패스·델타로만 짜인 파이프라인은 70%를 아끼면서 작업 성공률을 94%에서 81%로 슬그머니 떨어뜨릴 수 있다 — 받아들일 수도 아닐 수도 있는 거래지만, 절대 눈 감고 해서는 안 된다. 실제 프로덕션 입력에서 뽑은 고정 평가셋을 유지하고 최적화마다 돌려라. 더 자주 실패하는 더 싼 출력은 싼 게 아니다. 미뤄둔 비용에 더 나쁜 제품이 얹힌 것이다.
노력을 그에 맞게 순위 매겨라. 상한과 정지 시퀀스는 반나절이면 되고 최악의 결과로부터 당신을 보호한다. 장황함 제어와 스키마 조이기는 하루면 되고 흔히 3분의 1을 줄인다. 단계별 모델 라우팅은 가장 큰 단일 레버이며, 진짜 평가 시간을 투자할 가치가 있는 대상이다. 2패스, 응답 캐싱, 델타 계약은 워크로드 특화 강력 도구다 — 맞는 파이프라인에서는 엄청나지만 틀린 파이프라인에서는 복잡성만큼의 값어치가 없다. 입력/출력 비율을 먼저 측정하고, 그다음 이득 순서대로 기법을 공략하되, 단계마다 품질을 검증하라.
자주 묻는 질문
품질을 해치지 않으면서 출력 비용을 현실적으로 얼마나 줄일 수 있나?
전적으로 출발점과 워크로드에 달려 있으니, 단일한 숫자는 의심하고 봐라. 두 가지 변경은 품질 위험이 거의 없어 어디서나 할 가치가 있다: max_tokens 하드 상한 + 정지 시퀀스, 그리고 프롬프트 지시나 구조화 출력으로 대화용 군더더기 잘라내기. 이것만으로도 장황한 작업에서 흔히 20~40%를 회수한다. 단계별 모델 라우팅은 그걸 배가할 수 있다 — 3,000토큰 생성을 Claude Sonnet 4.6에서 Gemini 2.5 Flash로 옮기면 출력 항목이 6배 줄어든다 — 하지만 실질적 품질 위험이 따르므로 반드시 당신 평가셋에서 검증해야 한다. 목표 퍼센트를 맞추려 하지 말고 측정하는 것을 목표로 삼아라.
왜 출력 토큰이 입력 토큰보다 그렇게 비싼가?
생성이 자기회귀적이기 때문이다. 모델은 출력을 한 번에 한 토큰씩 만들어내고 새 토큰 각각이 앞선 모든 토큰에 의존하므로, 입력 프리필처럼 병렬화할 수 없다. 입력 토큰 10,000개를 읽는 것은 대체로 병렬인 한 번의 순전파(forward pass)지만, 출력 토큰 10,000개를 쓰는 것은 10,000번의 순차 단계다. 가격은 그 비용 구조를 그대로 반영하며, 그래서 2026년 거의 모든 모델이 출력:입력 5~6배 비율에 자리잡고 있다 — GPT-5.4는 2.50/15.00으로 6배, Claude Sonnet 4.6은 3.00/15.00으로 5배. 출력이 비싼 미터이므로, 최적화가 가장 크게 보답하는 곳도 바로 출력이다.
max_tokens를 낮추면 응답 품질이 나빠지나?
작업이 정당하게 필요로 하는 양보다 낮게 잡았을 때만 그렇다. P99 답변 길이보다 높은 상한은 정상 응답을 한 번도 자르지 않으면서 폭주 생성과 병적 루프로부터 보호한다. 위험은 너무 공격적으로 잡은 상한이 유효한 답을 조용히 끊어버리는 것이다 — 특히 절단된 JSON 객체가 다운스트림 파싱을 깨뜨리는 구조화 출력에서 위험하다. 항상 finish_reason을 확인하라: 길이 제한에 걸렸다고 나오면 반쯤 만들어진 결과를 내보내지 말고 더 높은 상한으로 재시도하거나 에러를 노출하라. 관측 데이터에서 상한을 잡고 절단 비율에 알림을 걸어라.
출력 비용 줄이기가 프롬프트 캐싱과 같은 건가?
아니다, 정반대의 미터를 겨냥한다. 여기서 다룬 기법들은 모델이 생성하는 출력 토큰 수를 줄이거나 그 생성을 더 싼 모델로 옮긴다. 프롬프트 캐싱은 반복되는 입력을 할인한다 — 여러 요청에 걸쳐 재사용되는 큰 시스템 프롬프트나 문서 접두부 — 출력 분량에는 아무 효과가 없다. 애플리케이션 수준 응답 캐싱이 유일한 출력 쪽 사촌이다: 완성된 응답 전체를 저장해서 동일 쿼리를 새 생성 대신 공짜 조회로 만든다. 입력 쪽은 전용 프롬프트 캐싱 ROI 가이드를 보고, 배치 API는 두 미터를 모두 할인하며 이 기법들 대부분과 겹쳐 쌓인다는 점도 기억하라.