LlamaIndex 集成 Azure AI Search:AzureAISearchVectorStore 向量存储完整实战指南
2026/9/10 1:15:39 网站建设 项目流程

LlamaIndex 集成 Azure AI Search:AzureAISearchVectorStore 向量存储完整实战指南

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

本指南围绕 LlamaIndex 官方集成的 Azure AI Search 向量存储(AzureAISearchVectorStore,即旧称CognitiveSearchVectorStore)展开,讲解如何在 LlamaIndex 应用中把文档向量与元数据写入 Azure AI Search 索引、执行向量/混合/语义混合检索,以及通过索引管理、字段映射和 OData 元数据过滤实现工程化落地。读完本文,你将掌握从安装、索引自动创建、批量写入到多模式查询的完整实战方案,并理解其底层实现原理。

集成概览:为什么选择 Azure AI Search 作为向量存储

Azure AI Search(前身 Azure Cognitive Search)是微软 Azure 上托管的搜索服务,原生支持向量索引(HNSW、Exhaustive KNN)、全文检索、语义排序(Semantic Ranker)与 OData 元数据过滤。在 LlamaIndex 的向量存储能力对比表中,Azure AI Search 被列为云托管型(cloud)向量存储,支持异步、元数据过滤等能力(见 vector_stores.md)。

在官方社区集成列表中,Azure AI Search 是首屈一指的 Azure 系向量存储方案(见 vector_stores.md 集成清单)。本集成由独立的 Python 包llama-index-vector-stores-azureaisearch提供,包版本 0.5.1,依赖azure-search-documents>=11.5.1,<12llama-index-core>=0.13.0,<0.15(见 pyproject.toml)。

注意:CognitiveSearchVectorStoreAzureAISearchVectorStore的别名,两者指向同一个类(见 base.py 源码 与init.py)。文档 API 参考页 azureaisearch.md 同时收录了这两个类名。

安装与最小可用示例

安装依赖

pip install llama-index-vector-stores-azureaisearch

该包会在安装时拉取azure-search-documentsllama-index-core。若缺少 SDK,构造向量存储时会抛出ImportError,提示先执行pip install azure-search-documents==11.4.0(见 base.py 导入检查)。

官方示例:完整初始化

以下代码取自类的 docstring 官方示例(见 base.py Examples),展示了从创建 Azure 客户端到初始化向量存储的完整链路:

from azure.core.credentials import AzureKeyCredential from azure.search.documents import SearchClient from azure.search.documents.indexes import SearchIndexClient from llama_index.vector_stores.azureaisearch import AzureAISearchVectorStore from llama_index.vector_stores.azureaisearch import IndexManagement, MetadataIndexFieldType # Azure AI Search setup search_service_api_key = "YOUR-AZURE-SEARCH-SERVICE-ADMIN-KEY" search_service_endpoint = "YOUR-AZURE-SEARCH-SERVICE-ENDPOINT" search_service_api_version = "2024-07-01" credential = AzureKeyCredential(search_service_api_key) # Index name to use index_name = "llamaindex-vector-demo" # Use index client to demonstrate creating an index index_client = SearchIndexClient( endpoint=search_service_endpoint, credential=credential, ) metadata_fields = { "author": "author", "theme": ("topic", MetadataIndexFieldType.STRING), "director": "director", } # Creating an Azure AI Search Vector Store vector_store = AzureAISearchVectorStore( search_or_index_client=index_client, filterable_metadata_field_keys=metadata_fields, hidden_field_keys=["embedding"], index_name=index_name, index_management=IndexManagement.CREATE_IF_NOT_EXISTS, id_field_key="id", chunk_field_key="chunk", embedding_field_key="embedding", embedding_dimensionality=1536, metadata_string_field_key="metadata", doc_id_field_key="doc_id", language_analyzer="en.lucene", vector_algorithm_type="exhaustiveKnn", semantic_configuration_name="mySemanticConfig", )

