Skip to content

Context rot ​

이 장에서 얻는 것

  • "advertised context window"(공식 스펙상 컨텍스트 길이)와 "effective context"(실제로 신뢰 가능한 길이)가 왜, 어느 정도 벌어지는지 1차 출처로 확인한다.
  • Lost in the Middle의 위치 편향(position bias)과 Chroma의 context rot가 서로 다른 현상이며 둘 다 대응이 필요함을 구분한다.
  • context rot 수치를 자신의 파이프라인 설계 근거로 그대로 가져다 쓰면 안 되는 이유와, 대신 무엇을 측정해야 하는지 체크리스트로 정리한다.

왜 문제가 되는가 ​

컨텍스트 윈도우가 128K, 200K, 1M 토큰까지 늘어나면서 "필요한 문서를 다 넣고 모델에게 맡기자"는 설계가 유혹적으로 보인다. 그러나 여러 독립 연구가 공통적으로 보이는 결론은, 컨텍스트 윈도우가 늘어나는 속도와 그 안에서 모델이 실제로 정보를 신뢰성 있게 활용하는 능력이 늘어나는 속도가 다르다는 것이다. 입력 토큰이 늘어날수록 정확도가 균일하게 유지되지 않고, 문서 안에서의 위치, 방해 정보(distractor)의 존재, 태스크의 성격에 따라 비선형적으로 무너진다. 이 현상을 Chroma의 2025년 기술 리포트는 "context rot"라 부른다.

이 장은 이 책의 대상 독자와 읽는 법 "이 책의 한계" 섹션에서 이미 경고한 대로, context rot 수치가 태스크·모델 쌍(task-model pair)에 의존하며 모델 단독 속성이 아니라는 점을 구체적인 1차 자료로 뒷받침한다. RAG 파이프라인에서 "몇 개 문서까지 넣어도 안전한가", "몇 K 토큰까지 컨텍스트를 채워도 되는가"를 결정하는 실무자는 이 장의 데이터를 최신 pricing/quota 문서처럼 재확인해야 할 대상으로 취급해야 한다 — 모델 버전이 바뀌면 숫자도 바뀐다.

핵심 개념 ​

Context rot vs. Lost in the Middle ​

두 용어를 혼용하는 경우가 많지만 엄밀히는 다른 관측을 가리킨다.

  • Lost in the Middle (Liu et al., TACL 2024)는 위치 편향을 가리킨다. 관련 정보가 컨텍스트의 시작이나 끝 근처에 있을 때 정확도가 가장 높고, 중간에 있을 때 가장 낮아지는 U자형 곡선(U-shaped curve)을 multi-document QA와 key-value retrieval 태스크에서 관찰했다. 이 저하는 "명시적으로 long-context를 지원하는 모델에서도" 나타난다고 논문 초록이 밝힌다.
  • Context rot (Chroma, 2025-07)는 길이 자체에 따른 저하를 가리킨다. GPT-4.1, Claude 4, Gemini 2.5, Qwen3를 포함한 18개 프런티어 모델 전부에서, 입력 길이가 늘어날수록 정확도가 불균일하게 떨어졌고, 일부 조건에서는 문서에 적힌 컨텍스트 윈도우 한계보다 훨씬 이전에 30~50%까지 정확도가 하락했다.

즉 "짧은 문서를 컨텍스트 앞쪽에 배치하면 문제가 해결된다"는 처방은 위치 편향만 완화할 뿐, 길이 자체가 유발하는 context rot는 그대로 남는다. 두 현상은 독립적으로 존재하므로 완화 전략도 따로 검증해야 한다.

Chroma "Context Rot" 리포트가 실제로 보인 것 ​

Chroma의 Kelly Hong, Anton Troynikov, Jeff Huber가 2025년 7월 14일 발표한 기술 리포트는 다음을 확인했다.

  • 테스트 대상: Anthropic(Claude Opus 4, Sonnet 4, Sonnet 3.7, Sonnet 3.5, Haiku 3.5), OpenAI(o3, GPT-4.1/mini/nano, GPT-4o, GPT-4 Turbo, GPT-3.5 Turbo), Google(Gemini 2.5 Pro/Flash, Gemini 2.0 Flash), Alibaba(Qwen3-235B-A22B, Qwen3-32B, Qwen3-8B) — 총 18개 모델.
  • needle-question 사이의 의미적 유사도가 낮을수록 긴 컨텍스트에서 정확도 하락이 가속화된다.
  • 방해 정보(distractor)가 하나만 있어도 성능이 떨어지고, 여러 개면 더 떨어진다.
  • 반직관적으로, haystack(배경 텍스트)이 논리적으로 매끄럽게 연결되어 있을 때가 무작위로 섞여 있을 때보다 성능이 더 나빴다.
  • 반복 단어(repeated words) 태스크에서 모델별 "응답 거부/미시도(non-attempt)" 비율 자체가 편차가 컸다(예: GPT-3.5 Turbo 60.29%, Claude Opus 4 2.89%, GPT-4.1 2.55%) — 이는 "정확도 저하"와는 구분되는 별도의 실패 양상이다.

