统一 Elastic 向量数据库与 LLM 功能,实现智能查询

news2025/3/14 13:12:08

作者:来自 Elastic Sunile Manjee

利用 LLM 功能进行查询解析,并使用 Elasticsearch 搜索模板,将复杂的用户请求转换为结构化的、基于模式的搜索,从而实现高精度查询结果。

想象一下,你在搜索“距离 Belongil Beach 250 米内、最近翻新、至少 4 星级、配有游泳池和健身房的住宿”,而搜索引擎精准地返回了符合你需求的结果。智能搜索能够理解查询意图并进行推理,仅靠启发式方法难以实现这种能力。这正是大型语言模型(LLM)功能与 Elasticsearch 搜索模板结合,打造真正智能搜索体验的关键所在。

亲自体验

如果你对此存疑,不必担心。完整的端到端示例已在 Python notebook 中提供,包含数据、索引映射、推理端点、搜索模板和 LLM 功能。你需要一个 Elastic Cloud 实例、Azure OpenAI 实例和 Google Maps API 密钥。

问题:处理复杂约束

传统的搜索方法,如基于关键词或向量的检索,在面对包含多重细节的复杂查询时往往难以提供理想结果。例如,在酒店搜索场景中,用户可能希望:

  • 位置:距离 Belongil Beach 250 米以内
  • 评分:至少 4 星级
  • 设施:包括游泳池和健身房
  • 状态:最近翻新

使用简单的关键词匹配或相似度评分可能会导致搜索结果不完整或不相关,影响用户体验和信任度。

LLMs + Elasticsearch:基于模式的搜索

Elasticsearch 采用索引模式架构,在索引数据时定义了诸如 “rating - 评分”“ geopoint - 地理位置 ” “amenities - 设施” 等字段,使得搜索结果的筛选和排名更加精准。然而,这也要求查询语句具备相应的结构化格式。

这正是 LLM(如 GPT 系列或生成式模型)发挥作用的关键。LLM 可以解析用户的自然语言查询,提取关键信息(例如 “distance = 250m” “rating >= 4” “amenities = pool, gym”, “靠近 Belongil Beach” 等),并在检测到地理信息时调用地理编码服务。然后,LLM 生成一个 JSON 负载,将其插入 Elasticsearch 搜索模板 —— 这是一个参数化查询,将查询逻辑与动态值分离。

这种方法结合了 LLMs 的语义理解能力和 Elasticsearch 的基于模式的筛选与分面搜索能力,实现真正智能的搜索体验。

示例实际应用

假设用户的查询是:

“recently renovated accommodations 250m from Belongil Beach with at least 4 stars and with a pool and gym.”

  1. LLM 处理: LLM 分析文本,识别出需要一个基于距离的筛选(250 米)、最低评分(rating - 4 星)、相关设施(ameniteis - 游泳池、健身房),以及 “recently renovated - 最近翻新” 的上下文提示。它还调用地理编码服务获取 “Belongil Beach” 的精确纬度和经度坐标。
  2. 搜索模板: 你可以创建一个 Elasticsearch 搜索模板,该模板接受 rating、distance、latitude、longitude 以及可能的自由文本查询作为参数。一旦 LLM 提供这些参数,你的应用程序就可以填充占位符并调用 Elasticsearch。在这里,不仅可以利用过滤,还可以结合向量搜索、ELSER 和词法搜索进行混合查询。
  3. 搜索结果: 返回的响应精确匹配了符合以下条件的住宿:距离 Belongil Beach 250 米内、至少 4 星级、标记为最近翻新,并且配有游泳池和健身房。例如:
    • Hotel name: Belongil Beach Apartment
    • Rating: 4 星
    • City: Byron Bay,新南威尔士州
    • Country: 澳大利亚

相比单纯依赖向量空间或混合搜索,你可以输入精确的过滤条件,从而提高召回的全面性和精确度。

为什么这种方法有效

  • 精准度和召回率: 通过按照索引模式结构化查询,可以消除歧义,确保不会错过有效结果(高召回率),同时排除无关结果(高精准度)。相比之下,仅依赖向量空间可能缺乏自然的筛选功能。

  • 可扩展性: Elasticsearch 设计用于处理海量数据。一旦提取出查询参数,即使在超大索引上,查询依然保持极高的执行速度。

  • 灵活性: 如果出现新的属性(例如 “EV charging station”),LLM 仍能识别该属性作为酒店设施,并将其注入 Elasticsearch 搜索模板。

  • 复杂查询的适应性: 无论用户查询多么复杂,LLM 的语义解析都能确保捕捉所有相关细节,包括距离限制、星级评分、基于位置的条件等。

