Skip to content
LlamaIndex 文档版本 跟随上游 源快照 708724e4 更新于 2026-10-18

全文搜索使用精确的关键词匹配,通常借助 BM25 等算法按相关性对文档排序。在**检索增强生成(RAG)**系统中,此方法检索相关文本以增强 AI 生成的响应。

同时,语义搜索解释上下文含义以提供更广泛的结果。结合这两种方法可以创建混合搜索,从而改善信息检索——尤其是在单一方法效果不佳的情况下。

借助 Milvus 2.5 的 Sparse-BM25 方法,原始文本会自动转换为稀疏向量。这消除了手动生成稀疏嵌入的需要,并启用了一种在语义理解与关键词相关性之间取得平衡的混合搜索策略。

在本教程中,你将学习如何使用 LlamaIndex 和 Milvus 构建一个使用全文搜索和混合搜索的 RAG 系统。我们将先单独实现全文搜索,然后通过集成语义搜索来增强它,以获得更全面的结果。

在继续本教程之前,请确保你熟悉全文搜索以及在 LlamaIndex 中使用 Milvus 的基础知识。

前置条件

安装依赖项

开始之前,请确保已安装以下依赖项:

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

如果你使用 Google Colab,可能需要重启运行时(转到界面顶部的 “Runtime” 菜单,然后从下拉菜单中选择 “Restart session”。)

设置账户

本教程使用 OpenAI 进行文本嵌入和答案生成。你需要准备 OpenAI API 密钥。

import openai

openai.api_key = "sk-"

要使用 Milvus 向量存储,请指定你的 Milvus 服务器 URI(并可选择提供 TOKEN)。要启动 Milvus 服务器,你可以按照 Milvus 安装指南进行设置,或者直接免费试用 Zilliz Cloud。

全文搜索目前在 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/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/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

将全文搜索集成到 RAG 系统中,可以在语义搜索与精确可预测的基于关键词的检索之间取得平衡。你也可以选择仅使用全文搜索,不过建议将全文搜索与语义搜索结合以获得更好的搜索结果。这里为了演示,我们将展示单独使用全文搜索和混合搜索。

首先,使用 SimpleDirectoryReaderLoad 加载 Paul Graham 的文章 “What I Worked On”:

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):输入文本字段(默认值:“text”)。它表示 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.

自定义文本分析器

分析器在全文本搜索中起着至关重要的作用,它将句子分解为 token 并执行词法处理,例如词干提取和停用词移除。它们通常与特定语言相关。更多详细信息请参见 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_ranker 和 hybrid_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 系统中获得更准确、更具上下文感知能力的响应。

BytesRouter 是社区翻译站点,所有译文仅供参考,一切以官方英文原文为准。