⚠️ 비공식 출처 기반 — 공식 문서 교차확인 필요 "실효 컨텍스트는 광고값의 1/4~1/10에 불과하다"는 표현은 실무 커뮤니티에서 널리 반복되지만, Chroma의 원문 리포트나 이 장에서 인용한 다른 1차 자료 어디에도 이 정확한 비율은 명시되어 있지 않다. Chroma 리포트가 확인한 것은 "일부 조건에서 문서상 한계 이전에 30~50%까지 정확도가 하락한다"는 것이며, 1M 토큰급 컨텍스트 모델에서는 대략 300,000~400,000 토큰 구간부터 저하가 눈에 띄게 관찰되는 사례가 보고된다. 이 챕터에서는 "1/4~1/10"이라는 비율을 사실로 서술하지 않는다. 별도로, 단일 저자·비주류 학술 트랙(AAIML, 2025년 9월 제출)에서 나온 Maximum Effective Context Window 논문은 일부 모델이 "광고된 컨텍스트 윈도우의 최대 99%까지" 실효 용량을 밑돈다고 주장하나, 저자 1인·동료 검증 범위가 좁은 최신 프리프린트이므로 공식 벤치마크로 인용하지 말고 독립 재현 전까지는 참고 자료로만 취급한다.

RAG 맥락에서의 저하: Databricks Mosaic 연구 ​

Databricks Mosaic Research의 "Long Context RAG Performance of LLMs"(arXiv:2411.03538, 2024-11-05)는 OpenAI, Anthropic, Google DeepMind, Meta, 오픈소스 모델 등 20개 모델을 Databricks DocsQA, FinanceBench, Natural Questions 세 데이터셋에서 2,000~2,000,000 토큰 범위로 비교했다.

  • Llama 3.1 405B: 약 32K 토큰을 넘어서면서 성능이 하락하기 시작.
  • GPT-4-0125-preview: 약 64K 토큰을 넘어서면서 성능이 하락하기 시작.
  • 다수의 오픈소스 모델(예: Mixtral-8x7B-instruct, DBRX-instruct)은 16K~32K 토큰 구간에서 이미 유효 RAG 태스크 한계에 도달한다.
  • Claude 3 Sonnet은 저작권(copyright) 우려를 이유로 답변을 거부하는 비율이 컨텍스트 길이에 따라 급격히 증가했다 — 16K에서 3.7%, 32K에서 21%, 64K에서 49.5%. (원문에 명시된 모델은 Claude 3 Sonnet이며, Claude 3.5 Sonnet이라는 표기는 이 리포트의 표현과 다르므로 인용 시 모델 버전을 정확히 구분해야 한다.)
  • 이 리포트는 실패를 다섯 범주로 분류한다: 오답(wrong answer), 반복 생성(repeated content, 예: Mixtral의 의미 없는 문자 반복), 무작위/무관 응답, 지시 불이행(instruction non-compliance, 예: DBRX가 답변 대신 요약을 출력), 거부(refusal, 저작권 등의 이유로 답변 자체를 하지 않음).

거부(refusal)를 "정확도 저하"와 별도의 실패 모드로 다뤄야 한다는 점이 이 리포트의 핵심 시사점 중 하나다. 정확도만 측정하면 "거부"는 오답과 동일하게 0점 처리되어 원인 분석이 왜곡된다.

미정착 영역

"실효 컨텍스트 길이"는 모델의 고정된 속성이 아니라 태스크·모델 쌍에 의존하는 값이다. 같은 모델이라도 needle-in-a-haystack 태스크에서는 200K에서도 안정적이지만, 다중 홉 추론이나 저작권 감수성이 높은 요약 태스크에서는 16K에서 이미 무너질 수 있다. 따라서 "이 모델의 실효 컨텍스트는 X K 토큰"이라는 단일 숫자로 요약하는 것 자체가 이 연구들이 경고하는 오독이다. 이 책의 대상 독자와 읽는 법 — 이 책의 한계에서도 동일하게 경고한다. 반드시 자신의 태스크·데이터·모델 조합으로 재측정하라.

