LlamaIndex 和 Elasticsearch Rerankers:无与伦比的简洁
作者:来自 Elastic Jeffrey Rengifo
Elasticsearch 与行业领先的 Gen AI 工具和提供商进行了原生集成。查看我们的网络研讨会,了解如何超越 RAG 基础知识,或构建生产就绪应用 Elastic Vector Database。
要为您的用例构建最佳搜索解决方案,请立即开始免费试用云或在您的本地计算机上试用 Elastic。
在本文中,我们将探讨如何使用 Llamaindex RankGPT Reranker 和 Elasticsearch 内置的 semantic reranker。Elastic 提供开箱即用的体验,在 retrievers pipeline 中部署和使用 reranker,无需额外操作,且具备可扩展性。
最初,在 Elasticsearch 中进行 rerank 需要多个步骤,但现在它已经直接集成进retrievers pipeline:第一阶段运行搜索查询,第二阶段对结果进行 rerank,如下图所示:
 
  什么是 rerank?
Rerank 是一种在检索出一组与用户查询相关的文档后,使用较昂贵的机制将最相关的文档推到结果顶部的过程。
有许多策略可以使用专门的 cross-encoder 模型对文档进行 rerank,比如 Elastic Rerank模型,或 MS Marco 的 Cross encoder( cross-encoder/ms-marco-MiniLM-L6-v2)。另一种方法是使用 LLM 进行 rerank。Elastic Rerank 模型的一个优点是,它既可以作为 semantic search pipeline 的一部分使用,也可以作为独立工具改进现有的 BM25 打分系统。
一个 reranker 需要一组候选文档和用户查询,根据用户查询重新排序这些候选文档,从最相关到最不相关。
在本文中,我们将探索 LlamaindexRankGPTReranker(即 RankGPT reranker 实现)和Elastic Semantic Reranker,后者使用Elastic Rerank模型。
完整示例可在此notebook中查看。
步骤
- Products 索引
- 用户问题
- LlamaIndex rerank
- Elasticsearch semantic rerank
Products 索引
让我们基于用户的问题为笔记本电脑创建一个 reranker。如果用户是重度玩家,他们应该获得性能最强的机器。如果他们是学生,轻便的机器可能就可以了。
让我们从在 Notebook 中创建一些文档开始:
products = [
    {
        "name": "ASUS ROG Strix G16",
        "description": "Powerful gaming laptop with Intel Core i9 and RTX 4070.",
        "price": 1899.99,
        "reviews": 4.7,
        "sales": 320,
        "features": [
            "Intel Core i9",
            "RTX 4070",
            "16GB RAM",
            "512GB SSD",
            "165Hz Display",
        ],
    },
    {
        "name": "Razer Blade 15",
        "description": "Premium gaming laptop with an ultra-slim design and high refresh rate." ,
        "price": 2499.99,
        "reviews": 4.6,
        "sales": 290,
        "features": [
            "Intel Core i7",
            "RTX 4060",
            "16GB RAM",
            "1TB SSD",
            "240Hz Display",
        ],
    },
    {
        "name": "Acer Predator Helios 300",
        "description": "Affordable yet powerful gaming laptop with RTX graphics.",
        "price": 1399.99,
        "reviews": 4.5,
        "sales": 500,
        "features": [
            "Intel Core i7",
            "RTX 3060",
            "16GB RAM",
            "512GB SSD",
            "144Hz Display",
        ],
    },
    {
        "name": "MSI Stealth 17",
        "description": "High-performance gaming laptop with a 17-inch display.",
        "price": 2799.99,
        "reviews": 4.8,
        "sales": 200,
        "features": ["Intel Core i9", "RTX 4080", "32GB RAM", "1TB SSD", "4K Display"],
    },
    {
        "name": "Dell XPS 15",
        "description": "Sleek and powerful ultrabook with a high-resolution display.",
        "price": 2199.99,
        "reviews": 4.7,
        "sales": 350,
        "features": [
            "Intel Core i7",
            "RTX 3050 Ti",
            "16GB RAM",
            "1TB SSD",
            "OLED Display",
        ],
    },
    {
        "name": "HP Omen 16",
        "description": "Gaming laptop with a balanced price-to-performance ratio.",
        "price": 1599.99,
        "reviews": 4.4,
        "sales": 280,
        "features": [
            "AMD Ryzen 7",
            "RTX 3060",
            "16GB RAM",
            "512GB SSD",
            "165Hz Display",
        ],
    },
    {
        "name": "Lenovo Legion 5 Pro",
        "description": "Powerful Ryzen-powered gaming laptop with high refresh rate.",
        "price": 1799.99,
        "reviews": 4.6,
        "sales": 400,
        "features": [
            "AMD Ryzen 9",
            "RTX 3070 Ti",
            "16GB RAM",
            "1TB SSD",
            "165Hz Display",
        ],
    },
    {
        "name": "MacBook Pro 16",
        "description": "Apple's most powerful laptop with M3 Max chip.",
        "price": 3499.99,
        "reviews": 4.9,
        "sales": 500,
        "features": [
            "Apple M3 Max",
            "32GB RAM",
            "1TB SSD",
            "Liquid Retina XDR Display",
        ],
    },
    {
        "name": "Alienware m18",
        "description": "High-end gaming laptop with extreme performance.",
        "price": 2999.99,
        "reviews": 4.8,
        "sales": 150,
        "features": [
            "Intel Core i9",
            "RTX 4090",
            "32GB RAM",
            "2TB SSD",
            "480Hz Display",
        ],
    },
    {
        "name": "Samsung Galaxy Book3 Ultra",
        "description": "Ultra-lightweight yet powerful laptop with AMOLED display.",
        "price": 2099.99,
        "reviews": 4.5,
        "sales": 180,
        "features": [
            "Intel Core i7",
            "RTX 4070",
            "16GB RAM",
            "512GB SSD",
            "AMOLED Display",
        ],
    },
    {
        "name": "Microsoft Surface Laptop 5",
        "description": "Sleek productivity laptop with great battery life.",
        "price": 1699.99,
        "reviews": 4.3,
        "sales": 220,
        "features": ["Intel Core i7", "16GB RAM", "512GB SSD", "Touchscreen"],
    },
    {
        "name": "Gigabyte AORUS 17",
        "description": "Performance-focused gaming laptop with powerful cooling.",
        "price": 1999.99,
        "reviews": 4.6,
        "sales": 250,
        "features": [
            "Intel Core i9",
            "RTX 4070",
            "16GB RAM",
            "1TB SSD",
            "360Hz Display",
        ],
    },
]用户问题
让我们定义一个将用于 rerank 结果的问题。
user_query = "Best laptops for gaming"LlamaIndex rerank
安装依赖并导入包
我们安装执行LlamaIndex 的 RankGPT reranker 和 Elasticsearch 文档检索所需的所有依赖。然后,我们将笔记本电脑数据加载到 ElasticsearchStore 中,ElasticsearchStore 是 LlamaIndex 对 Elasticsearch 向量数据库的抽象,并使用 VectorStoreIndex 类进行检索。
pip install llama-index-core llama-index-llms-openai rank-llm llama-index-postprocessor-rankgpt-rerank llama-index-vector-stores-elasticsearch elasticsearch -q
 
