지난 글에서는 RAG가 왜 필요한지 살펴봤습니다.
핵심은 간단했습니다.
LLM은 말을 잘 생성하지만, 최신 정보나 회사 내부 문서를 자동으로 알고 있는 것은 아닙니다.
그래서 답변하기 전에 관련 자료를 먼저 찾아보고, 그 자료를 근거로 답하게 만드는 구조가 필요합니다.
이번 글에서는 그 구조가 실제로 어떻게 동작하는지 살펴보겠습니다.
문서를 어떻게 준비하고,
왜 잘게 나누고,
임베딩은 어디에 쓰이며,
Vector Store는 무엇을 저장하고,
사용자의 질문이 들어왔을 때 어떤 방식으로 답변이 만들어지는지 순서대로 정리하겠습니다.
이번 글의 핵심 질문
RAG는 단순히 “문서를 검색해서 GPT에게 넣는 것”이 아닙니다. 긴 문서를 검색하기 좋은 형태로 나누고, 의미 기반으로 찾을 수 있게 변환한 뒤, 질문과 관련 있는 조각만 골라 LLM에게 전달하는 전체 흐름입니다.
1. RAG 전체 흐름
RAG는 크게 두 단계로 나누어 볼 수 있습니다.

- Indexing 단계(사내 문서 전처리 과정): 문서를 미리 정리해서 검색 가능한 상태로 만들어 두는 단계
- 도서관에 책을 정리해서 책장에 꽂아두는 과정
- Querying 단계(사내 문서 기반 답변 과정): 사용자의 질문이 들어왔을 때 관련 문서를 찾아 답변을 생성하는 단계
- 사용자가 질문했을 때 사서가 관련 책을 찾아 설명해 주는 과정
이 흐름에서 중요한 점은 LLM이 처음부터 모든 문서를 읽는 것이 아니라는 점입니다.
실제로는 질문과 관련 있어 보이는 문서 조각만 골라서 LLM에게 전달합니다.
RAG의 핵심은 전체 문서를 LLM에게 한꺼번에 넣는 것이 아니라, 질문에 필요한 부분만 찾아서 넣는 것입니다.
2. Indexing 단계
Indexing은 RAG 시스템이 답변을 잘하기 위해 미리 준비하는 단계입니다.
사용자가 질문하기 전에 문서를 수집하고, 정리하고, 검색 가능한 형태로 저장해 둡니다.
예를 들어 회사의 사내 규정 챗봇을 만든다고 해보겠습니다. 이 챗봇이 재택근무, 휴가, 복지, 보안 정책에 답하려면 먼저 관련 문서들이 준비되어 있어야 합니다.
| 단계 | 무엇을 하는가? | 예시 |
|---|---|---|
| Document Ingestion | 문서를 시스템에 가져오는 단계 | PDF, TXT, Word, HTML, CSV 수집 |
| Preprocessing | 검색하기 좋게 문서를 정리하는 단계 | 불필요한 공백 제거, 표 정리, 헤더/푸터 제거 |
| Chunking | 긴 문서를 작은 조각으로 나누는 단계 | 재택근무 규정 문서를 조항별로 분리 |
| Embedding | 문서 조각을 숫자 벡터로 변환하는 단계 | “재택근무 신청 조건” 문단을 벡터로 변환 |
| Vector Store 저장 | 벡터와 원문, 메타데이터를 저장하는 단계 | 문서명, 페이지, 조항 번호와 함께 저장 |
Indexing 단계가 잘못되면 이후 단계가 아무리 좋아도 답변 품질이 떨어집니다. 검색할 재료를 잘못 준비해 두면, 질문이 들어왔을 때 좋은 문서를 찾을 수 없기 때문입니다.
3. 문서 전처리
문서 전처리는 원본 문서를 RAG에 넣기 전에 정리하는 과정입니다. 이 과정은 생각보다 중요합니다.
사람이 보기에는 괜찮은 PDF라도, AI가 읽기에는 불필요한 요소가 많이 섞여 있을 수 있기 때문입니다.
예를 들어 PDF 문서에는 페이지 번호, 반복되는 회사 로고, 머리말, 꼬리말, 표 안의 깨진 텍스트, 줄바꿈 오류 등이 포함될 수 있습니다. 이런 것들이 그대로 들어가면 검색 품질이 낮아질 수 있습니다.
문서 전처리에서 자주 하는 작업
- 불필요한 공백, 줄바꿈, 특수문자 제거
- 반복되는 머리말, 꼬리말, 페이지 번호 제거
- 표, 목록, 제목 구조 정리
- PDF에서 추출된 깨진 문장 보정
- 문서 제목, 작성일, 버전 정보 추출
- 검색에 필요 없는 부록이나 이미지 설명 제거
전처리를 대충 하면 RAG는 엉뚱한 문서를 검색할 수 있습니다. LLM의 답변이 이상해 보일 때 원인이 모델이 아니라 문서 정리 상태에 있는 경우도 많습니다.
4. Chunking과 Overlap
Chunking은 긴 문서를 작은 단위로 나누는 과정입니다. 여기서 Chunk는 문서 조각을 의미합니다.
왜 문서를 굳이 잘게 나눌까요?
이유는 간단합니다. 사용자의 질문에 답할 때 전체 문서가 필요한 경우보다, 특정 문단이나 특정 조항만 필요한 경우가 훨씬 많기 때문입니다.
예를 들어 50페이지짜리 사내 규정 문서가 있다고 해보겠습니다. 사용자가 “재택근무는 주 몇 회까지 가능한가요?”라고 물었을 때 50페이지 전체를 LLM에게 넣을 필요는 없습니다. 재택근무 관련 조항만 찾으면 됩니다.
Chunk Size란?
Chunk Size는 하나의 문서 조각을 얼마나 크게 만들 것인지 정하는 기준입니다. 보통 글자 수, 토큰 수, 문단 수 등을 기준으로 나눕니다.
| Chunk 크기 | 장점 | 단점 |
|---|---|---|
| 너무 작음 | 검색 결과가 세밀해짐 | 앞뒤 문맥이 부족해 답변이 부정확해질 수 있음 |
| 적당함 | 검색 정확도와 문맥 보존의 균형이 좋음 | 문서 유형별로 조정이 필요함 |
| 너무 큼 | 문맥이 넉넉하게 포함됨 | 관련 없는 내용까지 함께 들어가 검색 품질이 떨어질 수 있음 |
Overlap이 필요한 이유
Overlap은 문서를 자를 때 앞뒤 내용을 조금 겹치게 나누는 방식입니다. 문서를 칼로 정확히 자르면 중요한 문맥이 경계에서 끊길 수 있습니다.
Overlap 없는 경우
Chunk 1:
재택근무는 부서장의 승인을 받아 신청할 수 있습니다.
Chunk 2:
단, 보안 문서를 다루는 업무는 재택근무 대상에서 제외됩니다.
이렇게 나뉘면 “보안 문서를 다루는 업무도 재택근무 가능한가요?”라는 질문에서 두 문장이 함께 필요할 수 있습니다. 그런데 검색 결과가 하나의 Chunk만 가져오면 조건이 빠질 수 있습니다.
Overlap 있는 경우
Chunk 1:
재택근무는 부서장의 승인을 받아 신청할 수 있습니다.
단, 보안 문서를 다루는 업무는 재택근무 대상에서 제외됩니다.
Chunk 2:
단, 보안 문서를 다루는 업무는 재택근무 대상에서 제외됩니다.
재택근무 신청은 매주 금요일까지 제출해야 합니다.
Overlap을 사용하면 경계에 걸린 정보가 사라지는 문제를 줄일 수 있습니다. 대신 중복 저장이 생기기 때문에 저장 공간과 검색 비용이 늘어날 수 있습니다.
Chunking의 목표는 문서를 무조건 작게 자르는 것이 아닙니다. 질문에 답할 만큼의 문맥은 유지하면서, 검색이 너무 넓어지지 않도록 적절한 크기로 나누는 것입니다.
5. Metadata 설계
Metadata는 문서 조각에 붙이는 추가 정보입니다.
Chunk의 본문이 “내용”이라면, Metadata는 그 내용이 어디서 왔는지 설명하는 꼬리표입니다.
RAG에서 Metadata는 매우 중요합니다. 답변에 출처를 붙일 때도 필요하고, 특정 조건으로 검색 범위를 좁힐 때도 필요합니다.
| Metadata 항목 | 역할 | 예시 |
|---|---|---|
| 문서명 | 출처 표시 | 2026_재택근무_운영지침.pdf |
| 페이지 | 근거 위치 추적 | p. 12 |
| 섹션 제목 | 문맥 파악 | 3. 재택근무 신청 기준 |
| 작성일/개정일 | 최신성 판단 | 2026-03-01 |
| 문서 유형 | 검색 필터링 | 인사 규정, 보안 정책, FAQ |
예를 들어 사용자가 “최신 재택근무 기준 알려줘”라고 물었다면, 단순히 내용이 비슷한 문서를 찾는 것뿐 아니라 개정일이 최신인 문서를 우선하는 것이 좋습니다. 이때 Metadata가 필요합니다.
6. Embedding과 Vector Store
Embedding은 텍스트를 숫자 벡터로 바꾸는 과정입니다.
벡터는 여러 숫자로 이루어진 배열입니다.
이 숫자들은 문장의 의미를 표현합니다.
왜 굳이 텍스트를 숫자로 바꿀까요? 컴퓨터가 의미가 비슷한 문장을 찾으려면, 문장을 비교 가능한 형태로 바꿔야 하기 때문입니다.
문장:
"재택근무는 주 2회까지 가능합니다."
Embedding 결과 예시:
[0.12, -0.33, 0.87, 0.04, ...]
실제로는 훨씬 긴 숫자 배열이 만들어집니다. 중요한 것은 의미가 비슷한 문장끼리는 벡터 공간에서도 가까워지도록 만든다는 점입니다.
Vector Store란?
Vector Store는 임베딩된 벡터를 저장하고 검색하는 저장소입니다.
일반 데이터베이스가 텍스트나 숫자를 저장한다면,
Vector Store는 벡터를 저장하고 “질문 벡터와 가까운 문서 벡터”를 빠르게 찾아줍니다.
| 저장되는 정보 | 설명 |
|---|---|
| Chunk 원문 | LLM에게 전달할 실제 문서 조각 |
| Embedding Vector | 검색을 위해 숫자로 변환된 문서 조각 |
| Metadata | 문서명, 페이지, 작성일, 카테고리 등 출처 정보 |
| ID | 각 Chunk를 구분하기 위한 고유 식별자 |
Embedding은 문장을 의미 기반으로 찾기 위한 변환 과정이고, Vector Store는 그 변환된 벡터를 저장하고 검색하는 공간입니다.
7. Querying 단계
이제 사용자가 질문을 던졌다고 해보겠습니다.
여기서부터는 Querying 단계입니다.
Querying은 사용자의 질문을 바탕으로 관련 문서 조각을 검색하고, 그 결과를 LLM에게 전달해 답변을 생성하는 과정입니다.
예시는 계속 사내 규정 챗봇으로 이어가겠습니다.
사용자 질문:
"보안 문서를 다루는 팀도 재택근무를 신청할 수 있나요?"
RAG 시스템은 이 질문을 그대로 LLM에게 던지지 않습니다. 먼저 이 질문과 의미적으로 가까운 문서 조각을 Vector Store에서 찾습니다.
Querying 흐름
1. 사용자 질문을 임베딩한다.
2. 질문 벡터와 가까운 문서 벡터를 찾는다.
3. 관련도가 높은 Top-N 문서 조각을 가져온다.
4. 질문과 문서 조각을 함께 프롬프트에 넣는다.
5. LLM이 문서 근거를 바탕으로 답변한다.
8. Similarity Search와 Top-N Retrieval
Similarity Search는 질문 벡터와 문서 벡터 사이의 유사도를 계산해, 의미적으로 가까운 문서 조각을 찾는 과정입니다.
예를 들어 사용자가 “보안 문서를 다루는 팀도 재택근무 가능한가요?”라고 물었다면, 정확히 같은 문장이 문서에 없어도 다음과 같은 문서 조각이 검색될 수 있습니다.
검색된 문서 조각 예시:
Chunk 1:
재택근무는 부서장의 승인을 받아 주 2회까지 신청할 수 있습니다.
Chunk 2:
보안 등급이 높은 문서 또는 고객 개인정보를 상시 취급하는 업무는
재택근무 대상에서 제외될 수 있습니다.
Chunk 3:
재택근무 신청은 매주 금요일까지 인사 시스템을 통해 제출해야 합니다.
Top-N Retrieval이란?
Top-N Retrieval은 유사도가 높은 문서 조각 N개를 가져오는 방식입니다. 예를 들어 Top-3라면 가장 관련성이 높은 문서 조각 3개를 가져옵니다.
| 설정 | 장점 | 주의점 |
|---|---|---|
| Top-N이 작음 | 프롬프트가 짧아지고 비용이 줄어듦 | 필요한 근거가 빠질 수 있음 |
| Top-N이 큼 | 더 많은 근거를 참고할 수 있음 | 관련 없는 내용이 섞이고 토큰 비용이 증가할 수 있음 |
Top-K와 Top-N은 같은 말인가?
RAG 문맥에서는 Top-K와 Top-N이 거의 비슷한 의미로 쓰이는 경우가 많습니다.
둘 다 “상위 몇 개의 검색 결과를 가져올 것인가”를 의미합니다.
다만 모델 매개변수에서 말하는 Top-K와는 구분해야 합니다.
모델 매개변수의 Top-K는 다음 토큰 후보를 몇 개로 제한할지에 대한 설정이고,
RAG에서의 Top-K 또는 Top-N은 검색 결과 문서 조각을 몇 개 가져올지에 대한 설정입니다.
| 구분 | 의미 | 예시 |
|---|---|---|
| 생성 모델의 Top-K | 다음 토큰 후보를 몇 개로 제한할지 | 다음 단어 후보 상위 40개만 고려 |
| RAG의 Top-K / Top-N | 검색 결과 문서 조각을 몇 개 가져올지 | 관련 문서 조각 상위 5개 검색 |
9. 검색 결과를 프롬프트에 넣는 방식
검색된 문서 조각은 그대로 답변이 되는 것이 아닙니다. LLM이 읽을 수 있도록 프롬프트에 포함됩니다.
이 과정을 Prompt Augmentation이라고 볼 수 있습니다.
즉, 사용자의 질문에 검색된 근거 자료를 추가해서 프롬프트를 보강하는 것입니다.
프롬프트 구성 예시
[시스템 지시]
당신은 사내 규정 안내 챗봇입니다.
반드시 제공된 문서 내용만 근거로 답변하세요.
문서에 없는 내용은 추측하지 마세요.
[검색된 문서]
문서 1: 재택근무는 부서장의 승인을 받아 주 2회까지 신청할 수 있습니다.
문서 2: 보안 등급이 높은 문서 또는 고객 개인정보를 상시 취급하는 업무는
재택근무 대상에서 제외될 수 있습니다.
[사용자 질문]
보안 문서를 다루는 팀도 재택근무를 신청할 수 있나요?
[답변 형식]
- 결론
- 근거
- 참고 문서
이렇게 하면 LLM은 자신의 기억만으로 답하는 것이 아니라, 프롬프트 안에 들어온 문서 내용을 근거로 답변합니다.
Grounded Answer란?
Grounded Answer는 근거에 기반한 답변을 의미합니다. RAG에서는 검색된 문서 조각이 Grounding Context 역할을 합니다. 쉽게 말해 “이 자료를 보고만 답해”라고 LLM에게 참고 자료를 주는 것입니다.
답변 예시:
결론:
보안 등급이 높은 문서나 고객 개인정보를 상시 취급하는 업무는
재택근무 대상에서 제외될 수 있습니다.
근거:
제공된 문서에는 "보안 등급이 높은 문서 또는 고객 개인정보를
상시 취급하는 업무는 재택근무 대상에서 제외될 수 있다"고 되어 있습니다.
참고 문서:
2026_재택근무_운영지침.pdf, 3. 재택근무 제한 기준
프롬프트에 검색 결과를 너무 많이 넣으면 오히려 답변 품질이 떨어질 수 있습니다. 관련 없는 내용이 섞이면 LLM이 핵심 근거를 놓치거나, 서로 충돌하는 문서를 보고 애매한 답을 만들 수 있습니다.
10. RAG 품질을 좌우하는 요소
RAG 답변 품질은 LLM 성능만으로 결정되지 않습니다. 오히려 실무에서는 검색 품질이 답변 품질을 크게 좌우합니다.
LLM이 아무리 좋아도 잘못된 문서 조각을 넣어주면 좋은 답변을 만들기 어렵습니다. 반대로 적절한 문서 조각이 들어가면 비교적 작은 모델도 꽤 정확한 답변을 만들 수 있습니다.
| 요소 | 왜 중요한가? | 개선 방법 |
|---|---|---|
| 문서 품질 | 원본 문서가 틀리면 답변도 틀릴 수 있음 | 최신 문서 관리, 중복 문서 제거, 오류 문서 정리 |
| Chunk 전략 | 너무 작으면 문맥 부족, 너무 크면 잡음 증가 | 문서 구조에 맞게 Chunk Size와 Overlap 조정 |
| Embedding 품질 | 의미적으로 가까운 문서를 잘 찾아야 함 | 문서 언어와 도메인에 맞는 임베딩 모델 선택 |
| Retrieval 품질 | 검색 결과가 답변의 근거가 됨 | Query Rewrite, Reranking, 필터링 적용 |
| Prompt 구성 | 검색 결과를 어떻게 넣느냐에 따라 답변이 달라짐 | 근거 기반 답변 지시, 출처 표시 형식 지정 |
Query Rewrite
Query Rewrite는 사용자의 질문을 검색에 더 적합한 형태로 바꾸는 과정입니다.
사용자는 자연스럽게 질문하지만, 검색 시스템은 더 명확한 키워드나 구조화된 질문을 좋아할 수 있습니다.
원래 질문:
"집에서 일하는 거 일주일에 몇 번 돼요?"
검색용 질문으로 변환:
"재택근무 주간 가능 횟수 규정"
이렇게 바꾸면 “집에서 일하는 거”라는 표현이 문서에 없더라도 “재택근무”라는 공식 표현으로 검색할 수 있습니다.
Reranking
Reranking은 1차 검색 결과를 다시 정렬하는 과정입니다.
처음 검색에서는 후보 문서 여러 개를 넓게 가져오고, 그중에서 질문과 정말 관련 있는 문서를 다시 위로 올립니다.
예를 들어 “재택근무 보안 문서”라는 질문에 대해 처음에는 재택근무 문서와 보안 정책 문서가 모두 검색될 수 있습니다. Reranking은 그중 질문에 더 직접적으로 답할 수 있는 문서를 우선순위로 올리는 역할을 합니다.
Context Stuffing 문제
Context Stuffing은 검색된 문서를 너무 많이 프롬프트에 넣는 문제입니다.
“많이 넣으면 더 정확하지 않을까?”라고 생각할 수 있지만, 항상 그렇지는 않습니다.
- 관련 없는 문서가 섞이면 답변이 흐려질 수 있음
- 토큰 수가 늘어나 비용이 증가함
- 중요한 근거가 긴 문맥 속에 묻힐 수 있음
- 서로 충돌하는 문서가 들어가면 답변이 애매해질 수 있음
RAG에서는 “얼마나 많이 넣을까?”보다 “얼마나 정확한 근거를 넣을까?”가 더 중요합니다. 검색 결과의 양보다 질이 답변 품질을 결정합니다.
11. 답변에 출처를 붙이는 방법
RAG의 큰 장점 중 하나는 답변에 출처를 붙일 수 있다는 점입니다.
사용자는 AI의 답변을 그대로 믿는 것이 아니라, 어떤 문서를 근거로 답했는지 확인할 수 있습니다.
출처를 붙이려면 Indexing 단계에서 Metadata를 잘 저장해 두어야 합니다. 문서명, 페이지, 조항 번호, URL, 작성일 같은 정보가 있어야 답변에 근거를 표시할 수 있습니다.
출처 포함 답변 예시:
보안 등급이 높은 문서나 고객 개인정보를 상시 취급하는 업무는
재택근무 대상에서 제외될 수 있습니다.
근거:
- 2026_재택근무_운영지침.pdf, p.12, "재택근무 제한 기준"
- 보안업무_처리규정.pdf, p.5, "외부 근무 제한 업무"
출처 표시는 사용자 신뢰를 높입니다. 특히 사내 규정, 법률, 금융, 의료처럼 근거 확인이 중요한 서비스에서는 거의 필수에 가깝습니다.
12. 전체 흐름 한 번에 정리
이제 RAG 동작 원리를 처음부터 끝까지 한 번에 연결해 보겠습니다.
- 문서 수집: PDF, TXT, 웹페이지, 데이터베이스 등 답변에 사용할 자료를 모은다.
- 문서 전처리: 불필요한 공백, 반복 문구, 깨진 텍스트를 정리한다.
- Chunking: 긴 문서를 검색하기 좋은 작은 조각으로 나눈다.
- Overlap 적용: 문맥이 경계에서 끊기지 않도록 일부 내용을 겹쳐 자른다.
- Metadata 저장: 문서명, 페이지, 작성일, 섹션 제목 등 출처 정보를 붙인다.
- Embedding: 각 문서 조각을 의미를 담은 숫자 벡터로 변환한다.
- Vector Store 저장: Chunk 원문, 벡터, Metadata를 함께 저장한다.
- 사용자 질문 입력: 사용자가 자연어로 질문한다.
- Query Embedding: 사용자 질문도 벡터로 변환한다.
- Similarity Search: 질문 벡터와 가까운 문서 벡터를 찾는다.
- Top-N Retrieval: 관련도가 높은 문서 조각 몇 개를 가져온다.
- Prompt Augmentation: 검색된 문서 조각을 사용자 질문과 함께 프롬프트에 넣는다.
- Generation: LLM이 제공된 근거를 바탕으로 답변을 생성한다.
- 출처 표시: 답변에 참고한 문서명, 페이지, 조항 등을 함께 표시한다.
정리
RAG는 LLM에게 외부 문서를 단순히 붙여주는 기능이 아닙니다. 문서를 검색하기 좋은 단위로 나누고, 의미 기반으로 찾을 수 있도록 벡터화하고, 질문과 가장 관련 있는 문서 조각만 골라 LLM에게 전달하는 전체 구조입니다.
이 과정에서 Chunking, Embedding, Vector Store, Retrieval, Prompt Augmentation, Grounded Answer가 서로 연결됩니다. 하나만 잘한다고 좋은 RAG가 되는 것이 아니라, 문서 준비부터 검색 결과를 프롬프트에 넣는 방식까지 전체 흐름이 맞아야 합니다.
RAG의 품질은 “좋은 LLM”만으로 결정되지 않습니다.
좋은 문서를 준비하고, 적절히 나누고, 정확히 검색하고, 필요한 근거만 프롬프트에 넣는 전체 설계가 답변 품질을 결정합니다.
다음 글에서는 RAG에서 검색을 담당하는 핵심 요소를 더 자세히 살펴보겠습니다. 특히 Azure AI Search를 기준으로 Keyword Search, Semantic Search, Vector Search, Hybrid Search가 어떻게 다르고, 각각 어떤 상황에서 필요한지 정리해 보겠습니다.