更新时间:2025-08-22 GMT+08:00
分享

使用Elasticsearch AI搜索实现语义检索

CSS服务结合搜索大模型的知识搜索能力,在传统字符搜索的基础上集成语义搜索能力,通过向量化技术提升搜索结果相关性。本方案兼容开源Elasticsearch生态,业务仅需适配multi_match查询语句即可实现语义检索。

应用场景

Elasticsearch AI语义搜索适用于以下场景:
  • 知识库检索:企业知识库、FAQ系统等需要理解用户查询意图的场景。
  • 内容推荐:基于语义相似度的内容推荐系统。

方案架构

图1 语义检索架构图

数据写入:使用Elasticsearch原生Bulk接口写入数据,搜索大模型插件自动调用Embedding模型将文本转换为向量,生成的语义向量存储在CSS向量数据库中。

语义查询:使用Elasticsearch原生multi_match查询语句,搜索大模型插件自动转换查询语句为语义向量查询,执行多路召回(关键词+向量相似度),调用精排模型对结果进行二次排序,返回最终结果。

方案优势

  • 提升搜索精度:通过语义理解与精排实现多路召回与重排序,提升结果相关性。
  • 兼容开源生态:兼容开源Elasticsearch,适配multi_match语句。
  • 易用性高:通过插件方式实现,仅需配置模型服务和索引,无需改造业务代码。

约束限制

Elasticsearch AI搜索功能依赖Embedding节点,该节点的配置采用白名单机制,如需试用,请提交工单申请权限。

前提条件

  • 确认Elasticsearch集群满足以下条件。
    • 集群状态:可用
    • 集群版本:7.10.2(在基本信息页面查看“集群版本”
    • 配置要求:已配置Embedding节点(在依赖服务页面查看是否存在“可用”状态的独享版集群)
  • 获取独享版集群的访问地址。
    1. 登录云搜索服务管理控制台
    2. 在左侧导航栏,选择“集群管理 > Elasticsearch”
    3. 在集群列表,单击目标集群名称,进入集群详情页。
    4. 选择“依赖服务管理”页签,进入依赖服务列表。
    5. 在依赖服务列表,选择目标服务,单击操作列的“查看详情”跳转到独享版集群的基本信息页面。
    6. 获取“内网访问IPv4地址”即独享版集群的访问地址,后续配置模型服务需要使用。
      图2 获取集群访问地址

步骤一:登录Kibana

登录Kibana进入命令执行页面。Elasticsearch集群支持多种客户端访问,本文仅以CSS服务集成的Kibana为例介绍配置指导。

  1. 登录云搜索服务管理控制台
  2. 在左侧导航栏,选择“集群管理 > Elasticsearch”
  3. 在集群列表,选择目标集群,单击操作列的“Kibana”,登录Kibana。
  4. 在Kibana左侧导航栏选择“Dev Tools”,进入操作页面。

步骤二:启用搜索大模型插件

在Kibana中执行以下命令,启用搜索大模型插件。
PUT _cluster/settings
{
  "persistent": {
    "pg_search.inference.enable": true
  }
}

返回如下信息,表示成功启用搜索大模型插件。

{
  "acknowledged" : true,
  "persistent" : {
    "pg_search" : {
      "inference" : {
        "enable" : "true"
      }
    }
  },
  "transient" : { }
}

步骤三:配置模型服务

  1. 在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
        }
      }
    }
  2. 在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字段可减少网络传输数据量并保护内部处理细节。

相关文档