import os
import nest_asyncio
from getpass import getpass
 
from llama_index.vector_stores.elasticsearch import ElasticsearchStore
from llama_index.core import (
    Document,
    VectorStoreIndex,
    QueryBundle,
    Settings,
    StorageContext,
)
from llama_index.core.retrievers import VectorIndexRetriever
from llama_index.postprocessor.rankgpt_rerank import RankGPTRerank
from llama_index.llms.openai import OpenAI
 
from elasticsearch import Elasticsearch
 
nest_asyncio.apply()设置密钥:
os.environ["OPENAI_API_KEY"] = "OPENAI_API_KEY"
os.environ["ELASTICSEARCH_ENDPOINT"] = "ELASTIC_ENDPOINT"
os.environ["ELASTICSEARCH_API_KEY"] = "ELASTIC_API_KEY"
 
INDEX_NAME = "products-laptops"Elasticsearch 客户端
我们实例化 Elasticsearch 客户端,用于索引文档并针对我们的集群运行查询。
_client = Elasticsearch(
    os.environ["ELASTICSEARCH_ENDPOINT"],
    api_key=os.environ["ELASTICSEARCH_API_KEY"],
)Mappings
我们将使用普通文本字段进行全文搜索,并创建一个 semantic_field,复制所有内容,以便运行 semantic 和 hybrid 查询。在 Elasticsearch 8.18+ 中,推理端点将自动部署。
# Creating mapping for the index
try:
    _client.indices.create(
        index=INDEX_NAME,
        body={
            "mappings": {
                "properties": {
                      "metadata": {
                        "properties": {
                            "name": {"type": "text", "copy_to": "semantic_field"},
                            "description": {
                                "type": "text",
                                "copy_to": "semantic_field",
                            },
                            "price": {
                                "type": "float",
                            },
                            "reviews": {
                                "type": "float",
                            },
                            "sales": {"type": "integer"},
                            "features": {
                                "type": "keyword",
                                "copy_to": "semantic_field",
                            },
                        }
                    },
                    "semantic_field": {"type": "semantic_text"},
                    "text": {
                        "type": "text"
                    },  # Field to store the text content for LlamaIndex
                    "embeddings": {"type": "dense_vector", "dims": 512},
 
                }
            }
        },
    )
 
    print("index created successfully")
