基于 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,包含id、values(稠密向量)、metadata、sparse_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=1536与metric="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使用BertTokenizerFast(bert-base-uncased)做分词,再以词频(term frequency)构造{token_id: 频率}形式的稀疏向量,实现细节见 utils.py; - 该开关也允许你通过
tokenizer或sparse_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, displayindex = 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 | 稠密 + 稀疏混合检索 |
当模式为sparse或hybrid时,PineconeVectorStore.query()会先用默认稀疏模型对查询串生成稀疏向量,再连同稠密向量一起提交给 Pinecone(见 base.py)。这里有两个值得注意的细节:
alpha权重参数:核心层的VectorStoreQuery.alpha注释明确为 "0 for bm25(稀疏), 1 for vector search(稠密)"(见 types.py)。在 Pinecone 实现中,若指定alpha,稠密向量按alpha缩放、稀疏向量按1 - alpha缩放,从而调节两种检索的贡献比例(base.py);- 查询串必填:
sparse与hybrid模式要求必须提供query_str,否则会抛出ValueError(base.py)。
元数据回传与结果组装
查询返回后,PineconeVectorStore会把 Pinecone 每条 match 中的 metadata 反序列化回 LlamaIndex 的TextNode(优先走新版metadata_dict_to_node,失败时回退到legacy_metadata_dict_to_node兼容旧数据),并组装出nodes、similarities、ids三要素的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 查询"的端到端链路。核心要点可归纳为四点:
- 直接复用 Fleet Context 的预计算 Embeddings,省去本地文档解析与向量化流水线,同时获得位置、类型、章节等丰富元数据;
- 混合检索要求
metric="dotproduct"与 1536 维,建索引时不可省略; add_sparse_vector=True是让PineconeVectorStore启用稀疏通道的关键参数;- 查询时指定
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),仅供参考