基于 Fleet Context 与 Pinecone 为 LlamaIndex 构建混合检索(dense + sparse)引擎
2026/9/11 15:41:34 网站建设 项目流程

基于 Fleet Context 与 Pinecone 为 LlamaIndex 构建混合检索(dense + sparse)引擎

【免费下载链接】llama_indexLlamaIndex is the leading document agent and OCR platform项目地址: https://gitcode.com/GitHub_Trending/ll/llama_index

本文以 Fleet Context 官方集成指南为主体,完整演示如何下载 LlamaIndex 全量文档的向量化数据(约 1.2 万 chunk、约 100MB 内容),并将其写入 Pinecone,最终基于 LlamaIndex 的PineconeVectorStore搭建支持稠密向量(dense)与稀疏向量(sparse)的混合检索查询引擎。读完本文,你将掌握fleet-context的用法、Pinecone 混合索引的建库要点、批量 upsert 的工程技巧,以及如何在 LlamaIndex 中一键切换hybrid查询模式。

技术背景:为什么用 Fleet Context 预生成的 Embeddings

Fleet Context(fleet-context包)为开源社区提供了面向 1220 多个知名开源库的预计算 Embeddings 下载能力。它内部维护了一条完整的 Embeddings 流水线,与自行对文档做load → split → embed相比,Fleet 的流水线保留了大量对检索与生成至关重要的信息,包括:

  • 页面内位置(position on page):可用于后续重排序(re-ranking);
  • Chunk 类型:类(class)、函数(function)、属性(attribute)等代码结构类型标注;
  • 父级章节(parent section):保留文档层级上下文。

这些元数据与文本一起被编码进 Embeddings 数据集,使得下游检索器不仅能命中"长得像"的文本,还能理解代码文档的结构语义。这正是本文"下载现成 Embeddings"而非"本地重新生成"的核心动机。

前置准备

首先安装依赖:

!pip install llama-index !pip install --upgrade fleet-context

然后配置 OpenAI API Key。Fleet Context 生成的稠密向量来自 OpenAI 的text-embedding-ada-002模型,维度为 1536:

import os import openai os.environ["OPENAI_API_KEY"] = "sk-..." # add your API key here! openai.api_key = os.environ["OPENAI_API_KEY"]

说明:当前仓库中llama-index-vector-stores-pinecone集成包的官方文档示例(见 base.py 的 docstring)同样基于 1536 维稠密向量与dotproduct度量,与本文流程完全对应。

从 Fleet Context 下载 LlamaIndex 文档 Embeddings

调用download_embeddings并传入库名即可:

from context import download_embeddings df = download_embeddings("llamaindex")

下载过程会显示进度条(示例中约 83.7M,速度约 27.4MiB/s):

100%|██████████| 83.7M/83.7M [00:03<00:00, 27.4MiB/s] id \ 0 e268e2a1-9193-4e7b-bb9b-7a4cb88fc735 1 e495514b-1378-4696-aaf9-44af948de1a1 2 e804f616-7db0-4455-9a06-49dd275f3139 3 eb85c854-78f1-4116-ae08-53b2a2a9fa41 4 edfc116e-cf58-4118-bad4-c4bc0ca1495e

返回的 DataFrame 每一行对应一个文档 Chunk,包含idvalues(稠密向量)、metadatasparse_values(稀疏向量)等字段。可以通过下标查看具体某条记录的元数据与文本:

# Show some examples of the metadata df["metadata"][0] display(Markdown(f"{df['metadata'][8000]['text']}"))

输出示例(第 8000 条记录展示的是某个类的 API 文档片段):

classmethod from_dict(data: Dict[str, Any], kwargs: Any) → Self classmethod from_json(data_str: str, kwargs: Any) → Self classmethod from_orm(obj: Any) → Model json(, include: Optional[Union[AbstractSetIntStr, MappingIntStrAny]] = None, exclude: Optional[Union[AbstractSetIntStr, MappingIntStrAny]] = None, by_alias: bool = False, skip_defaults: Optional[bool] = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, encoder: Optional[Callable[[Any], Any]] = None, models_as_dict: bool = True*, dumps_kwargs: Any) → unicode Generate a JSON representation of the model, include and exclude arguments as per dict().