except Exception as e:
    print(
        f"Error creating inference endpoint: {e.info['error']['root_cause'][0]['reason'] }"
    )向 LlamaIndex 索引数据
从我们定义的产品数组创建 ElasticsearchStore。这将创建一个 Elasticsearch 向量存储,后续可以使用 VectorStoreIndex 进行访问。
document_objects = []
 
es_store = ElasticsearchStore(
    es_url=os.environ["ELASTICSEARCH_ENDPOINT"],
    es_api_key=os.environ["ELASTICSEARCH_API_KEY"],
    index_name=INDEX_NAME,
    embedding_field="embeddings",
    text_field="text",
)
 
storage_context = StorageContext.from_defaults(vector_store=es_store)
 
for doc in products:
    text_content = f"""
      Product Name: {doc["name"]}
      Description: {doc["description"]}
      Price: ${doc["price"]}
      Reviews: {doc["reviews"]} stars
      Sales: {doc["sales"]} units sold
      Features: {', '.join(doc["features"])}
      """
 
    metadata = {
        "name": doc["name"],
        "description": doc["description"],
        "price": doc["price"],
        "reviews": doc["reviews"],
        "sales": doc["sales"],
        "features": doc["features"],
    }
 
    document_objects.append(Document(text=text_content, metadata=metadata))
 
index = VectorStoreIndex([], storage_context=storage_context)
 
for doc in document_objects:
    index.insert(doc)LLM 设置
定义将作为 reranker 的 LLM:
Settings.llm = OpenAI(temperature=0, model="gpt-4.1-mini")
Settings.chunk_size = 512Rerank 功能
我们现在创建一个函数,该函数先执行 retriever 从向量索引中获取与用户问题最相似的文档,然后在此基础上应用 RankGPTRerank 进行 rerank,最后返回重新排序后的文档。
def get_retrieved_nodes(
    query_str, vector_top_k=10, reranker_top_n=5, with_reranker=False
):
    query_bundle = QueryBundle(query_str)
    # configure retriever
    retriever = VectorIndexRetriever(
        index=index,
        similarity_top_k=vector_top_k,
    )
    retrieved_nodes = retriever.retrieve(query_bundle)
 
    if with_reranker:
        # configure reranker
        reranker = RankGPTRerank(
            llm=OpenAI(
                model="gpt-4.1-mini",
                temperature=0.0,
                api_key=os.environ["OPENAI_API_KEY"],
            ),
            top_n=reranker_top_n,
            verbose=True,
        )
        retrieved_nodes = reranker.postprocess_nodes(retrieved_nodes, query_bundle)
 
    return retrieved_nodes我们还创建了一个函数来格式化结果文档。
