STUDY/LLM

[LLM] RAG - Embedding VectorDB

seoyn 2026. 7. 1. 10:20

1. Embedding ๊ธฐ์ดˆ

 : ๋ถ„ํ• ๋œ ํ…์ŠคํŠธ๋ฅผ ๋ฒกํ„ฐ๋กœ ๋ณ€ํ™˜ํ™”๋Š” ๊ณผ์ • ๋‹ค๋ฃธ. LangChain ์ž„๋ฒ ๋”ฉ ๋ชจ๋ธ์€ ๊ณตํ†ต ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๋‘ ๋ฉ”์„œ๋“œ ์ œ๊ณต

embed_documents(texts: List[str]) : ์—ฌ๋Ÿฌ ๋ฌธ์„œ(์ปจํ…์ŠคํŠธ) ํ•œ ๋ฒˆ์— ๋ฒกํ„ฐํ™”

embed_query(text: str) : ์งˆ๋ฌธ ํ•˜๋‚˜๋ฅผ ๋ฒกํ„ฐํ™”

from langchain_openai import OpenAIEmbeddings
e_model = OpenAIEmbeddings(model='text-embedding-3-large')

# ์—ฌ๋Ÿฌ ๋ฌธ์„œ ์ž„๋ฒ ๋”ฉ
embedding_docs = e_model.embed_documents(docs)  # list[list[float]]
# ์งˆ๋ฌธ ์ž„๋ฒ ๋”ฉ
query_vector = e_model.embed_query(query)  # list[float]

 • text-embedding-3-small → 1536์ฐจ์›, text-embedding-3-large → 3072์ฐจ์›

 

2. ์ฝ”์‚ฌ์ธ ์œ ์‚ฌ๋„ ๊ธฐ๋ฐ˜ ๊ฒ€์ƒ‰

 : ์ฝ”์‚ฌ์ธ ์œ ์‚ฌ๋„ = ๋‘ ๋ฒกํ„ฐ์˜ ๋‚ด์  / ๊ฐ ๋ฒกํ„ฐ ํฌ๊ธฐ(L2 norm)์˜ ๊ณฑ → -1 ~ 1 ๋ฒ”์œ„(1์— ๊ฐ€๊นŒ์šธ์ˆ˜๋ก ์œ ์‚ฌ)

# ๋ฒกํ„ฐDB ์—†์ด numpy๋กœ ์ง์ ‘ ์œ ์‚ฌ๋„ ๊ณ„์‚ฐ, ์ƒ์œ„ k๊ฐœ ๋ฝ‘๊ธฐ
import numpy as np

def cosin_similarity(vector1, vector2):
    v1, v2 = np.array(vector1), np.array(vector2)
    return (v1 @ v2) / (np.linalg.norm(v1) * np.linalg.norm(v2))
    
