使用Elasticsearch AI搜索实现语义检索
CSS服务结合搜索大模型的知识搜索能力,在传统字符搜索的基础上集成语义搜索能力,通过向量化技术提升搜索结果相关性。本方案兼容开源Elasticsearch生态,业务仅需适配multi_match查询语句即可实现语义检索。
应用场景
- 知识库检索:企业知识库、FAQ系统等需要理解用户查询意图的场景。
- 内容推荐:基于语义相似度的内容推荐系统。
方案架构

数据写入:使用Elasticsearch原生Bulk接口写入数据,搜索大模型插件自动调用Embedding模型将文本转换为向量,生成的语义向量存储在CSS向量数据库中。
语义查询:使用Elasticsearch原生multi_match查询语句,搜索大模型插件自动转换查询语句为语义向量查询,执行多路召回(关键词+向量相似度),调用精排模型对结果进行二次排序,返回最终结果。
方案优势
- 提升搜索精度:通过语义理解与精排实现多路召回与重排序,提升结果相关性。
- 兼容开源生态:兼容开源Elasticsearch,适配multi_match语句。
- 易用性高:通过插件方式实现,仅需配置模型服务和索引,无需改造业务代码。
约束限制
Elasticsearch AI搜索功能依赖Embedding节点,该节点的配置采用白名单机制,如需试用,请提交工单申请权限。
前提条件
- 确认Elasticsearch集群满足以下条件。
- 集群状态:可用
- 集群版本:7.10.2(在基本信息页面查看“集群版本”)
- 配置要求:已配置Embedding节点(在依赖服务页面查看是否存在“可用”状态的独享版集群)
- 获取独享版集群的访问地址。
- 登录云搜索服务管理控制台。
- 在左侧导航栏,选择“集群管理 > Elasticsearch”。
- 在集群列表,单击目标集群名称,进入集群详情页。
- 选择“依赖服务管理”页签,进入依赖服务列表。
- 在依赖服务列表,选择目标服务,单击操作列的“查看详情”跳转到独享版集群的基本信息页面。
- 获取“内网访问IPv4地址”即独享版集群的访问地址,后续配置模型服务需要使用。
图2 获取集群访问地址
步骤一:登录Kibana
登录Kibana进入命令执行页面。Elasticsearch集群支持多种客户端访问,本文仅以CSS服务集成的Kibana为例介绍配置指导。
- 登录云搜索服务管理控制台。
- 在左侧导航栏,选择“集群管理 > Elasticsearch”。
- 在集群列表,选择目标集群,单击操作列的“Kibana”,登录Kibana。
- 在Kibana左侧导航栏选择“Dev Tools”,进入操作页面。
步骤二:启用搜索大模型插件
PUT _cluster/settings { "persistent": { "pg_search.inference.enable": true } }
返回如下信息,表示成功启用搜索大模型插件。
{ "acknowledged" : true, "persistent" : { "pg_search" : { "inference" : { "enable" : "true" } } }, "transient" : { } }
步骤三:配置模型服务
- 在Kibana中执行以下命令,配置Embedding模型服务。
PUT _inference/model_service/pangu_vector // pangu_vector为模型服务名称,支持自定义 { "description": "搜索大模型-语义向量化模型", // 服务描述信息 "service_config": { "semantic_vector": { // 模型类型 "service_urls": [ // Embedding模型服务的访问地址列表(数组格式) "http://{endpoint}/app/search/v1/vector" // 替换{endpoint}为独享版集群的访问地址,例如访问地址为10.20.30.40:18088,则此处应填写"http://10.20.30.40:18088/app/search/v1/vector" ], "algorithm": "GRAPH", // 使用图算法进行近似最近邻搜索 "metric": "inner_product", // 相似度度量方式:内积 "dimension": "768" // 向量维度768 } } }
- 在Kibana中执行以下命令,配置Rerank模型服务。
PUT _inference/model_service/pangu_ranking // pangu_ranking为模型服务名称,支持自定义 { "description": "搜索大模型-精排模型", // 服务描述信息 "service_config": { "reorder": { // 模型类型 "service_urls": [ // Rerank模型服务的访问地址列表(数组格式) "http://{endpoint}/app/search/v1/rerank" // 替换{endpoint}为独享版集群的访问地址,例如访问地址为10.20.30.40:18088,则此处应填写"http://10.20.30.40:18088/app/search/v1/rerank" ] } } }
更多配置参数及说明请参见配置模型服务。
步骤四:创建向量索引
在Kibana中执行以下命令,创建向量索引,如pangu_index,并将上一步配置的Embedding和Rerank模型服务关联到索引中。
PUT pangu_index { "aliases": { // 定义索引别名 "pangu_wiki": {} // 通过pangu_wiki别名访问索引 }, "mappings": { // 字段映射定义 "properties": { "title": { // 文档标题字段 "type": "text" // 全文检索类型 }, "desc": { // 描述字段 "type": "text" // 全文检索类型 }, "content": { // 正文内容字段 "type": "text" // 全文检索类型 }, "author": { // 作者字段 "type": "keyword" // 精确值类型,适合过滤和聚合 } } }, "settings": { // 索引设置 "index.vector": true, // 启用向量索引功能 "index.inference.semantic_search_enabled": true, // 启用语义搜索 "index.inference.field": [ // 参与向量化的字段及权重 "title:100", // 标题字段,权重100 "desc:80", // 描述字段,权重80 "content:30" // 内容字段,权重30 ], "index.inference.embedding_model": "pangu_vector", // Embedding模型服务的名称 "index.inference.reorder_enabled": true, // 启用结果重排序 "index.inference.reorder_model": "pangu_ranking", // 重排序模型服务的名称 "index.inference.semantic_search_type": "vector", // 语义搜索类型为向量搜索 "number_of_shards": 3 // 索引分片数为3(根据数据量调整) } }
步骤五:导入数据
在Kibana中,使用Bulk API批量导入数据到上一步创建的索引pangu_index。
// 操作类型为index(创建/更新文档),并指定文档ID为1 // title字段值(文本类型,将被向量化),desc字段值(文本类型,将被向量化),content字段值(文本类型,将被向量化),author字段值(关键字类型,用于精确匹配) PUT pangu_index/_bulk {"index":{"_id":"1"}} {"title":"热带雨林","desc":"丰富的热带植物世界","content":"生态系统","author":"李雷"}
批量导入说明:
- 向量生成过程:系统会自动将title(权重100)、desc(权重80)、content(权重30)拼接,调用pangu_vector模型生成768维的语义向量,向量数据存储在_inference.semantic_vector字段。
- 如果某条文档失败,不会影响其他文档的导入,Bulk API的详细使用说明请参见Bulk API。
- 性能建议:大批量导入时建议每批次500~1000个文档。
- 数据格式建议:
- 文本字段建议做基础清洗,去除特殊字符等。
- 关键业务字段建议设置非空校验。
- 中文文本不需要预先分词,大模型会自动处理。
步骤六:语义检索
在Kibana中执行以下命令,使用multi_match语句在pangu_index索引中执行语义检索。
GET pangu_index/_search { // 控制返回结果的字段内容 "_source": { "excludes": [ "_inference" // 排除返回结果中可能包含敏感或冗余信息的字段 ] }, // 查询主体部分 "query": { // 布尔查询 "bool": { // 必须满足的条件列表(逻辑AND) "must": [ { // 多字段匹配查询,目标字段匹配时会自动转换为语义向量搜索 "multi_match": { "query": "橡胶树在哪里", // 用户输入的搜索关键词/句 "fields": ["title","content","desc"] // 搜索的目标字段列表,必须和索引配置的index.inference.field字段对应 } } ] // 可选添加其他逻辑条件: // "filter": [...] // 不影响评分的过滤条件 // "should": [...] // 逻辑OR条件 // "must_not": [...] // 排除条件 } } // 可选添加搜索优化参数: // "size": 20, // 返回结果数量 // "explain": true, // 显示相关性评分计算细节 // "highlight": { ... } // 关键词高亮配置 }
- 该查询同时搜索title、content、desc三个字段,寻找与“橡胶树在哪里”相关的内容。
- 通过bool查询结构确保结果必须满足multi_match条件。
- 排除_inference字段可减少网络传输数据量并保护内部处理细节。