def visualize_retrieved_nodes(nodes):
    formatted_results = []
 
    for node in nodes:
        text = node.node.get_text()
 
        product_name = text.split("Product Name:")[1].split("\n")[0].strip()
        price = text.split("Price:")[1].split("\n")[0].strip()
        reviews = text.split("Reviews:")[1].split("\n")[0].strip()
        features = text.split("Features:")[1].strip()
 
        formatted_result = f"{price} - {product_name} ({reviews}) {features}"
        formatted_results.append(formatted_result)
 
    return formatted_results不使用 rerank
我们先运行不带 rerank 的请求。
new_nodes = get_retrieved_nodes(
    query_str=user_query,
    vector_top_k=5,
    with_reranker=False,
)
 
results = visualize_retrieved_nodes(new_nodes)
 
print("\nTop 5 results without rerank:")
for idx, result in enumerate(results, start=1):
    print(f"{idx}. {result}")使用 rerank
现在我们启用 rerank,它将执行相同的向量搜索,然后使用 LLM 对结果进行 rerank,应用 “Best laptops for gaming” 标准对前 5 个结果进行排序。我们可以看到细微差别,比如 Intel Core i7 处理器被排到最后,而 Alienware m18 升到了第 2 位。
new_nodes = get_retrieved_nodes(
    user_query,
    vector_top_k=5,
    reranker_top_n=5,
    with_reranker=True,
)
 
results = visualize_retrieved_nodes(new_nodes)
 
print("\nTop 5 results with reranking:")
for idx, result in enumerate(results, start=1):
    print(f"{idx}. {result}")答案:
Top 5 results with reranking:
1. $1899.99 - ASUS ROG Strix G16 (4.7 stars) Intel Core i9, RTX 4070, 16GB RAM, 512GB SSD, 165Hz Display
2. $2999.99 - Alienware m18 (4.8 stars) Intel Core i9, RTX 4090, 32GB RAM, 2TB SSD, 480Hz Display
3. $2799.99 - MSI Stealth 17 (4.8 stars) Intel Core i9, RTX 4080, 32GB RAM, 1TB SSD, 4K Display
4. $1999.99 - Gigabyte AORUS 17 (4.6 stars) Intel Core i9, RTX 4070, 16GB RAM, 1TB SSD, 360Hz Display
5. $2499.99 - Razer Blade 15 (4.6 stars) Intel Core i7, RTX 4060, 16GB RAM, 1TB SSD, 240Hz DisplayElasticsearch 语义 rerank
推理 rerank 端点
创建一个推理端点,可以独立调用它来根据查询对候选列表进行 rerank,或作为 retriever 的一部分使用:
INFERENCE_RERANK_NAME = "my-elastic-rerank"
 
try:
    _client.options(
        request_timeout=60, max_retries=3, retry_on_timeout=True
    ).inference.put(
        task_type="rerank",
        inference_id=INFERENCE_RERANK_NAME,
        body={
            "service": "elasticsearch",
            "service_settings": {
                "model_id": ".rerank-v1",
                "num_threads": 1,
                "adaptive_allocations": {
                    "enabled": True,
                    "min_number_of_allocations": 1,
                    "max_number_of_allocations": 4,
                },
            },
        },
    )
 
    print("Inference endpoint created successfully.")
 
except Exception as e:
    print(
        f"Error creating inference endpoint: {e.info['error']['root_cause'][0]['reason'] }"
    )我们定义一个函数来执行搜索查询,然后解析返回的命中结果。
