2026 04 01
2026-04-01¶
Embedding¶
- 개요
- 의미의 좌표화. 컴퓨터는 텍스트의 의미를 알지 못함
- 임베딩을 통해 텍스트를 계산할 수 있는 숫자 배열로 변환하는 기술
- 의미가 비슷한 문장일수록 벡터 공간에서 서로 가까운 거리에 위치하게 만듦
- 선정 기준
- 평가 프레임워크를 직접 만들기
- 골든 테스트셋 구축
- 실제 문의 50~100건 수집
- 각 질문에 대한 정답 문서를 직접 매핑
- ex) 배송 언제 와요 -> 정답: 배송정책_FAQ_chunk_3
- 후보 모델 선정
text-embedding-3-small / large(OpenAI) /voyage-3(Voyage) 등...
- 자동 평가 스크립트
- 골든 테스트셋 구축
- 평가 프레임워크를 직접 만들기
Embedding 모델 테스트 방법¶
- 1. 사전에 VectorDB에 CS 문서 청크들을 임베딩하여 저장
- 2. 골든셋 구축: 사람이 직접 이 질문의 정답은 이 청크에 있다 지정
- 3. 평가 과정
질문: "환불 어떻게 해요?" 정답: [chunk_001] 1) query_vec = model.embed("환불 어떻게 해요?") → [0.13, -0.31, ...] (숫자 벡터) 2) retrieved = vector_search(query_vec, top_k=5) → [chunk_001, chunk_004, chunk_012, chunk_007, chunk_003] (VectorDB가 코사인 유사도 순으로 반환한 청크 ID 목록) 3) 판정: chunk_001이 retrieved 안에 있는가? → 있다! (1번째 위치) → Hit ✓
-
4. 지표 계산
Recall@5: Top-5 안에 답변이 있으면 1, 아니면 0 => 전체 평균
MRR: 정답이 몇번째 있었는지를 봐서 평균
Chunking 전략¶
- 1. Q&A 한 쌍
- CS가 짧고 명확할 때 좋음. 200~500자 이내 방식이라면 권장
- 2. Q만 임베딩, A는 메타데이터로 저장
- 질문 <-> 질문 유사도만 비교하여, 긴 답변 테스트가 임베딩 벡터를 오염시키지 않게되는 장점
- Q끼리 비교하는게 유사도가 더 좋을 수 있음. 임베딩할 때, 같은 종류의 Q를 여러개로 변형된것을 chunk_id로 저장하면 성능 좋음
- 3. 긴 문서형 답변일 때 분할
- 답변이 길다면 분할이 필요하다.
- 권장 기준은 보통 200~500 토큰 (한국어 기준 300~800자)
- 오버랩은 앞뒤 50~100 토큰 정도 겹쳐 문맥 끊기는 것을 방지
- 답변이 길다면 분할이 필요하다.
- 임베딩 모델이 VectorDB 보다 답변 품질에 훨씬 큰 영향을 미친다!! - VectorDB는 규모 커지기 전까진 대부분 비슷한 성능 보여줌
-
VectorDB에 들어가는 건 "벡터 + 메타데이터"
- 최종적으로 VectorDB에 저장되는 것은... 1) 벡터값 / 2) 텍스트 원문 / 3) 메타데이터
-
여러가지 소스 (FAQ, 서비스 가이드, 공지사항) 을 모두 벡터 디비에 저장하기 위해서는 청킹 전략과 메타데이터 설계를 소스별로 다르게!
-
기존 Q&A → Q만 임베딩 (앞서 논의한 접근법 2)
-
서비스 가이드 문서 → 섹션 단위로 분할
-
공지사항 → 공지 하나 = 한 청크 (짧으면), 길면 분할
-
- Query는 이런식으로!
VectorDB¶
- 개요
- 사용자의 질문이 들어왔을 때 질문 벡터와 가장 가까운 문서 벡터들을 빠르게 찾아내는 DB
- 이 벡터와 가장 가까운 벡터 Top-K를 찾아라!
- 선정 기준
- 소규모 (1만건 이하): Chroma/Qdrant(로컬)
- 중규모 (1만~100만건): Qdrant(서버), Weaviate, Milvus
- 관리형 서비스: Pinecone
RAG 흐름¶
- 학습)
- CS Q&A 문서를 청크로 분할
- 각 청크를 임베딩하여 VectorDB에 저장
- 답변)
- 질의가 들어오면 고객 질문을 Embedding
- VectorDB에서 유사한 청크 Top-K 검색
- 검색된 청크 + 원래 질문 LLM에 전달하여 답변 생성
측정 방법¶
- 한국어 CS 데이터에 맞는 것을 찾아야 함
- 임베딩 모델의 성능이 너무 중요함!