패스노트
도메인 5. 컨텍스트 관리와 신뢰성

5.1컨텍스트 윈도우 관리

예상 학습 시간 40

컨텍스트 윈도우(context window)는 Claude가 한 번에 볼 수 있는 정보의 총량이며, 에이전틱 시스템의 성능과 비용을 좌우하는 핵심 자원입니다. 이 수업에서는 토큰 예산 수립, 긴 컨텍스트 배치 전략, 압축(compaction)의 함정, 프롬프트 캐싱(prompt caching)까지 컨텍스트를 자원으로 다루는 방법을 배웁니다.

컨텍스트 윈도우는 유한한 자원이다

Claude의 컨텍스트 윈도우는 시스템 프롬프트, 대화 이력, 툴 정의, 툴 결과, 그리고 모델이 생성하는 출력까지 모두 포함하는 단일 토큰 예산입니다. 최신 Claude 모델은 20만 토큰(일부 모델은 100만 토큰 베타)을 지원하지만, "많이 넣을 수 있다"와 "많이 넣어야 한다"는 다른 문제입니다.

핵심 원칙은 컨텍스트를 무한한 저장소가 아니라 한정된 작업 기억(working memory)으로 취급하는 것입니다. 컨텍스트가 커질수록 발생하는 문제는 세 가지입니다.

  • 비용: 입력 토큰은 매 요청마다 다시 과금됩니다. 에이전틱 루프에서는 같은 컨텍스트가 수십 번 재전송됩니다.
  • 지연 시간: 입력이 길수록 첫 토큰까지의 시간(TTFT)이 늘어납니다.
  • 주의력 희석: 관련 없는 정보가 많을수록 모델이 정말 중요한 지시를 놓칠 확률이 올라갑니다. Anthropic 엔지니어링 블로그는 이를 "컨텍스트 부패(context rot)"라 부르며, 가장 작은 고신호(high-signal) 토큰 집합을 찾으라고 권고합니다.

토큰 사용량은 추측하지 말고 측정해야 합니다. Messages API의 usage 필드 또는 토큰 카운팅 API를 사용합니다.

import anthropic

client = anthropic.Anthropic()
count = client.messages.count_tokens(
    model="claude-sonnet-4-5",
    system="당신은 계약서 검토 보조자입니다.",
    messages=[{"role": "user", "content": contract_text}],
)
print(count.input_tokens)  # 요청 전에 예산 초과 여부를 확인

시험에서는 "컨텍스트가 남아 있으면 문서를 전부 넣는 것이 항상 낫다"는 식의 선택지가 자주 등장합니다. 정답은 대부분 "필요한 최소한의 고신호 컨텍스트만 유지한다"입니다.

긴 컨텍스트 배치 전략

20만 토큰을 실제로 활용해야 하는 작업(계약서 비교, 대규모 로그 분석 등)에서는 배치 순서가 성능에 영향을 줍니다. Anthropic 공식 가이드의 권고는 다음과 같습니다.

  • 긴 문서를 위에, 질문·지시를 아래에 둡니다. 긴 자료 뒤에 지시가 오면 모델이 지시를 더 잘 따릅니다. 공식 문서는 문서를 상단에 두는 것만으로 응답 품질이 최대 30% 개선될 수 있다고 안내합니다.
  • XML 태그로 문서를 구조화합니다. 여러 문서를 넣을 때는 각 문서를 메타데이터와 함께 감쌉니다.
<documents>
  <document index="1">
    <source>2025년_공급계약서.pdf</source>
    <document_contents>...</document_contents>
  </document>
  <document index="2">
    <source>2026년_갱신계약서.pdf</source>
    <document_contents>...</document_contents>
  </document>
</documents>

두 계약서의 위약금 조항 차이를 표로 정리하세요.
  • 근거 인용을 먼저 요구합니다. 답변 전에 관련 구절을 인용하게 하면 모델이 문서의 해당 부분에 주의를 집중하게 되어 환각(hallucination)이 줄어듭니다.

또 하나의 설계 판단은 긴 컨텍스트 vs 검색 증강(RAG) 선택입니다. 자료 전체가 상호 참조되어야 하는 작업(계약서 전문 비교)은 긴 컨텍스트가 유리하고, 방대한 코퍼스에서 일부만 필요한 작업(사내 위키 질의응답)은 검색으로 필요한 조각만 가져오는 편이 비용·품질 모두 낫습니다. 시험에서는 작업의 성격을 보고 어느 쪽이 적절한지 고르게 합니다.

압축과 요약의 함정

장시간 실행되는 에이전트는 결국 컨텍스트 한도에 부딪히고, 이때 대화 이력을 요약해 새 세션으로 넘기는 **압축(compaction)**이 필요합니다. Claude Code의 자동 압축이 대표적인 구현입니다.

