SHIFTONE

토큰 단가는 그대로인데 요금만 늘어요 — AI 에이전트 비용이 대화 길이의 제곱으로 붙는 이유

AI 에이전트 비용을 요청 1건 단가로 잡으면 운영에서 어긋납니다. LLM API는 대화를 기억하지 않아 매 턴 이력 전체를 다시 보내고, 입력 토큰은 턴 수의 제곱으로 쌓이거든요. 공개 단가와 캐시 규칙으로 20턴 세션을 직접 계산해 봤어요.

벽면에 격자로 줄지어 붙은 전력 계량기들 — 세션마다 따로 돌아가는 토큰 미터

"요청 1건에 얼마예요?"

AI 에이전트 도입 검토 자리에서 가장 자주 받는 질문이에요. 답하기가 늘 곤란한데, 질문이 틀려서가 아니라 요청 1건이 과금의 단위가 아니기 때문입니다.

파일럿에서는 안 보여요. 질문 하나 던지고 답 하나 받고 끝내니까요. 운영에 올라간 에이전트는 되묻고, 검색하고, 다시 답합니다. 한 세션이 20턴쯤 이어지는 건 흔한 일이에요.

매 턴, 대화 전체가 다시 청구서에 올라가요

LLM API는 대화를 기억하지 않아요. Anthropic Messages API 문서도 이걸 "stateless multi-turn conversations"라고 적어 뒀습니다. 이전 턴을 이어가려면 대화를 전부 다시 담아 보내야 해요.

10번째 턴의 입력은 "방금 친 한 줄"이 아니라 "시스템 프롬프트 + 도구 정의 + 앞선 9턴 전부 + 방금 친 한 줄"이에요. 누적 입력 토큰이 턴 수가 아니라 턴 수의 제곱에 비례해 늘어나는 이유입니다.

턴이 넘어갈 때마다, 앞선 대화가 통째로 다시 실려 갑니다 1턴 · 2,100 5턴 · 8,500 10턴 · 16,500 20턴 · 32,500 40턴 · 64,500 막대 높이 = 그 턴 한 번에 청구되는 입력 토큰(값에 비례). 사용자가 새로 친 건 매번 100토큰인데, 20턴째에는 앞선 이력 30,400토큰이 함께 실려 갑니다.

그래서 단가표보다 계산기를 먼저 씁니다

견적 요청이 오면 단가를 곱하기 전에 세션 하나의 토큰 흐름부터 적어요. 가정은 넷입니다. 고정 프리픽스(시스템 프롬프트 + 도구 정의) 2,000, 사용자 발화 100, 응답 300, 도구 호출과 결과가 남기는 1,200토큰.

P, U, A, T = 2000, 100, 300, 1200   # 프리픽스 · 사용자 · 응답 · 도구결과
history, cumulative = 0, 0
for turn in range(1, 41):
    billed = P + history + U        # 이번 턴에 청구되는 입력
    cumulative += billed
    history += U + A + T            # 다음 턴부터는 이것도 매번 함께 간다

1턴짜리 요청은 2,100토큰인데, 20턴 세션은 누적 346,000토큰이에요. 턴당 평균으로 환산하면 첫 요청의 8.2배입니다.

세션 길이그 턴의 입력세션 누적 입력턴당 평균
1턴2,1002,1002,100
10턴16,50093,0009,300
20턴32,500346,00017,300
40턴64,5001,332,00033,300

실제 청구서가 아니라 위 가정으로 돌린 계산값이에요. 그래도 방향은 같습니다. 요청 단가로 잡은 견적은 세션이 길수록 아래로 틀려요.

불어나는 건 대화가 아니라 도구 결과였어요

줄일 대상은 대화 이력이 아니었어요. 사용자 발화는 턴당 100토큰인데 도구가 물어 온 결과는 1,200토큰이고, 그게 세션 끝까지 함께 실려 다니거든요. RAG 청크 대여섯 개면 이 크기가 됩니다.

