jo5ephengineering

Engineering blog

LLM에서 토큰이란?

"이 상품 추천 가능해?" 한 줄을 물었는데 요금 대시보드에는 만 단위 토큰이 찍혀 있었습니다. 질문은 열 글자 남짓인데 어디서 이만큼이 나온 걸까요.

답은 간단합니다. 모델이 읽은 것은 제 열 글자가 아니라 시스템 프롬프트, 규칙 문서, 지난 대화 스무 턴, 검색해온 문서 서른 개, 그리고 도구 정의 전부였습니다. 제가 쓴 문장은 그 뭉치의 맨 끝에 붙은 한 줄이었을 뿐입니다.

토큰을 아끼는 일은 프롬프트의 글자 수를 줄이는 일이 아닙니다. 모델이 읽어야 하는 것과 만들어야 하는 것을 줄이는 일입니다. 그러려면 토큰이 어디서 얼마나 새는지부터 알아야 하고, 이 글은 그 지도를 그리는 것을 목표로 합니다.

과금 방식은 제공업체와 모델마다 다르고 꽤 자주 바뀝니다. 그래서 특정 모델의 달러 단가 대신 구조적으로 잘 변하지 않는 비율과 원리에 무게를 뒀습니다. 실제 숫자는 사용하는 모델의 문서를 확인해 주세요.

토큰은 무엇인가

LLM에서 토큰(Token) 은 모델이 텍스트를 읽고 쓰는 최소 단위입니다.

모델은 우리가 쓴 문장을 글자 그대로 이해하지 않습니다. 입력을 여러 조각으로 자른 뒤 그 조각들을 숫자로 바꿔 처리합니다. 그래서 이런 문장이 있다면,

상품 추천 조건을 분석해줘

사람 눈에는 한 문장이지만 모델 내부에서는 여러 개의 토큰으로 쪼개진 배열입니다. 이 조각 하나하나가 곧 과금 단위이기도 합니다.

즉 토큰은 두 얼굴을 가집니다. 하나는 모델의 처리 단위, 다른 하나는 우리가 지불하는 화폐 단위입니다. 이 글은 주로 두 번째 얼굴을 다룹니다.

토큰은 모델이 텍스트를 처리하는 최소 단위이자, 사용자가 LLM을 쓸 때 소비하는 자원의 단위입니다.

토큰은 어디서 소비되는가

토큰이 소비되는 지점은 세 곳입니다.

구분무엇에 쓰이나과금
입력시스템 프롬프트, 도구 정의, Rule, Skill, 대화 기록, RAG 문서, 도구 실행 결과입력 단가
출력최종 답변, JSON·코드 등 구조화된 결과, 도구 호출 인자, 추론 토큰출력 단가
캐시반복되는 입력의 캐시 쓰기와 읽기쓰기는 할증, 읽기는 축소

여기서 한 가지를 짚고 가야 합니다. 추론 토큰을 입력·출력과 나란한 별도 항목으로 소개하는 글이 많은데, 실제 청구서에서 추론 토큰은 출력 토큰에 포함됩니다. 모델이 내부적으로 생각하며 만들어낸 토큰도 결국 모델이 생성한 토큰이기 때문입니다.

이 사실이 왜 중요하냐면, 뒤에서 다룰 "답변을 짧게 만들었는데 출력 비용이 그대로인 이유"가 바로 여기서 나오기 때문입니다.

입력 토큰

입력 토큰(Input Token) 은 모델이 답을 만들기 전에 읽어야 하는 모든 것에 붙는 비용입니다.

에이전트 환경에서 한 번의 요청에 실려 가는 것들을 늘어놓으면 이렇습니다.

  • 시스템 프롬프트와 개발자 지침
  • 사용할 수 있는 도구의 정의 전체 (이름, 설명, 파라미터 스키마)
  • Rule 파일과 로드된 Skill 문서
  • 이전 대화 기록
  • RAG로 검색해온 문서
  • 직전 도구 실행 결과와 API 응답

사용자 입력은 이 목록의 한 줄입니다. 그래서 질문을 아무리 짧게 써도, 시스템 프롬프트가 길거나 대화가 쌓였거나 검색 결과가 많으면 입력 토큰은 얼마든지 커집니다.

