3줄 요약
- 3개 프로젝트, 인접 응답 쌍 3,710개를 재현 측정한 결과 컨텍스트 증가분의 1위는 대체로 사고(thinking) 토큰이었다(환산계수 4.5 B/tok 기준 46.8%·57.3%·70.2%, 2026-08-10).
- 전사(transcript)의 thinking 블록은 본문이 빈 문자열이고 signature만 남는다. 블록 바이트를 그대로 세면 사고량이 아니라 서명 바이트를 세게 되며, 우리는 이 함정으로 만든 세 개의 귀속표(36.1%·29.9%·90.7%)를 전부 철회했다.
- 사고 비용은 출력을 축약해도 줄지 않는다. 압축 1단계(오래된 도구 출력 폐기)에도 걸리지 않고 다음 턴 프리픽스에 남기 때문이다. 줄이는 수단은 작업 분할, /clear, effort 등급 하향 순이다.
| 질문 | 답 |
|---|---|
| 컨텍스트 증가분에서 가장 큰 비중은 무엇인가 | 사고(thinking) 토큰. 3개 프로젝트 재현에서 환산계수 4.5 기준 46.8~70.2% |
| 왜 블록 바이트로 세면 안 되는가 | thinking 블록은 본문이 비어 있고 signature만 남아, 바이트를 세면 서명 길이를 세게 된다 |
| 정확히 재려면 어떻게 하는가 | 인접 assistant 쌍의 ctx 차분에서 보이는 바이트를 뺀 나머지를 per-pair median으로 판정한다 |
| 왜 median인가 | 총합비를 쓰면 극단값 몇 개가 그림을 바꾼다. 판정 통계는 쌍별 중앙값이다 |
| 출력을 줄이면 사고 비용도 주는가 | 줄지 않는다. 작업 분할, /clear, effort 하향 세 가지만 실제로 듣는다 |
이 글대로 하면 무엇이 달라지는가: 컨텍스트가 왜 늘어나는지 짐작으로 말하는 대신, 자기 프로젝트 전사에서 사고와 도구결과의 비중을 직접 재고, 자기 환경에서 실제로 듣는 레버가 출력 축약인지 작업 분할인지를 숫자로 정할 수 있게 된다.
Claude Code 세션에서 컨텍스트 증가분 1위는 무엇인가?
세 개의 서로 다른 Claude Code 프로젝트에서 인접 assistant 응답 쌍 3,710개를 재현 분석한 결과, 컨텍스트 증가분의 1위는 세 곳 모두 사고(thinking) 토큰이었다(2026-08-10). 각 쌍의 컨텍스트 증가분에서 도구 결과와 사용자 입력처럼 눈에 보이는 바이트를 빼고 남는 부분을 사고로 귀속했고, 환산계수를 4.5 B/tok으로 고정했을 때 값은 아래와 같았다.
| 프로젝트 A | 프로젝트 B | 프로젝트 C | |
|---|---|---|---|
| 표본 쌍 | 1,691 | 912 | 1,107 |
| per-pair median | 1.083 | 1.063 | 1.051~1.072 |
| 사고 비중(div 4.5) | 70.2% | 46.8% | 57.3% |
| 도구결과·입력(div 4.5) | 16.8% | 36.7% | 8.1% |
세 곳 모두 1위가 사고라는 점은 같았고, 갈린 것은 2위와 레버였다. 프로젝트 B는 도구결과·입력이 36.7%라 출력 축약이 실제로 먹히지만, 프로젝트 C는 8.1%라 같은 처방이 거의 듣지 않는다. 그래서 이 표는 그대로 옮겨 쓰라고 내놓은 것이 아니라 "자기 프로젝트에서 재라"는 뜻으로 내놓은 것이다.
왜 thinking 블록 바이트로 세면 틀리는가?
전사에 저장되는 thinking 블록은 본문이 빈 문자열이고 signature 필드만 채워져 남기 때문이다. 블록의 바이트 수를 사고량으로 계산하면 실제로 세는 것은 사고 내용이 아니라 서명의 길이가 된다.
오진 1단계. 전사에 남은 블록을 종류별로 바이트 점유율로 집계해 귀속표를 만들었다. 방법 자체는 단순하고 재현도 잘 됐다. 왜 틀렸나. 블록 종류 중 하나(thinking)만 본문이 비어 있다는 사실을 계산에 넣지 않았다. 그래서 사고가 실제로 얼마나 컸든 표에는 서명 길이만큼만 잡혔다. 드러난 방식. 세 프로젝트가 각각 36.1%, 29.9%, 90.7%라는 서로 크게 다른 값을 냈는데, 그중 하나는 "도구결과가 1위"라는 정반대 결론까지 냈다. 같은 방법이 프로젝트마다 다른 1위를 내놓는다면 의심할 것은 프로젝트가 아니라 방법이다. 결과. 세 귀속표를 전부 철회했다. 철회는 값을 고치는 것이 아니라 방법을 바꾸는 것이었다.
usage 델타란 전사 블록의 바이트가 아니라 각 응답에 기록된 사용량 값에서 컨텍스트 점유를 직접 계산하고 인접 응답 사이에서 차분하는 측정 방식이다. 보이지 않는 것을 세려면 보이는 것을 빼는 수밖에 없다.
그럼 어떻게 재야 정확한가?
블록 바이트 대신 usage 델타를 쓰고, 판정 통계를 쌍별 중앙값으로 잡는다. 절차는 다섯 단계다.
- 전사를 읽되
requestId로 중복을 제거한다. 전사는 같은 요청을 2~3행으로 중복 기록하므로 이 단계를 빼면 사용량이 약 1.9배로 과대 계상된다. - 각 assistant 응답의 컨텍스트 점유를 계산한다.
# ctx = input + cache_read + cache_creation
# 필드 이름은 자기 전사 스키마에 맞춰 바꾼다
def ctx_of(u):
return u["input"] + u["cache_read"] + u["cache_creation"]
- 인접한 두 응답에서 차분해 증가분을 얻고, 그 사이에 실제로 들어간 보이는 바이트(도구 결과, 사용자 입력, 가시 출력)를 토큰으로 환산해 뺀다. 남는 것이 사고 귀속분이다.
DIV = 4.5 # 바이트→토큰 환산 계수. 값을 바꾸면 결론이 바뀌므로 보고할 때 함께 적는다
def pair_ratio(prev, cur, visible_bytes):
delta = ctx_of(cur["usage"]) - ctx_of(prev["usage"])
visible = visible_bytes / DIV
return delta / visible if visible else None # 쌍마다 하나씩 나온다
- 쌍마다 나온 값을 모아 중앙값(per-pair median)으로 판정한다. 총합비를 쓰면 큰 쌍 몇 개가 전체를 끌고 간다.
- 계수를 명시해 보고한다. 계수를 적지 않은 구성비는 판단 근거가 되지 못한다.
이 방식으로 얻은 per-pair median은 세 프로젝트에서 1.083, 1.063, 1.051~1.072였다. 값이 1보다 크다는 것은 보이는 바이트만으로 설명되지 않는 증가분이 매 쌍마다 꾸준히 있다는 뜻이고, 그 잔차가 사고다. 그리고 사고가 다음 턴의 프리픽스에 남는다는 것은 세 프로젝트 모두에서 재현됐다(3/3).
환산 계수를 표기하지 않으면 왜 위험한가?
같은 데이터의 구성비가 계수 하나로 크게 흔들리기 때문이다. 같은 재현 데이터를 계수 3.5로 계산하면 0.670, 4.5로 계산하면 0.902가 나온다. 사고 비중도 4.5 기준으로는 46.8~70.2%지만 3.5 기준으로는 31.6~61.7%다. 계수는 이 측정에서 최대 오차원이고, 그래서 우리는 4.5로 고정하고 구성비를 말할 때 계수를 함께 적는다.
여기서 함께 챙길 판별 기준이 두 개 더 있다.
| 헷갈리는 지점 | 옳은 판정 |
|---|---|
| 총합비 대 중앙값 | 판정 통계는 per-pair median이다. 총합비는 극단값에 끌려간다 |
| 문자 수가 큰 것 대 토큰이 큰 것 | 이미지 base64는 문자 수만 클 뿐 토큰은 작다. 문자 수로 범인을 지목하면 오판한다 |
| 큰 도구 대 잦은 도구 | 범인은 큰 도구가 아니라 잦은 도구다. 한 프로젝트에서 Bash가 43.8%를 차지한 것은 316번 호출됐기 때문이다 |
마지막 줄의 도구별 귀속(Bash 43.8%, Edit 11.5%, Write 11.3%, 에이전트 보고 10%, Read 7.3%)은 한 프로젝트의 워크로드이고 바이트 기준 값이다. 다른 프로젝트에 그대로 옮기면 안 된다.
사고 비용은 어떻게 줄이는가?
출력을 축약하는 방법으로는 줄지 않는다. 사고는 압축의 1단계(오래된 도구 출력 폐기)에 걸리지 않고 다음 턴 프리픽스에 그대로 남기 때문이다. 실제로 듣는 수단은 세 가지이며, 순서대로 시도한다.
- [ ] 작업을 분할한다. 한 세션에서 끝까지 끌고 가려던 일을 경계에서 끊는다. 비용이 2차식이라 세션을 반으로 자르면 비용은 4분의 1이 된다(
cache_read 총량 = 평균 컨텍스트 × 턴 수, 실측 458k × 471 = 216M로 일치). - [ ] 주제가 바뀌면
/clear한다. 이건 무료다. 이름을 남기고 싶으면/rename후/clear, 필요하면 나중에/resume. - [ ] effort 등급을 낮춘다. 루틴 작업은 낮게, 어려운 설계·디버깅·검증만 높게 쓴다.
# 작업 난이도에 맞춰 사고량을 조절한다
/effort low
/effort xhigh
# 사고 자체를 끄는 설정 (문법 주의: thinking=false 가 아니다)
/config alwaysThinkingEnabled=false
effort를 내리는 것이 목록의 마지막인 이유가 있다. 사고를 끄면 도구 사용의 적극성이 함께 떨어지는 경향이 관찰돼, 조사·디버깅 같은 작업에서는 오히려 왕복이 늘 수 있다. 그래서 먼저 세션을 자르고, 그 다음에 등급을 내린다.
한편 자주 손대게 되는 고정 선두부(전역 지침 파일, 프로젝트 지침 파일, 메모리) 감량은 부차적 레버다. 46.6k짜리 선두부는 471턴 세션에서 총 사용의 0.26%p에 해당했다. 본문 누적이 본질이고 선두부는 곁가지다. 다만 선두부를 줄이면 압축 후 바닥과 압축 1회 비용이 함께 내려가므로, 압축이 누적이 아니라 한 턴에서 비롯된다는 실측과 함께 보면 여유 확보 수단으로서의 값어치는 따로 있다.
왜 매 턴 몰아서 하는 것이 그렇게 중요한가?
턴 수가 곧 비용이기 때문이다. cache_read 총량 = 평균 컨텍스트 × 턴 수라는 산식에서, 어떤 턴에 넣은 1토큰의 진짜 비용은 그 뒤에 남은 턴 수에 비례한다. 대표 세션(471요청) 실측에서 cache_read는 216.5M(총 사용의 2.54%p)이었고 output은 0.43M(0.05%p)이었다. 읽기가 쓰기의 50배다. 같은 세션에서 컨텍스트는 102k에서 814k까지 자랐다.
이것이 실무 규칙 두 개로 이어진다. 첫째, 순차 의존이 없는 명령은 한 턴에 몰아서 낸다. 둘째, 서브에이전트를 띄운 뒤 상태를 되묻는 확인 턴을 만들지 않는다. 확인 턴 하나가 전체 컨텍스트를 다시 태우기 때문에, 큰 컨텍스트에서는 확인 열 번이 서브에이전트 1기 값에 맞먹는다.
이 측정이 통하지 않는 조건은 무엇인가?
이 방법은 전사 파일에 접근할 수 있고 응답별 사용량 값이 남아 있는 환경을 전제한다. 그 값이 없으면 usage 델타를 만들 수 없고, 남은 선택지는 우리가 이미 철회한 바이트 세기뿐이다. 또한 잔차 귀속 방식이라 "보이는 바이트"를 얼마나 정확히 걷어내느냐에 결과가 달렸다. 걷어내지 못한 항목이 있으면 그만큼이 사고로 잘못 귀속된다. 계수 문제도 남아 있다. 4.5는 고정하기로 정한 값이지 검증된 상수가 아니며, 3.5로 바꾸면 같은 데이터가 0.670에서 0.902로 움직인다. 그래서 이 글의 숫자들은 "사고가 1위였다"는 순위 판정에는 쓸 수 있어도, 절대 비중을 그대로 인용하기에는 조건이 붙는다.
가장 중요한 한계는 이식성이다. 세 프로젝트에서 1위는 같았지만 2위와 레버는 8.1%와 36.7%로 크게 갈렸다. 남의 귀속표로 자기 프로젝트의 대책을 세우면, 듣지 않는 처방(출력 축약)에 시간을 쓰고 듣는 처방(작업 분할)을 미루게 된다. 표를 옮기지 말고 스크립트를 옮겨야 한다. 이 측정 방법론 자체도 직접 측정한 것만 쓴다는 규칙 아래서 철회와 재검증을 거친 값이다.
자주 묻는 질문
Q. Claude Code 컨텍스트 증가분에서 가장 큰 비중을 차지하는 것은 무엇인가?
A. 사고(thinking) 토큰이다. 3개 프로젝트 3,710쌍 재현에서 환산계수 4.5 기준 46.8~70.2%를 차지했고 세 곳 모두 1위였다. 계수를 3.5로 잡으면 같은 데이터가 31.6~61.7%가 된다.
Q. thinking 블록 바이트를 그대로 세면 왜 틀리는가?
A. 전사에 남는 thinking 블록은 본문이 빈 문자열이고 signature 필드만 채워져 있기 때문이다. 블록 바이트를 세면 사고량이 아니라 서명 길이를 세게 되며, 이 방식으로 만든 세 개의 귀속표(36.1%·29.9%·90.7%)를 우리는 전부 철회했다.
Q. 정확한 측정 절차는 무엇인가?
A. requestId로 중복을 제거하고, 각 응답의 ctx = input + cache_read + cache_creation을 계산해 인접 쌍에서 차분한 뒤, 보이는 바이트(도구 결과·사용자 입력)를 환산해 빼고 남는 잔차를 사고로 귀속한다. 판정은 총합비가 아니라 쌍별 중앙값으로 한다.
Q. 환산 계수는 왜 함께 표기해야 하는가?
A. 같은 데이터가 계수 3.5에서 0.670, 4.5에서 0.902로 흔들리기 때문이다. 계수는 이 측정의 최대 오차원이므로 계수를 적지 않은 구성비는 판단 근거가 되지 못한다.
Q. 사고 비용을 줄이려면 어떻게 해야 하는가?
A. 출력 축약으로는 줄지 않는다. 작업 분할, /clear, effort 등급 하향 순으로 시도한다. effort 하향이 마지막인 이유는 사고를 끄면 도구 사용 적극성이 함께 떨어지는 경향이 있어 조사형 작업에서는 왕복이 늘 수 있기 때문이다.
Comments
Comments (0)
Leave a Comment