社区集成文档还给出了更精简的启动方式:直接传入SearchIndexClientindex_nameembedding_dimensionality三个参数即可完成初始化(见 integrations 文档示例)。

客户端类型与校验规则

search_or_index_client是构造函数的必填参数,接受SearchClientSearchIndexClient及其异步版本。构造函数内部遵循如下校验逻辑(见 base.pyinit):

  • 传入SearchIndexClient时,必须同时提供index_name,否则抛出ValueError;内部会通过get_search_client(index_name)派生出用于读写文档的SearchClient
  • 传入SearchClient时,不能再提供index_name,否则抛出ValueError
  • index_management == CREATE_IF_NOT_EXISTS且未传入索引客户端(Index 类客户端),会抛出ValueError
  • 同步与异步客户端都未提供时抛出ValueError

此外,构造时会为 SDK 客户端注入llamaindex-python用户代理头(可通过user_agent参数追加自定义标识),测试用例 test_user_agent_configuration 验证了该行为。

构造函数核心参数全解

构造函数签名(见 base.pyinit)中的核心参数如下:

参数类型默认值说明
search_or_index_clientSearchClient/SearchIndexClient/ 异步版本无(必填)用于读写索引或管理索引的 Azure SDK 客户端
id_field_keystr无(必填)存储节点 ID 的索引字段名
chunk_field_keystr无(必填)存储节点文本(chunk)的索引字段名
embedding_field_keystr无(必填)存储向量(embedding)的索引字段名
metadata_string_field_keystr无(必填)以 JSON 字符串存储节点元数据的索引字段名
doc_id_field_keystr无(必填)存储 doc_id(源文档 ID)的索引字段名
async_search_or_index_client异步客户端None异步场景专用客户端,缺省时复用同步客户端类型
filterable_metadata_field_keysList[str]/Dict[str, str]/Dict[str, Tuple[str, MetadataIndexFieldType]]None需要作为独立可过滤字段落库的元数据键,见下文
hidden_field_keysList[str]None对客户端隐藏的字段(如["embedding"]),避免检索返回大向量
index_nameOptional[str]None索引名(使用 Index 类客户端时必填)
index_mappingCallable默认映射自定义「节点字段 → 索引字段」映射函数
index_managementIndexManagementNO_VALIDATION索引管理策略:不校验 / 校验 / 不存在则创建
embedding_dimensionalityint1536向量维度,需与嵌入模型输出维度一致
vector_algorithm_typestr"exhaustiveKnn"向量索引算法,仅支持exhaustiveKnnhnsw
language_analyzerstr"en.lucene"可搜索文本字段的语言分析器,多语言内容建议调整
compression_typestr"none"向量压缩类型,支持"binary""scalar""none"
semantic_configuration_nameOptional[str]NoneAzure 语义检索配置名,用于语义混合查询
user_agentOptional[str]None追加到 SDK 请求的自定义 User-Agent 标识

关键参数深入说明

字段映射(Field Mapping):五个必填字段键构成默认映射{"id", "chunk", "embedding", "metadata", "doc_id"}(见 base.py 字段映射)。index_mapping允许自定义(enriched_doc, metadata) -> index_doc函数,enriched_doc的键固定为["id", "chunk", "embedding", "metadata"]

可过滤元数据字段filterable_metadata_field_keys决定哪些节点元数据以独立字段形式写入索引(从而支持 OData 过滤)。支持三种写法(见 _normalise_metadata_to_index_fields):

  • List[str]:如["author"],索引字段名与元数据键同名,类型默认STRING
  • Dict[str, str]:如{"author": "author"},键为元数据键、值为索引字段名;
  • Dict[str, Tuple[str, MetadataIndexFieldType]]:如{"theme": ("topic", MetadataIndexFieldType.STRING)},可同时指定索引字段名与类型;
  • 若值为int/float/bool/list,会自动推断为INT32/DOUBLE/BOOLEAN/COLLECTION类型。