결정 표 ​

상황선택이유트레이드오프
RAG에서 검색 문서 수를 늘려 recall을 높이고 싶다문서 수 증가보다 reranking으로 상위 k개 품질을 높이는 쪽을 우선Chroma·Databricks 모두 방해 정보(distractor) 추가가 문서를 더 넣는 이득을 상쇄함을 보임reranking 지연시간·비용 추가
긴 컨텍스트에 여러 문서를 순서대로 이어붙인다정답 후보를 컨텍스트 앞/뒤쪽에 배치, 중간 배치 회피Lost in the Middle의 U자형 곡선문서 순서 재배열 로직 필요, 사전순/시간순 등 자연 순서 훼손 가능
컨텍스트 길이를 늘려 사전 청소(pre-filtering) 없이 원문을 통째로 넣으려 한다태스크별 상한선을 사전에 측정해 청킹·요약·검색 파이프라인 유지Databricks: Llama 3.1 405B ~32K, GPT-4-0125-preview ~64K 이후 저하, 다수 오픈소스 16~32K파이프라인 복잡도 증가, 청킹 경계에서 정보 손실 위험
모델이 답변하지 않는 사례가 늘어난다정확도(accuracy)와 별도로 거부율(refusal rate)을 SLI로 분리 계측Claude 3 Sonnet 저작권 거부율이 16K 3.7%→64K 49.5%로 급증한 사례처럼 거부가 정확도 지표에 숨어버릴 수 있음거부/오답/무응답 분류 로직 추가 필요
"이 모델은 1M 토큰까지 안전하다"는 벤더 스펙만으로 설계 확정자체 데이터셋으로 needle-question 유사도가 낮은 조건을 포함해 재측정Chroma: 낮은 유사도 쌍에서 저하 가속, 벤더 스펙은 이상적 조건에서 측정자체 평가셋 구축·유지 비용

실패 모드 ​

증상근본 원인확인 방법해결
컨텍스트를 채울수록 답변 품질이 서서히, 그러나 비선형적으로 나빠짐Context rot — 길이 증가 자체가 유발하는 저하(위치와 무관)동일 태스크를 여러 컨텍스트 길이(예: 4K/16K/64K/128K)에서 반복 실행해 정확도 곡선을 그림필요한 최소 컨텍스트로 축소, 검색·요약으로 사전 압축, 태스크별 상한선을 SLO로 고정
정답이 되는 문서가 중간에 있을 때만 정확도가 떨어짐Lost in the Middle 위치 편향동일 문서 집합에서 정답 위치를 처음/중간/끝으로 바꿔가며 A/B 비교핵심 정보를 프롬프트 앞/뒤쪽에 재배치, 또는 reranking으로 정답 후보를 상위/최근 위치로 이동
특정 모델에서 "답변 거부"가 급증하는데 정확도 지표에는 오답으로만 집계됨저작권·안전성 등의 이유로 인한 refusal이 별도 카테고리로 분리되지 않음응답을 accuracy가 아니라 {정답/오답/거부/무관} 4분류로 재분류거부율을 별도 SLI로 계측, 거부가 급증하는 길이 구간을 사전 회피
배경 텍스트가 논리적으로 매끈하게 연결된 문서일수록 오히려 성능이 나빠짐Chroma 리포트가 관찰한 haystack 구조 효과 — 원인은 아직 확정되지 않음동일 정보량을 가진 haystack을 shuffled/coherent 두 버전으로 만들어 비교확정된 해법 없음 — 관찰만 재현하고 자체 데이터로 검증 필요(미정착 영역)
"1M 토큰 지원"이라는 스펙만 믿고 사전 필터링 없이 원문 전체를 투입벤더가 명시한 컨텍스트 윈도우(advertised)와 실효 컨텍스트(effective) 혼동Databricks 방식으로 자체 데이터셋을 2K~해당 모델 최대치까지 스윕하여 저하 시작점 확인저하 시작점 이전으로 상한선 설정, RAG 검색·청킹 파이프라인 유지
오픈소스 모델을 상용 모델과 동일한 컨텍스트 길이 정책으로 운영다수 오픈소스 모델은 16K~32K 이후 급격히 저하되는데 상용 모델 기준 정책을 그대로 적용모델별로 개별 스윕 테스트 실행, 공용 정책 대신 모델별 상한선 테이블 관리모델별 컨텍스트 상한선을 라우팅 계층에 하드코딩

