news 2026/4/27 13:05:45

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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 界面有所不同。

步骤三:创建 DSL search template

在目前的情况下,在 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

我们按照如下的步骤创建 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 中完成我们所需要的功能。

祝大家学习愉快!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/27 13:04:44

机器学习必备:线性代数核心概念与实践指南

1. 线性代数与机器学习的关系线性代数是机器学习领域最基础的数学工具之一。从最简单的线性回归到复杂的深度学习模型&#xff0c;矩阵运算、特征值分解等线性代数概念无处不在。我见过太多初学者直接跳进神经网络的学习&#xff0c;结果在反向传播和权重更新阶段被矩阵求导卡住…

作者头像 李华
网站建设 2026/4/27 13:03:05

【Qt】常用控件(十七)QGroupBox,QTabWidget的属性和使用

小编个人主页详情<—请点击 小编个人gitee代码仓库<—请点击 Qt系列专栏<—请点击 倘若命中无此运&#xff0c;孤身亦可登昆仑&#xff0c;送给屏幕面前的读者朋友们和小编自己! 目录前言一、QGroupBoxQGroupBox的属性QGroupBox的使用&#xff0c;基于QGroupBox模拟华…

作者头像 李华
网站建设 2026/4/27 12:58:34

RAG技术实战:从核心原理到高级应用与评估调优

1. 从零到一&#xff1a;理解RAG的核心价值与演进脉络如果你最近在AI圈子里待过&#xff0c;肯定对RAG这个词不陌生。Retrieval-Augmented Generation&#xff0c;检索增强生成&#xff0c;听起来挺学术&#xff0c;但说白了&#xff0c;它解决的是大语言模型&#xff08;LLM&a…

作者头像 李华
网站建设 2026/4/27 12:51:21

深度探索:3大核心技术解密暗黑2存档编辑器的无限潜力

深度探索&#xff1a;3大核心技术解密暗黑2存档编辑器的无限潜力 【免费下载链接】d2s-editor 项目地址: https://gitcode.com/gh_mirrors/d2/d2s-editor 你是否曾因暗黑破坏神2的装备掉落机制而陷入无尽的刷怪循环&#xff1f;是否渴望测试一个技能build却不愿投入数百…

作者头像 李华