可以看到 Fleet 的 Chunk 保留了类方法签名、参数说明等结构化文档信息——这正是其 Embeddings 流水线的价值所在。

创建 Pinecone 混合搜索索引

Pinecone 支持在同一个索引中同时存储稠密向量与稀疏向量,从而支撑混合检索。混合检索要求使用dotproduct 相似度(而非 cosine),因此在建索引时必须指定metric="dotproduct"

先配置日志与客户端:

import logging import sys logging.basicConfig(stream=sys.stdout, level=logging.INFO) logging.getLogger().handlers = [] logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))
import pinecone api_key = "..." # Add your Pinecone API key here pinecone.init( api_key=api_key, environment="us-east-1-aws" ) # Add your db region here

创建索引(维度必须与text-embedding-ada-002对齐,即 1536):

# Fleet Context uses the text-embedding-ada-002 model from OpenAI with 1536 dimensions. # NOTE: Pinecone requires dotproduct similarity for hybrid search pinecone.create_index( "quickstart-fleet-context", dimension=1536, metric="dotproduct", pod_type="p1", ) pinecone.describe_index( "quickstart-fleet-context" ) # Make sure you create an index in pinecone

版本提示:上例使用的是 Pinecone 经典客户端 API(pinecone.init/pinecone.create_index)。当前仓库中PineconeVectorStore的实现已适配新版客户端,官方示例使用Pinecone(api_key=...).create_index(...)并配合ServerlessSpec(cloud="aws", region="us-west-2")创建 Serverless 索引,详见 base.py 的 docstring。两种方式二选一即可,关键在于dimension=1536metric="dotproduct"这两个混合检索的硬性要求。

在 LlamaIndex 中接入 Pinecone 向量存储

将 Pinecone 索引包装成 LlamaIndex 的PineconeVectorStore,其中add_sparse_vector=True是关键开关——它让 LlamaIndex 在写入与查询时同时处理稠密和稀疏两个通道:

from llama_index.vector_stores.pinecone import PineconeVectorStore pinecone_index = pinecone.Index("quickstart-fleet-context") vector_store = PineconeVectorStore(pinecone_index, add_sparse_vector=True)

从源码看,该开关背后有完整的实现支撑:

  • add_sparse_vector=True时,PineconeVectorStore.__init__会自动实例化一个稀疏 Embedding 模型(见 base.py);
  • 默认的稀疏模型DefaultPineconeSparseEmbedding使用BertTokenizerFastbert-base-uncased)做分词,再以词频(term frequency)构造{token_id: 频率}形式的稀疏向量,实现细节见 utils.py;
  • 该开关也允许你通过tokenizersparse_embedding_model参数自定义稀疏向量生成方式(base.py)。

批量 Upsert 向量到 Pinecone

Pinecone 官方推荐每次 upsert 100 条向量。下面用生成器将 DataFrame 逐行转换为 Pinecone 所需的(id, values, metadata, sparse_values)结构,并按 100 条一批写入:

import random import itertools def chunks(iterable, batch_size=100): """A helper function to break an iterable into chunks of size batch_size.""" it = iter(iterable) chunk = tuple(itertools.islice(it, batch_size)) while chunk: yield chunk chunk = tuple(itertools.islice(it, batch_size)) # generator that generates many (id, vector, metadata, sparse_values) pairs data_generator = map( lambda row: { "id": row[1]["id"], "values": row[1]["values"], "metadata": row[1]["metadata"], "sparse_values": row[1]["sparse_values"], }, df.iterrows(), ) # Upsert data with 1000 vectors per upsert request for ids_vectors_chunk in chunks(data_generator, batch_size=100): print(f"Upserting {len(ids_vectors_chunk)} vectors...") pinecone_index.upsert(vectors=ids_vectors_chunk)

补充说明:PineconeVectorStore内部同样以批处理方式工作,其DEFAULT_BATCH_SIZE = 100(见 base.py),并在add()时按此批量执行upsert;这一默认值与本指南的批量写入策略一致。

基于向量存储构建 LlamaIndex 索引

数据写入完成后,直接用已有的vector_store构建检索索引,无需重新加载文档:

from llama_index.core import VectorStoreIndex from IPython.display import Markdown, display
index = VectorStoreIndex.from_vector_store(vector_store=vector_store)

