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 中完成我们所需要的功能。

祝大家学习愉快!

相关推荐
梦想的旅途211 小时前
企业微信API二次开发:接入 AI 大模型实现外部群智能问答
人工智能·自动化·二次开发·企业微信
碧口科技11 小时前
湿地鸟类监测设备选型指南:复杂环境下的智能识别系统怎么选?
人工智能
2601_9494999411 小时前
硬件工程师实操:芯瑞科技两款 400G 高速互联方案参数、场景、选型全解析
大数据·运维·人工智能·科技·光模块
极昆仑智慧11 小时前
智能问数五级成熟度模型:从“能问“到“能协作“的演进路径
人工智能·语言模型·数据分析
火云牌神11 小时前
如何用项目规则给 AI 划定编码边界
人工智能·系统架构·ai编程·vibecoding
优氙费控11 小时前
报销审核效率低?AI费用审核正在改变财务工作方式
大数据·人工智能
神奇霸王龙11 小时前
MCP 微软教材背书:5 国产基座 Agent 承接力实测
microsoft·ai·ai作画·agent·ai编程·ai写作·mcp
云边云科技_云网融合11 小时前
金融医疗混合云组网如何满足数据安全与合规要求?
大数据·人工智能·物联网
开开心心就好11 小时前
视频播放器完美解码集成三款播放器切换使用
前端·人工智能·智能手机·电脑·音视频·virtualenv·pygame
MC皮蛋侠客11 小时前
Redis 系列(六):过期、内存淘汰与内存优化——让 Redis 活得更久
数据库·redis·bootstrap