RAG 파이프라인 튜토리얼을 진행하며, 잘 이해되지 않는 내용이나 정리가 필요하다고 생각이 든 것들을 아래에 정리해보겠다.
.env에 OPENAI API 키 설정json 데이터 로딩 및 구조 분석
텍스트 청킹: 페이지 기반 / 문서 기반 / 문단 기반
text-embedding-3-small 임베딩 모델 yuna_test 컬렉션batch_size 지정하여 여러 번 insertsearch_results 내부에는?search_results = vector_db.search(query, limit=3)
- 'id': 해당 청크의 고유 식별자
- 'score': 쿼리와의 코사인 거리(작을수록 유사, cosine distance)
- 'text': 검색된 청크의 본문 텍스트
- 'filenm': 원본 파일명
→ search_results는 청크id, 쿼리와의 코사인 거리, 청크 텍스트, 원본 파일명을 가진다.
2025-07-24 15:32:54,207 - src.vectordb.milvus_client - INFO - 컬렉션 'yuna_db_cs1000_co200_test'이 성공적으로 생성되었습니다.
2025-07-24 15:32:54,213 - src.nodes.vectordb_node - INFO - 컬렉션 설정 완료: {'exists': True, 'name': 'yuna_db_cs1000_co200_test', 'row_count': 0, 'vector_dimension': 1536}
→ 컬렉션의 속성으로는 exists, name, row_count, vector_dimension
데이터 청킹을 위해서는 chunk_size와 chunk_overlap을 지정해야 한다.
chunk_size: 하나의 청크가 가질 수 있는 최대 토큰 수 (ex. 500, 1000 등)chunk_overlap: 인접한 청크 간 겹치는 토큰 수 (ex. 50, 100 등)| 상황 | 추천 chunk_size | 추천 chunk_overlap | 이유 |
|---|---|---|---|
| 일반 문서 (리포트, 블로그, 기술문서) | 500~1000 | 50~200 | 문맥 유지와 검색 효율의 균형 |
| 짧고 구어체 문서 (FAQ, 채팅) | 200~500 | 20~100 | 빠르게 의미 단위로 쪼갬 |
| 법률, 논문 등 긴 문맥 필요 | 1000~1500 | 200~300 | 문맥 정보 손실을 최소화 |
| context window가 짧은 LLM 사용 시 | 200~600 | 50~100 | LLM context 제한 대응 |
💬 실전 팁:
해당 파이프라인에서는 문서를 청킹할 때 페이지/문서/문단 기반을 구현하였다.
| 전략 | 설명 | 장점 | 단점 | 적합한 상황 |
|---|---|---|---|---|
| 페이지 기반 | PDF 등에서 1페이지 단위로 자름 | 문서 흐름 유지 | 페이지는 의미 단위가 아님 | 스캔 문서, 레이아웃 보존 중요 |
| 문서 기반 | 전체 문서를 큰 단위로 자름 | 긴 문맥 유지 가능 | 하나의 청크가 너무 커질 수 있음 | 짧은 문서, 전체 흐름 이해 필요 |
| 문단 기반 | \n\n 기준 등으로 문단 단위 자름 | 의미 단위 기준, 적절한 청킹 가능 | 문단이 너무 작거나 커질 수 있음 | 대부분의 RAG 서비스에서 추천 ✅ |
| 문단+token chunking | 문단 기준 자른 후 token 수 기준 재조정 | 문맥 유지 + token 제어 가능 | 구현 복잡도 증가 | 최적화된 서비스 구축 시 추천 ⭐ |
페이지 기반 청킹을 진행할 때, 테이블이 여러 페이지에 걸쳐 나누어져 있는 경우에는
이를 어떻게 처리해야할까?
| 항목 | 내용 |
|---|---|
| 문제 상황 | PDF 문서에서 하나의 테이블이 여러 페이지에 걸쳐 분할되어 있음 |
| 페이지 기반 청킹 | chunk_size와 상관없이 각 페이지를 개별 청크로 처리함 |
| 발생 결과 | 문맥 단절, 테이블 정보 일부 누락, 검색 품질 저하, 답변 누락 가능성 |
💫 아래는 지피티가 제공해준 답변이다.
✅ PDF 전처리 단계에서 테이블 병합
: 테이블이 연속된 페이지에 걸쳐 있는 경우, 전처리 단계에서 이들을 하나의 논리 블록으로 병합
🧩 페이지 기반 + 구조 기반 혼합 청킹 전략
: 청킹 전략을 무조건 page_based로 하지 않고, 문서 구조 단위(테이블/문단 등)로 조건부 청킹
<table> 태그로 감싸진 덩어리를 통째로 chunk 처리🧠 후처리 기반 문맥 재조합 (Advanced)
: 검색된 청크가 잘렸더라도 LLM이 답변 생성 시 자동으로 이전/다음 문맥 보완
chunk_overlap을 높게 설정해 일부 이어진 내용이 유지되도록 유도🔸 코사인 유사도 (Cosine Similarity)
🔸 코사인 거리 (Cosine Distance)
distance=1−cosine similarity| 지표 | 설명 | 언제 유용한가 |
|---|---|---|
| L2 거리 | 유클리드 거리. 가까울수록 유사 | dense vector인 경우 기본적으로 사용됨 |
| Inner Product (IP) | 내적. 크기와 방향 모두 고려 | 임베딩에 크기 정보도 중요한 경우 |
| Dot Product Score | 정규화 안 된 벡터에 사용 | cosine보다 정확한 경우 있음 |
| Approximate Recall@k | Top-k 검색에서 정답 포함 비율 | 평가 데이터셋 존재 시 |
| NDCG (정규화된 DCG) | 검색 순위 기반 평가 | 검색 결과의 순서가 중요할 때 |
| 지표 | 설명 | 도구 |
|---|---|---|
| Faithfulness | LLM 응답이 context(청크) 내용에 기반했는가? | RAGAS, LangSmith |
| Context Precision/Recall | 검색된 청크에 실제 정답이 포함됐는가? | RAGAS |
| Answer Relevance | 응답이 질문에 제대로 대응하는가? | RAGAS, human eval |
| Answer Similarity | 정답과의 BLEU, ROUGE, BERTScore | RAGEval, Evaluate |
| Ground Truth Hit | 정답 문장이 Top-k 안에 존재하는가? | 커스텀 Recall@k |
| 도구 | 특징 |
|---|---|
| RAGAS | RAG 전용 정량 평가 프레임워크. context faithfulness, answer relevancy, retrieval recall 평가 가능 |
| LangSmith | LangChain 공식 평가 도구. prompt 실행 결과 + 평가 템플릿 활용 |
| Haystack eval | pipeline별 평가 (retrieval / reader) 구분 |
| [BERTScore / ROUGE / BLEU] | 정답 기준 answer evaluation (텍스트 정답이 있는 경우) |
참고