from_vector_store是 LlamaIndex 面向"外部向量库已就绪"场景的标准入口:它不再关心文档与 Embedding 的产生过程,只把向量库抽象为可查询的数据源。

以 Hybrid 模式查询索引

这是整个流程的收官一步。将查询引擎的vector_store_query_mode设为"hybrid",即可让 LlamaIndex 同时利用稠密向量(语义匹配)与稀疏向量(关键词匹配),并取两者综合结果:

query_engine = index.as_query_engine( vector_store_query_mode="hybrid", similarity_top_k=8 ) response = query_engine.query("How do I use llama_index SimpleDirectoryReader")
display(Markdown(f"<b>{response}</b>"))

输出示例:

<b>To use the SimpleDirectoryReader in llama_index, you need to import it from the llama_index library. Once imported, you can create an instance of the SimpleDirectoryReader class by providing the directory path as an argument. Then, you can use the `load_data()` method on the SimpleDirectoryReader instance to load the documents from the specified directory.</b>

Hybrid 模式的底层机制

vector_store_query_mode映射到核心层的VectorStoreQueryMode枚举(见 types.py),其中与本文相关的取值包括:

模式含义
default仅稠密向量检索
sparse仅稀疏向量(关键词)检索
hybrid稠密 + 稀疏混合检索

当模式为sparsehybrid时,PineconeVectorStore.query()会先用默认稀疏模型对查询串生成稀疏向量,再连同稠密向量一起提交给 Pinecone(见 base.py)。这里有两个值得注意的细节:

  • alpha权重参数:核心层的VectorStoreQuery.alpha注释明确为 "0 for bm25(稀疏), 1 for vector search(稠密)"(见 types.py)。在 Pinecone 实现中,若指定alpha,稠密向量按alpha缩放、稀疏向量按1 - alpha缩放,从而调节两种检索的贡献比例(base.py);
  • 查询串必填sparsehybrid模式要求必须提供query_str,否则会抛出ValueError(base.py)。

元数据回传与结果组装

查询返回后,PineconeVectorStore会把 Pinecone 每条 match 中的 metadata 反序列化回 LlamaIndex 的TextNode(优先走新版metadata_dict_to_node,失败时回退到legacy_metadata_dict_to_node兼容旧数据),并组装出nodessimilaritiesids三要素的VectorStoreQueryResult(base.py)。这也意味着 Fleet Context 预置在 metadata 里的位置、类型、章节等信息在检索链路中全程保留,可继续用于下游的重排序或过滤。

集成包的验证与扩展

仓库为PineconeVectorStore提供了完整的集成测试(见 test_vector_stores_pinecone.py),覆盖了向量写入(test_add_upserts_vectors_by_keyword)、基于 mock 的索引行为校验等场景,可作为你自行验证混合检索链路的参考模板。

此外,PineconeVectorStore还支持以下能力,可作为本文方案的进阶扩展:

  • 命名空间隔离:通过namespace参数在同一个 Pinecone 索引中隔离不同数据集;
  • 批量/过滤删除delete_nodes支持按node_ids或元数据过滤器删除,二者互斥(base.py);
  • 元数据过滤:标准MetadataFilters会被自动转换为 Pinecone 的$eq/$ne/$gt/$lt/$in等过滤语法(base.py),可在查询时叠加filter约束。

小结

本文完整走通了"Fleet Context 下载 Embeddings → Pinecone 混合索引建库 → 批量 upsert → LlamaIndex hybrid 查询"的端到端链路。核心要点可归纳为四点:

  1. 直接复用 Fleet Context 的预计算 Embeddings,省去本地文档解析与向量化流水线,同时获得位置、类型、章节等丰富元数据;
  2. 混合检索要求metric="dotproduct"与 1536 维,建索引时不可省略;
  3. add_sparse_vector=True是让PineconeVectorStore启用稀疏通道的关键参数;
  4. 查询时指定vector_store_query_mode="hybrid",并按需通过alpha调节稠密/稀疏检索权重。

这套方案不仅适用于 LlamaIndex 自身文档,任何 Fleet Context 支持的 1220 余个开源库都可复用同一套代码流程,快速搭建"语义 + 关键词"双通道的混合检索问答系统。

【免费下载链接】llama_indexLlamaIndex is the leading document agent and OCR platform项目地址: https://gitcode.com/GitHub_Trending/ll/llama_index

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询