압축은 강력하지만 손실 압축이라는 점을 잊으면 안 됩니다. 요약 과정에서 사라지기 쉬운 정보는 다음과 같습니다.

  • 실패한 시도와 그 이유 — 요약에서 빠지면 에이전트가 같은 실패를 반복합니다.
  • 정확한 식별자 — 파일 경로, 함수명, 오류 코드가 뭉뚱그려지면 이후 작업이 어긋납니다.
  • 사용자의 제약 조건 — "X는 절대 수정하지 말 것" 같은 지시가 유실되면 위험한 행동으로 이어집니다.

안전한 압축 설계의 원칙은 세 가지입니다.

  1. 구조화된 요약 템플릿을 사용합니다. 자유 서술 대신 "완료된 작업 / 미완료 작업 / 결정 사항과 근거 / 제약 조건 / 다음 단계" 같은 고정 항목을 채우게 합니다.
  2. 원본을 버리지 않습니다. 요약은 컨텍스트에 넣되, 원본 대화나 산출물은 파일·데이터베이스 등 외부 저장소에 남겨 필요할 때 다시 조회할 수 있게 합니다. 파일 시스템을 에이전트의 장기 기억으로 쓰는 패턴입니다.
  3. 압축 시점을 임계값으로 관리합니다. 예를 들어 컨텍스트의 70~80% 도달 시 압축을 트리거하면, 압축 자체를 수행할 여유 공간이 남아 있을 때 안전하게 전환할 수 있습니다.
[압축 요약 템플릿 예시]
## 완료: 결제 모듈 리팩터링 (src/pay/checkout.ts)
## 미완료: 환불 로직 테스트 3건 실패 중 (test/refund.test.ts:41)
## 결정: 재시도는 지수 백오프 3회로 확정 (사용자 승인됨)
## 제약: DB 스키마 변경 금지
## 다음 단계: 실패 테스트의 mock 데이터 수정

시험 함정: "컨텍스트가 가득 차면 오래된 메시지부터 자동으로 잘라낸다"는 선택지는 오답입니다. 무엇을 버릴지는 정보의 가치 기준으로 설계해야 하며, 단순 절단(truncation)은 제약 조건 유실 위험이 가장 큰 방식입니다.

프롬프트 캐싱으로 비용과 지연 줄이기

에이전틱 루프에서는 시스템 프롬프트, 툴 정의, 초기 문서처럼 **매 요청마다 반복되는 접두부(prefix)**가 큽니다. 프롬프트 캐싱(prompt caching)은 이 접두부를 서버에 캐시해 두고 재사용하는 기능으로, 캐시 히트 시 해당 구간의 입력 비용이 약 10분의 1로 줄고 지연도 크게 감소합니다.

response = client.messages.create(
    model="claude-sonnet-4-5",
    system=[
        {
            "type": "text",
            "text": long_system_prompt_and_reference_docs,
            "cache_control": {"type": "ephemeral"},
        }
    ],
    messages=conversation,
)

캐싱을 효과적으로 쓰기 위한 규칙은 다음과 같습니다.

  • 캐시는 접두부 단위로 동작합니다. cache_control 지점까지의 내용이 완전히 동일해야 히트합니다. 따라서 안정적인 내용(시스템 프롬프트, 툴 정의)은 앞에, 자주 바뀌는 내용(사용자 메시지)은 뒤에 배치합니다.
  • 접두부 중간에 타임스탬프나 난수를 넣으면 매번 캐시가 무효화됩니다. 동적 값은 가능한 한 메시지 뒤쪽에 둡니다.
  • 기본 캐시 수명(TTL)은 5분이며 히트할 때마다 갱신됩니다. 캐시 쓰기는 기본 요금보다 약간 비싸므로(약 1.25배), 같은 접두부를 두 번 이상 쓰는 경우에 이득입니다.
  • 최소 캐시 가능 길이(모델에 따라 1,024 또는 2,048 토큰) 미만의 짧은 접두부는 캐시되지 않습니다.

멀티턴 에이전트에서는 대화가 길어질수록 캐싱 이득이 커집니다. 이전 턴 전체를 캐시하고 새 턴만 비캐시로 처리하는 패턴이 표준입니다. 시험에서는 "캐싱은 응답 품질을 높인다"(오답 — 품질이 아니라 비용·지연 개선)와 "캐시 지점 이후 내용이 바뀌어도 히트한다"(오답 — 접두부 일치 필요) 같은 함정이 출제됩니다.

에이전틱 루프의 컨텍스트 위생