async def es_search(query):
    response = _client.search(index=INDEX_NAME, body=query)
    hits = response["hits"]["hits"]
 
    if not hits:
        return ""
 
    return hits与 LlamaIndex 一样,我们创建一个函数来格式化结果文档。
def format_es_results(hits):
    formatted_results = []
 
    for hit in hits:
        metadata = hit["_source"]["metadata"]
 
        name = metadata.get("name")
        price = metadata.get("price")
        reviews = metadata.get("reviews")
        features = metadata.get("features")
 
        formatted_result = f"{price} - {name} ({reviews}) {features}"
        formatted_results.append(formatted_result)
 
    return formatted_results语义查询
我们将从语义查询开始,返回与用户问题最相似的结果。
semantic_results = await es_search(
    {
        "size": 5,
        "query": {
            "semantic": {
                "field": "semantic_field",
                "query": user_query,
            }
        },
        "_source": {
            "includes": [
                "metadata",
            ]
        },
    }
)
 
semantic_formatted_results = format_es_results(semantic_results)
 
print("Query results:")
for idx, result in enumerate(semantic_formatted_results, start=1):
    print(f"{idx}. {result}")查询结果:
1. 2999.99 - Alienware m18 (4.8) ['Intel Core i9', 'RTX 4090', '32GB RAM', '2TB SSD', '480Hz Display']
2. 2799.99 - MSI Stealth 17 (4.8) ['Intel Core i9', 'RTX 4080', '32GB RAM', '1TB SSD', '4K Display']
3. 1599.99 - HP Omen 16 (4.4) ['AMD Ryzen 7', 'RTX 3060', '16GB RAM', '512GB SSD', '165Hz Display']
4. 1399.99 - Acer Predator Helios 300 (4.5) ['Intel Core i7', 'RTX 3060', '16GB RAM', '512GB SSD', '144Hz Display']
5. 1999.99 - Gigabyte AORUS 17 (4.6) ['Intel Core i9', 'RTX 4070', '16GB RAM', '1TB SSD', '360Hz Display']
rerank_results = await es_search(
    {
        "size": 5,
        "_source": {
            "includes": [
                "metadata",
            ]
        },
        "retriever": {
            "text_similarity_reranker": {
                "retriever": {
                    "standard": {
                        "query": {
                            "semantic": {
                                "field": "semantic_field",
                                "query": user_query,
                            }
                        }
                    }
                },
                "field": "semantic_field",
                "inference_id": INFERENCE_RERANK_NAME,
                "inference_text": "reorder by quality-price ratio",
                "rank_window_size": 5,
            }
        },
    }
)
 
rerank_formatted_results = format_es_results(rerank_results)
 
print("Query results:")
for idx, result in enumerate(rerank_formatted_results, start=1):
    print(f"{idx}. {result}")查询结果:
1. 1399.99 - Acer Predator Helios 300 (4.5) ['Intel Core i7', 'RTX 3060', '16GB RAM', '512GB SSD', '144Hz Display']
 
2. 2999.99 - Alienware m18 (4.8) ['Intel Core i9', 'RTX 4090', '32GB RAM', '2TB SSD', '480Hz Display']
 
3. 2799.99 - MSI Stealth 17 (4.8) ['Intel Core i9', 'RTX 4080', '32GB RAM', '1TB SSD', '4K Display']
 
4. 1999.99 - Gigabyte AORUS 17 (4.6) ['Intel Core i9', 'RTX 4070', '16GB RAM', '1TB SSD', '360Hz Display']
 
5. 1599.99 - HP Omen 16 (4.4) ['AMD Ryzen 7', 'RTX 3060', '16GB RAM', '512GB SSD', '165Hz Display']在下表中,我们可以看到不同测试中的排名对比:
 
  图例:破折号(-)表示该方法的前五名中未出现该项。