특히 도구 정의는 놓치기 쉽습니다. 도구를 열 개 붙여두면 모델이 하나도 쓰지 않아도 열 개의 스키마가 매 요청마다 입력으로 전달됩니다. 도구 설명을 성의 없이 길게 써두면 그 길이만큼 매번 돈이 나갑니다.

여기에 하나 더. 입력과 출력은 같은 컨텍스트 윈도우를 나눠 씁니다. 입력이 창을 가득 채우면 답변에 쓸 공간이 남지 않습니다. 컨텍스트 윈도우는 입력 한도가 아니라 입력과 출력의 합에 대한 한도입니다.

입력 토큰은 사용자가 쓴 질문이 아니라, 모델이 답하기 위해 읽어야 하는 모든 것의 총량입니다.

RAG란 무엇인가

RAG(Retrieval-Augmented Generation)는 답변을 만들기 전에 외부 데이터베이스나 문서에서 질문과 관련된 부분을 검색하고, 그 결과를 모델 입력에 함께 실어 보내는 기술입니다.

동작 순서는 이렇습니다.

사용자 질문
    
관련 문서 검색
    
검색된 문서 + 사용자 질문
    
LLM
    
답변

여기서 자주 나오는 오해가 하나 있습니다. MD 파일을 만들어 뒀다고 그게 RAG인 것은 아닙니다. MD든 PDF든 TXT든, 문서를 작성해 두는 것만으로는 아무 일도 일어나지 않습니다.

그 문서를 검색 가능한 형태로 저장하고, 질문이 들어올 때 관련된 부분만 찾아 모델 입력으로 넘기는 구조가 있어야 비로소 RAG이고, 그때 그 문서는 RAG의 데이터 소스가 됩니다.

그리고 검색 결과는 전부 입력 토큰입니다. RAG를 붙였다면 입력 비용을 결정하는 것은 사용자가 아니라 검색기입니다.

출력 토큰

출력 토큰(Output Token) 은 모델이 생성한 모든 것에 붙는 비용입니다. 사용자에게 보이는 답변만이 아닙니다.

에이전트에서 모델이 생성하는 것에는 이런 것들이 포함됩니다.

  • 사용자에게 표시되는 자연어 답변
  • JSON, HTML, SQL, 코드 같은 구조화된 출력
  • 도구 호출 인자

마지막 항목이 특히 눈에 잘 띄지 않습니다. 모델이 이런 도구 호출을 만들었다면,

{
  "tool": "search_product",
  "keyword": "기업대출",
  "limit": 10
}

이것도 모델이 생성한 텍스트이므로 출력 토큰으로 집계됩니다. 화면에는 "상품을 검색하고 있습니다"라는 한 줄만 보이더라도 말입니다.

추론 토큰

추론 토큰(Reasoning Token) 은 모델이 최종 답을 내기 전에 내부적으로 문제를 따져보며 생성하는 토큰입니다.

복잡한 상품 추천이라면 모델 내부에서는 대략 이런 일이 벌어집니다.

사용자 조건 확인
    
 상품 조건 비교
    
제외 조건 확인
    
예외 규칙 확인
    
최종 상품 선정

이 과정은 사용자에게 그대로 노출되지 않습니다. 요약된 형태만 보여주거나 아예 감추는 것이 최근 모델들의 기본값입니다. 하지만 보이지 않는 것과 무료인 것은 다릅니다. 추론 토큰은 노출 여부와 무관하게 생성된 만큼 출력 단가로 청구됩니다.

그래서 이런 일이 생깁니다. 프롬프트를 고쳐 답변을 다섯 문장에서 두 문장으로 줄였는데 출력 비용이 거의 그대로인 경우입니다. 줄어든 것은 눈에 보이는 두 문장이고, 그 앞에서 소비된 수백에서 수천 토큰의 추론은 그대로였기 때문입니다.

추론량을 조절하는 것은 문장 길이 지시가 아니라 모델이 제공하는 추론 강도 설정입니다. 답을 짧게 시키는 것과 덜 생각하게 만드는 것은 다른 레버입니다.

