단순(naive) RAG가 성능이 안 나오는 이유는 '임베딩'이 약해서가 아니라, 문서를 자르는 순간 문맥이 사라지고, 검색/정렬/전달 과정이 부실해지기 때문입니다.
이 문서는 RAG를 '버리자'가 아니라 RAG 스택을 현실적으로 고도화하자는 관점에서, 선택지와 트레이드오프를 정리합니다.
- LLM은 학습된 내용 밖의 최신 정보/사내 문서를 모릅니다.
- 그래서 질문과 관련된 문서를 찾아서(prompt에 붙여서) 답하게 만드는 방식이 RAG입니다.
- 핵심은 2가지입니다.
- 검색(retrieval): 필요한 조각을 잘 찾는다.
- 생성(generation): 찾은 조각을 근거로 답한다.
단순 RAG는 흔히 아래 파이프라인으로 구성됩니다.
- 문서를 chunk로 쪼갠다
- 각 chunk를 embedding으로 변환해 벡터 DB에 저장한다
- 질문도 embedding으로 변환한다
- 유사한 chunk top-k를 찾아 LLM에 넣는다
문제는 1)에서 시작됩니다.
- chunk에 "마케팅 비용이 전 분기 대비 15% 증가" 라고 적혀 있어도
- 어느 회사/어느 분기/어떤 기준인지 문맥이 앞뒤에 있을 수 있습니다.
- 하지만 chunk를 잘라버리면 그 문맥은 사라지고, chunk 하나만으론 진짜 의미가 약해집니다.
책 한 페이지를 뜯어서 주고는, "이걸로 전체 맥락을 이해해"라고 하는 것과 비슷합니다.
영상에서 소개된 Claude Code의 비유는 요점이 명확합니다.
- RAG처럼 미리 chunk/인덱싱을 설계하기보다
- 일단 파일/문서를 열어보고(처음엔 일부만), 구조를 파악하고, 더 필요하면 더 읽는 방식
이 접근은 특히 다음 상황에서 강합니다.
- 문서가 구조화되어 있고(목차/섹션), 사람이 읽으면 빠르게 파악되는 경우
- 코드/리포지토리처럼 "찾아가며 이해"가 자연스러운 도메인
다만, 검색 기반 인덱싱이 전혀 필요 없다는 뜻은 아닙니다.
- 대규모 조직 데이터/수십만 문서에서 에이전트가 무작정 탐색하면 비용/시간이 폭발할 수 있습니다.
- 단순 RAG(정교한 인덱싱/리트리버/리랭커로 정확도를 높이려는 스택) = 라이다
- 정밀하지만 시스템이 복잡해지고, 운영/유지보수 비용이 커지며, 한 부품이 흔들리면 전체가 흔들립니다.
- 에이전트의 직접 탐색(필요할 때 읽고, 검색하고, 반복) = 카메라
- 단순하지만 모델/도구가 발전할수록 함께 좋아지기 쉽습니다.
결론은 "둘 중 하나"가 아니라, 조직/데이터/예산에 맞게 균형을 잡는 것입니다.
단순 embedding 검색만으로는 실제 쿼리 분포(약어/에러코드/고유명사)에 약합니다.
그래서 실무에서는 아래 구조가 사실상 표준입니다.
- 키워드 기반(BM25): 고유명사, 제품 코드, 에러 메시지, 정확한 용어에 강함
- 의미 기반(Dense retrieval): 동의어/표현 차이에 강함
- 두 결과를 합치는 방식으로 RRF(Reciprocal Rank Fusion) 같은 방법이 자주 사용됩니다.
- 1단계 top-N(예: 20~50)을 대상으로 cross-encoder/LLM reranker가
- 질문-문서 쌍을 직접 비교해 관련성 점수를 매기고
- top-K(예: 3~5)만 최종 컨텍스트로 전달합니다.
실무 팁: "retrieval 품질"을 올리려면, 벡터 DB/임베딩만 바꾸기보다 (1) 하이브리드 + (2) 리랭킹을 먼저 붙이는 게 ROI가 큽니다.
GraphRAG는 비정형 텍스트에서 엔티티/관계를 추출해 지식 그래프를 만들고,
그래프 커뮤니티 요약을 생성해 "전역 질문"과 "다단계 추론"을 더 잘하게 만드는 접근입니다.
- 여러 문서에 흩어진 정보를 연결해 답해야 하는 경우(멀티홉)
- "이 데이터셋의 주요 테마는?", "A와 B의 관계는?" 같은 전역 질문
- 정책/규정/사건기록/대규모 코드베이스 등 관계성이 중요한 경우
- 초기 인덱싱에서 LLM 호출이 많이 발생할 수 있어 비용이 큼(인덱싱 세금)
- 데이터가 자주 갱신되면 증분 인덱싱/재구축이 필요해 운영 난이도가 상승
최근 모델은 컨텍스트 윈도우가 크게 늘었고, 문서가 "충분히 짧다면" 자르지 않고 통째로 넣는 것이
오히려 더 정확할 수 있습니다(문맥 끊김이 없으므로).
하지만 한계도 명확합니다.
긴 문서를 매번 프롬프트로 보내면 토큰 비용이 바로 증가합니다.
엔터프라이즈 데이터는 수십만 문서/상담 이력/계약서 등으로, 한 번에 다 넣을 수 없습니다.
긴 컨텍스트에서 중요한 정보가 중간에 있으면 모델이 놓치는 경향이 있습니다.
(Liu et al., "Lost in the Middle"은 긴 컨텍스트에서 양 끝단이 유리하고 중간이 불리한 U자형 성능을 보고합니다.)
그래서 "통째로 넣기"를 하더라도, 중요한 근거는 상단에 재배치하거나,
요약/인용을 앞부분에 두는 전략이 필요합니다.
Anthropic은 전통적 RAG의 문제를 "chunk가 문서 전체에서 무엇을 의미하는지"가 사라지는 것으로 정의하고,
chunk 앞에 **짧은 문맥 설명(보통 50~100 토큰 수준)**을 붙여 embedding/BM25/리랭킹 성능을 끌어올리는 방법을 제시합니다.
- 기존 chunk: "매출은 전 분기 대비 3% 성장"
- contextualized chunk: "(ACME Corp 2023 Q2 실적 공시의 매출 섹션 일부) 매출은 전 분기 대비 3% 성장"
- Contextual Embeddings: 5.7% → 3.7% (실패율 35% 감소)
- Contextual Embeddings + Contextual BM25: 5.7% → 2.9% (49% 감소)
-
- Reranking: 5.7% → 1.9% (67% 감소)
- 문맥 생성에 "가벼운 모델"을 쓰고(예: Haiku)
- 프롬프트 캐싱을 활용해 비용을 줄이는 것이 핵심입니다.
영상에서 소개된 실전적인 타협안입니다.
- 저장(인덱싱) 시점:
- 원문 단락을 LLM으로 요약하고
- "요약 + 소제목"을 검색용 텍스트로 저장
- 검색 시점:
- 생성 시점:
- 요약이 아니라 원문 단락 전체를 LLM에 전달
도서관 메타데이터로 책을 찾고, 실제로는 본문을 읽는 방식과 같습니다.
아래는 "일단 굴러가는" 기준입니다.
- 문서가 적고(짧고), 트래픽이 적다
- full-context(통째로 넣기) + 캐싱 + 중요한 근거는 상단에 배치
- 문서가 많고, 정확도가 필요하다(운영 가능한 수준)
- Hybrid Search(BM25 + dense) + Reranking
- chunk 전략(크기/overlap)과 평가셋을 반드시 같이 설계
- chunk 문맥 손실이 특히 치명적이다
- Anthropic Contextual Retrieval(문맥 프리픽스) 적용
- 특히 hybrid + rerank 조합에서 효과가 큼
- 전역 요약/관계/멀티홉이 핵심이다
- GraphRAG 고려
- 인덱싱 비용과 업데이트 전략(증분 가능 여부)을 먼저 계산
- 평가셋 없이 "감"으로 튜닝하지 말기
- 검색(top-k)과 리랭킹(top-k)의 목표를 분리하기(Recall vs Precision)
- 쿼리 로그를 분류(고유명사/약어/자연어/코드/에러로그)하고, 각 군에 맞는 최적화
- 긴 컨텍스트에 넣을 때는 "중간"을 믿지 말고, 중요한 근거를 상단/하단에 재배치