search_list = [(i, cosin_similarity(doc_v, query_vector)) for i, doc_v in enumerate(embedded_docs)]
search_list.sort(key=lambda x: x[1], reverse=True)  # ์œ ์‚ฌ๋„ ๋‚ด๋ฆผ์ฐจ์ˆœ ์ •๋ ฌ
top_k = 3
doc_idx = [idx for idx, score in search_list[:top_k]

 

3. ๋ฒกํ„ฐ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฐœ๋…

 : ๋น„์ •ํ˜• ๋ฐ์ดํ„ฐ(๋ฑ์ŠคํŠธ, ์ด๋ฏธ์ง€ ๋“ฑ)๋ฅผ ๊ณ ์ฐจ์› ๋ฒกํ„ฐ๋กœ ๋ณ€ํ™˜·์ €์žฅ, ์œ ์‚ฌ๋„/ANN(๊ทผ์‚ฌ ์ตœ๊ทผ์ ‘ ์ด์›ƒ) ๊ธฐ๋ฐ˜์œผ๋กœ ๋น ๋ฅด๊ฒŒ ๊ฒ€์ƒ‰ํ•˜๋Š” ํŠน์ˆ˜ DB

- ๋น„์Šทํ•œ ๋ฐ์ดํ„ฐ๋Š” ์ž„๋ฒ ๋”ฉ ๊ณต๊ฐ„์—์„œ ๊ฐ€๊น๊ฒŒ, ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ๋Š” ๋ฉ€๊ฒŒ ๋ฐฐ์น˜๋˜๋Š” ์„ฑ์งˆ ์ด์šฉ

์ฃผ์š” ๋ฒกํ„ฐ DB : Qdrant(Rust ๊ธฐ๋ฐ˜ ๊ณ ์„ฑ๋Šฅ), Pinecone(์™„์ „๊ด€๋ฆฌํ˜• ํด๋ผ์šฐ๋“œ), Chroma(์˜คํ”ˆ์†Œ์Šค, ๋Œ€๊ทœ๋ชจ ์ €์žฅ ์ตœ์ ํ™”), FAISS(Meta ๊ฐœ๋ฐœ, GPU ํ™œ์šฉ ANNS), Milvus(๋ถ„์‚ฐ ์•„ํ‚คํ…์ฒ˜, ๋Œ€๊ทœ๋ชจ ๋ฐ์ดํ„ฐ์…‹์šฉ) ๋“ฑ

 

4. LangChain Vector Store ์—ฐ๋™

 ์—ฐ๊ฒฐ ๋ฐฉ๋ฒ•

 - VectorStore.from_documents() : ๋ฌธ์„œ๋ฅผ insertํ•˜๋ฉด์„œ ๋™์‹œ ์—ฐ๊ฒฐ

 - VectorStore() : DB ์—ฐ๊ฒฐ๋งŒ ์ˆ˜ํ–‰

 

4-1. InMemoryVectorStore ๊ธฐ๋ณธ ์‚ฌ์šฉ

from langchain_core.documents import Document
from langchain_core.vectorstores import InMemoryVectorStore
from langchain_huggingface import HuggingFaceEmbeddings

# Upsert(SQL:insert) ํ•  Document ๋ฆฌ์ŠคํŠธ ์ƒ์„ฑ
d1 = Document(id=1, page_coutent="Apple, Pear, Watermelon", metadata={"category":"fruit"})
d2 = Document(id=2, page_content="Python, Java, C++", metadata={"category":"IT"})
d3 = Document(id=3, page_content="Football, Baseball, Basketball", metadata={"category":"Sport"})

# ์ž„๋ฒ ๋”ฉ ๋ชจ๋ธ ์ƒ์„ฑ
embedding_model = HuggingFaceEmbeddings(model="codefuse-ai/F2LLM-v2-1.7B")
# # VectorStore ์ƒ์„ฑ(VectorDB์™€ ์—ฐ๊ฒฐ) -> ์ž„๋ฒ ๋”ฉ ๋ชจ๋ธ ๋„ฃ์–ด ์ƒ์„ฑ(์ž„๋ฒ ๋”ฉ ๋ฒกํ„ฐ ๋ณ€ํ™˜์€ VectorStore ๋‹ด๋‹น)
vectorstore = InMemoryVectorStore(embedding_model)
# Upsert - add_documents(list[Document])
# Document.page_content๋ฅผ Embedding Vector๋กœ ๋ณ€ํ™˜ -> indedx, Document๋ฅผ value๋กœ ์ €์žฅ
vectorstore.add_documents(documents=[d1, d2, d3] 

result = vectorstore.similarity_search(query="์›”๋“œ์ปต", k=2)             # ๊ฒ€์ƒ‰๋งŒ 
result = vectorstore.similarity_search_with_score(query="์›”๋“œ์ปต", k=2)  # (๋ฌธ์„œ, ์œ ์‚ฌ๋„ ์ ์ˆ˜) ๋ฐ˜ํ™˜

 

4-2. MMR(Maximal Marginal Relevance) ์•Œ๊ณ ๋ฆฌ์ฆ˜ 

 : ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ๊ด€๋ จ์„ฑ&๋‹ค์–‘์„ฑ ๋™์‹œ ๊ณ ๋ คํ•˜๋Š” ๊ธฐ๋ฒ•

 ์ˆ˜์‹ : MMR = λ·Sim(d,Q) - (1-λ)·max Sim(d,d') - λ๋กœ ๊ด€๋ จ์„ฑ&๋‹ค์–‘์„ฑ ๋น„์ค‘ ์กฐ์ ˆ

result_docs_mmr = vectorstore.max_marginal_relevance_search(
    query=query, 
    k=5,             # ๋ฐ˜ํ™˜ํ•  ๋ฌธ์„œ ์ˆ˜
    fetch_k=15,      # ๋‹ค์–‘์„ฑ ๊ณ„์‚ฐ ์œ„ํ•ด ์šฐ์„  ๊ฐ€์ ธ์˜ฌ ํ›„๋ณด ์ˆ˜ 
    lambda_mult=0.5  # ๊ด€๋ จ์„ฑ vs ๋‹ค์–‘์„ฑ ๋น„์ค‘(1=๊ด€๋ จ์„ฑ ์œ„์ฃผ, 0=๋‹ค์–‘์„ฑ ์œ„์ฃผ)
)

# ์ผ๋ฐ˜ ์œ ์‚ฌ๋„ ๊ฒ€์ƒ‰๊ณผ ๋น„๊ต
vectorstore.similarity_search(query=query, k=5)

 → ์ผ๋ฐ˜ ๊ฒ€์ƒ‰ : ์œ ์‚ฌํ•œ ๋ฌธ์„œ๋ผ๋ฆฌ ์ค‘๋ณต๋  ์ˆ˜ ์žˆ์Œ vs MMR : ์ค‘๋ณต ์ค„์ด๊ณ  ๋‹ค์–‘ํ•œ ์ •๋ณด ํ•จ๊ป˜ ๊ฐ€์ ธ์˜ด

'STUDY > LLM' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[LLM] Qdrant - langchain  (0) 2026.07.03
[LLM] Qdrant  (1) 2026.07.02
[LLM] RAG  (1) 2026.06.30
[LLM] Chain - LCEL  (0) 2026.06.27
[LLM] Output Parser  (0) 2026.06.26