출력 토큰은 모델이 만들어낸 전부입니다. 사용자에게 보이는 답변, 도구 호출 인자, 그리고 보이지 않는 추론 과정까지 포함합니다.

캐시

매 요청마다 똑같은 시스템 프롬프트와 상품 설명 2만 토큰을 다시 보내는 것은 낭비입니다. 캐시는 이렇게 반복되는 앞부분을 한 번 처리해두고 다음 요청에서 재사용하는 기능입니다.

캐시 관련 비용은 두 가지로 나뉩니다.

  • 캐시 쓰기 — 처음 캐시를 만들 때. 일반 입력보다 비쌉니다. 유지 시간이 짧으면 약 1.25배, 길면 약 2배 수준입니다.
  • 캐시 읽기 — 만들어둔 캐시를 재사용할 때. 일반 입력의 약 10분의 1입니다.

쓰기가 할증이라는 점이 중요합니다. 캐시는 공짜 최적화가 아니라 선불입니다. 한 번 쓰고 마는 프롬프트를 캐시하면 오히려 손해입니다.

손익분기를 따져보면 이렇습니다. 짧은 유지 시간 기준으로 같은 프롬프트를 두 번 보낼 때, 캐시 없이는 1배 + 1배 = 2배를 냅니다. 캐시를 쓰면 1.25배 + 0.1배 = 1.35배입니다. 두 번째 요청부터 이득입니다. 유지 시간이 긴 옵션은 쓰기가 2배이므로 두 번으로는 본전을 못 찾고 세 번째 요청부터 이득으로 돌아섭니다.

정리하면 판단 기준은 두 가지입니다. 같은 앞부분이 몇 번 반복되는가, 그리고 그 반복이 캐시 유지 시간 안에 일어나는가. 요청이 하루에 한 번 들어오는 배치 작업이라면 캐시를 걸어도 매번 만료된 뒤라 쓰기 비용만 계속 냅니다.

캐시가 조용히 깨지는 이유

여기부터가 실무에서 진짜 문제가 되는 부분입니다.

캐시는 프리픽스 매칭으로 동작합니다. 요청의 맨 앞부터 한 글자씩 비교해서, 이전 요청과 똑같이 이어지는 구간까지만 재사용합니다. 그러니 앞쪽에서 한 글자라도 달라지면 그 뒤는 전부 무효입니다.

그리고 요청이 조립되는 순서는 대체로 이렇습니다.

도구 정의    시스템 프롬프트    대화 기록

도구 정의가 맨 앞이라는 점이 결정적입니다. 도구를 하나 추가하거나 순서를 바꾸면 그 뒤 전부가 새 프리픽스가 됩니다. 시스템 프롬프트도, 대화 기록도, 아무것도 재사용되지 않습니다.

캐시 적중률이 0에서 안 올라간다면 십중팔구 아래 중 하나가 앞쪽에 끼어 있습니다.

범인왜 문제인가
시스템 프롬프트에 박은 현재 시각매 요청마다 프리픽스가 달라짐
요청 ID, 세션 ID, 사용자 이름사용자 간·요청 간 캐시 공유가 불가능해짐
정렬하지 않은 JSON 직렬화키 순서가 실행마다 달라질 수 있음
조건부로 붙였다 뗐다 하는 시스템 프롬프트 절조합 수만큼 서로 다른 프리픽스가 생김
사용자마다 다르게 구성되는 도구 목록도구는 맨 앞이라 그 뒤 전부가 날아감

해법은 하나입니다. 바뀌지 않는 것을 앞에, 바뀌는 것을 뒤에 두는 것입니다. 현재 시각이 정말 필요하다면 시스템 프롬프트가 아니라 마지막 사용자 메시지에 넣으면 됩니다. 그러면 앞쪽 프리픽스는 그대로 살아남습니다.

한 가지 더. 캐시에는 최소 크기가 있습니다. 일정 토큰 수에 못 미치는 프리픽스는 캐시 지시를 넣어도 그냥 무시됩니다. 에러도 경고도 없이 조용히 넘어가기 때문에, 캐시를 걸었는데 아무 일도 안 일어난다면 프리픽스가 기준보다 짧은 것일 수 있습니다. 이 기준은 모델마다 다릅니다.

