RAG란 무엇인가
2분 요약
LLM은 학습할 때 본 것만 압니다. 우리 회사 문서, 어제 만든 보고서, 사내 규정은 모릅니다. 그렇다고 매번 모델을 다시 학습시킬 수는 없습니다.
RAG(Retrieval-Augmented Generation)의 발상은 단순합니다.
질문이 들어오면 ① 관련 있어 보이는 문서를 찾아서 ← Retrieval (검색) ② 질문과 함께 프롬프트에 붙여 넣고 ③ LLM에게 그걸 근거로 답하게 한다 ← Generation (생성)
모델을 건드리지 않고, 프롬프트에 넣어주는 것만 바꿔서 모르는 걸 알게 만듭니다.
이 랩에서 실측한 사례입니다. 질문
"2025년 예산이 삭감된 근본 원인은?"에
LLM은 이렇게 답했습니다:
"2024년도 사업 추진 실적이 목표 대비 미달했고, 집행률이 80%를 밑돌았기 때문입니다."유창하고, 논리적이고, 검색된 문서에 정확히 근거했고, 틀렸습니다. 진짜 원인은 장비 납품 지연인데 그 문서가 검색되지 않았을 뿐입니다.
모델은 지어내지 않았습니다. 받은 문서를 성실히 요약했습니다. 그리고 답변만 봐서는 틀렸다는 걸 알 방법이 없습니다.
→ 그래서 RAG 기법의 대부분은 "생성을 잘하게"가 아니라 "검색을 덜 틀리게" 만드는 것입니다.
전체 파이프라인
이 랩에서 조합할 수 있는 5개의 칸
┌──────────── 색인 시점 (미리 한 번) ────────────┐
문서 ──▶ [0.준비] ──▶ [1.청킹] ──▶ [2.임베딩] ──▶ 인덱스
└───────────────────────────────────────────────┘
┌──────────── 질의 시점 (매 질문마다) ───────────┐
질문 ──▶ [5.쿼리변환] ──▶ [3.검색] ──▶ [4.재순위] ──▶ [6.생성] ──▶ 답변
▲ │
└──────── [7.흐름제어] ─────────────┘
(판단하고, 필요하면 되돌아간다)
└───────────────────────────────────────────────┘| 칸 | 하는 일 | 언제 비용이 드나 |
|---|---|---|
| 1. 청킹 | 문서를 검색 단위로 자른다 | 색인 시점 (1회) |
| 2. 임베딩 | 텍스트를 벡터로 바꾼다 | 색인 시점 (1회) |
| 3. 검색 | 질문에 맞는 조각을 찾는다 | 질의마다 (빠름) |
| 4. 재순위 | 찾은 것을 다시 정렬한다 | 질의마다 (느림) |
| 5. 쿼리 변환 | 검색 전에 질문을 손본다 | 질의마다 (LLM 호출) |
| 6. 생성 | 근거로 답을 만든다 | 질의마다 (LLM 호출) |
| 7. 흐름 제어 | 판단하고 되돌아간다 | 질의마다 (LLM 여러 번) |
문서가 자주 안 바뀌고 질문이 많다면 색인 쪽에 투자하는 게 압도적으로 유리합니다.
0. 문서 준비 색인 시점
하는 일
PDF·HWP·PPT·HTML을 텍스트로 바꾸고, 표·이미지·머리말을 정리합니다.
이 랩은 학습이 목적이라 마크다운 문서로 시작했습니다. 실무에서는 여기에 전체 노력의 절반이 들어간다고 보시면 됩니다.
실무 논의
| 쟁점 | 흔한 선택 |
|---|---|
| 표를 어떻게 다루나 | 마크다운 표로 보존 / 행 단위로 풀어쓰기 / 별도 인덱스 |
| 이미지·도표 | 버림 / OCR / 멀티모달 모델로 캡션 생성 |
| 머리말·꼬리말·페이지번호 | 제거 권장 (모든 청크에 반복 등장해 노이즈) |
| 메타데이터 | 이때 뽑아둘 것 — 작성일·부서·문서유형 (13단계 참조) |
1. 청킹 색인 시점 이 랩 02~05, 14~15
하는 일
문서를 검색 단위로 자릅니다. 이 랩에서 가장 효과가 컸던 단계입니다.
왜 자르나
4,000자 문서를 벡터 하나로 압축하면 "무엇에 관한 문서인가"만 남고 "그 안에 무슨 사실이 있는가"는 사라집니다. 그리고 답에 필요한 건 두세 문장인데 문서 전체를 프롬프트에 넣으면 비용도 낭비되고 모델의 주의도 분산됩니다.
선택지
| 방식 | 어떻게 자르나 | 강점 / 약점 |
|---|---|---|
| 고정 길이 | 글자 수로 기계적으로 | 단순·빠름 / 문장·표 중간을 자름 |
| 재귀 분할 | 문단→줄→문장→절 순으로 구분자 존중 | 경계가 깔끔 / 의미는 여전히 모름 |
| 의미 기반 | 문장 임베딩 유사도가 떨어지는 곳에서 | 주제 경계 포착 / 느리고 비쌈 |
| 부모-자식 | 작게 찾고, 큰 덩어리를 프롬프트에 | 이 랩 종합 1위 / 프롬프트 커짐 |
| 문맥 부착 | 청크 앞에 "어디의 무슨 얘기" 붙임 | 싸고 효과적 / 헤딩 없는 문서엔 LLM 필요 |
이 랩 실측: 문서 평균이 1,000자인데 청크를 1,200자로 잡았더니 대부분 잘리지 않아 청킹을 안 한 것과 수치가 완전히 같았습니다.
자기 문서의 길이 분포를 먼저 보세요. 그다음 200/300/500/800을 실제로 돌려 비교하세요.
두 지표가 반대로 움직입니다. "정확도"라는 한 단어로 뭉뚱그리면 이 현상이 안 보입니다.
의미 기반이 빛나는 곳은 구분자가 의미와 어긋나는 문서입니다 — 전사록, 채팅 로그, OCR 결과처럼요.
recall 0.889 · MRR 0.944 · 전체조망 1.00 — 모든 지표 최상위.
· 오버랩만 복제된 무의미한 청크가 인덱스에 쌓입니다 (실제로 51자 중 새 내용 1글자)
· 청크가 작을수록 문서 다양성이 떨어져 한 문서가 top-k를 독식합니다
2. 임베딩 색인 시점 이 랩 00
하는 일
텍스트를 고정 길이 숫자 배열(벡터)로 바꿉니다. 의미가 비슷하면 벡터가 가까워집니다.
① 길수록 뭉개진다. 문장 10토큰을 1개로 평균하면 손실이 적지만, 문서 2,000토큰을 1개로 평균하면 개별 사실이 거의 사라집니다.
→ 이것 하나가 02~05단계 청킹이 존재하는 이유 전부입니다. 자르면 평균 대상이 줄어드니 개별 사실이 살아납니다.
② 압축할 때 질문을 모른다. 같은 문서라도 질문에 따라 중요한 단어가 다른데, 임베딩 시점엔 질문이 없으니 모든 단어를 똑같이 취급합니다.
→ 이것이 08단계 리랭커가 존재하는 이유입니다.
풀링 방식
| 방식 | 어떻게 | 쓰는 곳 |
|---|---|---|
| 평균 풀링 | 전체 토큰 벡터의 자리별 평균 | bge-m3, 대부분의 최신 모델 |
| CLS 풀링 | 맨 앞 [CLS] 토큰 벡터 하나만 | BERT 원조 방식 |
| 마지막 토큰 | 맨 끝 토큰 벡터만 | GPT 계열 임베딩 |
| 최대 풀링 | 자리별 최댓값 | 드묾 |
실측: 문서를 bge-m3로, 질문을 arctic으로 임베딩했더니 오류 없이 정답이 1위 → 7위로 밀렸습니다. 조용히 틀립니다.
| 모델 | recall@3 | 비고 |
|---|---|---|
| OpenAI 3-small | 0.917 | 1위 |
| bge-m3 (로컬·무료) | 0.889 | 차이 0.028뿐 |
| OpenAI 3-large | 0.736 | 더 비싼데 더 나쁨 |
| snowflake-arctic | 0.208 | 한국어 사실상 불가 |
그리고 arctic은 "습지 복원 사업"과 "점심에 김치찌개"의 유사도가 0.9968이었습니다 — 모든 한국어를 거의 같은 벡터로 뭉갭니다. 다국어 지원 여부를 반드시 먼저 확인하세요.
bge-m3 = 0.35 · 3-small = 0.18 · 3-large = 0.28 · arctic = 0.9968
bge-m3에서 0.8은 "거의 같다"는 뜻이고, arctic에서 0.8은 "무관하다"보다 낮습니다.
"유사도 0.7 이상이면 관련 있음" 같은 규칙을 모델 바꿔가며 그대로 쓰면 터집니다.
| HRE-2024-070 | 양양 하천 정비 | 21억원 | 같은 표 한 행을
임베딩하니 bge-m3가 NaN을 반환했습니다. NaN 하나가 순위 전체를 오염시킵니다.
색인 파이프라인은 이걸 견뎌야 합니다 (재시도 → 정제 → 0벡터 + 0나눗셈 가드).
유사도 계산 방식
코사인·내적·L2·L1이 있지만, 벡터가 정규화돼 있으면 넷 다 완전히 같은 순위를 냅니다.
정규화가 안 돼 있으면 내적이 특히 위험합니다(길이 큰 벡터가 무조건 이김).
np.linalg.norm(v)로 1초면 확인합니다.
3. 검색 질의 시점 이 랩 01, 06~07, 13
선택지
| 방식 | 원리 | 강점 | 실패 방식 |
|---|---|---|---|
| 벡터 | 임베딩 유사도 | 말을 바꿔 물어도 찾음 | 희귀 고유명사를 아예 못 봄 |
| BM25 | 단어 통계 (TF-IDF 계열) | 코드·숫자·고유명사 | 표현이 다르면 0점 |
| 하이브리드 | 둘의 순위를 RRF로 융합 | 양쪽 다 안전 | 가중치를 잘못 주면 손해 |
| 메타 필터 | 조건으로 후보를 먼저 좁힘 | MRR 1.000, 공짜 | 필터가 정답을 걸러낼 수 있음 |
그런데 질문 유형을 바꾸니 뒤집혔습니다. 고유 표현을 그대로 던지자:
| 질의 | 벡터 | BM25 | 하이브리드 |
|---|---|---|---|
노은지 (희귀 인명) | 실패 | 1위 | 1위 |
서버넷 (전문용어) | 실패 | 2위 | 1위 |
| top-3 적중 | 3/5 | 5/5 | 5/5 |
실무 해법은 점수를 버리고 순위만 쓰는 것입니다 (RRF):
score = Σ weight / (k + rank) — 스케일 문제가 원천적으로 사라집니다.
4. 재순위 질의 시점 이 랩 08
하는 일
| 임베딩 (bi-encoder) | 리랭커 (cross-encoder) | |
|---|---|---|
| 질문·문서가 만나는 시점 | 안 만남 (각자 벡터가 된 뒤 거리만 잼) | 모델 안에서 직접 |
| 문서 벡터 | 미리 계산해 저장 | 저장 불가 (질문마다 다름) |
| 100만 건 검색 | 내적 100만 번 — 순식간 | 모델 호출 100만 번 — 불가능 |
| 정확도 | 보통 | 높음 |
그래서 실무 표준은 2단계입니다: 빠른 검색기로 30~100개 → 리랭커로 상위 3~5개. 전부 리랭커로 훑는 건 불가능하고, 검색만으로는 순위가 거칠기 때문입니다.
| 저장량 | 속도 | 정확도 | |
|---|---|---|---|
| 임베딩 (풀링) | 벡터 1개 | 매우 빠름 | 보통 |
| ColBERT | 벡터 N개 | 중간 | 좋음 |
| 리랭커 | 저장 안 함 | 느림 | 최고 |
기법을 고를 때 "성능이 좋은가"만 보지 말고 우리 인프라에서 도는가를 먼저 보세요.
리랭커는 검색이 이미 잘 되는 곳에서는 얻을 게 없습니다.
5. 쿼리 변환 질의 시점 이 랩 09~12
검색하기 전에 질문을 손봅니다. 네 가지가 같은 축의 변주입니다.
| 기법 | 무엇을 바꾸나 | 노리는 것 |
|---|---|---|
| 재작성 | 표현을 다듬는다 (같은 층위, 하나) | 구어체·지시어·생략 복원 |
| 멀티쿼리 | 표현을 늘린다 (같은 층위, 여럿) | recall — 여러 그물 |
| HyDE | 형태를 바꾼다 (질문→답변) | 질문·문서 형태 격차 해소 |
| Step-back | 층위를 올린다 | 배경·구조 문단 확보 |
검색에 필요한 건 사실이 아니라 올바른 모양의 벡터입니다.
단, 이 랩에서는 유일하게 기준선보다 나빴습니다(0.736 < 0.778). LLM이 이 가상 사업단을 전혀 몰라서 일반적인 공문 어휘로 지어냈기 때문입니다. HyDE는 LLM이 그 도메인을 이미 아는 경우(의학·법률·프로그래밍)에 쓰는 기법입니다.
6. 생성 질의 시점
유의사항
RAG의 병목은 거의 항상 LLM이 아니라 검색입니다. 모델을 올려서 해결하려는 시도가 실패하는 이유가 이것입니다.
프롬프트에서 챙길 것
| 근거 밖 내용 금지 | "자료에 없으면 '찾을 수 없습니다'라고 답하세요" |
| 출처 표기 | 청크 id를 함께 넣어 사용자가 확인할 수 있게 |
| 길이 제한 | 길수록 근거에서 멀어질 여지가 커짐 |
| 중복 제거 | 같은 부모를 공유하는 청크가 여러 개 잡히면 한 번만 |
7. 흐름 제어 질의 시점 이 랩 16~18
여기까지는 전부 "한 번 검색하고 한 번 생성"이었습니다. 이 단계는 흐름 자체를 바꿉니다.
| 기법 | 무엇을 추가하나 |
|---|---|
| Self-RAG | ① 검색이 필요한가 ② 이 문서가 관련 있나 ③ 답이 근거에 있나 |
| CRAG | 검색 품질을 채점 → 나쁘면 질의를 고쳐 재검색 |
| Agentic | 매 턴 LLM이 다음 행동을 스스로 결정 (연쇄 검색) |
판단3: 근거 없는 주장 감지 → 답변 보류
다른 기법들은 전부 확신에 찬 오답을 냈습니다. 실무에서는 "모르겠다"가 훨씬 안전합니다. 그런데 이 가치는 recall로 안 잡힙니다. 오답률을 따로 재야 합니다.
검색 품질 자기평가는 정밀도는 봐도 누락(recall)은 못 봅니다.
doc_18 → doc_16 → doc_22. 그런데 진짜 원인 문서에는 도달하지 못했습니다.
매 턴 텍스트 유사도로 검색하기 때문입니다. 현재 발견물과 다음 고리가 어휘를 공유하지 않으면 점프할 방법이 없습니다.
텍스트 검색을 몇 번 반복해도, 텍스트로 연결되지 않은 것은 연결되지 않습니다.
→ 이것이 GraphRAG가 존재하는 정확한 이유입니다.
8. GraphRAG 색인 시점 이 랩 19~22
발상
조각을 찾지 말고, 개체 사이의 관계를 미리 그려둡니다.
한빛계측 ──납품지연──▶ 수중조사장비 ──필요──▶ 2차정밀조사
│
연기(3개월)
▼
2025년예산 ◀──삭감── 실적미달 ◀──원인── 상반기실적
이 그래프가 있으면 "2025년 예산" 노드에서 간선을 거꾸로 타고
"한빛계측 납품지연"까지 어휘 유사도 없이 도달합니다.| 단계 | 하는 일 |
|---|---|
| 19 그래프 구축 | LLM으로 (개체, 관계, 대상) 삼중항 추출 → 그래프 |
| 20 Local | 질문 속 개체에서 간선을 타고 이웃 탐색 |
| 21 Global | 커뮤니티 탐지 → 요약 → 인덱스에 추가 |
| 22 하이브리드 | 벡터·BM25·Local·Global 네 경로 융합 |
| doc_11 | doc_14 |
|---|---|
양평 습지 2차 정밀조사 | 2차 정밀조사, 양평 습지 복원 대상지 2차 정밀조사 |
생태조사 장비 납품 | 계측 장비 확보 지연 |
해소 전후 실측
| 노드 | 연결요소 | 최대 요소 | 사슬 연결 | |
|---|---|---|---|---|
| 해소 없음 | 381 | 103 | 63 | 1/3 |
| 해소 0.86 | 343 | 78 | 142 | 3/3 |
예산 조정 → 시민참여 프로그램 → HRE-2024-07
문서번호가 허브 역할을 해서 우연히 이어진 것이지 인과가 아닙니다.
→ 인과 간선(
원인·사유·지연·삭감)에 낮은 비용을 주고,
"근본 원인"을 물을 때는 들어오는 간선을 거슬러 올라가야 합니다.
| 기법 | 골든셋 recall | 핵심 질문 근거 발견 |
|---|---|---|
| 하이브리드 | 0.861 | 1/3 |
| Agentic (3턴) | 0.861 | 1/3 |
| GraphRAG Local | 0.431 (꼴찌) | 2/3 — doc_11 도달 |
구축 비용도 가장 큽니다. 문서마다 LLM 호출이 필요합니다. "관계를 따라가야 답이 나오는 질문"이 실제로 있을 때만 도입하세요.
📕 용어 사전
읽다가 모르는 말이 나오면 여기서 찾으세요
가장 헷갈리는 두 개
질문과 문서는 생긴 게 다릅니다. 질문은 짧고 물음표가 붙은 구어체, 문서는 길고 서술형인 공문 말투죠. 내용이 맞아도 모양이 안 맞아 유사도가 깎입니다.
그래서 LLM에게 답을 지어내게 한 뒤 그 가짜 답변으로 검색합니다. 가짜 답변은 진짜 문서와 모양이 같으니까 잘 붙습니다.
비유: 실종자를 찾을 때 몽타주를 그려 CCTV 사진과 대조하는 것. 몽타주가 실물은 아니지만, 말로 설명하는 것보다 사진끼리 비교하는 게 낫습니다.
비유: "친구의 친구" = 2홉. 지하철 환승 횟수와 같습니다.
2025년 예산 삭감 ──1홉──▶ 실적 미달 ──2홉──▶ 조사 연기 ──3홉──▶ 장비 납품 지연 (doc_18) (doc_16) (doc_14) (doc_11)
약어
| 약어 | 읽기 | 풀어쓰면 | 쉽게 말하면 |
|---|---|---|---|
| RAG | 래그 | Retrieval-Augmented Generation | 찾아서 붙여주고 답하게 하기 |
| LLM | 엘엘엠 | Large Language Model | 챗GPT 같은 대형 언어모델 |
| BM25 | 비엠25 | Best Matching 25 | 단어가 겹치는지 세는 고전 검색법 |
| TF-IDF | 티에프아이디에프 | Term Frequency–Inverse Document Frequency | 많이 나오면 높게, 흔한 단어면 깎기 |
| RRF | 알알에프 | Reciprocal Rank Fusion | 점수 말고 등수로 합치기 |
| MRR | 엠알알 | Mean Reciprocal Rank | 정답이 평균 몇 등으로 나왔나 |
| HyDE | 하이드 | Hypothetical Document Embeddings | 가짜 답을 지어내 그걸로 검색 |
| CRAG | 씨래그 | Corrective RAG | 검색이 나쁘면 다시 찾는 RAG |
| RAPTOR | 랩터 | Recursive Abstractive Processing… | 요약을 계층으로 쌓아 인덱스에 넣기 |
| MMR | 엠엠알 | Maximal Marginal Relevance | 비슷한 것만 뽑지 말고 다양하게 |
| BFS | 비에프에스 | Breadth-First Search | 그래프에서 가까운 것부터 훑기 |
| NaN | 난 | Not a Number | 숫자가 아님 — 계산이 망가졌다는 신호 |
검색 기본
| 용어 | 쉽게 말하면 |
|---|---|
| 임베딩 | 문장을 숫자 배열(벡터)로 바꾸는 것. 뜻이 비슷하면 숫자도 비슷해집니다 |
| 벡터 | 숫자를 나열한 것. bge-m3는 1,024개를 씁니다 |
| 토큰 | 모델이 글을 자르는 단위. "AX전략본부는" → [AX][전략][본부][는] |
| 풀링 | 토큰 벡터 여러 개를 하나로 합치는 것. 보통 자리별 평균. 여기가 정보 손실 지점 — 청킹과 리랭커가 존재하는 이유 |
| 정규화 | 벡터 길이를 1로 맞추는 것 (방향만 비교하려고) |
| 코사인 유사도 | 두 벡터가 얼마나 같은 방향인지. 1에 가까울수록 비슷 |
| 청크 / 청킹 | 문서를 잘게 자른 조각 / 자르는 행위 |
| 오버랩 | 자를 때 앞 조각 끝을 조금 겹쳐 넣는 것 (문맥 보존) |
| 인덱스 / 색인 | 검색할 수 있게 미리 정리해둔 자료 (책 뒤 찾아보기와 같음) |
| 코퍼스 | 문서 뭉치 전체. 이 랩은 24개 |
| top-k | 검색 결과 상위 몇 개를 쓸 것인가 |
| 어휘 검색 | 단어가 겹치는지로 찾기 (BM25, Fuse.js) |
| 의미 검색 | 뜻이 비슷한지로 찾기 (임베딩·벡터) |
| bi-encoder | 질문·문서를 따로 벡터화해 비교. 빠름, 대신 거침 |
| cross-encoder | 질문·문서를 붙여서 한 번에 읽고 채점. 정확함, 대신 느림 |
| 토큰 | LLM이 글을 세는 단위. 한글은 대략 1.7자 = 1토큰 |
| 정규화 | 벡터 길이를 1로 맞추는 것 (방향만 비교하려고) |
GraphRAG 용어
| 용어 | 쉽게 말하면 |
|---|---|
| 그래프 | 점(개체)과 선(관계)으로 그린 그림 |
| 노드 | 그래프의 점 = 사람·기관·사업 같은 개체 |
| 간선(엣지) | 그래프의 선 = 개체 사이의 관계 |
| 개체 해소 | 2차 정밀조사와 양평 습지 2차 정밀조사가 같은 것임을 알아내 합치는 일 |
| 연결요소 | 서로 이어진 점들의 덩어리. 103개면 그래프가 103조각으로 흩어졌다는 뜻 |
| 커뮤니티 | 그래프에서 유난히 촘촘히 뭉친 무리 |
| 클러스터링 | 비슷한 것끼리 자동으로 묶는 것 |
지표 — 이게 제일 헷갈립니다
질문: "예산 삭감 원인은?" 정답 근거: doc_11, doc_14, doc_18 검색 결과(top-3): 1위 doc_22 2위 doc_18 ✓ 3위 doc_23
| 지표 | 무엇을 재나 | 이 경우 | 읽는 법 |
|---|---|---|---|
| hit@3 | 정답이 하나라도 있나 | 1.0 (만점) | "있긴 있다" |
| recall@3 | 정답 중 몇 %를 찾았나 | 0.33 | "3개 중 1개뿐" |
| MRR | 정답이 몇 등인가 | 0.5 (2등 → 1/2) | "1등은 아니었다" |
hit@3 만 보면 만점이라 완벽해 보입니다.
그런데 실제로는 근본 원인 문서를 못 찾았습니다.
지표 하나만 보면 망가진 시스템이 만점을 받습니다.
| 용어 | 쉽게 말하면 |
|---|---|
| 골든셋 | 정답을 미리 정해둔 시험 문제지 (이 랩은 12문항) |
| recall(재현율) | 놓치지 않았나 — 넓게 건지는 능력 |
| precision(정밀도) | 헛것을 안 가져왔나 — 정확히 집는 능력 |
| lift | 1등 점수가 평균보다 얼마나 튀나. 안 튀면 순위가 무작위란 뜻 |
기법 이름 한 줄 요약
| 기법 | 한 줄 |
|---|---|
| 멀티쿼리 | 질문을 여러 표현으로 늘려 각각 검색 |
| Step-back | 한 걸음 물러선 큰 질문도 같이 검색 |
| doc2query | 문서에 "이런 질문 받으면 나"를 미리 붙여두기 |
| parent-child | 작게 찾고 크게 답하기 |
| contextual retrieval | 조각 앞에 "어디의 무슨 얘기" 붙이기 |
| RAPTOR | 요약을 계층으로 쌓아 인덱스에 함께 넣기 |
| Self-RAG | 스스로 "이거 맞나?" 점검하며 진행 |
| CRAG | 검색이 나쁘면 다시 찾기 |
| Agentic | LLM이 다음에 뭘 할지 스스로 정하기 |
| GraphRAG | 조각 말고 관계를 그려두고 타고 다니기 |
자주 하는 실수 8가지
| # | 실수 | 왜 문제인가 |
|---|---|---|
| 1 | 남의 기본값을 그대로 씀 | 청크 1200자 → 문서 평균이 1000자라 아무 일도 안 일어남 |
| 2 | 지표 하나만 봄 | hit@k는 근거 3개 중 1개만 걸려도 만점 → 실패를 숨김 |
| 3 | 평가셋을 자연어 질문으로만 채움 | BM25·어휘 검색의 가치가 통째로 안 보임 |
| 4 | 유사도 임계값을 고정 | 바닥이 모델마다 다름 (0.18 ~ 0.9968) |
| 5 | 질문/문서 임베딩 모델 불일치 | 오류 없이 조용히 순위가 무너짐 |
| 6 | 모델 업그레이드로 해결하려 함 | 병목은 거의 항상 검색 |
| 7 | 후보 3개 뽑고 리랭커 적용 | 재정렬할 게 없음. 30개 이상 뽑아야 함 |
| 8 | 정교한 기법부터 도입 | 가장 싼 메타데이터 필터가 MRR 만점을 냄 |
어디서부터 시작할까
2단계. 메타데이터 정리 (작성일·부서·유형) → 가장 싼 개선
3단계. 청크 크기 실측 (내 문서 길이 분포 → 200/300/500/800 비교)
4단계. 부모-자식 도입 → 추가 비용 0에 모든 지표 최상위
5단계. 하이브리드 (가중치는 자기 데이터로 재기)
6단계. 오답이 치명적이면 Self-RAG
7단계. 관계를 따라가야 하는 질문이 실제로 있으면 GraphRAG
| 상황 | 추천 조합 |
|---|---|
| 일반 사내 문서 QA | 부모-자식 + 하이브리드 + 메타필터 |
| 코드·제품번호가 많음 | BM25 가중치 1.5 이상 |
| "전체적으로 뭐야" 질문이 많음 | RAPTOR 또는 커뮤니티 요약 |
| 여러 문서를 이어야 함 | GraphRAG Local (개체 해소 필수) |
| 오답이 치명적 | Self-RAG |
| 사용자가 구어체로 물음 | 쿼리 재작성 |
평가에 대하여
이 랩에서 같은 교훈이 다섯 번 나왔습니다.
| 발견 | 어디서 |
|---|---|
| hit@k는 근거 하나만 걸려도 만점 → multi_hop 실패를 숨김 | 01단계 |
| 골든셋에 어휘형 질의가 없어 BM25가 12전 0승 | 06단계 |
| 요약 노드가 문서 단위 정답과 매칭 안 돼 RAPTOR 저평가 | 15단계 |
| answer_hit은 키워드 매칭이라 종합 품질 판정 불가 | 20단계 |
| 평균 지표는 "가장 어려운 문제"를 재지 않음 | 23단계 |
평가셋을 만들 때 최소한 이 네 유형은 넣으세요:
· 사실 — 답이 한 문장에 있음
· 어휘형 — 코드·고유명사를 그대로 던짐 (빠뜨리기 쉬움)
· 다중연결 — 여러 문서를 이어야 함
· 전체조망 — 어느 한 문서에도 답이 없음
단계별 실습자료 읽기
각 단계의 실측 결과와 상세 분석. 클릭하면 여기서 바로 읽힙니다.