LLM & Generative AI/RAG in Practice

[LangChain RAG 구축 시리즈 Ep.07] 💬 사용자 질문을 벡터와 어떻게 매칭할까?

ygtoken 2025. 4. 5. 19:40
728x90

이 글에서는 RAG 시스템에서 사용자 질문을 어떻게 벡터로 변환하고,
그 벡터가 문서와 어떤 방식으로 매칭되는지를 실제 원리와 예시를 통해 쉽게 설명합니다.


🎯 오늘의 주제 요약

“사용자 질문도 벡터로 바꾼 다음,
이미 저장된 문서 벡터들과 비교해서
가장 유사한 것(top-k)을 고른다.”

이 과정을 정확히 이해하면 RAG 검색기의 작동 방식이 명확해집니다.


🔢 Step 1: 사용자 질문 → 벡터로 변환

사용자가 "상품 정보를 담고 있는 테이블이 뭐야?"라고 질문하면,
이 문장은 아래처럼 벡터로 변환됩니다. (예시)

[0.124, -0.554, 0.223, ..., 0.039]  # 1536차원의 벡터

➡️ 이 벡터는 embedding.embed_query()를 통해 생성됩니다.


🧠 Step 2: 문서 벡터들과 거리 계산

앞서 벡터화한 metadata.json 문서들도 모두 같은 방식으로 벡터가 저장되어 있습니다.

이제 질문 벡터와 각각의 문서 벡터 간 "거리(distance)" 를 계산합니다.

문서 내용 거리
products 테이블 설명 0.12
orders 테이블 설명 0.38
customers 테이블 설명 0.43

➡️ 거리가 가장 가까운 문서일수록 유사도 ↑, 즉 관련성 ↑


📦 Step 3: top-k 문서 선택

우리는 거리 계산 후, 가장 가까운 문서 상위 k개(top-k) 를 추출합니다.

retriever = db.as_retriever(search_kwargs={"k": 2})
docs = retriever.get_relevant_documents("상품 정보를 담고 있는 테이블이 뭐야?")

 

결과적으로 GPT에게는 이렇게 전달됩니다:

질문: 상품 정보를 담고 있는 테이블이 뭐야?

참고 문서:
📂 테이블: products  
🧾 컬럼: product_id, product_name  
🧩 파티션: category

➡️ 이 문서를 기반으로 GPT가 답변을 생성합니다.


🧪 실습 코드 예시

from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma

# 1. 임베딩 모델 생성
embedding_model = OpenAIEmbeddings()

# 2. 문서 임베딩 및 저장소 생성
docs = ["📂 테이블: products", "📂 테이블: orders"]
vectordb = Chroma.from_texts(docs, embedding_model)

# 3. 질문 벡터와 유사 문서 검색
retriever = vectordb.as_retriever(search_kwargs={"k": 1})
results = retriever.get_relevant_documents("상품 정보를 담고 있는 테이블이 뭐야?")
print(results[0].page_content)

📌 검색의 핵심: 거리 계산 방식

방식 설명
cosine similarity 각 벡터의 각도 비교 → 가장 일반적
Euclidean distance 벡터 간 거리 (절대적 크기 비교)
dot product 방향성과 크기 동시에 고려

➡️ 대부분의 Vector DB는 기본적으로 Cosine 유사도를 사용합니다.


📎 요약 및 핵심 정리

  • 사용자 질문도 벡터로 변환되며,
  • 저장된 문서 벡터들과의 거리(유사도) 를 계산해서
  • 가장 가까운(top-k) 문서를 GPT에게 전달하게 됩니다.
  • 이 과정을 통해 GPT는 단순 추측이 아닌 정확한 문서 기반 응답을 생성할 수 있습니다.
728x90