캐시가 실제로 동작하는지는 응답의 사용량 정보를 보면 됩니다. 대부분의 API가 캐시로 쓴 토큰 수와 캐시에서 읽은 토큰 수를 따로 알려줍니다. 같은 프리픽스로 반복 호출했는데 읽기가 계속 0이라면 위 표의 범인 중 하나가 숨어 있는 것입니다.

캐시는 앞에서부터의 완전 일치로 동작합니다. 앞쪽에 변하는 값을 하나만 끼워 넣어도 뒤쪽 전부가 캐시되지 않습니다.

같은 문장인데 모델마다 토큰이 다른 이유

입력과 출력이 완전히 같다면 모델이 달라도 토큰 수는 같을까요. 아닙니다. 이유는 두 가지입니다.

토크나이저의 차이

모델은 문장을 그대로 읽지 않고 토크나이저로 잘라서 읽습니다. 그리고 이 토크나이저는 모델 계열마다 다릅니다.

같은 문장을 두 모델이 이렇게 다르게 자를 수 있습니다.

모델 A
[상품] [추천] [조건을] [분석해줘]         4 토큰

모델 B
[] [] [추천] [조건] [] [분석] [해줘]   7 토큰

실제 분절 결과는 이보다 훨씬 불규칙합니다. 위 예시는 "같은 글자 수라도 자르는 방식에 따라 토큰 수가 달라진다"는 점을 보여주기 위한 것입니다.

같은 계열 안에서도 세대가 바뀌면서 토크나이저가 교체되기도 합니다. 그래서 모델을 올리기만 했는데 같은 프롬프트의 토큰 수가 달라지는 일이 실제로 일어납니다. 단가는 그대로인데 청구액이 오르는 상황이 여기서 나옵니다.

추론량의 차이

같은 질문에 같은 답을 내더라도 내부에서 쓰는 추론량은 모델마다 다릅니다.

최종 출력이 이 한 줄로 똑같다고 해봅시다.

조건을 충족하므로 추천 가능합니다.

모델 A는 추론 500토큰에 출력 20토큰을 쓰고, 모델 B는 추론 2,000토큰에 출력 20토큰을 쓸 수 있습니다. 화면에 보이는 결과는 완전히 같지만 청구되는 출력 토큰은 네 배 가까이 차이가 납니다.

그러니 모델을 비교할 때 눈에 보이는 답변 길이만 재는 것은 의미가 없습니다. 응답의 사용량 정보에 찍힌 실제 출력 토큰을 봐야 합니다.

토큰을 세는 올바른 방법

여기까지 왔으면 자연스럽게 "그래서 내 프롬프트는 몇 토큰인데?"라는 질문이 나옵니다.

주의할 점이 하나 있습니다. 토큰 계산 라이브러리 중 가장 널리 쓰이는 tiktokenOpenAI 모델용 토크나이저입니다. 다른 회사 모델에 이걸 쓰면 그냥 틀린 숫자가 나옵니다. 영어 산문에서도 오차가 나고, 코드나 비영어권 텍스트에서는 차이가 훨씬 커집니다.

대부분의 제공업체는 토큰 카운팅 API를 따로 제공합니다. 실제 추론 요청을 보내지 않고 토큰 수만 받아볼 수 있고, 무엇보다 그 모델의 실제 토크나이저를 사용합니다.

정리하면 이렇습니다.

  • 쓸 모델과 같은 모델 ID로 카운팅 API를 호출한다
  • 다른 모델에서 잰 숫자를 그대로 가져다 쓰지 않는다
  • 어림짐작 계산기나 타사 토크나이저로 비용을 추정하지 않는다

Rule, Skill, Hook은 어디에 해당하는가

이전 글에서 정리했던 Rule, Skill, Hook을 토큰 관점에서 다시 보면 이렇습니다.

기능주로 쓰는 토큰이유
Rule입력 · 캐시규칙 내용이 매 요청 프롬프트에 포함됨
Skill입력 · 출력 · 캐시절차가 입력되고, 그 절차대로 추론과 도구 호출과 출력이 발생
Hook대체로 없음단순 프로그램 실행이면 모델을 호출하지 않음