为什么使用搜索模板

Elasticsearch 搜索模板支持创建参数化查询,将查询逻辑与动态值分离。这在根据用户输入或其他可变数据构建动态查询时尤为重要。

例如,假设酒店索引包含以下字段:

  • Description
  • Attractions
  • Rating
  • Facilities
  • Location
    • Latitude
    • Longitude

用户可能在搜索查询中包含这些属性的任意组合。随着字段数量的增加,手动为每种可能的输入组合构建查询变得不可行。搜索模板通过根据用户输入动态生成适当的查询,解决了这一问题。例如:

  • 如果用户指定了 rating 和 attractions,则会生成相应的查询。
  • 如果用户提供了 location 和 rating,则搜索模板会生成匹配这些输入的查询。

搜索模板采用 JSON 格式定义,并包含用于动态值的占位符。在执行搜索模板时,Elasticsearch 会用实际值替换占位符并执行查询。

搜索模板可用于执行多种任务,例如:

  • 根据用户输入筛选结果
  • 提升特定结果的相关性
  • 添加自定义评分函数
  • 进行结果聚合

下面是一个示例搜索模板,它会根据输入参数动态创建查询。

{
    "script": {
        "lang": "mustache",
        "source": """{
            "_source": false,
            "fields": [
                "HotelName",
                "HotelRating",
                "countryName",
                "cityName",
                "countryCode",
                "Attractions"
            ],
            "retriever": {
                "standard": {
                    "query": {
                        "semantic": {
                            "field": "semantic_description_elser",
                            "query": "{{query}}"
                        }
                    },
                    "filter": {
                        "bool": {
                            "must": [
                                {{#distance}}
                                {
                                    "geo_distance": {
                                        "distance": "{{distance}}",
                                        "location": {
                                            "lat": {{latitude}},
                                            "lon": {{longitude}}
                                        }
                                    }
                                }
                                {{/distance}}

                                {{#rating}}{{#distance}},{{/distance}}
                                {
                                    "range": {
                                        "HotelRating": {
                                            "gte": {{rating}}
                                        }
                                    }
                                }
                                {{/rating}}

                                {{#countryName}}{{#distance}}{{^rating}},{{/rating}}{{/distance}}{{#rating}},{{/rating}}
                                {
                                    "term": {
                                        "countryName": "{{countryName}}"
                                    }
                                }
                                {{/countryName}}

                                {{#city}}{{#distance}}{{^rating}},{{/rating}}{{/distance}}{{#rating}},{{/rating}}
                                {
                                    "match": {
                                        "cityName": "{{city}}"
                                    }
                                }
                                {{/city}}

                                {{#countryCode}}{{#distance}}{{^rating}},{{/rating}}{{/distance}}{{#rating}},{{/rating}}
                                {
                                    "term": {
                                        "countryCode": "{{countryCode}}"
                                    }
                                }
                                {{/countryCode}}

                                {{#distance}}{{^rating}}{{/rating}}{{/distance}}{{#rating}}{{/rating}}
                            ],
                            "should": [
                                {{#attraction}}
                                {
                                    "wildcard": {
                                        "Attractions": {
                                            "value": "*{{attraction}}*",
                                            "case_insensitive": true
                                        }
                                    }
                                }
                                {{/attraction}}
                            ]
                        }
                    }
                }
            }
        }"""
    }
}

如果你想对 search template 有更深入的了解,请参考文章 “Elasticsearch:search template”。

LLM 功能

大型语言模型(LLM)具备强大的推理能力,可用于解析数据、调用 API 或请求额外信息,以确定最佳的下一步操作。当 LLM 与搜索模板结合时,它能够判断用户查询是否包含搜索模板支持的属性。如果识别出受支持的属性,LLM 将执行相应的用户定义方法调用。

