Claude 세션 한 번에 1,880달러 지출: 트윗 하나를 쓰기 위해 소설 네 권을 읽다
요약
Claude Code 사용 중 발생한 급격한 비용 상승 원인을 로그 분석을 통해 규명합니다. 특정 장기 세션에서 컨텍스트 누적과 캐시 효율 저하로 인해 읽기 대 쓰기 비율이 1,000:1에 달하며 막대한 비용이 발생했음을 보여줍니다.
핵심 포인트
- Claude Code의 세션 로그(`~/.claude/projects`)를 통해 상세 사용량 분석 가능
- 장기 세션의 컨텍스트 누적으로 인해 대화 후반부 턴당 비용 급증
- 읽기 대 쓰기 비율이 1,000:1에 달하는 비효율적인 워크플로우 주의 필요
- 프롬프트 캐시를 사용하더라도 컨텍스트가 커지면 비용 부담이 가중됨
월요일에 저는 아직 이틀이나 남았음에도 불구하고 Claude의 주간 제한(weekly limit)에 도달했습니다. 그 전주는 괜찮았습니다. 제 워크플로우(workflow)에서 달라진 점은 전혀 없었는데, 바로 이런 상황이 추측을 멈추고 데이터를 읽어야 할 때입니다.
Claude Code는 모든 세션의 전체 기록을 ~/.claude/projects에 작성하며, API 메시지당 한 줄의 JSONL 형식으로 저장됩니다. 각 줄에는 입력 토큰(input tokens), 캐시 쓰기(cache writes), 캐시 읽기(cache reads), 출력(output)을 포함한 완전한 사용량 블록이 포함되어 있습니다. 아무도 이 파일들을 보지 않지만, 이것이 바로 모든 해답을 담고 있습니다.
저는 이 파일들을 집계하는 스크립트를 작성했습니다. 지난주와 그 전주를 비교하면 다음과 같습니다:
| 전주 | 급증한 주 | |
|---|---|---|
| 예상 비용 (API 환산) | $991 | $4,199 |
| ... |
절대적인 수치로 보면, 급증한 주에는 API를 통해 14억 8천만 개의 토큰이 통과되었습니다. 소설 한 권당 약 10만 토큰이라고 가정할 때, 이 모델은 한 명의 개발자를 일주일 동안 돕기 위해 15,000권 분량의 소설에 해당하는 컨텍스트(context)를 읽었습니다. 그리고 그 토큰의 99.6%는 입력(input)이었습니다. 모델이 실제로 무언가를 말한 것은 550만 토큰뿐이었습니다. 나머지는 다시 읽는 과정이었습니다.
저의 첫 번째 의심 대상은 백그라운드 시스템들이었습니다. 저는 예약된 Sonnet 호출을 통해 동기화되는 세컨드 브레인(second-brain) 위키를 운영하고 있으며, Haiku로 모든 세션을 관찰하는 메모리 플러그인도 사용합니다. 둘 다 비용이 많이 들 것 같은 종류의 작업들입니다. 하지만 이 둘을 합쳐도 청구 금액의 5% 미만이었으며, 급증한 주에는 오히려 그 비중이 줄어들었습니다. 모든 압축 스타트업이 저를 위해 줄이고 싶어 하는 도구 출력(Tool output)은 오차 범위 수준이었습니다.
진짜 정답은 세션별 상세 내역의 네 줄에 있었습니다. 각각 98시간에서 133시간 동안 유지된 네 개의 세션이 $4,199 중 약 $3,150를 차지했습니다. 그중 소셜 미디어 모니터링 루프(social-media watch loop)를 수행한 단 한 번의 세션이 혼자서 $1,880를 소모했습니다. 이는 단 하나의 대화가 일주일 사용량의 45%를 차지한 것입니다. 그 한 세션은 38만 4천 토큰을 내뱉기 위해 약 4억 개의 토큰을 처리했습니다. 즉, 읽기 대 쓰기 비율(read-to-write ratio)이 1,000 대 1이었습니다. 턴(turn)당 모델은 약 470 토큰, 즉 긴 트윗 하나를 생성하기 위해 약 40만 토큰, 즉 소설 네 권 분량을 읽었습니다.
마라톤 세션의 메커니즘
내부에서 볼 때 해당 세션들은 전혀 비싸 보이지 않았습니다. 개별 메시지 하나하나에는 평범했습니다. 비용은 두 가지 복합적인 메커니즘 속에 숨어 있습니다.
첫째, 컨텍스트 누적 (context accumulation)입니다. 대화는 추가만 가능한 로그 (append-only log)이며, 모델은 매 턴마다 그 모든 내용을 다시 읽습니다. 워치 루프 (watch-loop) 세션은 마지막에 이르러 API 호출당 평균 40만 토큰의 컨텍스트를 기록했습니다. 이 정도 규모에서는 "새로운 내용 없음, 다시 확인 중"이라고 말하는 한 번의 턴만으로도 전체 히스토리 비용을 지불하게 됩니다. 세션 후반부의 턴들은 각각 1달러 이상의 비용이 들었습니다. 해당 턴들의 출력은 평균 470 토큰이었습니다. 저는 문장 하나를 받기 위해 소설 한 권 분량의 비용을 지불하고 있었던 것입니다.
둘째, 캐시 혼란 (cache churn)입니다. Anthropic의 프롬프트 캐시 (prompt cache)는 재독 컨텍스트 비용을 입력 가격의 10분의 1 수준으로 저렴하게 만들어 주지만, 캐시에는 TTL (Time To Live, 생존 시간)이 있습니다. 저의 사용 패턴은 폭발적 (bursty)입니다. 저는 원격 제어 세션을 통해 휴대폰으로 작업하기 때문에, 한 세션 내에서 메시지가 몰아치다가도 몇 시간 동안 정적이 흐르곤 합니다. TTL보다 긴 모든 정적은 캐시를 방출 (evict)하며, 다음 턴은 캐시 쓰기 (cache-write) 가격으로 전체 컨텍스트를 다시 작성하게 됩니다. 이는 가장 비싼 토큰 클래스입니다. 해당 세션 하나에서 7,270만 토큰의 캐시 쓰기가 기록되었습니다. 컨텍스트 전체가 수십 번에 걸쳐 캐시에 다시 작성된 것입니다.
대화 기록을 단 하나도 읽지 않고도 데이터에서 이 특징을 직접 확인할 수 있습니다. 바로 캐시 읽기 (cache reads) 대 캐시 쓰기 (cache writes)의 비율입니다. 저의 비율은 평범한 주간의 17:1에서 급증한 주간에는 7:1로 떨어졌습니다. 비율이 떨어진다는 것은 컨텍스트가 제공 (served)되는 대신 재구축 (rebuilt)되고 있음을 의미합니다.
또한 언급할 가치가 있는 세 번째 발견이 있는데, 다른 사람들도 현재 이와 같은 실수를 하고 있을 것이라 의심됩니다. 워치 루프는 세션 내 스케줄러 (in-session scheduler)에서 실행되었습니다. 즉, 라이브 세션 내부에서 생성되어 매시간 프롬프트를 다시 실행하는 반복 작업 (recurring job)입니다. 이러한 작업들은 자신을 생성한 세션 내부에서 실행됩니다. 매 실행은 동일한 대화에 내용을 추가합니다. 세션 내부의 시간 단위 스케줄은 당신의 한도를 바닥내는 정확히 40만 토큰의 컨텍스트를 제조하는 기계와 같습니다.
왜 압축을 시도하지 않았는가
저는 지난달에 토큰 압축 도구(token-compression tool) 환경에 대해 글을 썼으며, 저 또한 그 도구 중 하나를 직접 운영하고 있습니다. 따라서 압축 기술을 적용하는 것이 당연한 선택처럼 보였습니다. 하지만 데이터는 아니라고 말했습니다. 해당 분야에서 가장 성숙한 도구인 Headroom은 도구 출력값과 JSON을 축소함으로써 코딩 에이전트(coding agents)의 비용을 15-20% 절감한다고 주장합니다. 하지만 제 도구의 출력값은 노이즈였습니다. 비용 급증의 80% 이상은 대화 기록(conversation history)이 반복해서 읽히고 다시 캐싱(re-cached)되는 데서 발생했습니다. 종료하기를 거부하는 대화에서 압축만으로는 문제를 해결할 수 없습니다.
올바른 최적화 단위는 세션 수명(session lifetime)입니다.
해결책: 핸드오프(handoff), 종료(kill), 콜드 스타트(cold start)
제가 그 세션들을 절대 닫지 않았던 이유는, 세션을 닫는 것이 상태(state)를 잃는 것처럼 느껴졌기 때문입니다. 대화 속에는 결정 사항, 미결 항목, 컨텍스트(context)가 담겨 있었습니다. 따라서 해결책은 상태가 '죽음' 이후에도 살아남게 만든 다음, 자유롭게 세션을 종료하는 것입니다.
-
핸드오프 노트 (Handoff notes). 작업 단위(work chunk)를 마친 세션은 리포지토리(repo)에
HANDOFF-<date>.md파일을 작성합니다: 상태, 이유를 포함한 결정 사항, 미결 항목, 다음 단계. 이미 종료된 세션들의 경우, 요약 스크립트(digest script)와 각각 단 한 번의 Haiku 호출을 통해 대화 기록(transcripts)으로부터 노트를 생성했습니다. 비용은 프로젝트당 약 1센트 정도였습니다. -
자동 주입 (Auto-injection).
SessionStart훅(hook)이 프로젝트 내에서 가장 최신 핸드오프 노트를 찾아 모든 새로운 세션의 컨텍스트에 주입합니다. 또한 이는/clear명령 시에도 실행되어,/clear를 단 한 번의 키 입력으로 리셋할 수 있게 만듭니다. 동일한 세션, 동일한 전화 스레드(phone thread)를 유지하면서도 컨텍스트는 수십만 토큰에서 약 1만 5천 토큰으로 떨어지며, 핸드오프 노트는 이미 로드된 상태가 됩니다. -
방치된 세션을 위한 상한선. 설정의 `
상시 가동 세션을 위한 일일 재순환 (Daily recycling). 전화 워크플로우는 24시간 내내 세션이 살아있어야 하므로, 이제 각 프로젝트는 이름이 지정된 tmux 세션에서 실행됩니다. 새벽 4시에 실행되는 launchd 작업은 어제의 트랜스크립트 (transcript)를 요약하고, 새로운 핸드오프 (handoff) 노트를 작성하며, 세션을 종료한 뒤 아침 브리핑과 함께 깨끗한 상태로 세션을 다시 생성합니다. 도달 가능성은 동일하게 유지하면서, 컨텍스트 (context)는 최악의 경우에도 하루 전 상태로 유지됩니다.
워치 루프 (watch loop) 자체는 퇴보한 사례가 되었습니다. 그것은 애초에 지속적인 대화 형태여서는 안 되었습니다. 이제 그것은 디스크 상의 상태 파일 (state file)이며, 제가 필요할 때마다 실행하는 새로운 스캔 및 초안 작성 세션입니다. 루프 버전이 하루 평균 300달러를 소모했던 것에 비해, 각 실행 비용은 단 몇 센트에 불과합니다.
도구 (The tooling)
감사 스크립트와 핸드오프 메커니즘은 이제 debloat라는 이름의 작은 오픈 소스 Claude Code 플러그인이 되었습니다. /usage-audit은 사용량이 어디에 쓰였는지 알려주고 마라톤 세션을 표시하며, /handoff는 노트를 작성하고, 훅 (hook)은 이를 다시 로드하며, 상시 가동 재순환 레시피는 문서에 포함되어 있습니다. 감사는 전적으로 사용자의 로컬 트랜스크립트에서 실행됩니다. 네트워크도, API 키도 필요 없으며, 단 30초면 당신에게도 1,880달러짜리 세션이 있었는지 확인할 수 있습니다.
마지막으로 수치를 정리하겠습니다. 급증했던 주간에는 하루 평균 600달러를 기록했으며, 정점은 1,639달러였습니다. 수정 후 첫 전체 영업일에는 유사한 작업량 하에서 125달러가 발생했으며, 이는 사고 이전의 기준치보다 낮은 수준입니다. 마라톤 세션 후반부의 턴 (turn)당 비용은 1달러 이상이었습니다. 리셋 후 동일한 프로젝트, 동일한 작업에서의 턴당 비용은 약 5센트였습니다. 모델이 저렴해진 것이 아닙니다. 대화가 짧아진 것입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기