질문의 배경
2024-2025년 사이에 LLM의 컨텍스트 윈도우는 폭발적으로 커졌습니다.
- Gemini 1.5 Pro: **100만 토큰**
- Claude 3.5/3.7: **20만 토큰**
- GPT-4o: **12.8만 토큰**
이 숫자를 보고 많은 개발자들이 이런 생각을 했습니다: "100만 토큰이면 책 10권도 넣을 수 있는데, 굳이 벡터 DB 구축하고 RAG 파이프라인 만들 필요가 있나? 그냥 다 집어넣으면 되는 거 아니야?"
솔직히 합리적인 질문입니다. RAG는 구축이 복잡합니다. 청킹 전략, 임베딩 모델 선택, 벡터 DB 운영, 검색 품질 튜닝... 이 모든 게 사라진다면 얼마나 편할까요.
하지만 실제로 프로덕션 시스템을 만들어본 사람이라면 "그렇게 단순하지 않다"는 걸 알 것입니다. 오늘은 데이터와 코드를 바탕으로 솔직하게 비교해보겠습니다.
Long Context vs RAG: 진짜 비교
1. 비용 비교 — 숫자가 모든 걸 말합니다
시나리오: 10,000개 문서 지식베이스, 각 500 토큰
하루 1,000번 쿼리
total_docs_tokens = 10_000 * 500 # 5,000,000 토큰
방법 A: Long Context (모든 문서를 컨텍스트에)
GPT-4o 인풋 가격: $2.50 / 1M tokens
cost_long_context_per_query = total_docs_tokens * (2.50 / 1_000_000)
daily_cost_long_context = cost_long_context_per_query * 1000
print(f"Long context 하루 비용: ${daily_cost_long_context:.2f}")
출력: Long context 하루 비용: $12500.00 (!!)
방법 B: RAG (관련 청크 상위 5개, ~1,000 토큰)
rag_context_tokens = 1000
cost_rag_per_query = rag_context_tokens * (2.50 / 1_000_000)
daily_cost_rag = cost_rag_per_query * 1000
print(f"RAG 하루 비용: ${daily_cost_rag:.2f}")
출력: RAG 하루 비용: $2.50
ratio = daily_cost_long_context / daily_cost_rag
print(f"RAG가 {ratio:.0f}배 저렴")
출력: RAG가 5000배 저렴
하루에 $12,500 vs $2.50. 월로 환산하면 $375,000 vs $75. 스타트업이라면 서비스가 성장하기도 전에 망할 수 있는 차이입니다.
물론 이건 극단적인 예시입니다. 하지만 지식베이스가 클수록, 쿼리가 많을수록 이 격차는 더 벌어집니다.
2. 속도 비교
실제 프로덕션 환경에서 측정한 대략적인 수치입니다:
- **200K 토큰 컨텍스트**: 처리에 5-10초 소요 (첫 토큰까지)
- **RAG + 2K 컨텍스트**: 0.3-0.8초 (검색 포함)
사용자 입장에서는 엄청난 차이입니다. 10초를 기다리는 챗봇과 0.5초 안에 답하는 챗봇 중 어떤 걸 쓰고 싶으신가요?
Streaming으로 어느 정도 완화할 수 있지만, 긴 컨텍스트는 TTFT(Time To First Token)도 느린 경향이 있습니다.
3. 품질 비교 — "Lost in the Middle" 문제
가장 중요한 비교입니다. 많은 분들이 "길게 넣으면 LLM이 더 잘 보지 않을까?"라고 생각하는데, 연구 결과는 반대입니다.
Liu et al. (2023)의 연구 "Lost in the Middle: How Language Models Use Long Contexts"에서:
긴 컨텍스트에서 위치별 성능:
처음 부분: ████████████ 85% ← LLM이 잘 집중함
중간 부분: ████████ 65% ← 성능 저하! (Lost in the Middle)
끝 부분: ████████████ 87% ← LLM이 잘 집중함
RAG는 관련 정보를 항상 앞에 배치 → 이 문제를 회피
50만 토큰짜리 컨텍스트 중간에 중요한 정보가 있으면? LLM이 그걸 놓칠 가능성이 높습니다. RAG는 검색된 청크를 컨텍스트 앞부분에 배치하기 때문에 이 문제를 자연스럽게 회피합니다.
언제 Long Context가 RAG보다 나은가
그렇다고 Long Context가 항상 나쁜 건 아닙니다. 이런 상황에서는 Long Context가 더 좋습니다:
**1. 전체 문서 분석이 필요할 때**
"이 소설의 주인공 성격 변화를 전체 흐름에서 분석해줘"처럼 책 한 권 전체를 이해해야 할 때는 당연히 긴 컨텍스트가 맞습니다.
**2. 문서 간 복잡한 추론이 필요할 때**
계약서 A와 계약서 B의 미묘한 충돌을 찾거나, 10개 보고서에 걸친 인과관계를 추적할 때 RAG의 청크 기반 검색으로는 놓치는 부분이 생길 수 있습니다.
**3. 질문이 완전히 예측 불가능할 때**
어떤 내용을 물어볼지 전혀 모르는 상황이라면 모든 내용을 넣는 게 안전할 수 있습니다.
**4. 소규모 지식베이스**
문서가 50개 미만이고 각 문서가 짧다면? 그냥 다 넣는 게 더 단순하고 효과적일 수 있습니다.
언제 RAG가 Long Context보다 나은가
반면 이런 상황에서는 RAG를 선택해야 합니다:
**1. 대규모 지식베이스**
수천, 수만 개의 문서가 있다면 Long Context는 물리적으로 불가능하거나 비용이 폭발합니다.
**2. 비용 민감한 서비스**
B2C 서비스나 프리 티어가 있는 서비스라면 쿼리당 비용이 생사를 가릅니다.
**3. 빠른 응답이 핵심인 서비스**
고객 서비스 챗봇, 실시간 도움말 시스템 등에서 10초 응답은 허용할 수 없습니다.
**4. 자주 업데이트되는 지식베이스**
RAG는 새 문서를 추가하면 즉시 검색 가능합니다. Long Context 방식은 매번 새 프롬프트를 조합해야 합니다.
**5. 출처 추적이 필요한 경우**
"이 답변의 근거 문서가 뭔가요?"라는 질문에 RAG는 검색된 청크를 바로 보여줄 수 있습니다.
최적의 답: Long Context RAG (두 가지 조합)
실전에서 가장 좋은 결과를 내는 방법은 두 가지를 조합하는 것입니다.
Long Context RAG 패턴
1단계: RAG로 후보 청크 많이 검색 (recall 중시)
2단계: 긴 컨텍스트에 넣어 LLM이 꼼꼼히 읽게 함
def long_context_rag_query(query: str, vectordb, llm):
일반 RAG: top-5 청크
Long Context RAG: top-20 청크
retrieved_chunks = vectordb.similarity_search(query, k=20)
약 20K-40K 토큰 컨텍스트
context = "\n\n---\n\n".join([chunk.page_content for chunk in retrieved_chunks])
prompt = f"""다음 문서들을 바탕으로 질문에 답해주세요.
문서:
{context}
질문: {query}
답변:"""
return llm.invoke(prompt)
이 방식의 장점:
- 검색 단계에서 recall 향상 (top-20이면 놓치는 게 적음)
- 비용은 Long Context 방식보다 훨씬 저렴 (전체 문서 대비)
- "Lost in the Middle" 문제는 20K 컨텍스트 정도면 심각하지 않음
Reranking: RAG 품질을 높이는 추가 전략
RAG를 쓰면서도 품질을 높이고 싶다면 Reranker를 추가하세요.
from sentence_transformers import CrossEncoder
Cross-encoder reranker (Cohere, Jina, BGE-reranker 등)
reranker = CrossEncoder("cross-encoder/ms-marco-MiniLM-L-6-v2")
def rag_with_reranking(query: str, vectordb, llm, top_k=20, rerank_top=5):
1. 넓게 검색 (recall 중시)
candidates = vectordb.similarity_search(query, k=top_k)
2. Reranker로 정밀 순위 재조정
pairs = [(query, chunk.page_content) for chunk in candidates]
scores = reranker.predict(pairs)
3. 상위 5개만 컨텍스트로 사용
ranked = sorted(zip(scores, candidates), reverse=True)
top_chunks = [chunk for _, chunk in ranked[:rerank_top]]
context = "\n\n".join([chunk.page_content for chunk in top_chunks])
return llm.invoke(f"Context:\n{context}\n\nQuestion: {query}")
Reranking은 검색 품질을 크게 높여주면서 추가 LLM 호출 비용이 없습니다. Cross-encoder는 작은 모델이라 로컬에서 빠르게 실행됩니다.
미래 전망: Context Window는 계속 커진다
컨텍스트 윈도우는 계속 커질 것이고, 비용도 계속 내려갈 것입니다:
2023: GPT-4 → 8K 토큰
2024: Claude 3 → 200K, Gemini 1.5 → 1M
2025: ...?
토큰당 비용 추세:
2023 GPT-4: $30 / 1M tokens (input)
2024 GPT-4o: $2.50 / 1M tokens
2025: 더 내려갈 것
그렇다고 RAG가 죽는 건 아닙니다. RAG는 진화할 것입니다:
- **Single-stage RAG** → **Multi-hop RAG** (여러 단계 검색)
- **Keyword/Semantic Search** → **Hybrid Search + Reranking**
- **Flat Retrieval** → **Hierarchical/GraphRAG**
- RAG 자체가 **컨텍스트 관리 전략**으로 발전
미래에는 "RAG vs Long Context"가 아니라 "어떤 RAG 전략이 최적인가"가 질문이 될 것입니다.
실무 의사결정 가이드
지식베이스 크기는?
├─ 50개 미만 문서, 각 짧음 → Long Context 고려
├─ 수백~수천 개 → Long Context RAG (top-20 + 50K context)
└─ 수만 개 이상 → Standard RAG + Reranking
쿼리 종류는?
├─ 특정 사실 검색 → Standard RAG
├─ 복잡한 추론, 여러 문서 연결 → GraphRAG 또는 Multi-hop RAG
└─ 전체 요약/분석 → Long Context 또는 Global GraphRAG
응답 속도 요구사항은?
├─ 1초 미만 → Standard RAG (작은 컨텍스트)
├─ 3초 이내 → Long Context RAG (30K 이하)
└─ 유연 → Long Context
월 예산은?
├─ $100 미만 → 반드시 Standard RAG
├─ $1,000 이하 → Long Context RAG 가능
└─ 제한 없음 → 품질 우선으로 선택
결론
**RAG는 사라지지 않습니다.** 오히려 더 정교해질 것입니다.
Long Context는 특정 시나리오(소규모 문서, 전체 분석, 복잡한 추론)에서 강력한 도구입니다. 하지만 프로덕션 서비스에서는 비용, 속도, 확장성 때문에 대부분의 경우 RAG가 여전히 최선입니다.
현실적인 조언: **Long Context RAG 패턴을 시작점으로 삼으세요.** RAG로 후보를 넓게 검색하고, 어느 정도 긴 컨텍스트로 LLM에게 충분한 정보를 주는 방식이 비용, 속도, 품질의 균형을 가장 잘 맞춥니다.
완벽한 정답은 없습니다. 여러분의 서비스 특성에 맞게 실험하고 측정하세요.
현재 단락 (1/112)
2024-2025년 사이에 LLM의 컨텍스트 윈도우는 폭발적으로 커졌습니다.