Milvus와 Cognee로 RAG 구축하기
Cognee는 확장 가능한 모듈식 ECL(추출, 인지, 로드) 파이프라인을 통해 AI 애플리케이션 개발을 간소화하는 개발자 우선 플랫폼입니다. Milvus와 원활하게 통합되어 대화, 문서, 트랜스크립션을 효율적으로 연결하고 검색할 수 있는 Cognee는 착각을 줄이고 운영 비용을 최적화합니다.
Milvus와 같은 벡터 저장소, 그래프 데이터베이스, LLM을 강력하게 지원하는 Cognee는 검색 증강 생성(RAG) 시스템 구축을 위한 유연하고 사용자 정의 가능한 프레임워크를 제공합니다. 프로덕션에 바로 사용할 수 있는 아키텍처는 AI 기반 애플리케이션의 정확성과 효율성을 향상시킵니다.
이 튜토리얼에서는 Milvus 및 Cognee를 사용하여 검색 증강 생성(RAG) 파이프라인을 구축하는 방법을 보여드리겠습니다.
$ pip install pymilvus git+https://github.com/topoteretes/cognee.git
Google Colab을 사용하는 경우 방금 설치한 종속 요소를 사용하려면 런타임을 다시 시작해야 할 수 있습니다(화면 상단의 '런타임' 메뉴를 클릭하고 드롭다운 메뉴에서 '세션 다시 시작'을 선택).
이 예제에서는 기본적으로 OpenAI를 LLM으로 사용합니다. API 키를 준비하여 set_llm_api_key()
함수에서 설정해야 합니다.
Milvus를 벡터 데이터베이스로 구성하려면 VECTOR_DB_PROVIDER
을 milvus
으로 설정하고 VECTOR_DB_URL
및 VECTOR_DB_KEY
을 지정합니다. 이 데모에서는 Milvus Lite를 사용하여 데이터를 저장하기 때문에 VECTOR_DB_URL
만 제공하면 됩니다.
import os
import cognee
cognee.config.set_llm_api_key("YOUR_OPENAI_API_KEY")
os.environ["VECTOR_DB_PROVIDER"] = "milvus"
os.environ["VECTOR_DB_URL"] = "./milvus.db"
환경 변수는 VECTOR_DB_URL
와 VECTOR_DB_KEY
입니다:
VECTOR_DB_URL
를 로컬 파일(예:./milvus.db
)로 설정하는 것이 가장 편리한 방법인데, Milvus Lite를 자동으로 활용하여 모든 데이터를 이 파일에 저장하기 때문입니다.- 데이터 규모가 큰 경우, 도커나 쿠버네티스에 더 고성능의 Milvus 서버를 설정할 수 있습니다. 이 설정에서는 서버 URL(예:
http://localhost:19530
)을VECTOR_DB_URL
으로 사용하세요. - 밀버스의 완전 관리형 클라우드 서비스인 질리즈 클라우드를 사용하려면, 질리즈 클라우드의 퍼블릭 엔드포인트와 API 키에 해당하는
VECTOR_DB_URL
와VECTOR_DB_KEY
을 조정하세요.
데이터 준비
Milvus 문서 2.4.x의 FAQ 페이지를 RAG의 비공개 지식으로 사용하며, 이는 간단한 RAG 파이프라인을 위한 좋은 데이터 소스입니다.
zip 파일을 다운로드하고 문서를 milvus_docs
폴더에 압축을 풉니다.
$ wget https://github.com/milvus-io/milvus-docs/releases/download/v2.4.6-preview/milvus_docs_2.4.x_en.zip
$ unzip -q milvus_docs_2.4.x_en.zip -d milvus_docs
milvus_docs/en/faq
폴더에서 모든 마크다운 파일을 로드합니다. 각 문서에 대해 "#"를 사용하여 파일의 내용을 구분하기만 하면 마크다운 파일의 각 주요 부분의 내용을 대략적으로 구분할 수 있습니다.
from glob import glob
text_lines = []
for file_path in glob("milvus_docs/en/faq/*.md", recursive=True):
with open(file_path, "r") as file:
file_text = file.read()
text_lines += file_text.split("# ")
RAG 빌드
코그니 데이터 재설정
await cognee.prune.prune_data()
await cognee.prune.prune_system(metadata=True)
이제 깨끗한 슬레이트가 준비되었으므로 데이터 집합을 추가하여 지식 그래프로 처리할 수 있습니다.
데이터 추가 및 인지하기
await cognee.add(data=text_lines, dataset_name="milvus_faq")
await cognee.cognify()
# [DocumentChunk(id=UUID('6889e7ef-3670-555c-bb16-3eb50d1d30b0'), updated_at=datetime.datetime(2024, 12, 4, 6, 29, 46, 472907, tzinfo=datetime.timezone.utc), text='Does the query perform in memory? What are incremental data and historical data?\n\nYes. When ...
# ...
add
메서드는 데이터 세트(Milvus FAQ)를 Cognee에 로드하고 cognify
메서드는 데이터를 처리하여 엔티티, 관계 및 요약을 추출하여 지식 그래프를 구성합니다.
요약 쿼리하기
이제 데이터가 처리되었으므로 지식 그래프를 쿼리해 보겠습니다.
from cognee.api.v1.search import SearchType
query_text = "How is data stored in milvus?"
search_results = await cognee.search(SearchType.SUMMARIES, query_text=query_text)
print(search_results[0])
{'id': 'de5c6713-e079-5d0b-b11d-e9bacd1e0d73', 'text': 'Milvus stores two data types: inserted data and metadata.'}
이 쿼리는 지식 그래프에서 쿼리 텍스트와 관련된 요약을 검색하고 가장 관련성이 높은 후보가 인쇄됩니다.
청크 쿼리하기
요약은 개괄적인 인사이트를 제공하지만, 더 세분화된 세부 정보를 얻으려면 처리된 데이터 세트에서 직접 특정 데이터 청크를 쿼리할 수 있습니다. 이러한 청크는 지식 그래프를 만드는 동안 추가되고 분석된 원본 데이터에서 파생됩니다.
from cognee.api.v1.search import SearchType
query_text = "How is data stored in milvus?"
search_results = await cognee.search(SearchType.CHUNKS, query_text=query_text)
가독성을 높이기 위해 서식을 지정하고 표시해 보겠습니다!
def format_and_print(data):
print("ID:", data["id"])
print("\nText:\n")
paragraphs = data["text"].split("\n\n")
for paragraph in paragraphs:
print(paragraph.strip())
print()
format_and_print(search_results[0])
ID: 4be01c4b-9ee5-541c-9b85-297883934ab3
Text:
Where does Milvus store data?
Milvus deals with two types of data, inserted data and metadata.
Inserted data, including vector data, scalar data, and collection-specific schema, are stored in persistent storage as incremental log. Milvus supports multiple object storage backends, including [MinIO](https://min.io/), [AWS S3](https://aws.amazon.com/s3/?nc1=h_ls), [Google Cloud Storage](https://cloud.google.com/storage?hl=en#object-storage-for-companies-of-all-sizes) (GCS), [Azure Blob Storage](https://azure.microsoft.com/en-us/products/storage/blobs), [Alibaba Cloud OSS](https://www.alibabacloud.com/product/object-storage-service), and [Tencent Cloud Object Storage](https://www.tencentcloud.com/products/cos) (COS).
Metadata are generated within Milvus. Each Milvus module has its own metadata that are stored in etcd.
###
이전 단계에서는 요약과 특정 데이터 청크 모두에 대해 Milvus FAQ 데이터 집합을 쿼리했습니다. 이를 통해 상세한 인사이트와 세분화된 정보를 얻을 수 있었지만 데이터 세트가 너무 커서 지식 그래프 내에서 종속성을 명확하게 시각화하기가 어려웠습니다.
이 문제를 해결하기 위해 코그니 환경을 재설정하고 더 작고 집중된 데이터 세트로 작업할 것입니다. 이렇게 하면 코그니파이 프로세스 중에 추출된 관계와 종속성을 더 잘 보여줄 수 있습니다. 데이터를 단순화함으로써 Cognee가 지식 그래프에서 정보를 어떻게 구성하고 구조화하는지를 명확하게 확인할 수 있습니다.
코그니 초기화
await cognee.prune.prune_data()
await cognee.prune.prune_system(metadata=True)
집중 데이터 세트 추가하기
여기서는 한 줄의 텍스트만 있는 작은 데이터 집합을 추가하고 처리하여 집중적이고 쉽게 해석할 수 있는 지식 그래프가 되도록 합니다.
# We only use one line of text as the dataset, which simplifies the output later
text = """
Natural language processing (NLP) is an interdisciplinary
subfield of computer science and information retrieval.
"""
await cognee.add(text)
await cognee.cognify()
인사이트 쿼리하기
이 작은 데이터 세트에 집중함으로써 이제 지식 그래프 내의 관계와 구조를 명확하게 분석할 수 있습니다.
query_text = "Tell me about NLP"
search_results = await cognee.search(SearchType.INSIGHTS, query_text=query_text)
for result_text in search_results:
print(result_text)
# Example output:
# ({'id': UUID('bc338a39-64d6-549a-acec-da60846dd90d'), 'updated_at': datetime.datetime(2024, 11, 21, 12, 23, 1, 211808, tzinfo=datetime.timezone.utc), 'name': 'natural language processing', 'description': 'An interdisciplinary subfield of computer science and information retrieval.'}, {'relationship_name': 'is_a_subfield_of', 'source_node_id': UUID('bc338a39-64d6-549a-acec-da60846dd90d'), 'target_node_id': UUID('6218dbab-eb6a-5759-a864-b3419755ffe0'), 'updated_at': datetime.datetime(2024, 11, 21, 12, 23, 15, 473137, tzinfo=datetime.timezone.utc)}, {'id': UUID('6218dbab-eb6a-5759-a864-b3419755ffe0'), 'updated_at': datetime.datetime(2024, 11, 21, 12, 23, 1, 211808, tzinfo=datetime.timezone.utc), 'name': 'computer science', 'description': 'The study of computation and information processing.'})
# (...)
#
# It represents nodes and relationships in the knowledge graph:
# - The first element is the source node (e.g., 'natural language processing').
# - The second element is the relationship between nodes (e.g., 'is_a_subfield_of').
# - The third element is the target node (e.g., 'computer science').
이 출력은 지식 그래프 쿼리의 결과를 나타내며, 처리된 데이터 세트에서 추출된 엔티티(노드)와 그 관계(에지)를 보여줍니다. 각 튜플에는 소스 엔티티, 관계 유형, 대상 엔티티와 함께 고유 ID, 설명, 타임스탬프와 같은 메타데이터가 포함됩니다. 그래프는 주요 개념과 그 의미론적 연결을 강조하여 데이터 집합을 구조적으로 이해할 수 있도록 해줍니다.
Milvus를 통해 코그니의 기본 사용법을 배웠습니다. 코그니의 고급 사용법을 더 알고 싶으시다면 공식 페이지 를 참조하세요.