Open In Colab GitHub Repository

LlamaIndex 및 Milvus로 전체 텍스트 검색 사용하기

전체 텍스트 검색은 정확한 키워드 매칭을 사용하며, 종종 BM25와 같은 알고리즘을 활용하여 관련성별로 문서 순위를 매깁니다. 검색 증강 생성(RAG) 시스템에서 이 방법은 관련성 있는 텍스트를 검색하여 AI가 생성한 응답을 향상시킵니다.

반면, 시맨틱 검색은 문맥적 의미를 해석하여 더 광범위한 결과를 제공합니다. 두 가지 접근 방식을 결합하면 하이브리드 검색이 생성되어 정보 검색을 개선할 수 있으며, 특히 단일 방법만으로는 부족한 경우에 유용합니다.

Milvus 2.5의 스파스-BM25 접근 방식을 사용하면 원시 텍스트가 스파스 벡터로 자동 변환됩니다. 따라서 수동으로 스파스 임베딩을 생성할 필요가 없으며, 의미론적 이해와 키워드 관련성의 균형을 맞추는 하이브리드 검색 전략이 가능합니다.

이 튜토리얼에서는 전체 텍스트 검색과 하이브리드 검색을 사용하는 RAG 시스템을 구축하기 위해 LlamaIndex와 Milvus를 사용하는 방법을 알아봅니다. 먼저 전체 텍스트 검색만 구현한 다음 시맨틱 검색을 통합하여 보다 포괄적인 결과를 얻을 수 있도록 개선해 보겠습니다.

이 튜토리얼을 진행하기 전에 전체 텍스트 검색과 LlamaIndex에서 Milvus 사용의 기본 사항을 숙지하세요.

전제 조건

종속성 설치

시작하기 전에 다음 종속성이 설치되어 있는지 확인하세요:

$ $pip install llama-index-vector-stores-milvus
$ $pip install llama-index-embeddings-openai
$ $pip install llama-index-llms-openai

Google Colab을 사용하는 경우 런타임을 다시 시작해야 할 수 있습니다(인터페이스 상단의 "런타임" 메뉴로 이동한 후 드롭다운 메뉴에서 "세션 다시 시작"을 선택합니다).

계정 설정하기

이 튜토리얼에서는 텍스트 임베딩 및 답변 생성을 위해 OpenAI를 사용합니다. OpenAI API 키를 준비해야 합니다.

import openai

openai.api_key = "sk-"

Milvus 벡터 스토어를 사용하려면 Milvus 서버 URI (또는 선택적으로 TOKEN)를 지정합니다. 밀버스 서버를 시작하려면 밀버스 설치 가이드에 따라 밀버스 서버를 설정하거나 질리즈 클라우드를 무료로 체험해 보세요.

전체 텍스트 검색은 현재 Milvus Standalone, Milvus Distributed 및 Zilliz Cloud에서 지원되지만, Milvus Lite(향후 구현 예정)에서는 아직 지원되지 않습니다. 자세한 내용은 support@zilliz.com 으로 문의하세요.

URI = "http://localhost:19530"
# TOKEN = ""

예제 데이터 다운로드

다음 명령을 실행하여 샘플 문서를 "data/paul_graham" 디렉터리에 다운로드하세요:

$ mkdir -p 'data/paul_graham/'
$ $wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/docs/examples/data/paul_graham/paul_graham_essay.txt' -O 'data/paul_graham/paul_graham_essay.txt'
--2025-03-27 07:49:01--  https://raw.githubusercontent.com/run-llama/llama_index/main/docs/docs/examples/data/paul_graham/paul_graham_essay.txt
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 75042 (73K) [text/plain]
Saving to: ‘data/paul_graham/paul_graham_essay.txt’

data/paul_graham/pa 100%[===================>]  73.28K  --.-KB/s    in 0.07s   

2025-03-27 07:49:01 (1.01 MB/s) - ‘data/paul_graham/paul_graham_essay.txt’ saved [75042/75042]