Rule은 매 요청마다 시스템 프롬프트와 함께 실려 가므로 항상 입력 토큰입니다. 대신 내용이 잘 안 바뀌고 요청 앞쪽에 놓이므로 캐시가 가장 잘 듣는 대상이기도 합니다.

Skill은 여러 축에 걸쳐 있습니다. Skill 문서를 읽는 것은 입력이고, 그 안의 판단 기준을 따져보는 것은 추론이며, 도구 호출과 최종 결과를 만드는 것은 출력입니다. 다만 Skill은 항상 로드되지 않고 필요할 때만 선택적으로 읽히므로, 설치해둔 Skill 전부가 매번 비용이 되지는 않습니다. 그래서 핵심 절차는 짧게 쓰고 상세 설명은 별도 참고 파일로 빼는 편이 효율적입니다.

Hook은 조금 다릅니다. 파일을 저장할 때 린트를 돌리는 것처럼 셸 명령만 실행한다면 모델을 부르지 않으니 LLM 토큰은 0입니다.

Hook 자체             토큰 사용 없음
Hook  LLM 호출        호출에서 입력·출력 토큰 발생
Hook 출력  다음 프롬프트   그만큼 입력 토큰 증가

세 번째 줄을 조심해야 합니다. Hook이 모델을 부르지 않더라도, Hook의 실행 결과가 다음 모델 입력에 포함되는 구조라면 그 출력 길이만큼 입력 토큰이 늘어납니다. 로그를 그대로 뱉는 Hook을 걸어두면 조용히 비용이 붙습니다.

토큰의 가치는 모델마다 다르다

모든 LLM이 "토큰"이라는 같은 단어를 쓰지만, 1토큰의 가치는 전혀 같지 않습니다. 토크나이저, 단가, 추론량, 캐시 정책이 전부 다르기 때문입니다.

가상의 숫자로 예를 들면,

Model A   1,000 토큰 = $0.01
Model B   1,000 토큰 = $0.03

같은 1,000토큰이라도 비용은 세 배 차이입니다. 게다가 같은 문장이 A에서는 800토큰, B에서는 1,100토큰으로 잘릴 수도 있습니다. 그러면 실제 격차는 세 배가 아니라 네 배가 넘습니다.

그래서 여러 모델의 사용량을 하나의 시스템에서 관리한다면, 원시 토큰 수를 그대로 쌓는 것은 의미가 없습니다.

모델별 토큰 
    
모델별 실제 단가 적용 (입력 · 출력 · 캐시 쓰기 · 캐시 읽기)
    
실제 비용 산출
    
공통 Credit으로 환산

이렇게 비용 기준으로 환산한 뒤 공통 단위로 통일하는 편이 정확합니다. 이때 입력과 출력의 단가가 다르고 캐시 쓰기와 읽기의 단가도 다르다는 점을 잊으면 안 됩니다. 네 가지를 하나로 뭉뚱그리면 환산 자체가 틀어집니다.

여러 모델을 함께 쓴다면 원시 토큰이 아니라 실제 비용으로 환산한 Credit을 기준으로 삼아야 합니다.

입력 토큰 줄이기

지금까지가 지도였다면 여기부터는 실제로 손을 대는 부분입니다.

시스템 프롬프트와 Rule을 압축합니다. 중복된 규칙과 비슷한 예시는 지웁니다. 이런 문단이 있다면,

절대로 다른 상품의 조건을 현재 상품에 적용해서는  됩니다.
 상품은 독립적으로 판단해야 하며 다른 상품의 문구를 참고하면  됩니다.
다른 상품의 조건을 사용하여 현재 상품을 판단해서도  됩니다.

세 문장은 같은 말을 세 번 한 것입니다.

상품별 조건을 독립적으로 판단하고, 다른 상품의 조건을 전용하지 마라.

길다고 모델이 더 잘 지키지 않습니다. 오히려 긴 프롬프트 안에서는 정말 중요한 규칙이 묻힙니다. 판단 기준과 금지 조건을 명확히 유지하면서 최대한 짧게 쓰는 것이 낫습니다.

