**컨텍스트 창(Context Window)**은 언어 모델이 응답을 생성할 때 한 번에 참조할 수 있는 모든 텍스트의 총량이며, 에이전트 시스템에서는 **작업 기억(Working Memory)**에 해당합니다. 모델 내부에 고정된 사전 학습 지식과 달리 사용자의 현재 지시, 읽어 들인 파일 내용, 이전 대화 및 도구 실행 결과가 실시간으로 이곳에 담깁니다.

하지만 언어 모델 API는 기본적으로 **무상태(Stateless)**로 동작합니다. 따라서 Claude Code 같은 에이전트가 이전 맥락을 기억하며 작업을 완수하려면 매 요청마다 지금까지 주고받은 전체 대화 기록을 매번 다시 전송해야 합니다. 이 구조적 특성 때문에 작업이 길어질수록 단순한 한 줄 질문조차 거대한 토큰을 소모하게 되며, 컨텍스트가 차오를 때 발생하는 **자동 압축(Auto-compaction)**과 **컨텍스트 부패(Context Rot)**를 제어하는 능력이 에이전트 운용의 성패를 가릅니다.

요청이 진행될수록 시스템 지침과 누적된 이전 대화 전체가 매번 다시 실려 요청 크기가 점점 커지는 구조


1. 무상태 API와 누적되는 컨텍스트

대화형 챗봇이나 코딩 에이전트를 쓸 때 흔히 착각하는 점은 “모델이 이전 대화를 서버 어딘가에 기억하고 있을 것”이라는 생각입니다. 실제로는 그렇지 않습니다.

  1. 매 요청 시 전체 재전송: 모델 자체는 이전 턴의 기억을 보관하지 않습니다. 에이전트 런타임은 세션을 유지하기 위해 [시스템 프롬프트 + CLAUDE.md + 1턴 대화 + 2턴 대화 + ... + 현재 요청]을 하나의 거대한 프롬프트로 묶어 매번 새로 보냅니다. 도구를 한 번 실행할 때마다 도구 결과가 대화에 추가되어 다음 요청의 크기가 계속 불어납니다.
  2. 턴의 누적과 토큰 폭증: 10번째 턴에서 사용자가 “계속해줘”라는 짧은 한 문장을 보내더라도, 모델이 실제로 읽고 처리하는 입력 토큰은 1번째부터 9번째 턴까지의 모든 파일 읽기 결과와 로그 출력이 합쳐진 수만~수십만 토큰에 달합니다.
  3. 컨텍스트 부패(Context Rot): 컨텍스트 창의 최대 크기가 수십만~수백만 토큰으로 늘어났다고 해서 모든 문제가 해결되지는 않습니다. 컨텍스트에 담긴 텍스트 양이 많아질수록 모델이 세부 지침을 놓치거나 오래된 정보에 혼란을 겪는 회상률 저하(Context Rot) 현상이 발생합니다. 따라서 창이 넓더라도 불필요한 데이터를 비우고 핵심만 남기는 작업이 필수적입니다.

2. 세션 컨텍스트의 구성요소: 고정 비용과 가변 비용

세션 안에서 소비되는 토큰은 아무것도 묻지 않은 첫 요청부터 이미 발생하는 고정 베이스라인과, 작업을 수행하며 쌓이는 가변 누적 비용으로 나뉩니다.

시점 및 분류컨텍스트에 포함되는 항목비용 특성
고정 베이스라인 (세션 시작 즉시)시스템 프롬프트, CLAUDE.md, 자동 영구 메모리(Auto Memory), 등록된 스킬의 설명(Description), MCP 도구 목록세션 내 모든 요청마다 매번 기본 포함되는 고정 비용
가변 누적 비용 (작업 진행 중)파일 읽기 내용(Read), 터미널 명령 출력(Bash), 대화 히스토리, 호출된 스킬 본문작업이 진행될수록 선형적·지수적으로 계속 누적
온디맨드 주입 (필요 시)특정 파일 경로와 일치할 때 로드되는 하위 규칙(.claude/rules/), 하위 디렉터리 CLAUDE.md관련 파일을 수정하거나 읽을 때만 일시적으로 주입

이 구조를 알면 왜 공식 문서가 **“CLAUDE.md를 200줄 미만으로 유지하라”**고 강조하는지 이해할 수 있습니다. CLAUDE.md의 모든 문장은 에이전트가 도구를 호출할 때마다 수십, 수백 번씩 반복해서 모델에 재전송되기 때문입니다. 매번 알 필요가 없는 절차성 지침은 스킬로 분리하여 필요할 때만 호출하도록 만드는 것이 컨텍스트 엔지니어링의 기본입니다.


3. 한계와 생존: 자동 압축(Auto-compaction)의 메커니즘

작업을 계속 이어가 컨텍스트 창이 한계 용량에 근접하면, 세션이 끊기거나 에러가 발생하는 대신 **자동 압축(Auto-compaction)**이 실행됩니다.

