728x90
이 글에서는 여러 Iceberg 테이블 정보를 다루는 상황을 가정하여
멀티 문서, 멀티 컬렉션, 문서 메타데이터 기반 필터링 전략을 구성해봅니다.
모든 코드는 초보자도 이해할 수 있도록 주석을 보강했습니다.
🎯 목표
- 여러 문서를 벡터로 임베딩하여 저장하는 방법 학습
- 문서마다 메타데이터를 지정하여 검색 시 필터링 가능하도록 구성
- 테이블별 컬렉션으로 분리하여 관리하는 구조 설계
🧪 예시 1: 멀티 문서 단일 컬렉션 구성하기
# src/embed_documents.py
from langchain.vectorstores import Chroma # ChromaDB를 위한 모듈
from langchain.embeddings import OpenAIEmbeddings # OpenAI 임베딩 모델 불러오기
def embed_multiple_documents(docs: list[str], metadatas: list[dict], db_path: str, collection: str):
"""
여러 개의 문서를 받아서 하나의 Chroma 컬렉션에 저장합니다.
문서별로 메타데이터를 지정하여 이후 검색 시 필터링이 가능하게 만듭니다.
"""
# ✅ 1. OpenAI 임베딩 모델 초기화
# 문서를 벡터화할 때 사용할 모델입니다 (text-embedding-ada-002 등 내부적으로 사용)
embedding = OpenAIEmbeddings()
# ✅ 2. ChromaDB에 벡터 저장소 생성 및 저장
# 각 문서를 벡터로 변환한 후 컬렉션에 저장합니다.
vectordb = Chroma.from_texts(
texts=docs, # 벡터화할 문서 리스트 (예: products, customers 테이블 정보)
embedding=embedding, # 사용할 임베딩 모델
metadatas=metadatas, # 각 문서에 대응하는 메타데이터 (예: {"table": "products"})
persist_directory=db_path, # 로컬 저장 경로 지정
collection_name=collection # 저장할 컬렉션 이름
)
# ✅ 3. 저장한 벡터 정보를 디스크에 저장
vectordb.persist()
# ✅ 4. 완료 메시지 출력
print("✅ 벡터 저장 완료 (멀티 문서)")
▶️ 호출 예시
docs = [
"📂 테이블명: products\n🧾 컬럼 목록:\n- id (long)\n- name (string)",
"📂 테이블명: customers\n🧾 컬럼 목록:\n- id (long)\n- region (string)"
]
metas = [
{"table": "products"}, # products 테이블로 태깅
{"table": "customers"} # customers 테이블로 태깅
]
embed_multiple_documents(docs, metas, db_path="chroma_db", collection="iceberg_all")
🔍 예시 2: 메타데이터 기반 검색기 구성하기
# 메타데이터 필터링을 포함한 검색기 구성
retriever = vectordb.as_retriever(
search_kwargs={
"k": 1, # 유사한 문서 1개만 반환
"filter": {"table": "products"} # "products" 태그가 달린 문서만 검색 대상으로 설정
}
)
✅ 이 방식은 다양한 문서가 같은 컬렉션에 있을 때
필요한 테이블만 골라 검색하는 데 유용합니다.
📂 예시 3: 테이블별로 분리된 멀티 컬렉션 전략
# 사용자가 요청한 테이블 이름에 따라 다른 컬렉션을 선택하여 로드합니다.
from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings
# ✅ 사용자 입력 예시 (예: "products" 또는 "customers")
user_table = "products"
# ✅ 컬렉션 이름을 동적으로 생성
collection = f"iceberg_{user_table}" # 예: iceberg_products
# ✅ 해당 컬렉션의 벡터 저장소 로딩
vectordb = Chroma(
persist_directory="./chroma_db", # 벡터 저장소가 있는 폴더
collection_name=collection, # 선택된 테이블 이름 기반 컬렉션
embedding_function=OpenAIEmbeddings() # 임베딩 모델 설정
)
# ✅ 검색기 구성 (top-k 설정 포함)
retriever = vectordb.as_retriever(search_kwargs={"k": 2})
💡 어떤 전략이 좋은가요?
상황 | 추천 전략 |
문서 수가 적고 단순한 경우 | 단일 컬렉션에 저장 |
테이블별로 완전히 분리하고 싶을 때 | 멀티 컬렉션 구성 |
컬렉션 수를 줄이면서 필터링 기능까지 사용하고 싶을 때 | 메타데이터 기반 필터링 전략 |
📎 요약 및 핵심 정리
- 여러 문서를 RAG 시스템에서 다룰 경우, 컬렉션 또는 메타데이터를 활용해 분리할 수 있습니다.
- 메타데이터 기반 필터링은 동일 컬렉션 내 다양한 문서를 효율적으로 구분할 수 있게 합니다.
- 멀티 컬렉션 방식은 보안 영역 분리, 논리적 경계 분리가 필요한 상황에서 유리합니다.
- 실무에서는 보통 "단일 컬렉션 + 메타데이터 필터링" 전략이 가장 유연합니다.
728x90