필요한 문서만 검색해 넘깁니다. 답에 필요한 문서가 3개인데 30개를 넘기면 입력 토큰만 늘어나는 게 아닙니다. 관련 없는 정보가 섞이면서 모델의 판단 난이도까지 같이 올라갑니다. 검색 정확도가 충분하다면 Top-K를 30에서 5로 줄이는 편이 비용과 품질 양쪽에서 낫습니다.

오래된 대화는 요약합니다. 채팅형 에이전트는 대화가 계속 쌓이고, 그 전체를 매번 실어 보내면 입력 토큰은 단조 증가합니다. 오래된 턴은 핵심만 요약해 남기고 원문은 버리는 편이 낫습니다.

구조화된 데이터는 필요한 필드만 넘깁니다. API 응답 JSON을 통째로 던지는 경우가 많은데,

{
  "product_id": 101,
  "product_name": "기업성장대출",
  "created_at": "...",
  "updated_at": "...",
  "manager_id": 25,
  "internal_code": "...",
  "description": "...",
  "condition": "..."
}

모델이 실제로 봐야 하는 것이 상품명과 조건뿐이라면,

{
  "name": "기업성장대출",
  "condition": "..."
}

이것만 보내면 됩니다. 모델에 넘기기 전에 프로그램 단에서 필드를 걸러내는 것은 가장 확실하고 부작용 없는 절약 수단입니다.

표현 방식을 점검합니다. 같은 의미라도 표현에 따라 토큰 수가 달라집니다.

입력 형태예시효율
영어Hello world대체로 효율적
한글안녕하세요모델에 따라 차이가 큼
ASCII 코드72 101 108 108 111비효율적
이진수01001000 01100101 ...매우 비효율적

한때는 영어가 한글보다 토큰 효율이 확실히 좋았지만, 최근 모델들은 다국어 토큰화가 계속 개선되고 있어 항상 그렇다고 일반화하기 어렵습니다. 쓰려는 모델의 카운팅 API로 직접 재보는 것이 유일하게 정확한 방법입니다.

중요한 것은 영어로 바꾸는 게 아니라 표현 자체를 간결하게 만드는 것입니다. 불필요하게 긴 자연어는 짧고 명확한 자연어로, 복잡한 인코딩은 원래 데이터로, 반복되는 설명은 구조화된 규칙으로 바꾸는 쪽이 훨씬 큰 효과를 냅니다.

반복되는 앞부분은 캐시합니다. 시스템 프롬프트, Rule, 상품 설명, 공통 정책 문서처럼 매 요청 반복되고 잘 변하지 않는 것들이 대상입니다. 다만 앞서 본 대로 캐시는 선불이고 프리픽스 매칭이므로, 걸기 전에 "이게 유지 시간 안에 두세 번 이상 반복되는가"와 "앞쪽에 변하는 값이 끼어 있지 않은가"를 먼저 확인해야 합니다.

응답 속도가 급하지 않다면 배치 API를 봅니다. 대량 분류나 야간 일괄 처리처럼 실시간성이 필요 없는 작업은 배치 API로 돌리면 대체로 절반 가격입니다. 프롬프트를 한 글자도 고치지 않고 비용을 반으로 줄이는 몇 안 되는 방법입니다.

출력 토큰 줄이기

입력만큼 중요한 것이 출력 통제입니다. 에이전트는 긴 설명, 반복되는 분석 과정, 불필요한 JSON을 스스로 만들어내면서 예상보다 많은 출력 토큰을 씁니다.

출력 형식을 명확히 제한합니다. "상품 추천 결과를 알려줘"라고만 하면 모델은 필요 이상으로 설명합니다. 대신 형식을 정해줍니다.

다음 형식으로만 출력한다.

상품명:
추천 여부:
사유: (2문장 이내)

설명이 필요 없는 작업은 결과만 내게 합니다. 판단 과정을 전부 출력하게 하면,

기업규모 조건을 확인하면...
신용등급 조건을 확인하면...
담보 조건을 확인하면...
업종 조건을 확인하면...

따라서 해당 상품은 추천 가능합니다.

사용자에게 필요한 것이 결론뿐이라면 이렇게 줄일 수 있습니다.

