BQ개발자입니다.
지난 편에서 임베딩으로 텍스트의 의미를 벡터로 변환할 수 있다고 배웠습니다.
이제 RAG 시스템을 만들어볼까요?
📱 LLM 어플리케이션 7편: 임베딩 - 의미를 숫자로 바꾸는 기술
🔍 RAG의 데이터 흐름
먼저 RAG가 어떻게 작동하는지 봅시다.
1. 문서 저장: "인사규정.pdf" → 임베딩 → 벡터 DB에 저장
2. 질문 처리: "연차 몇 개야?" → 임베딩 → 질문 벡터 생성
3. 검색: 질문 벡터와 가장 유사한 문서 벡터 찾기
4. 답변: 찾은 문서를 LLM에 전달 → 답변 생성
간단해 보이죠?
그런데 1번 단계에서 중요한 결정을 해야 합니다.
"문서를 어떤 단위로 저장할 것인가?"
⚠️ 청킹 없이 그냥 저장하면?
100페이지짜리 인사규정을 통째로 하나의 벡터로 만들었다고 가정해봅시다.
사용자: "신입사원 연차 몇 개야?"
RAG 시스템:
1. 질문을 벡터로 변환
2. 가장 유사한 문서 검색 → "인사규정.pdf" (100페이지 전체)
3. LLM에게 전달: "이 100페이지에서 신입사원 연차를 찾아서 답해줘"
결과:
- LLM이 100페이지를 다 읽어야 함 (비용 폭발)
- 토큰 한계 초과로 처리 불가능
- 설령 처리해도 답변 정확도 떨어짐
이래서는 검색이 무의미합니다.
🤔 청킹(Chunking)이란?
청킹은 긴 문서를 검색 가능한 작은 단위로 나누는 과정입니다.
100페이지를 적절히 나누면:
- 3페이지: 근무시간 규정
- 4페이지: 연차 규정 ← 이것만 검색됨
- 5페이지: 병가 규정
...
이제 질문과 관련된 부분만 정확히 찾을 수 있습니다.
⚡ 정보의 원자성 vs 맥락성
청킹은 두 가지 상충하는 요구사항 사이의 균형입니다.
원자성 (Atomicity)
- 각 청크가 하나의 명확한 정보를 담아야 함
- 작을수록 검색 정확도 향상
- 하지만 맥락 없이는 의미가 불완전
맥락성 (Context)
- 정보를 이해하는 데 필요한 배경 포함
- 클수록 이해도 향상
- 하지만 불필요한 정보로 인한 노이즈 증가
최적의 청킹은 이 둘 사이의 균형점을 찾는 것입니다.
📏 청킹 방법론의 진화
1. 고정 크기 청킹
- 300자, 500자 등 일정 크기로 자르기
- 문제: 문장이나 단어가 중간에 잘림
- "...연차는 15일이며, 2년차부터는 매년 1일씩 추|"
2. 재귀적 청킹
- 우선순위: 문장 → 절 → 단어 경계
- 의미 단위를 최대한 보존
- 크기 제한도 지키면서 가독성 확보
3. 의미 기반 청킹
- 문서의 논리적 구조 활용 (제목, 단락, 섹션)
- 주제가 바뀌는 지점에서 분할
- 자연스러운 의미 단위 유지
🎯 고급 청킹 전략
부모-자식 청킹 (Parent-Child)
핵심 아이디어: 검색과 제공을 분리
자식 청크 (검색 최적화):
- "신입사원의 연차는 15일입니다."
- 작고 구체적, 정확한 매칭 가능
부모 청크 (답변 최적화):
- 자식 청크 + 주변 맥락
- "신입사원의 연차는 15일입니다. 2년차부터는..."
- 완전한 정보 제공
스몰-투-빅 (Small-to-Big)
검색된 청크의 앞뒤 문맥을 자동 포함:
- 핵심: "연차는 15일입니다."
- 제공: [이전 문장] + 핵심 + [다음 문장]
- 자연스러운 흐름 유지
💡 청킹이 RAG 성능을 좌우하는 이유
임베딩은 의미를 수치화하는 기술이지만,
청킹은 어떤 의미를 수치화할지 결정하는 요소입니다.
같은 정보도 청킹에 따라:
- "15일" → 의미 없는 숫자
- "신입사원 연차 15일" → 명확한 정보
RAG의 품질은 임베딩 모델보다 청킹 전략에 더 의존합니다.
검색의 정밀도와 답변의 완전성이 여기서 결정되기 때문입니다.
정보를 어떻게 구조화하고 보존할 것인가.
이것이 청킹의 본질입니다.
이렇게 오늘은 지식을 효과적으로 저장하고 검색하는 방법을 배웠습니다.
다음은 이 지식을 활용해 능동적으로 사고하는 시스템, 에이전트를 알아보겠습니다!
---
여러분의 좋아요와 공유는 사랑입니다 🥰
