Milvus와 WhyHow 통합하기
이 가이드에서는 whyhow.ai와 Milvus Lite를 사용하여 규칙 기반 검색을 수행하는 방법을 설명합니다.
개요
WhyHow는 개발자가 복잡한 RAG를 수행하기 위해 비정형 데이터를 구성, 문맥화 및 안정적으로 검색하는 데 필요한 빌딩 블록을 제공하는 플랫폼입니다. 규칙 기반 검색 패키지는 고급 필터링 기능을 갖춘 검색 증강 생성(RAG) 애플리케이션을 만들고 관리할 수 있도록 해주는 WhyHow에서 개발한 Python 패키지입니다.
설치
시작하기 전에 나중에 사용할 수 있도록 필요한 모든 Python 패키지를 설치하세요.
pip install --upgrade pymilvus, whyhow_rbr
다음으로 Milvus Lite를 사용해 규칙 기반 검색을 구현하기 위해 Milvus 클라이언트를 초기화해야 합니다.
from pymilvus import MilvusClient
# Milvus Lite local path
path="./milvus_demo.db" # random name for local milvus lite db path
# Initialize the ClientMilvus
milvus_client = ClientMilvus(path)
밀버스 클라우드를 통해 밀버스 클라이언트를 초기화할 수도 있습니다.
from pymilvus import MilvusClient
# Milvus Cloud credentials
YOUR_MILVUS_CLOUD_END_POINT = "YOUR_MILVUS_CLOUD_END_POINT"
YOUR_MILVUS_CLOUD_TOKEN = "YOUR_MILVUS_CLOUD_TOKEN"
# Initialize the ClientMilvus
milvus_client = ClientMilvus(
milvus_uri=YOUR_MILVUS_CLOUD_END_POINT,
milvus_token=YOUR_MILVUS_CLOUD_TOKEN,
)
컬렉션 만들기
필요한 변수 정의
# Define collection name
COLLECTION_NAME="YOUR_COLLECTION_NAME" # take your own collection name
# Define vector dimension size
DIMENSION=1536 # decide by the model you use
스키마 추가
밀버스 라이트 데이터베이스에 데이터를 삽입하기 전에 먼저 데이터 필드를 정의해야 하는데, 이를 여기서 스키마라고 합니다. CollectionSchema
객체를 생성하고 add_field()
을 통해 데이터 필드를 추가하면 데이터 유형과 특성을 제어할 수 있습니다. 이 단계는 Milvus에 데이터를 삽입하기 전에 필수적으로 수행해야 합니다.
schema = milvus_client.create_schema(auto_id=True) # Enable id matching
schema = milvus_client.add_field(schema=schema, field_name="id", datatype=DataType.INT64, is_primary=True)
schema = milvus_client.add_field(schema=schema, field_name="embedding", datatype=DataType.FLOAT_VECTOR, dim=DIMENSION)
인덱스 생성
각 스키마마다 인덱스가 있으면 쿼리가 훨씬 더 효율적입니다. 인덱스를 생성하려면 먼저 index_params
이 필요하고 나중에 이 IndexParams
객체에 인덱스 데이터를 더 추가합니다.
# Start to indexing data field
index_params = milvus_client.prepare_index_params()
index_params = milvus_client.add_index(
index_params=index_params, # pass in index_params object
field_name="embedding",
index_type="AUTOINDEX", # use autoindex instead of other complex indexing method
metric_type="COSINE", # L2, COSINE, or IP
)
이 방법은 공식 Milvus 구현(공식 문서)에 대한 얇은 래퍼입니다.
컬렉션 만들기
모든 데이터 필드를 정의하고 색인을 생성한 후에는 이제 데이터에 빠르고 정확하게 액세스할 수 있도록 데이터베이스 컬렉션을 만들어야 합니다. 여기서 한 가지 언급해야 할 것은 모든 데이터를 자유롭게 업로드할 수 있도록 enable_dynamic_field
을 true로 초기화했다는 것입니다. 그 대가는 데이터 쿼리가 비효율적일 수 있다는 것입니다.
# Create Collection
milvus_client.create_collection(
collection_name=COLLECTION_NAME,
schema=schema,
index_params=index_params
)
문서 업로드
컬렉션을 만든 후에는 컬렉션을 문서로 채울 준비가 되었습니다. whyhow_rbr
에서는 upload_documents
의 MilvusClient
메서드를 사용하여 이 작업을 수행합니다. 내부적으로 다음 단계를 수행합니다:
- 전처리: 제공된 PDF 파일을 읽고 청크로 분할합니다.
- 임베딩: 임베딩: OpenAI 모델을 사용하여 모든 청크를 임베딩합니다.
- 삽입: 임베딩과 메타데이터를 모두 Milvus Lite에 업로드하기
# get pdfs
pdfs = ["harry-potter.pdf", "game-of-thrones.pdf"] # replace to your pdfs path
# Uploading the PDF document
milvus_client.upload_documents(
collection_name=COLLECTION_NAME,
documents=pdfs
)
질문 답변
이제 드디어 검색 증강 생성으로 넘어갈 수 있습니다.
# Search data and implement RAG!
res = milvus_client.search(
question='What food does Harry Potter like to eat?',
collection_name=COLLECTION_NAME,
anns_field='embedding',
output_fields='text'
)
print(res['answer'])
print(res['matches'])
규칙
이전 예제에서는 인덱스의 모든 문서를 고려했습니다. 그러나 때로는 미리 정의된 일부 조건(예: filename=harry-potter.pdf
)을 충족하는 문서만 검색하는 것이 유리할 수 있습니다. whyhow_rbr
에서는 검색 매개변수를 조정하여 이 작업을 수행할 수 있습니다.
규칙은 다음과 같은 메타데이터 속성을 제어할 수 있습니다.
filename
파일 이름page_numbers
페이지 번호에 해당하는 정수 목록(0 인덱싱)id
청크의 고유 식별자(가장 "극단적인" 필터)- 부울 표현식을 기반으로 하는 기타 규칙
# RULES(search on book harry-potter on page 8):
PARTITION_NAME='harry-potter' # search on books
page_number='page_number == 8'
# first create a partitions to store the book and later search on this specific partition:
milvus_client.crate_partition(
collection_name=COLLECTION_NAME,
partition_name=PARTITION_NAME # separate base on your pdfs type
)
# search with rules
res = milvus_client.search(
question='Tell me about the greedy method',
collection_name=COLLECTION_NAME,
partition_names=PARTITION_NAME,
filter=page_number, # append any rules follow the Boolean Expression Rule
anns_field='embedding',
output_fields='text'
)
print(res['answer'])
print(res['matches'])
이 예에서는 먼저 해리포터 관련 PDF를 저장하는 파티션을 만들고, 이 파티션 내에서 검색을 통해 가장 직접적인 정보를 얻을 수 있습니다. 또한 페이지 번호를 필터로 적용하여 검색하고자 하는 정확한 페이지를 지정합니다. 파일러 매개변수는 부울 규칙을 따라야 한다는 점을 기억하세요.
정리
마지막으로 모든 지침을 구현한 후 drop_collection()
을 호출하여 데이터베이스를 정리할 수 있습니다.
# Clean up
milvus_client.drop_collection(
collection_name=COLLECTION_NAME
)