LeanX

RAG ②: 임베딩과 벡터스토어

임베딩은 텍스트의 의미를 숫자 좌표로 바꾸는 기술이고, 벡터스토어(Chroma 등)는 그 좌표를 저장해 두었다가 질문과 의미가 가까운 청크를 찾아주는 의미 기반 검색 창고입니다.

청크를 잘라 놨으니 이제 '검색이 되게' 만들 차례입니다. 문제는 컴퓨터가 '환불 규정'과 '반품 정책'이 비슷한 말이라는 걸 모른다는 것. 글자가 다르니까요. 임베딩(Embedding)이 이 문제를 풉니다.

임베딩: 의미를 지도 위의 좌표로

임베딩은 텍스트를 수백~수천 개의 숫자 배열(벡터)로 바꿉니다. 이 숫자들은 '의미 지도' 위의 좌표입니다. '강아지'와 '반려견'은 지도에서 가까운 곳에, '강아지'와 '자동차'는 먼 곳에 찍힙니다. 좌표 사이 거리를 재면 의미가 얼마나 비슷한지 계산할 수 있습니다.

임베딩 맛보기: 텍스트가 숫자가 되는 순간

# pip install langchain-openai
from langchain_openai import OpenAIEmbeddings

embeddings = OpenAIEmbeddings(model='text-embedding-3-small')

# 문장 하나를 벡터로 변환
vector = embeddings.embed_query('강아지가 공원에서 뛰어놀아요')
print(len(vector))   # 1536 (숫자 1536개짜리 좌표)
print(vector[:5])    # [0.012, -0.034, ...] 앞 5개만 미리보기

벡터스토어: 좌표 전용 검색 창고

벡터스토어는 청크와 그 좌표(벡터)를 함께 저장해 두는 데이터베이스입니다. 질문이 들어오면 질문도 좌표로 바꾼 뒤, 저장된 좌표들 중 가장 가까운 것들을 순식간에 찾아냅니다. 도서관 사서가 '주제가 비슷한 책'을 바로 뽑아 주는 것과 같습니다. 입문용으로는 설치가 간단한 Chroma를 추천합니다.

Chroma에 청크 저장하고 유사도 검색하기

# pip install langchain-chroma
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
from langchain_core.documents import Document

# 실습용 미니 문서들 (실전에서는 이전 레슨의 chunks를 넣습니다)
docs = [
    Document(page_content='환불은 구매 후 7일 이내에 가능합니다.'),
    Document(page_content='배송은 결제 후 평균 2~3일 걸립니다.'),
    Document(page_content='회원 등급은 구매 금액에 따라 결정됩니다.'),
]

# 문서를 임베딩해서 Chroma에 저장 (persist_directory로 디스크 보존)
vectorstore = Chroma.from_documents(
    documents=docs,
    embedding=OpenAIEmbeddings(model='text-embedding-3-small'),
    persist_directory='./chroma_db',
)

# 의미 기반 검색: '반품'이라는 단어가 문서에 없어도 찾아냅니다!
results = vectorstore.similarity_search('반품하고 싶어요', k=1)
print(results[0].page_content)  # 환불은 구매 후 7일 이내에 가능합니다.

핵심을 보셨나요? '반품'으로 검색했는데 '환불' 문서가 나왔습니다. 키워드가 아니라 의미로 찾기 때문입니다. 이것이 RAG 검색이 일반 텍스트 검색보다 강력한 이유입니다.

점수와 함께 검색하기

유사도 점수 확인

# 점수가 낮을수록(거리가 가까울수록) 더 유사합니다
results = vectorstore.similarity_search_with_score('배송 기간 알려줘', k=2)
for doc, score in results:
    print(f'[거리 {score:.3f}] {doc.page_content}')
벡터스토어특징추천 상황
Chroma로컬 파일 기반, 설치 간단학습, 프로토타입
FAISS메타(구 페이스북)제, 매우 빠름로컬 대용량 검색
pgvectorPostgreSQL 확장기존 DB에 통합 (Supabase 등)
Pinecone클라우드 관리형운영 서비스, 스케일링

임베딩 모델은 저장할 때와 검색할 때 반드시 같은 것을 써야 합니다. 지도가 다르면 좌표를 비교할 수 없는 것과 같은 원리입니다. 중간에 임베딩 모델을 바꾸면 전체를 다시 저장해야 합니다.

임베딩 API 호출에도 비용이 듭니다. 큰 문서를 반복 실습할 때는 persist_directory로 저장해 두고 재사용하세요. Chroma(persist_directory='./chroma_db', embedding_function=...)으로 기존 저장소를 다시 열 수 있습니다.