RAG 시스템에 전체 텍스트 검색을 통합하면 시맨틱 검색과 정확하고 예측 가능한 키워드 기반 검색의 균형을 맞출 수 있습니다. 전체 텍스트 검색만 사용하도록 선택할 수도 있지만, 더 나은 검색 결과를 위해 전체 텍스트 검색과 시맨틱 검색을 결합하는 것이 좋습니다. 여기에서는 데모 목적으로 전체 텍스트 검색만 사용하는 경우와 하이브리드 검색을 사용하는 경우를 보여드리겠습니다.

시작하려면 SimpleDirectoryReaderLoad 에서 폴 그레이엄의 "내가 작업한 것"이라는 에세이를 로드하세요:

from llama_index.core import SimpleDirectoryReader

documents = SimpleDirectoryReader("./data/paul_graham/").load_data()

# Let's take a look at the first document
print("Example document:\n", documents[0])
Example document:
 Doc ID: 16b7942f-bf1a-4197-85e1-f31d51ea25a9
Text: What I Worked On  February 2021  Before college the two main
things I worked on, outside of school, were writing and programming. I
didn't write essays. I wrote what beginning writers were supposed to
write then, and probably still are: short stories. My stories were
awful. They had hardly any plot, just characters with strong feelings,
which I ...

BM25를 사용한 전체 텍스트 검색

LlamaIndex의 MilvusVectorStore 는 전체 텍스트 검색을 지원하여 키워드 기반의 효율적인 검색을 가능하게 합니다. sparse_embedding_function 와 같은 내장된 기능을 사용하여 BM25 점수를 적용하여 검색 결과의 순위를 매깁니다.

이 섹션에서는 전체 텍스트 검색을 위해 BM25를 사용하여 RAG 시스템을 구현하는 방법을 보여드리겠습니다.

from llama_index.core import VectorStoreIndex, StorageContext
from llama_index.vector_stores.milvus import MilvusVectorStore
from llama_index.vector_stores.milvus.utils import BM25BuiltInFunction
from llama_index.core import Settings

# Skip dense embedding model
Settings.embed_model = None

# Build Milvus vector store creating a new collection
vector_store = MilvusVectorStore(
    uri=URI,
    # token=TOKEN,
    enable_dense=False,
    enable_sparse=True,  # Only enable sparse to demo full text search
    sparse_embedding_function=BM25BuiltInFunction(),
    overwrite=True,
)

# Store documents in Milvus
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(documents, storage_context=storage_context)
Embeddings have been explicitly disabled. Using MockEmbedding.

위의 코드는 Milvus에 예제 문서를 삽입하고 전체 텍스트 검색을 위한 BM25 랭킹을 사용할 수 있도록 인덱스를 구축합니다. 밀도 임베딩을 비활성화하고 기본 파라미터로 BM25BuiltInFunction 을 활용합니다.

BM25BuiltInFunction 파라미터에서 입력 및 출력 필드를 지정할 수 있습니다:

  • input_field_names (str): 입력 텍스트 필드(기본값: "텍스트"). BM25 알고리즘이 적용된 텍스트 필드를 나타냅니다. 다른 텍스트 필드 이름을 가진 자체 컬렉션을 사용하는 경우 이 값을 변경합니다.
  • output_field_names (str): 이 BM25 함수의 출력이 저장되는 필드(기본값: "sparse_embedding").

벡터 저장소가 설정되면 쿼리 모드가 "sparse" 또는 "text_search"인 Milvus를 사용하여 전체 텍스트 검색 쿼리를 수행할 수 있습니다:

import textwrap

query_engine = index.as_query_engine(
    vector_store_query_mode="sparse", similarity_top_k=5
)
answer = query_engine.query("What did the author learn at Viaweb?")
print(textwrap.fill(str(answer), 100))
The author learned several important lessons at Viaweb. They learned about the importance of growth
rate as the ultimate test of a startup, the value of building stores for users to understand retail
and software usability, and the significance of being the "entry level" option in a market.
Additionally, they discovered the accidental success of making Viaweb inexpensive, the challenges of
hiring too many people, and the relief felt when the company was acquired by Yahoo.