隐藏字段hidden_field_keys中的字段不会在检索结果中返回,典型用法是把embedding字段隐藏以减小响应体(官方示例与测试 create_mock_vector_store 均如此配置)。

索引管理:自动建索引的三种策略

IndexManagement枚举定义三种策略(见 base.py):

枚举值行为
NO_VALIDATION不做任何校验,索引需由用户在 Azure 侧预先创建
VALIDATE_INDEX初始化时校验索引是否存在,不存在则抛出ValueError
CREATE_IF_NOT_EXISTS初始化时检查索引,不存在则自动创建

当选择CREATE_IF_NOT_EXISTS时,_create_index会生成一份默认索引 Schema(见 _create_index):

  • 固定字段idEdm.String,主键 key、可过滤)、chunkEdm.String,可搜索,应用language_analyzer)、embeddingCollection(Edm.Single),向量维度为embedding_dimensionality,绑定向量检索 Profile)、metadataEdm.String,JSON 字符串)、doc_idEdm.String,可过滤);
  • 元数据字段:根据filterable_metadata_field_keys生成对应的SimpleField,映射到Edm.String/Edm.Int32/Edm.Int64/Edm.Double/Edm.Boolean/Collection(Edm.String)(见 _create_metadata_index_fields);
  • 向量检索算法:同时配置myHnsw(HNSW,参数m=4ef_construction=400ef_search=500,COSINE 度量)与myExhaustiveKnn(Exhaustive KNN,COSINE 度量)两套算法及对应 Profile;vector_algorithm_type决定向量字段绑定的 Profile;
  • 压缩compression_type"binary"/"scalar"时分别附加BinaryQuantizationCompression/ScalarQuantizationCompression(见 _get_compressions)。注意 Exhaustive KNN Profile 暂不支持压缩;
  • 语义检索:默认创建名为mySemanticConfig(或semantic_configuration_name指定值)的SemanticConfiguration,其 content 字段绑定 chunk 字段;若元数据中存在titlekeyWords键,会自动将其配置为语义标题字段与关键词字段。

同步初始化时自动建索引(异步客户端传入时改为惰性创建,在首次async_add时触发)。

写入:节点批量写入与自动分批

add(nodes)async_add(nodes)负责把带嵌入向量的节点写入索引(见 base.py add)。实现要点:

  • 批量上传统一采用 merge/upload 语义:通过IndexDocumentsBatch.add_upload_actions累积文档;
  • 自动分批:默认每批最多DEFAULT_MAX_BATCH_SIZE = 700个文档,或累计字节数达到DEFAULT_MAX_MB_SIZE = 14MB时立即上传(见 base.py 常量),避免超大请求被服务端拒绝;
  • 索引文档构造_create_index_documentnode.node_id写入 id 字段、node.get_content(MetadataMode.NONE)写入 chunk 字段、node.get_embedding()写入 embedding 字段、node.ref_doc_id写入 doc_id 字段,元数据经node_to_metadata_dict(..., remove_text=True, flat_metadata=self.flat_metadata)序列化为 JSON 字符串存入 metadata 字段(见 _create_index_document);
  • 测试用例 test_azureaisearch_add_two_batches 验证了多批次写入路径。

查询:向量 / 稀疏 / 混合 / 语义混合四种模式

query(query, **kwargs)根据VectorStoreQuery.mode分发到不同的检索实现(见 base.py query):

查询模式实现类行为说明
VectorStoreQueryMode.DEFAULTAzureQueryResultSearchDefault纯向量检索:用query_embedding构造VectorizedQueryk_nearest_neighborshybrid_top_ksimilarity_top_k,返回@search.score
VectorStoreQueryMode.SPARSEAzureQueryResultSearchSparse纯文本检索:以query_str作为search_text执行关键词搜索
VectorStoreQueryMode.HYBRIDAzureQueryResultSearchHybrid向量 + 全文混合:同时提供向量查询与文本查询
VectorStoreQueryMode.SEMANTIC_HYBRIDAzureQueryResultSearchSemanticHybrid语义混合:额外指定query_type="semantic"与语义配置名,向量k固定为 50(对齐 Azure 语义重排模型的文档接受上限),相似度取@search.reranker_score(见 base.py L1716-L1792)

