Elasticsearch:智能搜索 - AI builder,workflow 及 skills

想象一下,我们如何搜索如下的一个问题:

复制代码
Find a home within 10 miles of Miami, Florida that has 2 bedrooms, 2 bathrooms, central air, and tile floors, with a budget up to $300,000.

这类问题存在于很多的电子商务网站搜索中。它也是一种非常实用的搜索方式之一。那么要实现这样的搜索方式,我们有如下的几种方式来实现:

  1. 使用 Python 代码实现工具,并让 LLM 来进行调用。我们需要调用 LLM 来提取我们搜索的参数。为了精准搜索,我们可以使用 template 来下继续搜索。详细的情况,可以参考文章 "统一 Elastic 向量数据库与 LLM 功能,实现智能查询"
  2. 我们可以为这个搜索用 Python 创建一个定制的 MCP 服务器,然后在客户端里进行调用。我们可以参考文章 "Elasticsearch:智能搜索的 MCP"
  3. 我们使用 AI Builder 及 Workflow 来实现。在 workflow 里实现类似于在 DSL 中的模版搜索从而达到精确搜索的目的。详细的使用说明,请参考文章 "Elasticsearch:智能搜索 - AI Builder 及 Workflow"。

在如上的三种方案里,第三种方案的实现最为简捷,因为它不需要另外单独的编程。我们只需要在 Kibana 里创建 agent 及 workflow 来完成即可。维护起来也非常简单直接。那么我们有没有更为方便的方法呢?答案是肯定的。在即将推出的 Elastic Stack 9.4 中(目前在 Elastic Serverless cloud 中可用),我们可以使用 skill 来更进一步简化的目的。

步骤一:写入数据

我们需要按照文章 "Elasticsearch:智能搜索的 MCP" 写入文档到 Elasticsearch 中。

步骤二:创建 geocoding worflow 及相应的工具

在我们的实现里,我们需要根据位置信息来得到一个精确的经纬度,以便实现相应的搜索。我们可以仿照之前的文章 "Elasticsearch:创建 geocoding workflow,并在 agent 中使用它进行位置搜索"。
:上面的界面为 Elastic Serverless Cloud 界面。它和我们在本地部署的 Elastic Stack 界面有所不同。

在目前的情况下,在 agent 里,我们只能创建如下的几种 tools:

也就是说,如果我们想创建一个类似于 DSL search template 的搜索,在当前的 agent 设计中,DSL 是不被支持的。那么我们该如何实现这个呢?

答案是,我们可以为 agent 设计一个 skill。这个 skill 可以为我们的 agent 提供额外的能力。我们按照如下的步骤来创建一个这样的 elasticsearch_dsl_template skill:

