토큰과 비용 감각 — 대화가 길어지면 얼마가 드나
한 줄 요약
토큰(token) 은 LLM이 글을 세는 단위이고, 요금은 이 숫자로 매겨집니다. 멀티턴은 매번 대화 전체를 다시 보내므로 턴이 늘수록 한 번 말할 때마다 입력량이 늘어납니다. 실제 숫자로 확인해 봅니다.
1. 토큰이란
LLM은 글을 글자 단위도, 단어 단위도 아닌 "토큰"이라는 조각 단위로 처리합니다. 자주 쓰는 덩어리는 통째로 한 토큰, 드문 것은 여러 토큰으로 쪼개집니다.
직접 세어 볼 수 있습니다.
아래는 개념 설명용 코드입니다 — 실습 파일에 넣지 않습니다.
print(client.models.count_tokens(model=GEMINI_MODEL, contents="안녕하세요").total_tokens)
실제 측정값입니다.
| 문자열 | 글자 수 | 토큰 수 |
|---|---|---|
"안녕하세요" |
5 | 2 |
"hello world" |
11 | 3 |
"승승장구몰 주문 O001203은 지금 어떤 상태인가요?" |
28 | 21 |
한글은 영어보다 토큰을 많이 씁니다. 흔한 단어("안녕하세요")는 잘 뭉쳐지지만, 상품 코드나 고유명사("승승장구몰", "O001203")는 잘게 쪼개집니다. 대략 한글 1~2글자에 1토큰 정도로 감을 잡아 두면 충분합니다.
2. 사용량 확인하기
응답 객체에 들어 있습니다.
아래는 개념 설명용 코드입니다 — 실습 파일에 넣지 않습니다.
resp = client.models.generate_content(...)
print(resp.usage_metadata)
prompt_token_count=70 candidates_token_count=14 total_token_count=84
| 이름 | 무엇 | 요금 |
|---|---|---|
prompt_token_count |
입력 — 시스템 지시 + 대화 전체 | 싸다 |
candidates_token_count |
출력 — 모델이 만든 답변 | 비싸다 (보통 입력의 몇 배) |
thoughts_token_count |
모델이 속으로 생각한 양 (모델에 따라) | 출력 쪽으로 계산 |
total_token_count |
합계 | — |
출력이 입력보다 비쌉니다. 그래서 "간결하게 답하라"는 시스템 지시는 품질뿐 아니라 비용에도 직접 영향을 줍니다.
3. 멀티턴에서 실제로 무슨 일이
앞 절의 대화를 실제로 측정한 값입니다.
| 턴 | 실어 보낸 대화 | 입력 토큰 | 출력 토큰 | 합계 |
|---|---|---|---|---|
| 1턴 | 1개 | 70 | 14 | 84 |
| 2턴 | 3개 | 93 | 8 | 101 |
| 3턴 | 5개 | 111 | 28 | 139 |
출력은 그대로인데 입력이 계속 늘어납니다. 70 → 93 → 111.
이유는 앞 절에서 본 그대로입니다. 매번 지난 대화를 전부 다시 보내니까요.
1턴 입력 = 시스템 지시(약 60) + "김민준입니다"(약 10)
2턴 입력 = 시스템 지시(약 60) + 1턴 대화 전체 + 이번 질문
3턴 입력 = 시스템 지시(약 60) + 1·2턴 대화 전체 + 이번 질문
막대로 그리면 이렇게 보입니다. 글자가 든 칸만 실제로 나가는 내용입니다. 칸의 가로 폭은 대략적인 비율이니, 정확한 값은 칸 안에 적힌 숫자를 보세요.
사용자는 매번 짧은 한마디만 던지는데, 왼쪽 칸 전부가 매번 다시 나갑니다. 그 왼쪽 첫 칸이 무엇인지는 바로 다음 4절에서 이어집니다.
이게 왜 중요한가
대화가 20턴, 50턴으로 길어지면 한마디를 주고받을 때 보내는 입력량이 처음의 수십 배가 됩니다. 사용자는 짧은 질문 하나를 던졌을 뿐인데도요.
이걸 왜 알아야 하나 — 이걸 모르면 챗봇을 만들어 놓고 "왜 이렇게 요금이 많이 나오지?" 라고 할 때, 원인이 대화 길이라는 걸 떠올리지 못합니다. 그리고 그 해결책(오래된 대화 잘라내기, 요약해서 넣기)도 생각해 낼 수 없습니다.
4. 시스템 지시도 매번 나갑니다
위 표에서 1턴 입력이 70토큰이었습니다. 그런데 사용자가 보낸 건 "제 이름은 김민준입니다." 뿐입니다.
나머지 약 60토큰은 시스템 지시입니다.
아래는 code/ch02_chat.py 의 일부입니다 — 위에서 이미 붙여 넣었으니 다시 넣지 마세요.
SYSTEM = (
"너는 승승장구몰의 CS 상담원이다. "
"고객에게 존댓말로, 두 문장 이내로 간결하게 답한다. "
"확실하지 않은 정보는 '확인 후 안내드리겠습니다'라고 답한다. "
"생각 과정은 쓰지 않고 최종 답변만 말한다."
)
이 지시가 호출할 때마다 함께 나갑니다. 100줄짜리 시스템 지시를 쓰면 대화 100번에 100번 모두 그 요금을 냅니다. 2절에서 "길다고 좋은 게 아니다"라고 한 이유입니다.
5. 8장에서 특히 조심할 것
미리 알아 두세요. 이 과정에서 호출량이 가장 많은 곳은 8장입니다.
계산식은 1 + 2N + 1 입니다. 담당자가 몇 명이냐에 따라 호출 수가 그대로 늘어납니다.
질문 하나에 열 번 안팎으로 호출됩니다. 팀장이 작업을 잘게 나눌수록(= N이 커질수록) 늘어납니다. 짧은 시간에 여러 번 연달아 실행하면 API 한도(429 RESOURCE_EXHAUSTED)에 걸리기 쉽습니다. 한 번 실행한 뒤 1~2분 간격을 두고 실행하세요.
이것 역시 멀티에이전트의 실제 비용입니다. 답의 품질이 올라가는 대신 호출 수가 몇 배가 됩니다. 무엇을 얻고 무엇을 내주는지 아는 것이 설계입니다.
6. 요금은 얼마나 드나
모델별 단가는 자주 바뀌므로 이 교재에 숫자를 박아 두지 않습니다. 확인은 여기서 하세요.
- 공식 가격표: https://ai.google.dev/pricing
대신 감만 잡아 둡시다.
gemini-2.5-flash는 이름 그대로 빠르고 저렴한 모델입니다. 같은 계열의pro보다 몇 배 저렴합니다.- 이 과정의 실습 전체(8장을 여러 번 반복 실행해도)는 무료 티어 한도 안에서 대체로 진행됩니다.
- 실제 서비스로 넘어갈 때 비용을 좌우하는 것은 단가보다 호출 횟수와 대화 길이입니다.
비용을 줄이는 실질적인 방법 세 가지 — ① 시스템 지시를 짧게, ② 답변을 간결하게(출력이 비싸다), ③ 오래된 대화를 잘라내거나 요약해서 보내기. 셋 다 코드 몇 줄로 되는 일입니다.
스스로 해 보기
ch02_chat.py 의 chat() 이 사용량도 함께 돌려주도록 고쳐 보세요.
직접 고쳐 보기 —
agentic_ai/code/ch02_chat.py의chat()을 열어, 원래generate_content(...)호출은 그대로 둔 채return바로 앞에 아래 두 줄만 끼워 넣고 다시 실행하세요.
u = resp.usage_metadata
print(f" (입력 {u.prompt_token_count} / 출력 {u.candidates_token_count} 토큰)")
그리고 [3] 의 대화를 5턴 이상으로 늘려 보세요. 입력 토큰 수가 어떻게 늘어나는지 직접 확인하는 것이 이 연습의 목적입니다.
핵심 정리
- 토큰은 LLM이 글을 세는 단위입니다. 한글은 대략 1~2글자에 1토큰입니다.
- 사용량은
resp.usage_metadata에 들어 있고, 입력(prompt)과 출력(candidates) 이 나뉩니다. 출력이 더 비쌉니다. - 멀티턴은 매번 대화 전체를 다시 보내므로 턴이 늘수록 입력 토큰 수가 늘어납니다 (실측 70 → 93 → 111).
- 시스템 지시도 호출할 때마다 함께 나갑니다. 짧게 쓰는 것이 곧 비용 절감입니다.
- 8장은 질문 하나에
1 + 2N + 1번 호출합니다 — 작업 수에 따라 8번에서 20번 가까이. 멀티에이전트의 대가입니다. - 비용을 줄이는 법: 짧은 지시 · 간결한 답변 · 오래된 대화 정리.