Milvus와 LlamaIndex로 RAG를 위한 AI 에이전트 구축하기
2023년에는 대규모 언어 모델(LLM)의 인기와 그 결과로 LLM 애플리케이션이 폭발적으로 증가했습니다. 전면에 부상한 가장 인기 있는 두 가지 LLM 애플리케이션 유형은 검색 증강 생성(RAG)과 AI 에이전트입니다. RAG는 Milvus와 같은 벡터 데이터베이스를 사용하여 컨텍스트 데이터를 주입하는 것입니다. AI 에이전트는 LLM을 사용하여 다른 도구를 사용하게 하는 것입니다. GitHub의 노트북을 확인할 수 있습니다.
OpenAI는 소개가 필요 없습니다. OpenAI 서비스에 접근하려면 openai api key를 추가해야 하며, 특히 임베딩 및 ChatGPT 사용과 같은 기능에 필요합니다.
이 글에서는 이 둘을 결합해 보겠습니다. 다룰 내용은 다음과 같습니다:
기술 스택: Milvus 및 LlamaIndex
Milvus Lite
Docker Compose의 Milvus
LlamaIndex
RAG를 위한 AI 에이전트 구축
Milvus 시작하기
LlamaIndex를 통해 Milvus에 데이터 로드하기
AI 에이전트를 위한 쿼리 엔진 도구 만들기
RAG를 위한 AI 에이전트 만들기
Milvus 및 LlamaIndex로 RAG를 위한 AI 에이전트 구축 요약
RAG를 위한 Milvus 및 LlamaIndex 소개
Milvus와 LlamaIndex는 검색 증강 생성(RAG) 시스템을 구축하는 데 함께 사용할 수 있는 두 가지 강력한 도구입니다. Milvus는 대량의 데이터를 효율적으로 저장하고 쿼리할 수 있게 해주는 벡터 데이터베이스이며, LlamaIndex는 Milvus 및 기타 벡터 데이터베이스와 상호작용할 수 있는 간단하고 유연한 방법을 제공하는 라이브러리입니다. 이 두 도구를 결합함으로써 개발자는 주어진 프롬프트를 기반으로 텍스트를 효율적으로 검색하고 생성할 수 있는 RAG 시스템을 구축할 수 있습니다.
Milvus는 대규모 벡터 데이터를 처리하는 데 뛰어나 고성능 유사도 검색이 필요한 애플리케이션에 이상적입니다. 반면 LlamaIndex는 이 데이터를 인덱싱하고 쿼리하는 과정을 단순화하여 개발자에게 매끄러운 인터페이스를 제공합니다. 함께 사용하면 RAG 시스템을 위한 견고한 기반을 형성하여 관련 정보 검색과 문맥적으로 정확한 응답 생성을 가능하게 합니다.
기술 스택: Milvus Vector Store 및 LlamaIndex
RAG를 수행하는 이 AI 에이전트에는 실제로 Milvus, LlamaIndex, OpenAI라는 세 가지 기술을 사용합니다. OpenAI는 소개가 필요 없습니다. OctoAI 또는 HuggingFace LLM을 드롭인으로 사용할 수도 있습니다. 나중에 이들 중 하나를 사용하는 버전으로 업데이트할 수 있습니다.
Milvus를 사용하는 방법은 많습니다. Jupyter 노트북에서 직접 시작할 수 있는 Milvus Lite와 Docker를 통한 Milvus가 있습니다. Milvus lite는 pip install milvus를 사용하여 PyPi를 통해 설치할 수 있습니다. milvus vector store는 데이터를 로드하고 쿼리 벡터를 기반으로 검색 기능을 활성화할 수 있게 합니다. 그런 다음 노트북에서 직접 시작하고, 사용하고, 종료할 수 있습니다.
Milvus는 분산 시스템이므로 자연스럽게 Docker Compose로 Milvus를 시작하는 것이 합리적입니다. docker compose 파일은 해당 페이지와 Milvus GitHub에서 사용할 수 있습니다. Docker Compose로 Milvus를 시작하면 세 개의 컨테이너가 표시되며 기본적으로 포트 19530을 통해 Milvus에 연결합니다.
LlamaIndex
LlamaIndex는 LLM 앱을 구축하는 가장 인기 있는 프레임워크 중 하나입니다. 이는 세 가지 인기 프로젝트인 LlamaIndex, LangChain, and Haystack 중 하나입니다. LlamaIndex의 주요 초점은 검색 작업에 특화된 프레임워크를 제공하는 것입니다. 또한 AI 에이전트를 구축하기 위한 도구를 제공합니다.
RAG와 AI 에이전트를 구축하는 방법은 많습니다. 이 예제는 제가 원래 작성한 RAG AI 에이전트 튜토리얼을 기반으로 합니다. 이 두 예제의 주요 차이점은 이번 예제에서는 Milvus를 LlamaIndex와 함께 사용하는 영구 벡터 저장소로 사용한다는 것입니다. LlamaIndex 임포트는 동일하게 유지됩니다. LlamaIndex의 핵심 부분에서 가져오는 세 가지 임포트는 디렉터리 리더, 벡터 저장소 인덱스, 그리고 스토리지 컨텍스트입니다.
또한 RAG용 도구를 만들고 설명하기 위해 쿼리 엔진 도구와 도구 메타데이터 객체를 가져옵니다. 이전 버전과 비교했을 때, 여기서 추가로 임포트하는 것은 LlamaIndex용 MilvusVectorStore 객체를 가져오는 것입니다. 이 모든 것을 가져오려면 pip install -U llama-index llama-index-vector-stores-milvus pymilvus llama-index-llms-openai llama-index-readers-file를 실행해야 합니다.
from llama_index.core import (
SimpleDirectoryReader,
VectorStoreIndex,
StorageContext
)
from llama_index.core.tools import QueryEngineTool, ToolMetadata
from llama_index.vector_stores.milvus import MilvusVectorStore
벡터 데이터베이스 백엔드로 RAG를 수행할 때 중요한 단계는 벡터 데이터베이스를 실행하는 것입니다. Milvus는 시장에서 유일한 분산 벡터 데이터베이스이며, 두 가지 방식으로 실행됩니다. 첫째, default_server를 직접 임포트하고 start()할 수 있습니다. 둘째, Docker Compose를 통해 실행할 수 있습니다. 두 방식의 코드는 아래에 나와 있습니다.
from milvus import default_server
default_server.start()
또는 docker compose up -d를 터미널에서 docker-compose.yml 파일이 있는 동일한 디렉터리에서 실행하세요.
데이터를 보관하는 Milvus 인스턴스 간의 유일한 차이점은 컬렉션 이름입니다. 작업 중 데이터 무결성을 보장하기 위해 일관성 수준을 설정하는 것이 중요하며, 기본 설정은 'Strong'입니다.
LlamaIndex를 통해 문서 데이터를 Milvus에 로드하기
RAG 앱을 구축하는 첫 번째 단계는 데이터를 벡터 데이터베이스에 로드하는 것입니다. 이 튜토리얼에서는 LlamaIndex를 통해 이를 수행합니다. 입력 파일을 읽기 위해 이들의 간단한 디렉터리 리더를 사용합니다. 이 경우 Lyft와 Uber의 재무 문서를 살펴봅니다. 컬렉션 생성 과정에는 데이터가 구조화되고 인덱싱되는 데이터베이스를 설정하는 작업이 포함되며, 이를 통해 효과적인 데이터 관리와 검색이 보장됩니다.
# load data
lyft_docs = SimpleDirectoryReader(
input_files=["./data/10k/lyft_2021.pdf"]
).load_data()
uber_docs = SimpleDirectoryReader(
input_files=["./data/10k/uber_2021.pdf"]
).load_data()
데이터가 로드되면, 이를 보관하기 위해 LlamaIndex에서 MilvusVectorStore 객체를 생성해야 합니다. 이 예제에서는 임베딩 모델과 LLM 모두에 OpenAI를 사용하므로 1536의 차원을 전달합니다. 데이터를 보관하는 Milvus 인스턴스 간의 유일한 차이점은 컬렉션 이름입니다. 필요한 경우 동일한 이름의 기존 컬렉션을 덮어쓰는 것도 가능합니다.
Docker Compose를 통한 Milvus 대신 Milvus Lite를 사용하는 경우, 올바른 포트에 연결되도록 호스트와 포트도 전달해야 합니다. listen_port 옵션을 통해 기본 서버에서 포트를 가져와야 합니다.
# build index
vector_store_lyft = MilvusVectorStore(dim=1536, collection_name="lyft", overwrite=True)
vector_store_uber = MilvusVectorStore(dim=1536, collection_name="uber", overwrite=True)
# for milvus lite users
if milvuslite:
vector_store_lyft = MilvusVectorStore(host="localhost", port=default_server.listen_port, dim=1536, collection_name="lyft", overwrite=True)
vector_store_uber = MilvusVectorStore(host="localhost", port=default_server.listen_port, dim=1536, collection_name="uber", overwrite=True)
우리는 데이터를 단순히 로드하는 것뿐만 아니라 여기저기로 전달할 수 있어야 합니다. LlamaIndex는 StorageContext 객체를 제공하여 이 추상화를 처리합니다. Lyft와 Uber 모두에서 해당 데이터를 전달할 수 있도록 벡터 스토어를 스토리지 컨텍스트에 전달합니다. 그런 다음, 해당 벡터 스토어에 인덱스를 생성합니다. 이 블록의 마지막 두 줄은 다음번에 스토리지에서 이를 검색할 수 있도록 해당 벡터 스토어를 로컬 디스크에 유지합니다.
storage_context_lyft = StorageContext.from_defaults(vector_store=vector_store_lyft)
storage_context_uber = StorageContext.from_defaults(vector_store=vector_store_uber)
lyft_index = VectorStoreIndex.from_documents(lyft_docs, storage_context=storage_context_lyft)
uber_index = VectorStoreIndex.from_documents(uber_docs, storage_context=storage_context_uber)
# persist index
lyft_index.storage_context.persist(persist_dir="./storage/lyft")
uber_index.storage_context.persist(persist_dir="./storage/uber")
AI 에이전트를 위한 쿼리 엔진 도구 생성
AI 에이전트가 RAG를 수행하려면 벡터 데이터베이스에서 쿼리를 수행하는 도구를 사용할 수 있어야 합니다. 다음 블록에서는 우리가 생성한 벡터 인덱스를 가장 유사한 상위 3개의 결과를 검색하는 쿼리 엔진으로 변환합니다.
lyft_engine = lyft_index.as_query_engine(similarity_top_k=3)
uber_engine = uber_index.as_query_engine(similarity_top_k=3)
그런 다음 쿼리 엔진을 도구로 변환합니다. LlamaIndex의 ReAct 에이전트(다음 섹션에서 가져옴)는 입력의 일부로 도구 목록을 받습니다. 따라서 이 섹션에서는 해당 도구 목록을 생성합니다. 거의 동일한 구조를 가진 두 개의 도구만 생성하면 됩니다. Query Engine Tool에는 쿼리 엔진과 메타데이터가 필요합니다. 메타데이터는 도구의 이름을 지정하고 LLM에 이 도구가 무엇을 하는지, 어떻게 사용하는지 알려주는 데 사용됩니다.
query_engine_tools = [
QueryEngineTool(
query_engine=lyft_engine,
metadata=ToolMetadata(
name="lyft_10k",
description=(
"Provides information about Lyft financials for year 2021. "
"Use a detailed plain text question as input to the tool."
),
),
),
QueryEngineTool(
query_engine=uber_engine,
metadata=ToolMetadata(
name="uber_10k",
description=(
"Provides information about Uber financials for year 2021. "
"Use a detailed plain text question as input to the tool."
),
),
),
]
마지막 단계, 즉 에이전트의 구성 요소들을 조합할 준비가 모두 끝났습니다. 여기서는 LlamaIndex에서 ReAct Agent 도구와 OpenAI를 가져옵니다. LLM을 GPT-3.5로 정의하지만, 실제로는 원하는 어떤 LLM이든 사용할 수 있습니다. 에이전트에는 앞서 만든 도구 목록, LLM, 그리고 이 특정 예시에서는 그 “생각”을 보기 위해 “verbose”를 전달합니다.
from llama_index.core.agent import ReActAgent
from llama_index.llms.openai import OpenAI
llm = OpenAI(model="gpt-3.5-turbo-0613")
agent = ReActAgent.from_tools(
query_engine_tools,
llm=llm,
verbose=True
)
response = agent.chat("What was Lyft's revenue growth in 2021?")
print(str(response))
Lyft의 2021년 매출 성장률이 얼마였는지 질문하면, 아래와 같은 응답을 기대할 수 있습니다.
Milvus와 LlamaIndex로 데이터 쿼리 및 검색
Milvus와 LlamaIndex로 데이터를 쿼리하고 검색하려면 Milvus 컬렉션을 생성하고 LlamaIndex를 사용하여 인덱싱해야 합니다. Milvus 컬렉션은 벡터 집합을 저장하는 컨테이너이며, 인덱스는 벡터를 효율적으로 쿼리할 수 있게 해주는 데이터 구조입니다. 컬렉션을 생성하고 인덱싱한 후에는 LlamaIndex를 사용하여 컬렉션을 쿼리하고 관련 벡터를 검색할 수 있습니다.
LlamaIndex를 사용하여 Milvus 컬렉션을 쿼리하려면 쿼리 벡터와 유사도 메트릭을 제공해야 합니다. 쿼리 벡터는 데이터를 검색하려는 프롬프트 또는 쿼리를 나타내며, 유사도 메트릭은 두 벡터가 얼마나 유사한지 측정합니다. LlamaIndex는 유사도 메트릭을 사용하여 컬렉션의 벡터 순위를 매기고 상위 순위의 벡터를 반환합니다.
예를 들어, 주어진 문서와 유사한 문서를 검색하려는 경우 해당 문서를 나타내는 쿼리 벡터를 만들고 LlamaIndex를 사용하여 컬렉션을 쿼리할 수 있습니다. LlamaIndex는 쿼리 문서와 유사한 문서 목록을 유사도 점수와 함께 반환합니다. 이 프로세스는 가장 관련성 높은 문서가 검색되도록 하여 추가 분석 또는 텍스트 생성을 위한 탄탄한 기반을 제공합니다.
AI 에이전트 구축 및 통합
Milvus 및 LlamaIndex와 함께 AI 에이전트를 구축하고 통합하려면, 에이전트가 텍스트를 생성하는 데 사용할 데이터를 저장하는 지식 베이스를 만들어야 합니다. 지식 베이스는 텍스트 조각을 각각 나타내는 벡터 집합을 저장하는 Milvus 컬렉션일 수 있습니다.
AI 에이전트를 Milvus 및 LlamaIndex와 통합하려면 LlamaIndex를 사용하여 지식 베이스를 쿼리하고 관련 벡터를 검색해야 합니다. 그런 다음 AI 에이전트는 이러한 벡터를 사용하여 주어진 프롬프트를 기반으로 텍스트를 생성할 수 있습니다.
예를 들어, 특정 주제에 대한 질문에 답할 수 있는 AI 에이전트를 구축하려는 경우, 해당 주제와 관련된 문서를 나타내는 벡터 집합을 저장하는 지식 베이스를 만들 수 있습니다. 에이전트가 질문을 받으면 LlamaIndex를 사용하여 지식 베이스를 쿼리하고 관련 벡터를 검색할 수 있습니다. 그런 다음 에이전트는 이러한 벡터를 사용하여 질문에 대한 답변을 생성할 수 있습니다.
전반적으로 Milvus와 LlamaIndex는 RAG 시스템과 AI 에이전트를 구축하기 위한 강력한 도구 조합을 제공합니다. 이러한 도구를 함께 사용함으로써 개발자는 주어진 프롬프트를 기반으로 텍스트를 효율적으로 검색하고 생성할 수 있는 시스템을 구축할 수 있으며, 이는 고객 지원부터 콘텐츠 생성에 이르기까지 다양한 도메인의 애플리케이션에 매우 유용합니다.
Milvus 및 LlamaIndex를 사용한 검색 증강 생성을 위한 AI 에이전트 구축 요약
이 글에서는 Milvus, LlamaIndex 및 GPT 3.5를 사용하여 RAG용 AI Agent를 구축했습니다. RAG는 벡터 데이터베이스를 사용하여 사용자의 데이터를 컨텍스트로 LLM에 주입하는 LLM 기반 앱 아키텍처입니다. AI Agent는 다른 도구를 사용할 수 있는 LLM 기반 애플리케이션입니다. AI Agent로 RAG를 수행하기 위해, 벡터 데이터베이스에서 쿼리를 수행하는 데 필요한 도구를 제공합니다.
이 튜토리얼에서는 Lyft와 Uber의 샘플 데이터를 사용하여 이 아키텍처를 구축하는 방법을 보여주었습니다. 먼저 RAG를 수행할 수 있도록 데이터를 Milvus에 주입했습니다. 그런 다음 Milvus collections를 쿼리 엔진으로, 쿼리 엔진을 사용 가능한 도구로 전환했습니다. 마지막으로 이러한 도구를 AI Agent에 제공하고 이를 사용하여 문서에 대해 RAG를 수행했습니다.
계속 읽기

How to Choose the Best Embedding Model for RAG in 2026: 10 Models Benchmarked
We benchmarked 10 embedding models on cross-modal, cross-lingual, long-document, and dimension compression tasks. See which one fits your RAG pipeline.

Why Not All VectorDBs Are Agent-Ready
Explore why choosing the right vector database is critical for scaling AI agents, and why traditional solutions fall short in production.

The Great AI Agent Protocol Race: Function Calling vs. MCP vs. A2A
Compare Function Calling, MCP, and A2A protocols for AI agents. Learn which standard best fits your development needs and future-proof your applications.