它的设置如下:

  • ID:elasticsearch_dsl_template

  • Name:Elasticsearch DSL search template

  • Description:Construct Elasticsearch using DSL search template.

  • Instructions

    The details for implementing a search template can be found at https://www.elastic.co/docs/solutions/search/search-templates.

    For our search template, we need to use the following search template to do the DSL search:

    {
    "_source": false,
    "size": 5,
    "fields": ["title", "tax", "maintenance_fee", "bathrooms", "bedrooms", "square_footage", "home_price", "property_features"],
    "retriever": {
    "standard": {
    "query": {
    "semantic": {
    "field": "body_content_semantic_text",
    "query": "{{query}}"
    }
    },
    "filter": {
    "bool": {
    "must": [
    {{#distance}}{
    "geo_distance": {
    "distance": "{{distance}}",
    "location": {
    "lat": {{latitude}},
    "lon": {{longitude}}
    }
    }
    }{{/distance}}
    {{#bedrooms}}{{#distance}},{{/distance}}{
    "range": {
    "bedrooms": {
    "gte": {{bedrooms}}
    }
    }
    }{{/bedrooms}}
    {{#bathrooms}}{{#distance}}{{^bedrooms}},{{/bedrooms}}{{/distance}}{{#bedrooms}},{{/bedrooms}}{
    "range": {
    "bathrooms": {
    "gte": {{bathrooms}}
    }
    }
    }{{/bathrooms}}
    {{#tax}}{{#distance}}{{bedrooms}}{{bathrooms}},{{/bathrooms}}{{/bedrooms}}{{/distance}}{{#bedrooms}}{{^bathrooms}},{{/bathrooms}}{{/bedrooms}}{{#bathrooms}},{{/bathrooms}}{
    "range": {
    "tax": {
    "lte": {{tax}}
    }
    }
    }{{/tax}}
    {{#maintenance}}{{#distance}}{{bedrooms}}{{bathrooms}}{{tax}},{{/tax}}{{/bathrooms}}{{/bedrooms}}{{/distance}}{{#bedrooms}}{{bathrooms}}{{tax}},{{/tax}}{{/bathrooms}}{{/bedrooms}}{{#bathrooms}}{{tax}},{{/tax}}{{/bathrooms}}{{#tax}},{{/tax}}{
    "range": {
    "maintenance_fee": {
    "lte": {{maintenance}}
    }
    }
    }{{/maintenance}}
    {{#square_footage_max}}{{#distance}}{{bedrooms}}{{bathrooms}}{{tax}}{{maintenance}},{{/maintenance}}{{/tax}}{{/bathrooms}}{{/bedrooms}}{{/distance}}{{#bedrooms}}{{bathrooms}}{{tax}}{{maintenance}},{{/maintenance}}{{/tax}}{{/bathrooms}}{{/bedrooms}}{{#bathrooms}}{{tax}}{{maintenance}},{{/maintenance}}{{/tax}}{{/bathrooms}}{{#tax}}{{maintenance}},{{/maintenance}}{{/tax}}{{#maintenance}},{{/maintenance}}{
    "range": {
    "square_footage": {
    "gte": {{#square_footage_min}}{{square_footage_min}}{{/square_footage_min}}{{^square_footage_min}}0{{/square_footage_min}},
    "lte": {{square_footage_max}}
    }
    }
    }{{/square_footage_max}}
    {{#home_price_max}}{{#distance}}{{bedrooms}}{{bathrooms}}{{tax}}{{maintenance}}{{square_footage}},{{/square_footage}}{{/maintenance}}{{/tax}}{{/bathrooms}}{{/bedrooms}}{{/distance}}{{#bedrooms}}{{bathrooms}}{{tax}}{{maintenance}}{{square_footage}},{{/square_footage}}{{/maintenance}}{{/tax}}{{/bathrooms}}{{/bedrooms}}{{#bathrooms}}{{tax}}{{maintenance}}{{square_footage}},{{/square_footage}}{{/maintenance}}{{/tax}}{{/bathrooms}}{{#tax}}{{maintenance}}{{square_footage}},{{/square_footage}}{{/maintenance}}{{/tax}}{{#maintenance}}{{^square_footage}},{{/square_footage}}{{/maintenance}}{{#square_footage}},{{/square_footage}}{
    "range": {
    "home_price": {
    "gte": {{#home_price_min}}{{home_price_min}}{{/home_price_min}}{{^home_price_min}}0{{/home_price_min}},
    "lte": {{home_price_max}}
    }
    }
    }{{/home_price_max}}
    {{#feature}},{
    "bool": {
    "should": [
    {
    "match": {
    "property_features": {
    "query": "{{feature}}",
    "operator": "or"
    }
    }
    }
    ],
    "minimum_should_match": 1
    }
    }{{/feature}}
    ]
    }
    }
    }
    }
    }

    We need to use "properties" index to do the search. **please do see the range searches for bedrooms and bathrooms". We want to have bigger or equal matches. For the price, we need to have equal or smaller matches

我们保存好上面的 skill。

我们按照如下的步骤创建 Property search agent:

其中的设置:

  • Agent ID:property_search

  • Custom Instructions:

    This agent is used to search for properties:

    Step 1:

    You are an information extraction assistant.
    Extract real estate search parameters from the user query.

    复制代码
          Parameter descriptions:
          - bathrooms: Number of bathrooms
          - bedrooms: Number of bedrooms
          - tax: Real estate tax amount
          - maintenance: Maintenance fee amount
          - square_footage_min: Minimum property square footage. If only a max square footage is provided, set this to 0. Otherwise set this to the minimum square footage specified by the user.
          - square_footage_max: Maximum property square footage
          - home_price_min: Minimum home price. If only a max home price is provided, set this to 0. Otherwise set this to the minimum home price specified by the user.
          - home_price_max: Maximum home price
          - property_features: Home features such as AC, pool, updated kitchens, etc should be listed as a single string.
          - location: City, state, or full address if present.
    
          Rules:
          - Only include parameters explicitly mentioned.
          - property_features must be a single space-separated string.
          - Return ONLY a JSON object (not a string, no quotes, no extra text, no explanations).
          - Do not include explanations.
    
          Example JSON:
          {
            "query": "Find a home within 10 miles of Miami, Florida that has 2 bedrooms, 2 bathrooms, central air, and tile floors, with a budget up to $300,000."
            "bathrooms": 2,
            "bedrooms": 2,
            "home_price_min": 0,
            "home_price_max": 300000,
            "property_features": "central air tile floors",
            "location": "Miami, Florida"
          }

    Step 2:

    Based on the last extracted location, please use the get_coordinate_by_location tool to get the location, and finally get its coordinate info. The final data format is like:

    复制代码
          Example JSON:
          {
             "query": "Find a home within 10 miles of Miami, Florida that has 2 bedrooms, 2              bathrooms, central air, and tile floors, with a budget up to $300,000.",
              "bathrooms": "2",
              "bedrooms": "2",
              "home_price_max": "300000",
              "property_features": "central air, tile floors",
              "longitude": -80.1917902,
              "latitude": 25.7616798,
              "distance_meters": 16093.4
        }

    Step 3:

    Use the above constructed JSON format, and do a DSL template search. Please print out the search template used for search, and then print out the top 4 results for viewing.

  • Display name:Property search

  • Display description:Search for property

为 agent 添加所需要的 geocoding 工具:

为 agent 添加 skill

这样我们的 agent 就设计好了。

测试

我们使用如下的搜索例子来做测试:

复制代码
Find a home within 10 miles of Miami, Florida that has 2 bedrooms, 2 bathrooms, central air, and tile floors, with a budget up to $300,000.

上面显示了我们所需要的结果。和我们之前的搜索结果是一样的。我们可以查看一下它的思索过程:

很显然,它使用我们提供的 skill 来完成这个搜索。我们可以看到 Calling tool filestore.read。它使用了我们的 skill。更加有意思的是,它理解我们的意图,并使用 ES|QL 生成相应的 ES|QL 查询:

复制代码
FROM properties
| WHERE ST_DISTANCE(location, TO_GEOPOINT("POINT(-80.1917902 25.7616798)")) <= 16093.44
  AND bedrooms >= 2
  AND bathrooms >= 2
  AND home_price >= 0
  AND home_price <= 300000
  AND MATCH(property_features, "central air tile floors")
| KEEP title, tax, maintenance_fee, bathrooms, bedrooms, square_footage, home_price, property_features
| LIMIT 4

很显然,这个就是我们所需要的类似于 DSL template 的查询。根据含有的字段来做相应的搜索,虽然它使用的不是 DSL template 查询。

我们使用另外一个例子来展示:

复制代码
Find a home within 10 miles of DeBary, Florida with 5 bedrooms, at least 2 bathrooms, central air, and a garage, with a budget up to $600,000.

结论

Skill 是在即将发布的 Elastic Stack 9.4 里一个非常重要的功能。它极大地方便了我们对 agent 的设计。在很多的设计中,我们甚至不需要使用任何的代码实现就可以在 Kibana 中完成我们所需要的功能。

祝大家学习愉快!

相关推荐
这个DBA有点耶7 分钟前
数据库集群与分布式架构:三条技术路线对比、金仓KES RAC实测数据与决策框架
数据库·程序员·架构
guoran_shini11 分钟前
SVD矩阵分解
人工智能
MayBaymax19 分钟前
MongoDB 索引与事务
java·数据库·mongodb
SelectDB22 分钟前
Doris vs ClickHouse:企业 OLAP 走向下一阶段,两种技术路线如何选择
大数据·数据库·数据分析
烟锁池塘柳023 分钟前
【Agent】如何从大模型构建真正的 Agent?以 Claude Code 为例,理解能构建智能体的真正的 Harness 工程
人工智能·agent
vx-程序开发26 分钟前
【计算机毕设】django校园跑腿服务系统83141
java·数据库·vue.js·spring boot·spring·elasticsearch·django
qq_1998868727 分钟前
第6板块 第2节 CUDA运行时API与驱动API 核心笔记
c++·人工智能·gpu算力
m0_7345717628 分钟前
深入理解人工智能 最核心的算法模块
人工智能
当下新鲜事44 分钟前
脱硫脱硝塔动力系统科普:四方DL500变频器工作原理解析
大数据·运维·物联网·业界资讯
烈风逍遥1 小时前
第六篇:RAG 知识库构建与检索全链路
前端·人工智能·后端