자동 압축은 지금까지의 긴 대화와 도구 출력 기록을 모델을 통해 간결한 **요약본(Summary)**으로 치환하는 과정입니다. 이 요약을 통해 작업 공간을 대폭 확보하지만, 필연적으로 정보의 선별과 유실이 발생합니다.

압축 후 살아남는 것과 유실되는 것

구분압축 후 상태 및 동작
시스템 프롬프트 & CLAUDE.md디스크에서 다시 읽어와 완벽하게 복원 및 유지
작업 계획(Plan) & Auto memory디스크에서 재주입되어 보존
최근 읽거나 수정한 파일최근 작업한 파일 최대 5개를 디스크에서 다시 읽음 (초과 파일은 경로 참조로 축소)
호출했던 스킬 본문지정된 토큰 상한 내에서 최신 순으로 유지 (초과분은 앞부분만 남거나 버려짐)
대화 중 말로 전달한 세부 규칙요약 과정에서 누락되거나 사라질 위험이 매우 높음
장황한 터미널 출력·검색 결과핵심 결론만 요약에 남고 원본 로그는 폐기됨

영구 규칙은 대화창이 아니라 CLAUDE.md에

대화 도중 사용자가 “앞으로는 항상 X 방식으로 작성해줘”라고 입력한 지침은 자동 압축이 한 번 돌고 나면 요약 과정에서 흔적도 없이 사라질 수 있습니다. 세션 내내 유지되어야 하는 프로젝트 불변의 법칙은 반드시 CLAUDE.md에 작성해 두어야 디스크에서 안전하게 재주입됩니다.


4. 토큰이 실제 비용과 사용량이 되는 원리

Claude Code의 사용량 과금은 모델이 처리한 입력(Input) 토큰, 생성한 출력(Output) 토큰, 그리고 **프롬프트 캐싱(Prompt Caching)**의 적중 여부에 의해 결정됩니다.

1) 프롬프트 캐싱의 실체와 착시

최신 LLM 환경에서는 반복 전송되는 시스템 프롬프트와 이전 대화 기록을 재사용하는 프롬프트 캐싱 기술이 적용됩니다. 캐시된 입력 토큰은 일반 입력 토큰보다 훨씬 저렴한 요율(약 10% 수준)로 계산됩니다.

하지만 주의할 점은 캐싱이 비용을 낮춰줄 뿐, 컨텍스트 창의 점유 자체를 줄여주지는 않는다는 사실입니다. 아무리 캐시 할인을 받더라도 컨텍스트 창은 물리적으로 가득 차며, 긴 세션에서는 단순한 질문에도 거대한 캐시 읽기(Cache Read) 비용이 매번 누적됩니다. 또한 일정 시간(캐시 수명) 동안 대화를 멈췄다가 다시 시작하면 캐시 미스(Cache Miss)가 발생하여 전체 컨텍스트를 정가로 다시 읽어 들이게 됩니다.

2) 사고 토큰(Extended Thinking)의 가중치

복잡한 문제 해결을 위해 활성화되는 모델의 심층 사고(Thinking) 과정에서 생성되는 토큰은 일반 응답과 동일하게 출력 토큰으로 과금됩니다. 단순한 작업에 불필요하게 높은 사고 예산이 잡혀 있으면 턴마다 수천에서 수만 개의 토큰이 추가 소모되므로, 작업의 복잡도에 따라 사고 강도(/effort)나 모델 선택을 조절하는 것이 경제적입니다.


5. 컨텍스트 엔지니어링과 제어 전략

컨텍스트와 비용을 능동적으로 통제하기 위한 핵심 원칙은 다음과 같습니다.

  1. 작업 주제 전환 시 과감한 /clear: 버그 수정을 마치고 새로운 기능 개발로 넘어갈 때는 이전 대화를 계속 이어가지 말고 /clear로 컨텍스트를 비웁니다. 이전 대화 기록은 로컬에 안전하게 보존되므로 필요하면 언제든 /resume으로 돌아올 수 있으며, 새 세션은 깨끗한 0 토큰 상태에서 가장 빠르고 정확하게 동작합니다.
  2. 초점을 지정한 압축 (/compact [지침]): 컨텍스트가 차오르기 전에 사용자가 직접 /compact Focus on authentication logic and test results처럼 남겨야 할 핵심 정보를 명시하여 요약의 질을 통제합니다.
  3. 서브에이전트를 통한 컨텍스트 차단벽 구축:
    • 수백 개의 파일을 스캔하거나 방대한 빌드 로그를 분석해야 하는 작업은 메인 대화창에서 직접 수행하지 않고 **서브에이전트(Subagent)**에게 위임합니다.
    • 서브에이전트는 완전히 분리된 자기만의 컨텍스트 창에서 시끄러운 작업을 수행한 뒤, 메인 대화창에는 정제된 결론 요약만 전달합니다. 메인 대화창의 컨텍스트가 오염되지 않으므로 세션 전체의 수명과 가성비가 획기적으로 향상됩니다.

연관 노트와 구현

컨텍스트 관리 원리가 다중 에이전트 구조와 확장 단위에서 어떻게 구현되는지는 아래 글에서 확인할 수 있습니다.