RAG(Retrieval-Augmented Generation)는 질문에 답하기 전에 외부 문서를 찾아 근거로 붙이는 구조다. 파이프라인은 크게 두 덩어리로 갈린다. 미리 해 두는 인덱싱과, 질의가 들어올 때마다 도는 검색 · 생성이다.
질의와 무관하게 배치로 미리 돌린다.
| 단계 | 하는 일 |
|---|---|
| 적재 | PDF · DB · 웹 등에서 원본을 가져온다 |
| 청킹 | 문서를 의미 단위로 자른다. 보통 300~1,000 토큰, 겹침 10~20% |
| 임베딩 | 각 청크를 벡터로 바꾼다 |
| 저장 | 벡터 DB 에 메타데이터와 함께 넣는다 |
민감정보가 섞인 문서는 인덱싱 전에 마스킹한다. 벡터로 바뀐 뒤에는 무엇이 들어갔는지 사람이 확인하기 어렵고, 검색 결과로 원문이 그대로 나온다.
| 단계 | 하는 일 | 필수 여부 |
|---|---|---|
| 입력 검증 | 길이 제한, 프롬프트 인젝션 필터, 민감정보 마스킹 | 운영이면 사실상 필수 |
| 캐시 조회 | 같거나 유사한 질의면 기존 결과 재사용 | 선택 |
| 라우팅 | 검색이 필요한 질문인지, 어느 인덱스로 보낼지 판단 | 선택 |
| 질의 재작성 | 대명사 · 생략 복원. "그거 얼마야" → "A 제품 가격은 얼마야" | 멀티턴이면 사실상 필수 |
| 질의 분해 · 확장 | 복합 질문 쪼개기, 동의어 · 약어 확장 | 선택 |
| HyDE | 가상 답변을 먼저 만들고 그것을 임베딩 | 선택 |
| 질의 임베딩 | 인덱싱과 같은 모델로 벡터화 | 필수 |
| 검색 | 유사도 상위 K 추출 | 필수 |
| 재순위화 | cross-encoder 로 정밀 정렬 후 상위 N 만 남김 | 선택 |
| 프롬프트 구성 | 검색 결과 + 질문 + 시스템 지침 결합 | 필수 |
| 생성 | 근거 기반 답변 작성 | 필수 |
| 후처리 | 출처 표기, 환각 검증, 필터링 | 선택 |
단발성 질의에 순수 벡터 검색만 쓴다면 "질의 → 임베딩 → 검색" 이 맞다. 그러나 챗봇 형태로 가는 순간 질의 재작성이 거의 반드시 필요해진다. 후속 질문에 "그건 얼마야" 처럼 대명사가 들어가면, 그 문장을 그대로 임베딩해 봐야 아무 문서와도 가깝지 않다.
하이브리드 검색이면 임베딩이 유일한 경로도 아니다. 원문 질의를 토크나이징해 BM25 같은 키워드 검색으로도 보내고, 두 결과를 RRF(Reciprocal Rank Fusion) 등으로 합친다. 고유명사 · 코드 · 제품명처럼 임베딩이 약한 질의를 키워드 쪽이 받아 준다.
| 지점 | 역할 | 필수 여부 |
|---|---|---|
| 인덱싱 | 청크 요약, 키워드 · 메타데이터 추출, 가상 질문 생성 | 선택 |
| 질의 재작성 | 대명사 복원, 맥락 반영 | 멀티턴이면 사실상 필수 |
| 질의 분해 · 확장 | 복합 질문 분리 | 선택 |
| HyDE | 가상 답변 생성 | 선택 |
| 라우팅 | 검색 필요 여부 판단 | 선택 |
| 재순위화 | LLM 을 리랭커로 사용 | 선택 (보통 cross-encoder 가 싸다) |
| 최종 생성 | 근거 기반 답변 | 필수 |
| 검증 | 환각 · 근거 일치 확인 | 선택 |
최소 구성이면 LLM 호출은 마지막 하나뿐이다. 품질을 올릴수록 앞단에 호출이 붙어 운영 챗봇은 보통 2~4회를 호출한다.
앞단 호출은 사용자 체감 지연에 그대로 더해진다. 재작성 · 라우팅처럼 짧고 판단만 하는 작업은 작고 빠른 모델로 돌리고, 최종 생성에만 큰 모델을 쓰는 구성이 일반적이다.
Agentic RAG 로 가면 단계라는 개념 자체가 흐려진다. 모델이 "검색한다 → 결과가 부족하다 → 다시 검색한다 → 답한다" 를 스스로 반복하므로 선형 파이프라인이 아니게 되고, 호출 횟수와 지연의 상한을 따로 걸어야 한다.
생성 모델을 바꾸는 것은 대체로 가장 늦게 할 일이다. 품질 병목은 거의 청킹 전략과 검색 단계에 있다.