텍스트 분석기 사용자 지정

분석기는 문장을 토큰으로 나누고 어간 및 중단어 제거와 같은 어휘 처리를 수행함으로써 전체 텍스트 검색에서 중요한 역할을 합니다. 일반적으로 언어에 따라 다릅니다. 자세한 내용은 Milvus 분석기 가이드를 참조하세요.

Milvus는 두 가지 유형의 분석기를 지원합니다: 기본 제공 분석 기와 사용자 정의 분석기입니다. 기본적으로 BM25BuiltInFunction 웹사이트는 구두점을 기준으로 텍스트를 토큰화하는 표준 기본 제공 분석기를 사용합니다.

다른 분석기를 사용하거나 기존 분석기를 사용자 정의하려면 analyzer_params 인수에 값을 전달하면 됩니다:

bm25_function = BM25BuiltInFunction(
    analyzer_params={
        "tokenizer": "standard",
        "filter": [
            "lowercase",  # Built-in filter
            {"type": "length", "max": 40},  # Custom cap size of a single token
            {"type": "stop", "stop_words": ["of", "to"]},  # Custom stopwords
        ],
    },
    enable_match=True,
)

리랭커를 사용한 하이브리드 검색

하이브리드 검색 시스템은 시맨틱 검색과 전체 텍스트 검색을 결합하여 RAG 시스템에서 검색 성능을 최적화합니다.

다음 예에서는 시맨틱 검색에는 OpenAI 임베딩을, 전체 텍스트 검색에는 BM25를 사용합니다:

# Create index over the documnts
vector_store = MilvusVectorStore(
    uri=URI,
    # token=TOKEN,
    # enable_dense=True,  # enable_dense defaults to True
    dim=1536,
    enable_sparse=True,
    sparse_embedding_function=BM25BuiltInFunction(),
    overwrite=True,
    # hybrid_ranker="RRFRanker",  # hybrid_ranker defaults to "RRFRanker"
    # hybrid_ranker_params={},  # hybrid_ranker_params defaults to {}
)

storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(
    documents,
    storage_context=storage_context,
    embed_model="default",  # "default" will use OpenAI embedding
)

작동 방식

이 접근 방식은 벡터 필드가 모두 포함된 Milvus 컬렉션에 문서를 저장합니다:

  • embedding: 시맨틱 검색을 위해 OpenAI 임베딩 모델에 의해 생성된 고밀도 임베딩.
  • sparse_embedding: 전체 텍스트 검색을 위해 BM25BuiltInFunction을 사용해 계산된 스파스 임베딩.

또한, 기본 파라미터로 "RRFRanker"를 사용하여 재랭크 전략을 적용했습니다. 리랭커를 커스터마이징하려면 Milvus 리랭킹 가이드에 따라 hybrid_rankerhybrid_ranker_params 에서 설정할 수 있습니다.

이제 샘플 쿼리로 RAG 시스템을 테스트해 보겠습니다:

# Query
query_engine = index.as_query_engine(
    vector_store_query_mode="hybrid", similarity_top_k=5
)
answer = query_engine.query("What did the author learn at Viaweb?")
print(textwrap.fill(str(answer), 100))
The author learned several important lessons at Viaweb. These included the importance of
understanding growth rate as the ultimate test of a startup, the impact of hiring too many people,
the challenges of being at the mercy of investors, and the relief experienced when Yahoo bought the
company. Additionally, the author learned about the significance of user feedback, the value of
building stores for users, and the realization that growth rate is crucial for the long-term success
of a startup.

이 하이브리드 접근 방식은 의미론적 검색과 키워드 기반 검색을 모두 활용하여 RAG 시스템에서 보다 정확하고 문맥을 인식하는 응답을 보장합니다.

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started
피드백

이 페이지가 도움이 되었나요?