도구 결과를 200토큰 요약으로 접고 원문은 참조 키만 남기면 누적 입력이 156,000토큰, 약 55% 줄어듭니다. 모델을 싼 걸로 바꾸는 것보다 이쪽이 먼저예요.

캐시는 이 곱셈을 나눗셈으로 바꾸지만, 조건이 붙어요

매 턴 다시 보내는 앞부분은 직전 요청과 토큰 단위로 같으니, 프롬프트 캐싱이 정확히 들어맞아요. Anthropic 기준 캐시 읽기는 기본 입력 단가의 0.1배, 5분 쓰기 1.25배, 1시간 쓰기 2배입니다(OpenAI도 GPT-5.6 이후 같은 모양). 매 턴 적중을 가정하면 20턴 세션의 실효 입력이 36,900 수준으로 떨어져요.

다만 최선의 경우고, 실제로는 세 곳에서 깨집니다.

  • 프리픽스가 최소 길이 미달일 때. 모델별 최소 토큰 수(512 · 1,024 · 2,048 · 4,096)에 못 미치면 조용히 캐시 없이 처리되고 에러도 안 나요.
  • 브레이크포인트를 변하는 값 위에 걸었을 때. 시스템 프롬프트 끝에 현재 시각을 넣는 패턴이요. 해시가 달라져 적중률이 0이 됩니다.
  • 도구 정의를 요청마다 손댈 때. 무효화가 toolssystemmessages 순으로 흘러내려요. 사용자별 도구 목록을 동적 조립하면 여기 걸립니다.
AS-ISTO-BE
견적 단위요청 1건당 토큰세션 1건당 토큰
도구 결과원문 그대로 이력에 적재최근 2턴만 원문, 이전은 요약 + 참조 키
프리픽스요청마다 동적 조립고정하고 브레이크포인트를 정적 꼬리에
경보 기준월 총액 초과 시 알림세션당 토큰 p95 초과 시 알림

결국 견적서와 대시보드의 단위를 바꾸는 일이에요

처방은 위 표가 거의 전부인데, 더 자주 고쳐 드리는 건 단위예요. 견적서에 요청당 원가가 적혀 있으면 운영 팀은 요청 수를 봅니다. 정작 튀는 건 세션 길이인데요. 파일럿에서 프로덕션으로 넘어갈 때 무너지는 지점에서 관측을 세션 단위로 잡자고 적었는데, 비용도 같아요. 토크나이저를 손봐 정답 문서를 상위로 올렸을 때처럼 처음부터 맞는 걸 넣으면 되묻는 턴도 줄어듭니다(관련 역량).

"요청 1건에 얼마예요?"에 요즘 드리는 답은 이렇습니다. 요청이 아니라 세션으로 물어봐 주세요. 답은 단가표가 아니라, 그 세션에서 컨텍스트를 어떻게 쓰기로 했는지가 정합니다.

자주 묻는 질문

Q. AI 에이전트 비용을 미리 추정하려면 무엇부터 정해야 하나요? A. 모델보다 세션의 모양을 먼저 정하세요. 평균 턴 수, 턴당 도구 호출 수, 도구 결과의 평균 토큰, 프리픽스 길이면 누적 입력 토큰이 나옵니다. 단가는 그다음이에요.

Q. 프롬프트 캐싱을 켰는데 청구액이 그대로면 무엇을 봐야 하나요? A. 응답 usagecache_read_input_tokens가 0인지 보세요. 0이면 적중이 없는 겁니다. 프리픽스가 최소 길이에 미달하거나, 브레이크포인트 앞에 매번 바뀌는 값이 있거나, 도구 정의가 요청마다 달라지는 경우예요.

Q. 컨텍스트를 줄이면 답변 품질이 떨어지지 않나요? A. 무엇을 줄이느냐에 달렸어요. 원문 JSON을 통째로 남기는 건 품질에 거의 기여하지 않으면서 토큰만 차지합니다. 반대로 앞선 요구사항을 잘라 내면 품질이 바로 떨어져요. 도구 결과부터 접고 대화 이력은 마지막에 손대는 이유예요.

Sources