참고
지난 시간에 이어 진행한다.
이번 시간에는 RAG(Retrieval Augmented Generation)의 전체적인 파이프라인을 알아보자.
[1] 데이터 준비
↓
[2] 문서 쪼개기 (청킹)
↓
[3] 의미 추출 (임베딩)
↓
[4] 벡터 저장소에 넣기 (벡터 DB)
🧠 그리고 사용자 질문이 들어오면...
[5] 질문 재작성 (리라이팅) ← 이해 어려운 질문이라면
↓
[6] 질문 벡터화 (임베딩)
↓
[7] 관련 문서 검색 (벡터 DB + 문맥 검색)
↓
[8] 문서 조합해서 LLM에게 전달 (Context 포함)
↓
[9] LLM 사고 시작 (Chain of Thought)
↓
[10] 답변 생성 (Answer)
RAG의 파이프라인 구성도이다.
🛠 중간에 검색이 여러 번 일어났다면?
→ RRF(Reciprocal Rank Fusion)를 써서 결과를 합쳐서 더 똑똑한 검색 순위로 정렬!
📌 모델이 부족한 경우엔?
→ 파인튜닝으로 우리 회사에 맞게 개조!
[ 문서 수집 ]
↓
[ 문서 파싱 ]
↓
[ 문서 청킹 ]
↓
[ 임베딩 (문서 청크들) ]
↓
[ 벡터 DB 저장 ] ←────────────┐
│
사용자 질문 ↓
↓ [ 문서 검색 ]
[ 질문 임베딩 ] (유사 문서 Top-K)
↓ ↓
[ 벡터 DB 검색 ] ─────→ [ 관련 문서 ]
↓
[ LLM + 문서 + 질문 ]
↓
[ 답변 생성 및 제공 ]
✅ RAG는 어떤 구조인가?
: 사용자의 질문을 벡터화 → 벡터 DB에서 유사한 문서 검색 → 문서 내용을 LLM에 넣고 답변 생성
→ 즉, RAG는 “기억이 짧은 LLM에게, 외부 지식을 실시간으로 찾아서 넣어주는 구조”
| 단계 | 설명 |
|---|---|
| 문서 처리 | 문서 → 청크 → 임베딩 → 벡터 DB |
| 질문 처리 | 질문 → 임베딩 → 유사 문서 검색 |
| 응답 생성 | 문서+질문으로 LLM이 답변 생성 |
🧠 흐름을 순서대로 정리해보자!
1. 문서 준비 및 임베딩 (사전 작업)
2. 질문 처리 (실시간 동작)
⬇️ 사용자 질문:
"연차는 얼마나 쓸 수 있어?"
질문을 벡터화
→ 질문도 의미 기반 숫자 벡터로 바꿈
벡터 DB에서 유사한 문서 검색
→ 질문 벡터와 가장 가까운 문서 벡터를 코사인 유사도 등으로 비교
→ 관련 문서 청크들 Top-k 추출
LLM에 문서 + 질문 전달 (프롬프트 구성)
→ "이 문서들을 참고해서 사용자의 질문에 대답해줘"
LLM이 답변 생성 (Generation)
→ "우리 회사는 연차를 연 15일 사용할 수 있으며..."와 같은 자연어 답변 출력
💁♀️ 위 내용을 바탕으로 표로 간단하게 정리해보자.
| 벡터 DB에서 하는 일 | 설명 |
|---|---|
| 문서 벡터 저장 | 각 문서를 벡터로 바꿔 저장 |
| 질문 벡터와 비교 | 질문 벡터와 비슷한 문서 벡터를 빠르게 찾아냄 |
| 의미 기반 검색 | 단어가 달라도 의미가 비슷하면 찾아줌 (ex. “휴가” ↔ “연차”) |
[문서]
"우리 회사는 연차 15일을 제공하며, 사용은 부서장 승인 후 가능하다."
[사용자 질문]
"휴가는 며칠 쓸 수 있어?"
→ 임베딩된 질문 벡터와 위 문서 벡터가 의미상 유사하므로 매칭됨
→ LLM이 문서를 참고해 자연스러운 답변 생성
💁♀️ 문득 든 의문점을 해결하고 넘어가자.
| 질문 | 답변 |
|---|---|
| 벡터 DB마다 정확도가 다른가요? | ✔️ 다를 수 있다, 특히 설정 방식이나 hybrid 지원 여부에 따라 |
| 가장 큰 영향은? | ❗ 임베딩 품질이 가장 중요 |
| 세부 튜닝이 가능한 DB는? | Weaviate, Qdrant 등 |
| 가볍고 빠르게 테스트하려면? | FAISS (로컬, 빠르고 쉬움) |
🤷♀️ 확실히 짚고 넘어가자!
| 질문 | 정리 |
|---|---|
| 질문도 벡터화되나요? | ✅ 예, 질문도 임베딩해서 벡터로 바꿈 |
| 문서 벡터와 비교하나요? | ✅ 예, 질문 벡터와 문서 벡터를 비교해서 유사한 문서를 찾음 |
| LLM은 문서를 기반으로 답하나요? | ✅ 예, 검색된 문서를 프롬프트에 넣어 답변을 생성 |
| 벡터 DB가 중요한가요? | ✅ 매우 중요합니다! 검색 정확도가 전체 품질을 결정 |