它保持了一致性,将高端笔记本如 Alienware m18 和 MSI Stealth 17 保持在前列 —— 就像 LlamaIndex rerank 一样 —— 同时实现了更好的性价比。
结论
Reranker 是提升搜索系统质量的强大工具,确保我们总能检索到每个用户问题中最重要的信息。
LlamaIndex 提供多种 reranker 策略,使用专门模型或 LLM。在最简单的实现中,你可以创建内存中的向量存储并本地保存文档,然后进行检索和 rerank,或者使用 Elasticsearch 作为持久化的向量存储。
另一方面,Elasticsearch 提供开箱即用的推理端点框架,可以将 reranker 作为检索管道的一部分或独立端点使用。你还可以选择 Elastic 自身、Cohere、Jina 或阿里巴巴等多种服务商,或部署任何兼容的第三方模型。在 Elasticsearch 的最简单实现中,你的文档和 rerank 模型都存储在 Elasticsearch 集群中,便于扩展。
原文:LlamaIndex and Elasticsearch Rerankers: Unbeatable simplicity - Elasticsearch Labs
 关注公众号
关注公众号
					低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 
							
								
								    上一篇
								      构建 AI 护城河的六大常见误区分析> 编者按: 大家都在争相构建自己的“人工智能护城河”,但究竟什么才是真正有效的竞争壁垒?是海量的历史数据、定制化的模型,还是华丽的数据看板? > > 我们今天为大家带来的文章,系统分析了当前企业在构建 AI 护城河时的六大常见误区,文章的核心观点是:真正的 AI 护城河需要长期积累、扎实的基础能力,而不是依赖表面功夫或单点突破。 > > 希望这篇文章能为您的 AI 战略提供启发,帮助您避免陷入常见误区,构建可持续发展的竞争壁垒。 本文系原作者观点,Baihai IDP 仅进行编译分享 作者 | Shaili Guru 编译 | 岳扬 在上一篇文章中,我分享了“AI Moat Pyramid”框架,企业团队可以用它来构建真正的人工智能防御壁垒。 这篇文章是反面教材:介绍六种最常见的误区 —— 它们看似是护城河,实则因未能夯实金字塔的核心能力层,而在悄然削弱你的竞争优势。 01 误区一:“我们拥有数十年积累的数据,因此占据优势。” 现实情况:历史数据往往分散杂乱、标注混乱,或尘封在无人愿意触碰的旧系统中。 这种误区使团队无法真正构建金字塔的第二层:专有数据。... 
- 
							
								
								    下一篇
								      五年磨一剑:Agent 时代追风不如造风作者:墨飏 "我有一剑,可破万剑"------2025年,Agent Infra 领域迎来"破局之剑"。 引子 2025 年,AI Agentic 基础设施(Agent Infra)迎来爆发拐点。DeepSeek、Qwen 等开源大模型的突破为 Agent 提供了强大的认知"大脑",而模型上下文协议(MCP)的生态繁荣则赋予其灵活"四肢"------据 IDC 预测,全球 80% 企业将在年内部署 Agent。"大脑"与"四肢"的协同进化,正在倒逼承载二者的"躯干"全面升级:Agent Infra 成为技术攻坚的核心战场。 云厂商竞相推出新一代 Agent Infra 技术架构: AWS 推出 AgentCore (预览版) ,官方明确其是基于 Lambda FaaS 基础设施深度定制和优化的全托管运行时,为 Bedrock Agents 解决了标准 Lambda 的关键限制,如长时执行、状态记录、会话隔离等。 Azure 推出 AI Foundry Agent Service,官方明确其集成 Functions FaaS 事件驱动使得 Agent Service 能够利用 Serve... 
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Docker安装Oracle12C,快速搭建Oracle学习环境
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- Linux系统CentOS6、CentOS7手动修改IP地址
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Docker容器配置,解决镜像无法拉取问题
- Crontab安装和使用
- Dcoker安装(在线仓库),最新的服务器搭配容器使用
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- CentOS7,8上快速安装Gitea,搭建Git服务器

 
			 
				 
				 
				 
				 
				 
				 
				



 微信收款码
微信收款码 支付宝收款码
支付宝收款码