안티패턴 ​

  • ❌ 벤더가 광고하는 컨텍스트 윈도우 크기를 그대로 설계 상한선으로 사용한다 → ✅ 자체 태스크·데이터로 스윕 테스트를 돌려 실제 저하 시작점을 찾고 그 이전 값을 상한선으로 쓴다.
  • ❌ "컨텍스트가 커졌으니 검색 단계 없이 문서를 다 넣자"고 RAG의 검색·랭킹 단계를 생략한다 → ✅ 컨텍스트가 커져도 distractor를 줄이기 위한 검색·reranking은 유지한다.
  • ❌ 정확도(accuracy) 한 지표로만 롱컨텍스트 성능을 평가한다 → ✅ 거부(refusal), 무관 응답, 반복 생성을 accuracy와 분리해 별도로 집계한다.
  • ❌ 한 모델·한 태스크에서 측정한 "실효 컨텍스트 길이" 숫자를 다른 모델이나 다른 태스크에도 그대로 적용한다 → ✅ 모델·태스크 조합마다 별도로 스윕 테스트를 재실행한다.
  • ❌ 정답 후보가 되는 핵심 문서를 검색 결과 중간 순서에 방치한다 → ✅ reranking 결과에서 최상위 후보를 컨텍스트 앞쪽(또는 프롬프트 구조상 끝쪽)에 배치한다.

계측 (SLI) ​

컨텍스트 길이에 따른 저하는 정확도 하나로 요약할 수 없다. 최소한 다음을 길이(bucket)별로 나누어 계측한다.

  • 정확도(accuracy) — 컨텍스트 길이 버킷별: 4K/16K/32K/64K/128K 등 구간별로 별도 곡선을 유지한다. 단일 평균값은 저하 시작점을 숨긴다.
  • 거부율(refusal rate): "답변을 시도하지 않음" 또는 "저작권/안전 등을 이유로 거부"를 정확도와 분리해 별도 카운트한다. Databricks 사례처럼 거부율만 급증하고 정답률은 안정적으로 보이는 착시를 방지한다.
  • 위치별 정확도(position-sensitivity): 정답 근거가 컨텍스트의 처음/중간/끝에 있을 때 정확도를 구분 계측한다. Lost in the Middle 재현 테스트를 CI에 포함시킨다.
  • needle-question 유사도별 정확도: 정답과 질문 사이의 어휘·의미적 유사도가 낮은 케이스를 별도 버킷으로 관리한다. 유사도가 높은 케이스만으로 평가하면 실전보다 낙관적인 결과가 나온다.
  • distractor 개수별 정확도: 검색 결과에 방해 정보가 0개/1개/다수 포함될 때 정확도 변화를 추적한다.

이 SLI들은 6대 통증점의 전환 임계치 표와 함께, 프로덕션 배포 전 반드시 자체 데이터로 재측정해야 하는 항목이다.

체크리스트 ​

  • [ ] 사용 중인 모델·태스크 조합에 대해 컨텍스트 길이별 정확도 스윕 테스트를 자체 데이터로 실행했다.
  • [ ] 정확도와 거부율(refusal rate)을 분리된 지표로 계측하고 있다.
  • [ ] 정답 근거 문서의 위치(처음/중간/끝)를 바꿔가며 Lost in the Middle 재현 테스트를 CI에 포함시켰다.
  • [ ] "벤더가 광고한 컨텍스트 윈도우 크기"를 설계 상한선으로 그대로 채택하지 않았다.
  • [ ] RAG 파이프라인에서 컨텍스트가 커져도 검색·reranking 단계를 생략하지 않았다.
  • [ ] "1/4~1/10" 같은 비공식 통념을 설계 문서에 근거로 인용하지 않았다 — 인용했다면 출처를 명시했다.
  • [ ] 오픈소스 모델과 상용 모델에 동일한 컨텍스트 길이 정책을 적용하지 않고, 모델별 상한선 테이블을 관리하고 있다.
  • [ ] 이 챕터의 수치를 인용할 때 원문 링크를 열어 모델 버전(예: Claude 3 Sonnet vs 3.5 Sonnet)이 정확히 일치하는지 재확인했다.

참고 ​

⚠️ 비공식 출처 기반 — 공식 문서 교차확인 필요 마지막 참고 항목(MECW 논문)은 단일 저자·비주류 트랙 프리프린트로, 이 장 본문에서 인용한 다른 수치보다 검증 강도가 낮다. 독립 재현이나 추가 동료 검증 전까지는 참고용으로만 취급할 것.