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

祝大家学习愉快!

相关推荐
日取其半万世不竭几秒前
Ollama + Open WebUI 部署教程:本地运行大语言模型,自建私有 AI 助手
人工智能·语言模型·自然语言处理
weixin_446260854 分钟前
本地部署与实践指南:构建免费的AI开发助手系统(Claude Code + Ollama)
人工智能
南宫萧幕10 分钟前
Simulink 从零搭建 HEV ECMS 环境:模块解析、排坑指南与智能算法接口预留
人工智能·算法·matlab·汽车·控制
YuanDaima204813 分钟前
Docker 工程化安装与核心命令实战
运维·人工智能·docker·微服务·容器·bash
杰之行14 分钟前
Fast-DDS 接收数据完整时序分析
c++·人工智能
闲人编程14 分钟前
Agent的评估体系(AgentEval):如何判断一个Agent好坏?
大数据·人工智能·python·算法·agent·智能体·swe
hnult15 分钟前
知识竞赛考试平台怎么选?2026 考试云全功能选型与实践指南
大数据·人工智能
tzc_fly15 分钟前
Latent-Y:经实验室验证的从头药物设计自主智能体
人工智能
weixin_4462608517 分钟前
hermes agent的版本更新与web控制台
人工智能
瑞华丽PLM19 分钟前
瑞华丽 AI 智能体研发数字化实战指南
人工智能·cae·工业软件·仿真软件·国产软件·瑞华丽plm·瑞华丽