추천 가능

사유: 기업규모·신용등급·업종·담보 조건 충족

JSON 구조를 최소화합니다. 구조화된 출력이 필요하다면 키 이름도 토큰입니다.

{
  "product_recommendation_result": {
    "product_name": "기업성장대출",
    "recommendation_status": true,
    "recommendation_reason": "조건 충족"
  }
}

이것보다는,

{
  "name": "기업성장대출",
  "ok": true,
  "reason": "조건 충족"
}

이 정도면 충분합니다. 다만 사람이 직접 읽거나 여러 시스템이 공유하는 API라면 지나친 축약은 유지보수를 해칩니다. 절약과 가독성 사이에서 균형이 필요합니다.

중복 출력을 막습니다. 모델은 같은 내용을 다른 표현으로 반복하는 습관이 있습니다.

추천 가능합니다.
해당 상품은 모든 조건을 충족합니다.
따라서  상품을 추천할  있습니다.

세 문장이 사실상 같은 말입니다. "결론은 한 번만 작성한다" 같은 짧은 규칙 한 줄로 대체로 해결됩니다.

최대 출력 길이는 안전장치로만 씁니다. 실제 결과가 2,000토큰이면 충분한데 상한을 20,000으로 열어둘 이유는 없습니다. 다만 대부분의 서비스는 실제로 생성된 토큰에 과금하므로, 상한을 낮추는 것 자체가 비용을 줄여주지는 않습니다. 상한은 폭주를 막는 안전장치이고, 실제 절약은 모델이 짧게 답하도록 프롬프트와 출력 구조를 설계하는 데서 나옵니다.

여기서 반드시 알아야 할 함정이 하나 있습니다. 최대 출력 길이는 추론 토큰과 답변 토큰의 합을 제한합니다. 추론을 켜둔 상태에서 상한을 빡빡하게 잡으면, 모델이 생각하다가 예산을 다 쓰고 답변이 잘려버립니다. 응답이 중간에 끊긴다면 상한을 올리거나 추론 강도를 낮춰야 합니다.

사용자용 답변과 시스템용 데이터를 분리합니다. 하나의 응답에 상세 분석, 추천 결과, JSON, 로그를 전부 담게 하면 출력 토큰이 크게 늘어납니다. 프로그램이 계산할 수 있는 것은 프로그램이 하고, 모델은 언어 판단이 필요한 부분만 맡는 것이 낫습니다.

LLM           판단
Application   데이터 변환, 정렬, 계산, JSON 구성

모델에게 모든 일을 맡기지 않는 것 자체가 가장 강력한 토큰 최적화입니다.

마무리

서두의 상황으로 돌아가 봅시다. 열 글자 질문에 만 단위 토큰이 나온 이유는 이제 분명합니다. 제가 통제한 것은 그 뭉치의 마지막 한 줄뿐이었고, 나머지는 전부 제가 신경 쓰지 않던 곳에서 왔습니다.

토큰 최적화를 한 문장으로 줄이면 이렇습니다.

필요한 정보만 입력하고, 필요한 판단만 모델에게 맡기고, 필요한 결과만 출력한다.

실무에서 이 원칙이 풀리는 순서는 대략 이렇습니다. 프롬프트와 Rule을 압축하고, 검색은 필요한 문서만 가져오고, 오래된 대화는 요약하고, 반복되는 앞부분은 캐시하고, 도구 결과에서 불필요한 필드를 걸러내고, 출력 형식을 제한하고, 중복 출력을 막고, 프로그램으로 할 수 있는 일은 모델에게 맡기지 않는 것입니다.

그리고 이 중 어느 것도 감으로 하면 안 됩니다. 응답에 찍히는 사용량 정보 — 입력 토큰, 출력 토큰, 캐시 쓰기, 캐시 읽기 — 를 기록해두지 않으면 무엇이 새고 있는지 알 수 없고, 알 수 없는 것은 줄일 수도 없습니다. 최적화의 첫걸음은 프롬프트를 고치는 게 아니라 계량기를 다는 일입니다.

이 글이 도움이 되었나요?

좋아요를 표시하지 않았습니다.

Share this article