在 Notebook 中,包含了一些 LLM 功能。每个功能都在工具列表(tools list)中进行了定义。

  tools = [
        {
            "type": "function",
            "function": { ...

让我们简要回顾每个功能。extract_hotel_search_parameters LLM 函数的作用是从用户查询中提取搜索模板支持的参数。

"type": "function",
            "function": {
                "name": "extract_hotel_search_parameters",
                "description": "Extract search parameters for finding hotels (excluding the query itself).  the parameters are extracted from the input query",

geocode_location LLM 函数将在识别出位置属性(例如 “500 meters from Belongil Beach”)时被调用。

{
    "type": "function",
    "function": {
        "name": "geocode_location",
        "description": "Resolve a location to its latitude and longitude.",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "The name of the location, e.g., Belongil Beach."
                }
            },
            "required": ["location"]
        }
    }
}

LLM 函数 query_elasticsearch 将使用 geocode_location(如果在用户查询中找到)和 extract_hotel_search_parameters 提取的参数进行调用。

"type": "function",
            "function": {
                "name": "extract_hotel_search_parameters",
                "description": "Extract search parameters for finding hotels (excluding the query itself).  the parameters are extracted from the input query",

Completions API 将每个 LLM 函数注册为一个工具。本文前面已详细介绍了这些工具列表。

   while True:
        # Call the LLM with tools
        response = client.chat.completions.create(
            model=deployment_name,
            messages=messages,
            tools=tools,
            tool_choice="auto",
        )

Azure OpenAI

该 Notebook 使用 Azure OpenAI completions 模型运行。要运行它,你需要 Azure OpenAI 密钥(Key 1 或 Key 2)、端点(Endpoint)、部署名称(Deployment Name)和版本号(Version number)。所有这些信息都可以在 Azure OpenAI → Keys and Endpoint 下找到。

部署一个 completions 模型,该部署名称将在 Notebook 中使用。

在 Chat Playground 中,点击 View code 以查找 API 版本。

Google Maps API

该 Notebook 使用 Google Maps API 对用户查询中识别的位置进行地理编码。此功能需要一个 Google 账户和 API 密钥,可在此处生成。

将 LLM 功能与搜索模板付诸实践

LLM 通过推理确定所需的功能及其执行顺序,基于给定查询进行处理。例如,当执行查询 recently renovated accommodations 250m from Belongil Beach with at least 4 stars and with a pool and gym 时,LLM 的推理层被激活:

提取参数

初始 LLM 函数调用旨在从查询中提取参数。

Role: assistant
Tool Calls:
  Tool Call ID: call_VHhjy0TMxPnefibSssrTa5r0
  Function Name: extract_hotel_search_parameters
  Arguments: {"query":"recently renovated accommodations 250m from Belongil Beach with at least 4 stars and with a pool and gym","distance":"250m","rating":4,"location":"Belongil Beach","attraction":"recently renovated, pool, gym"}

地理编码

LLM 随后判断查询包含 “from” 位置,并确定应调用地理编码函数。

--------------------------------------------------
Updated parameters after geocode_location:
{'query': 'recently renovated accommodations 250m from Belongil Beach with at least 4 stars and with a pool and gym', 'distance': '250m', 'rating': 4, 'location': 'Belongil Beach', 'attraction': 'recently renovated, pool, gym', 'latitude': -28.6337328, 'longitude': 153.6003455}

Formatted Messages:
Message 1:
Role: assistant
Tool Calls:
  Tool Call ID: call_jr4jJ04lW0y0E2AKnVmNumyh
  Function Name: query_elasticsearch
  Arguments: {"query":"recently renovated accommodations 250m from Belongil Beach with at least 4 stars and with a pool and gym","latitude":-28.6337328,"longitude":153.6003455,"distance":"250m","rating":4,"attraction":"recently renovated, pool, gym"}

--------------------------------------------------

智能查询

LLM 的推理层利用先前函数调用提取的参数,结合搜索模板执行 Elasticsearch 查询。

--------------------------------------------------
Function Arguments for query_elasticsearch:
{'query': 'recently renovated accommodations 250m from Belongil Beach with at least 4 stars and with a pool and gym', 'latitude': -28.6337328, 'longitude': 153.6003455, 'distance': '250m', 'rating': 4, 'attraction': 'recently renovated, pool, gym'}
Parameters for Elasticsearch:
{'query': 'recently renovated accommodations 250m from Belongil Beach with at least 4 stars and with a pool and gym', 'latitude': -28.6337328, 'longitude': 153.6003455, 'distance': '250m', 'rating': 4, 'attraction': 'recently renovated, pool, gym'}
Elasticsearch Query:
{
  "id": "hotel_search_template",
  "params": {
    "query": "recently renovated accommodations 250m from Belongil Beach with at least 4 stars and with a pool and gym",
    "latitude": -28.6337328,
    "longitude": 153.6003455,
    "distance": "250m",
    "rating": 4,
    "attraction": "recently renovated, pool, gym"
  }
}
Elasticsearch query successful.

精准结果

通过 LLM 功能与搜索模板执行智能查询,成功找到完美匹配的结果。

Number of results found: 1

Formatted Messages:
Message 1:
Role: assistant
Content: I found one recently renovated accommodation within 250 meters of Belongil Beach that has at least 4 stars and offers both a pool and gym:

- **Hotel Name:** Belongil Beach Apartment
- **Rating:** 4 stars
- **Location:** Byron Bay, New South Wales, Australia

If you need more information or assistance with booking, please let me know!

结论

将大型语言模型(LLM)功能与 Elasticsearch 搜索模板相结合,实现了对查询意图的理解和推理能力。与其将查询视为一段无结构的文本,我们通过系统性拆解,将其匹配到已知的模式,并让 Elasticsearch 负责搜索、筛选和评分的核心工作。最终,用户获得了一种高度精准且友好的搜索体验 —— 他们只需输入需求,系统便能准确理解其意图。

立即体验向量搜索!你可以通过 Search AI 的自学实践课程进行操作,也可以选择启动免费的云试用,或在本地机器上尝试 Elastic。

原文:Unifying Elastic vector database and LLM functions for intelligent query - Elasticsearch Labs

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2314888.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[操作系统] 学校课程关于“静态优先级抢占式调度“作业

今天我们来分享两道题目哈, 学校弄得题目. T1: 静态优先级, 抢占式(1为高优先级) 图解: 以下是静态优先级抢占式调度的解题过程和结果: 解题思路: 优先级规则: 数值越小优先级越高。新进程到达时,若其优先级高于当前运行进程&…

【SpringBoot】MD5加盐算法的详解

目录 一、什么是加盐算法 二、如何实现加盐算法 2.1 加盐算法代码实现 2.2 注册页面中进行密码加盐 2.3 登录页面进行加盐的解密 2.4 注册和登录 一、什么是加盐算法 加盐算法是一种用于增强密码安全性的技术。这种技术通过在密码存储过程中添加一个随机生成的盐值&…

累计完工数量达到了xxxx超过了最大可完工数量xxxx

之前解决过一次,没有记录下来,不记得发生什么事情。又浪费几个小时去分析问题。这次的经历有点痛苦,碰上多表关连数据的勾稽。分析是河南用户的非法操作造成的。没有领料记录入不了库,跨月了。财务要求删单处理。删单之后&#xf…

飞鸟与鱼不同路

看,好美的太阳。 正是因为有人看才会觉得美,若无人问津,美又从何而来。 嘿嘿,今天提出辞去综合教研室主任一职,不想在这个管理上废时间啦~ 把时间用来考试.........用来做自己的事情,花在自己的身上&…

若依RuoYi-Cloud-Plus微服务版(完整版)前后端部署

一.目标 在浏览器上成功登录进入 二.源码下载 后端源码:前往Gitee下载页面(https://gitee.com/dromara/RuoYi-Cloud-Plus)下载解压到工作目录。 前端源码: 前往Gitee下载页面(https://gitee.com/JavaLionLi/plus-ui)下载解压到工作目录。 文档地址&a…

【redis】list类型:基本命令(下)

文章目录 LLENLREMLTRIMLSET阻塞版本命令BLPOP 和 BRPOP区别使用方式 命令小结内部编码 LLEN 获取 list 的长度 语法: LLEN key时间复杂度: O ( 1 ) O(1) O(1)返回值: list 长度 LREM 删除 count 个 key 中的元素 语法: LREM…

【数据挖掘】知识蒸馏(Knowledge Distillation, KD)

1. 概念 知识蒸馏(Knowledge Distillation, KD)是一种模型压缩和知识迁移技术,旨在将大型复杂模型(称为教师模型)中的知识传递给一个较小的模型(称为学生模型),以减少计算成本&…

VSCode 搭建C++编程环境 2025新版图文安装教程(100%搭建成功,VSCode安装+C++环境搭建+运行测试+背景图设置)

名人说:博观而约取,厚积而薄发。——苏轼《稼说送张琥》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、VScode下载及安装二、安装 MinGW-w64 工具链三、Windows环境变量配置四、检查 M…

Ubuntu24.04 LTS 版本 Linux 系统在线和离线安装 Docker 和 Docker compose

一、更换软件源并更新系统 在 Ubuntu 24.04 LTS 中,系统引入了全新的软件源配置格式。现在的源配置文件内容更加结构化且清晰,主要包含了软件类型 (Types)、源地址 (URIs)、版本代号 (Suites) 以及组件 (Components) 等信息。 # cat /etc/apt/sources.li…

MTK Android12 最近历史任务 最左侧的清除历史任务改到页面底部

Android最近历史任务页面 -清除所有- 功能按钮放到底部 文章目录 需求需求原因 修改的核心文件实现方案最近历史任务基本UI结构了解代码实现思路实现方案RecentsViewTaskOverlayFactory在overview_actions_containerOverviewActionsView 实际效果 总结 需求 最近历史任务重&am…

TCP协议支持全双工原因TCP发送接收数据是生产者消费者模型

一、TCP支持全双工的原因 TCP协议支持全双工,即使用TCP协议进行通信时,服务端和客户端可以同时进行数据的发送和接收,互不干扰,实现同时双向传输数据。 这是因为使用TCP协议通信时,读写套接字的文件描述符既用来发送…

文件操作2

7. ⽂件读取结束的判定 7.1 被错误使用的 feof 牢记:在文件读取过程中,不能用 feof 函数的返回值直接来判断文件的是否结束。 feof 的作用是:当文件读取结束的时候,判断读取结束的原因是否是:遇到文件尾结束。 1. …

《又是二叉树?递归与回溯的经典应用》

“ 我喜欢晴天,你恰好是最好的太阳” 226.翻转二叉树 力扣题目链接(opens new window) 翻转一棵二叉树。 这道题我们可以通过递归法解决,我们只要递归的把每一个节点的左右孩子反转一下就能解决了。 代码如下: var invertTree function(ro…

Qt/C++音视频开发82-系统音量值获取和设置/音量大小/静音

一、前言 在音视频开发中,音量的控制分两块,一个是控制播放器本身的音量,绝大部分场景都是需要控制这个,这个不会影响系统音量的设置。还有一种场景是需要控制系统的音量,因为播放器本身的音量是在系统音量的基础上控…

从零到精通文本指令:打造个人AI助理的完整指令库(Prompt 指令实操)

文章目录 从零到精通文本指令:打造个人AI助理的完整指令库(Prompt 指令实操)创作指令创作指令**润色指令****扩写指令** 问答指令直接问答材料问答时间逻辑问答 总结、摘要、翻译指令总结信息抽取翻译 从零到精通文本指令:打造个人AI助理的完整指令库(Pr…

C# NX二次开发:获取模型中所有的草图并获取草图中的对象

大家好&#xff0c;今天接着讲NX二次开发获取草图相关。 获取草图的方法是从workPart中获取&#xff0c;如下面的例子所示&#xff1a; List<Tag> tags new List<Tag>(); SketchCollection sketchCollection workPart.Sketches; …

基于SpringBoot和MybatisPlus实现通用Controller

基于SpringBoot和MybatisPlus实现通用Controller&#xff0c;只需要创建实体类和mapper接口&#xff0c;单表增删改查接口就已经实现&#xff0c;提升开发效率 1.定义通用controller package com.xian.controller;import cn.hutool.core.map.MapUtil; import com.baomidou.my…

锤头线和倒锤头线

1、锤头线 是指一根没有上影线或上影线很短,而下影线很长,实体却很小的K线。其K线实体可以是阴线或是阳线,类似于T字。 锤头线的特征有以下三点: 实体很小,下影线长度大于或等于实体的两倍。下影线越长时,如股价处于低位,则上涨的可能性越大。 如股价处于高位,则下跌…

蓝桥杯嵌入式组第十二届省赛题目解析+STM32G431RBT6实现源码

文章目录 1.题目解析1.1 分而治之&#xff0c;藕断丝连1.2 模块化思维导图1.3 模块解析1.3.1 KEY模块1.3.2 LED模块1.3.3 LCD模块1.3.4 TIM模块1.3.5 UART模块1.3.5.1 uart数据解析 2.源码3.第十二届题目 前言&#xff1a;STM32G431RBT6实现嵌入式组第十二届题目解析源码&#…

STM32上实现简化版的AUTOSAR DEM模块

文章目录 摘要摘要 在一些可以不使用AUTOSAR的项目中,往往也有故障检测和DTC存储的需求,开发一套类似于AUTOSAR DEM模块的软件代码,能够满足DTC的检出和存储,使用FalshDB代替Nvm模块,轻松构建持久化存储,如果你也有这样的需求,请阅读本篇,希望能够帮到你。 /*********…