所有模式都支持通过kwargs直接透传 Azure SDK 的搜索参数(如odata_filters/odata_filterscoring_profile等)。查询结果统一封装为VectorStoreQueryResult:先尝试用metadata_dict_to_node还原节点,失败时走legacy_metadata_dict_to_node兼容旧格式(见 base.py L1574-L1590)。

节点读取get_nodes/aget_nodes支持按node_idsMetadataFilters分页拉取节点,每批 1000 条,命中limit后停止(见 base.py get_nodes),底层由 azureaisearch_utils.py 中的create_search_requestcreate_node_from_resultprocess_batch_results辅助完成。

元数据过滤:OData 过滤器的生成机制

Azure AI Search 使用 OData 语法过滤。本集成将 LlamaIndex 的MetadataFilters翻译为 OData 表达式(见 _create_odata_filter):

  • 基本运算符映射EQ→eqNE→neGT→gtLT→ltGTE→geLTE→le(见 BASIC_ODATA_FILTER_MAP);
  • FilterOperator.IN:字符串集合生成{field}/any(t: t eq 'a' or t eq 'b')形式(COLLECTION 字段)或search.in(field, 'a,b', ',')(删除场景);
  • 字符串转义:单引号自动转义为''防止 OData 注入;
  • 组合条件:支持FilterCondition.AND/OR/NOT,嵌套MetadataFilters递归加括号;
  • 约束:过滤的元数据键必须出现在filterable_metadata_field_keys中,否则抛出ValueError提示补充映射;不支持的运算符同样抛错。

删除操作delete(ref_doc_id)通过doc_id eq '{ref_doc_id}'定位并分批(每批 1000)删除;delete_nodes支持按node_idsMetadataFilters构造过滤条件删除(见 base.py delete)。

资源清理与异步注意事项

向量存储实现了close()aclose()与析构函数__del__(见 base.py L838-L884):

  • 只关闭由本类内部创建的搜索客户端(_owns_search_client/_owns_async_search_client标记),用户传入的客户端不代为关闭;
  • close()在存在运行中事件循环时以create_task方式调度异步客户端关闭,否则用asyncio.run临时关闭;
  • 文档建议对确定性清理优先显式调用close()/aclose(),不要依赖垃圾回收。

异步使用注意:若只传入同步客户端而未传async_search_or_index_client,构造时会打印警告——同步或异步方法可能只有其一可用(见 base.py L687-L691)。

端到端实践建议

  1. 维度对齐embedding_dimensionality必须与所选嵌入模型输出维度一致(如 OpenAItext-embedding-3-small的 1536 维);
  2. 元数据过滤前置规划:凡是查询阶段需要过滤的元数据键,写入前就必须在filterable_metadata_field_keys中声明,因为 Azure AI Search 的过滤字段需预先定义在索引 Schema 中;
  3. 隐藏 embedding 字段:将embedding加入hidden_field_keys可显著减小查询响应体积,向量检索本身不受影响;
  4. 大数据量写入:依赖内置的 700 文档/14MB 自动分批机制,无需手动切分;
  5. 语义检索:使用SEMANTIC_HYBRID模式前,需确保 Azure 侧已配置语义搜索(可用semantic_configuration_name指定);索引创建时默认生成的mySemanticConfig可开箱即用;
  6. 在 LlamaIndex 中的应用AzureAISearchVectorStore实现了BasePydanticVectorStore接口(stores_text=Trueflat_metadata=False),可直接传给VectorStoreIndexStorageContext,配合VectorIndexRetrieverQueryEngine构建 RAG 流水线。

更完整的 Notebook 演练可参考仓库中的 AzureAISearchIndexDemo.ipynb,测试套件位于 tests,可供深入理解各功能分支的行为。

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

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

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

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

立即咨询