툴을 반복 호출하는 에이전트는 툴 결과가 컨텍스트에 계속 쌓입니다. 수십 KB짜리 검색 결과나 로그 덤프가 몇 번만 쌓여도 컨텍스트가 급격히 소모됩니다. 이를 관리하는 실무 기법을 **컨텍스트 위생(context hygiene)**이라 부를 수 있습니다.

  • 툴 결과를 요약·절단해서 반환합니다. 툴 자체가 상위 N건, 관련 필드만 반환하도록 설계하는 것이 모델에게 후처리를 맡기는 것보다 낫습니다.
  • 오래된 툴 결과 정리: 최신 Claude API의 컨텍스트 편집(context editing) 기능은 오래된 툴 결과를 자동으로 비워 컨텍스트를 회수합니다. 결과의 상세 내용은 이미 모델의 후속 판단에 반영되었으므로, 원문 자체는 제거해도 되는 경우가 많습니다.
  • 탐색은 서브에이전트에게 위임합니다. 대량의 파일을 읽어야 하는 탐색 작업을 서브에이전트에 맡기면, 부모 컨텍스트에는 결론 요약만 돌아오고 중간 산출물은 부모 컨텍스트를 오염시키지 않습니다.
  • 외부 메모리 활용: 진행 상황을 NOTES.md 같은 파일에 기록하게 하면, 컨텍스트가 초기화되어도 파일을 다시 읽어 작업을 복원할 수 있습니다.
나쁜 패턴: grep 결과 3,000줄 전체를 툴 결과로 반환
좋은 패턴: 일치 파일 목록 + 파일당 대표 매치 2줄 + "총 214건" 요약 반환

이 원칙들은 도메인 1(서브에이전트 컨텍스트)과 직접 연결됩니다. 시험에서는 "메인 에이전트가 모든 파일을 직접 읽어 전체 맥락을 확보해야 한다"는 선택지가 전형적인 오답입니다.

시험 함정

  • "컨텍스트 윈도우가 크므로 가능한 모든 자료를 넣는 것이 항상 유리하다" — 오답. 관련 없는 토큰은 비용·지연을 늘리고 주의력을 희석시킵니다.
  • "프롬프트 캐싱은 응답 품질을 개선한다" — 오답. 캐싱은 비용과 지연을 줄일 뿐 출력 내용에는 영향이 없습니다.
  • "캐시 지점 앞의 내용이 조금 바뀌어도 캐시는 유지된다" — 오답. 캐시는 접두부가 완전히 일치해야 히트합니다.
  • "컨텍스트가 차면 오래된 메시지부터 잘라내는 것이 표준이다" — 오답. 단순 절단은 제약 조건 유실 위험이 가장 크며, 구조화된 요약(압축)이 표준입니다.
  • "요약은 무손실이므로 원본을 버려도 된다" — 오답. 압축은 손실 과정이므로 원본은 외부 저장소에 보존해야 합니다.
  • "긴 문서는 질문 뒤에 두는 것이 좋다" — 오답. 공식 가이드는 긴 문서를 상단에, 질문을 하단에 두라고 권고합니다.

실습 시나리오

실제 시험과 같은 형식의 시나리오 문제입니다.

고객 지원 에이전트가 40턴 넘게 이어진 대화에서 컨텍스트 한도의 85%에 도달했습니다. 대화 초반에는 고객의 계정 ID와 "환불은 절대 자동 처리하지 말 것"이라는 운영 제약이 있었습니다. 가장 적절한 조치는 무엇입니까?

빌드 연습 · 압축 파이프라인 구현

50
  1. 1.토큰 사용량 계측

    count_tokens API로 대화 이력의 토큰량을 측정하는 함수를 작성합니다.

    기대 결과 · 메시지 배열을 받아 입력 토큰 수를 반환하는 measure() 함수가 동작합니다.

  2. 2.임계값 트리거 설계

    한도의 75% 도달 시 압축을 트리거하는 조건 분기를 추가합니다.

    기대 결과 · 긴 더미 대화를 넣으면 압축 분기로 진입하는 것이 로그로 확인됩니다.

  3. 3.구조화된 요약 프롬프트 작성

    완료/미완료/결정/제약/다음 단계 5개 항목을 강제하는 요약 프롬프트를 만듭니다.

    기대 결과 · 요약 결과에 5개 항목이 모두 포함되고, 파일 경로·ID가 원문 그대로 보존됩니다.

  4. 4.원본 보존

    압축 전 대화 원본을 타임스탬프가 붙은 JSON 파일로 저장합니다.

    기대 결과 · 압축 후에도 원본 대화를 파일에서 복원할 수 있습니다.

  5. 5.유실 검증

    압축 전후로 '제약 조건' 항목이 보존되는지 확인하는 테스트를 작성합니다.

    기대 결과 · 제약 조건이 요약에서 누락되면 테스트가 실패합니다.

출처 및 더 읽기