将 CrewAI 与 Elasticsearch 结合使用
作者:来自 Elastic Jeffrey Rengifo

学习如何使用 CrewAI 为你的代理团队创建一个 Elasticsearch 代理,并执行市场调研任务。
CrewAI 是一个用于编排代理的框架,它通过角色扮演的方式让多个代理协同完成复杂任务。
如果你想了解更多关于代理及其工作原理的内容,建议你阅读这篇文章。
CrewAI 声称比类似的框架(如 LangGraph)更快速、更简单,因为它不需要像 Autogen 那样大量的样板代码或额外的代理编排代码。此外,CrewAI 与 Langchain 工具兼容,带来了更多可能性。
CrewAI 的应用场景十分广泛,包括研究代理、股市分析、潜在客户捕捉、合同分析、网站生成、旅行推荐等。
在本文中,你将创建一个使用 Elasticsearch 作为数据检索工具的代理,与其他代理协作,对我们的 Elasticsearch 产品进行市场调研。

基于诸如 “summer clothes - 夏季服装” 这样的概念,专家代理(expert agent)将会在 Elasticsearch 中搜索最具语义相似性的产品;研究员代理(researcher agen)则会在网上查找相关的网站和产品;最后,写作代理(writer agent)会将所有内容整合成一份市场分析报告。
你可以在这里找到包含完整示例的 Notebook。
要使这组代理(crew agent)正常运行,请完成以下步骤:
步骤如下:
-
安装并导入相关包
-
准备数据
-
创建 Elasticsearch 的 CrewAI 工具
-
配置代理
-
配置任务
安装并导入包
pip install elasticsearch==8.17 'crewai[tools]'
import json
import osfrom getpass import getpass
from elasticsearch import Elasticsearch
from elasticsearch.helpers import bulkfrom crewai import Agent, Crew, Task
from crewai.tools import tool
from crewai_tools import SerperDevTool, WebsiteSearchTool
我们导入 SerperDevTool 以使用 Serper API 在互联网上搜索与我们的查询相关的网站,并使用 WebsiteSearchTool 在找到的内容中进行 RAG 搜索。
Serper 提供 2,500 次免费查询,你可以在这里领取。
准备数据
Elasticsearch 客户端
os.environ["ELASTIC_ENDPOINT"] = "your_es_url"
os.environ["ELASTIC_API_KEY"] = "es_api_key"_client = Elasticsearch(os.environ["ELASTIC_ENDPOINT"],api_key=os.environ["ELASTIC_API_KEY"],
)
创建推理端点
为了启用语义搜索功能,你需要使用 ELSER 创建一个推理端点:
_client.options(request_timeout=60, max_retries=3, retry_on_timeout=True
).inference.put(task_type="sparse_embedding",inference_id="clothes-inference",body={"service": "elasticsearch","service_settings": {"adaptive_allocations": { "enabled": True},"num_threads": 1,"model_id": ".elser_model_2" }}
)
创建映射
现在,我们将把 ELSER 模型应用于一个单一的 semantic_text 字段,以便使代理能够运行混合查询。
_client.indices.create(index="summer-clothes",body={"mappings": {"properties": {"title": {"type": "text","copy_to": "semantic_field"},"description": {"type": "text","copy_to": "semantic_field"},"price": {"type": "float"},"semantic_field": {"type": "semantic_text","inference_id": "clothes-inference"}}}})
索引数据
我们将存储一些关于衣服的数据,以便将我们的来源与研究员代理在互联网上找到的信息进行比较。
documents = [{"title": "Twist-Detail Crop Top","description": "Fitted crop top in woven, patterned fabric with linen content. Wide shoulder straps, sweetheart neckline, and gathered side seams for a gently draped effect. Twisted detail at center bust, cut-out section at front, and wide smocking at back. Lined","price": 34.99},{"title": "Rib-knit Tank Top","description": "Short, fitted top in a soft rib knit. Extra-narrow shoulder straps and a square neckline.","price": 7.49},{"title": "Linen-blend Shorts","description": "Shorts in an airy, woven linen blend. High, ruffle-trimmed waist, narrow drawstring and covered elastic at waistband, and discreet side pockets.","price": 13.99},{"title": "Twill Cargo Shorts","description": "Fitted shorts in cotton twill with a V-shaped yoke at front and back. High waist, zip fly with button, and patch front pockets.","price": 20.99},{"title": "Slim Fit Ribbed Tank Top","description": "Slim-fit tank top in medium weight, ribbed cotton-blend jersey with a fitted silhouette. Straight-cut hem.","price": 8.49},{"title": "Relaxed Fit Linen Resort Shirt","description": "Relaxed-fit shirt in airy linen. Resort collar, buttons without placket, yoke at back, and short sleeves. Straight-cut hem. Fabric made from linen is breathable, looks great when ironed or wrinkled, and softens over time.","price": 17.99},{"title": "Swim Shorts","description": "Swim shorts in woven fabric. Drawstring and covered elastic at waistband, side pockets, and a back pocket with hook-loop fastener. Small slit at sides. Mesh liner shorts.","price": 14.99},{"title": "Baggy Fit Cargo Shorts","description": "Baggy-fit cargo shorts in cotton canvas with a generous but not oversized silhouette. Zip fly with button, diagonal side pockets, back pockets with flap and snap fasteners, and bellows leg pockets with snap fasteners.","price": 20.99},{"title": "Muslin Shorts","description": "Shorts in airy cotton muslin. High, ruffle-trimmed waist, covered elastic at waistband, and an extra-narrow drawstring with a bead at ends. Discreet side pockets.","price": 15.99},{"title": "Oversized Lyocell-blend Dress","description": "Short, oversized dress in a woven lyocell blend. Gathered, low-cut V-neck with extra-narrow ties at front, 3/4-length, raglan-cut balloon sleeves with narrow elastic at cuffs, and seams at waist and hips with delicate piping. Unlined.","price": 38.99}
]def build_data():for doc in documents:yield {"_index": "summer-clothes","_source": doc}try:success, errors = bulk(_client, build_data())print(f"{success} documents indexed successfully")if errors:print("Errors during indexing:", errors)except Exception as e:print(f"Error: {str(e)}")
创建 Elasticsearch CrewAI 工具
CrewAI 的工具装饰器简化了将常规 Python 函数转换为代理可以使用的工具。以下是我们如何创建一个 Elasticsearch 搜索工具:
@tool("es tool")
def elasticsearch_tool(question: str) -> str:"""Search in Elasticsearch using hybrid search capabilities.Args:question (str): The search query to be semantically matchedReturns:str: Concatenated hits from Elasticsearch as string JSON"""response = _client.search(index="summer-clothes",body={"size": 10,"_source": {"includes": ["description", "title", "price"]},"retriever": {"rrf": {"retrievers": [{"standard": {"query": {"match": {"title": question}}}},{"standard": {"query": {"semantic": {"field": "semantic_field","query": question,}}}},]}},},)hits = response["hits"]["hits"]if not hits:return ""result = json.dumps([hit["_source"] for hit in hits], indent=2)return result
导入其他需要的工具和凭证
现在,我们实例化一开始准备的工具,用于在互联网上搜索并在找到的内容中进行 RAG。
你还需要一个 OpenAI API 密钥,用于与 LLM 的通信。
os.environ["SERPER_API_KEY"] = "your-key"
os.environ["OPENAI_API_KEY"] = "your-key"search_tool = SerperDevTool()
web_rag_tool = WebsiteSearchTool()
配置代理
现在,你需要定义代理:
-
检索器/Retriever:能够使用之前创建的工具在 Elasticsearch 中进行搜索。
-
研究员/Researcher:使用 search_tool 在互联网上搜索。
-
撰写者/Writer:将来自其他两个代理的信息总结成一个 Markdown 博客文件。
es_retriever_agent = Agent(role="Retriever",goal="Retrieve Elasticsearch documents",backstory="You are an expert researcher",tools=[elasticsearch_tool],verbose=True,
)internet_researcher_agent = Agent(role="Research analyst",goal="Provide up-to-date market analysis of the industry",backstory="You are an expert analyst",tools=[search_tool, web_rag_tool],verbose=True,
)writer_agent = Agent(role="Content Writer",goal="Craft engaging blog posts about the information gathered",backstory="A skilled writer with a passion for writing about fashion",tools=[],verbose=True,
)
配置任务
现在你已经定义了代理和工具,你需要为每个代理创建任务。你将指定不同的任务,以包括内容来源,以便撰写者代理能够引用它们,确保检索器和研究员代理都在提供信息。
es_retriever_task = Task(description="Retrieve documents from the Elasticsearch index.",expected_output="A list of documents retrieved from the Elasticsearch index based on the query.",agent=es_retriever_agent,
)internet_research_task = Task(description="Conduct research on the latest fashion trends for summer 2025. Identify five key trends that are shaping the industry, including popular colors, fabrics, and styles. Use reliable sources such as fashion magazines, retail market reports, and industry analyses. For each trend, provide a concise summary explaining its significance and why it is gaining popularity. Clearly cite your sources using a format like [Source Name]. Your response should be structured and fact-based",expected_output="A structured summary of the top five fashion trends for summer 2025, including citations for each trend in the format [Source Name]",agent=internet_researcher_agent,
)write_task = Task(description="Compare the fashion trends from the Research Agent with product listings from Elasticsearch. Write a short report highlighting how the store's products align with trends. Use '[Elasticsearch]' for database references and '[Source Name]' for external sources",expected_output="A short, structured report combining trend insights with product recommendations, with clearly marked references",agent=writer_agent,output_file="blog-posts/new_post.md",
)

现在,你只需要实例化包含所有代理和任务的 crew 并运行它们:
# Use in a crew
crew = Crew(agents=[es_retriever_agent, internet_researcher_agent, writer_agent],tasks=[es_retriever_task,internet_research_task,write_task,],
)# Execute tasks
crew.kickoff()
我们可以在 new_post.md 文件中看到结果:
“**Short Report on Fashion Trends and Product Alignment**In this report, we will explore how the current fashion trends for summer 2025 align with the offerings in our store, as evidenced by product listings from [Elasticsearch]. The analysis focuses on five prominent trends and identifies specific products that reflect these aesthetics.**1. Romantic Florals with Kitsch Twist**The resurgence of floral patterns, particularly those that are intricate rather than large, embodies a whimsical approach to summer fashion. While our current inventory lacks offerings specifically featuring floral designs, there is an opportunity to curate products that align with this trend, potentially expanding into tops or dresses adorned with delicate floral patterns. [Source: Teen Vogue]**2. High Waisted and Baggy Silhouettes**High-waisted styles are a key trend for summer 2025, emphasizing comfort without sacrificing style. Among our offerings, the following products fit this criterion:- **Baggy Fit Cargo Shorts** ($20.99): These cargo shorts present a relaxed, generous silhouette, complementing the cultural shift towards practical fashion that allows ease of movement.- **Twill Cargo Shorts** ($20.99): These fitted options also embrace the high-waisted trend, providing versatility for various outfits.**3. Bold Colors: Turquoise and Earthy Tones**This summer promises a palette of vibrant turquoise alongside earthy tones. While our current collection does not showcase products that specifically reflect these colors, introducing pieces such as tops, dresses, or accessories in these hues could strategically cater to this emerging aesthetic. [Source: Heuritech]**4. Textured Fabrics**As textured fabrics gain popularity, we recognize an opportunity in our offerings:- **Oversized Lyocell-blend Dress** ($38.99): This dress showcases unique fabric quality with gathered seams and balloon sleeves, making it a textural delight that speaks to the trend of tactile experiences in fashion.- **Twist-Detail Crop Top** ($34.99): Featuring gathered side seams and a twist detail, it embraces the layered, visually engaging designs consumers are seeking.**5. Quiet Luxury**Quiet luxury resonates with those prioritizing quality and sustainability over fast fashion. Our offerings in this category include:- **Relaxed Fit Linen Resort Shirt** ($17.99): This piece’s breathable linen fabric and classic design underline a commitment to sustainable, timeless pieces that exemplify understated elegance.In conclusion, our current product listings from [Elasticsearch] demonstrate alignment with several key summer fashion trends for 2025. There are unique opportunities to further harness these trends by expanding our collection to include playful floral designs and vibrant colors. Additionally, leveraging the existing offerings that emphasize comfort and quality can enhance our customer appeal in the face of evolving consumer trends.We are well positioned to make strategic enhancements to our inventory, ensuring we stay ahead in the fast-evolving fashion landscape.”
结论
CrewAI 简化了实例化带有角色扮演的代理工作流的过程,并且支持 Langchain 工具,包括自定义工具,使得通过像工具装饰器这样的抽象方式创建工具变得更加容易。
这个代理 crew 展示了执行结合本地数据源和互联网搜索的复杂任务的能力。
如果你想继续改进这个工作流,你可以尝试创建一个新的代理,将 writer_agent 的结果写入 Elasticsearch!
想要获得 Elastic 认证吗?查找下次 Elasticsearch 工程师培训的时间!
Elasticsearch 拥有许多新功能,可以帮助你为你的使用场景构建最佳搜索解决方案。深入探索我们的示例笔记本,了解更多,开始免费云试用,或者现在就在你的本地机器上尝试 Elastic。
原文:Using CrewAI with Elasticsearch - Elasticsearch Labs
相关文章:
将 CrewAI 与 Elasticsearch 结合使用
作者:来自 Elastic Jeffrey Rengifo 学习如何使用 CrewAI 为你的代理团队创建一个 Elasticsearch 代理,并执行市场调研任务。 CrewAI 是一个用于编排代理的框架,它通过角色扮演的方式让多个代理协同完成复杂任务。 如果你想了解更多关于代理…...
wait 和notify ,notifyAll,sleep
wait 使线程进入阻塞状态,释放CPU,以及锁 sleep 使线程进入睡眠状态,sleep方法不会释放CPU资源和锁资源,而是让出CPU的使用权。操作系统会将CPU分配给其他就绪线程,但当前线程依然存在,不会释放其占用的…...
ECMAScript 6 新特性(二)
ECMAScript 6 新特性(二) ECMAScript 6 新特性(一) ECMAScript 6 新特性(二)(本文) ECMAScript 7~10 新特性 1. 生成器 生成器函数是 ES6 提供的一种解决异步编程方案,一…...
SpringBoot接口覆盖上一次调用的实现方案
调用springboot接口时,如何实现覆盖上一次调用 Spring Boot 接口覆盖上一次调用的实现方案 以下是多种实现覆盖上一次接口调用的方案,适用于不同场景。 方案一:同步锁控制(单机环境) 适用场景:单实例…...
Spring 的 IoC 和 DI 详解:从零开始理解与实践
Spring 的 IoC和 DI 详解:从零开始理解与实践 一、IoC(控制反转) 1、什么是 IoC? IoC 是一种设计思想,它的核心是将对象的创建和管理权从开发者手中转移到外部容器(如 Spring 容器)。通过这种…...
Python Cookbook-5.12 检查序列的成员
任务 你需要对一个列表执行很频繁的成员资格检査。而in操作符的 O(n)时间复杂度对性能的影响很大,你也不能将序列转化为一个字典或者集合,因为你还需要保留原序列的元素顺序。 解决方案 假设需要给列表添加一个在该列表中不存在的元素。一个可行的方法…...
签名过期怎么办?
1无论是证书到期还是被封停,只需要找到签名服务商,重新签名就可以了,但签名经常性过期会造成app用户流失,所以我们在选择签名时需要注意,在资金充足的情况下,优先选择独立、稳定签名,接下来我们…...
ZYNQ笔记(四):AXI GPIO
版本:Vivado2020.2(Vitis) 任务:使用 AXI GPIO IP 核实现按键 KEY 控制 LED 亮灭(两个都在PL端) 一、介绍 AXI GPIO (Advanced eXtensible Interface General Purpose Input/Output) 是 Xilinx 提供的一个可…...
实操(环境变量)Linux
环境变量概念 我们用语言写的文件编好后变成了程序,./ 运行的时候他就会变成一个进程被操作系统调度并运行,运行完毕进程相关资源被释放,因为它是一个bash的子进程,所以它退出之后进入僵尸状态,bash回收他的退出结果&…...
【补题】P9423 [蓝桥杯 2023 国 B] 数三角
题意:小明在二维坐标系中放置了 n 个点,他想在其中选出一个包含三个点的子集,这三个点能组成三角形。然而这样的方案太多了,他决定只选择那些可以组成等腰三角形的方案。请帮他计算出一共有多少种选法可以组成等腰三角形ÿ…...
Word / WPS 页面顶部标题 段前间距 失效 / 不起作用 / 不显示,标题紧贴页眉 问题及解决
问题描述: 在 Word 或者 WPS 里面,如果不是新的一节,而是位于新的一页首行时,不管怎么设置段前间距,始终是失效的,实际段前间距一直是零。 解决方案: 查询了很多方案均无法解决问题ÿ…...
Mysql自动增长数据的操作(修改增长最大值)
在MySQL中,如果你想要修改一个表的自增长(auto-increment)属性的起始值,可以使用ALTER TABLE语句。这对于初始化新环境或修复损坏的自增长计数器特别有用。下面是如何操作的一些步骤: 查看当前自增长值 首先ÿ…...
Linux自行实现的一个Shell(15)
文章目录 前言一、头文件和全局变量头文件全局变量 二、辅助函数获取用户名获取主机名获取当前工作目录获取最后一级目录名生成命令行提示符打印命令行提示符 三、命令处理获取用户输入解析命令行执行外部命令 四、内建命令添加环境变量检查和执行内建命令 五、初始化初始化环境…...
在 Q3D 中提取汇流条电感
汇流条排简介和设计注意事项 汇流条排是用于配电的金属导体,在许多应用中与传统布线相比具有设计优势。在设计母线排时,必须考虑几个重要的因素: 低电感:高频开关内容会导致无功损耗,从而降低效率电容:管…...
MySQL:事务的理解
一、CURD不加控制,会有什么问题 (1)因为,MySQL里面存的是数据,所以很有可能会被多个客户访问,所以mysqld可能一次会接受到多个关于CURD的请求。(2)且mysql内部是采用多线程来完成数…...
[raspberrypi 0w and respeaker 2mic]实时音频波形
0. 环境 ubuntu22主机, 192.168.8.162, raspberry 0w, 192.168.8.220 路由器 1. 树莓派 # rpi - send.py # 或者命令行:arecord -D plughw:1,0 -t wav -f cd -r 16000 -c 2 | nc 192.168.8.162 12345import socket imp…...
python 基础:句子缩写
n int(input()) for _ in range(n):words input().split()result ""for word in words:result word[0].upper()print(result)知识点讲解 input()函数 用于从标准输入(通常是键盘)读取用户输入的内容。它返回的是字符串类型。例如在代码中…...
Ruoyi-vue plus 5.2.2 flowble 结束节点异常错误
因业务要求, 我在结束节点的结束事件中,制作了一个归档的事件,来执行一个业务。 始终都会报错, 错误信息 ${archivTemplateListener} did not resolve to an implementation of interface org.flowable.engine.delegate.Execution…...
Sublime Text使用教程(用Sublime Text编写C语言程序)
Sublime Text 是一款当下非常流行的文本编辑器,其功能强大(提供有众多的插件)、界面简洁、还支持跨平台使用(包括 Mac OS X、Linux 和 Windows)。 在程序员眼中,Sublime Text 不仅仅是一个文本编辑器&…...
【1】k8s集群管理系列--包应用管理器之helm
一、helm概述 Helm核心是模板,即模板化K8s YAML文件。 通过模板实现Chart高效复用,当部署多个应用时,可以将差异化的字段进行模板化,在部署时使用-f或 者–set动态覆盖默认值,从而适配多个应用 helm工作流程…...
【书籍】DeepSeek谈《持续交付2.0》
目录 一、深入理解1. 核心理念升级:从"自动化"到"双环模型"2. 数字化转型的五大核心能力3. 关键实践与案例4. 组织与文化变革5. 与其它框架的关系6. 实际应用建议 二、对于开发实习生的帮助1. 立刻提升你的代码交付质量(技术验证环实…...
Mysql表的操作(2)
1.去重 select distinct 列名 from 表名 2.查询时排序 select 列名 from 表名 order by 列名 asc/desc; 不影响数据库里面的数据 错误样例 : 但结果却有点出乎意料了~为什么会失败呢? 其实这是因为书写的形式不对,如果带了引号,…...
智能物联网网关策略部署
实训背景 某智慧工厂需部署物联网网关,实现以下工业级安全管控需求: 设备准入控制:仅允许注册MAC地址的传感器接入(白名单:AA:BB:CC:DD:EE:FF)。协议合规性:禁止非Modbus TCP(端口…...
神经网络语言模型与统计语言模型的比较
神经网络语言模型(Neural Language Models, NLMs)与统计语言模型(Statistical Language Models, SLMs)是自然语言处理(NLP)中两类核心的语言建模方法,其核心差异体现在建模方式、表示能力、数据…...
Java学习总结-线程池
线程池是什么? 线程池就是一个可以复用线程的技术。 假若不用线程池的问题:创建新线程开销很大,不能来一个任务就就创建一个新线程。 如何创建线程池对象? 方法一:使用ExecutorService的实现类ThreadPoolExecutor创…...
Android 中绕过hwbinder 实现跨模块对audio 的HAL调用
需求 Audio 模块中专门为 TV 产品添加了一些代码,需要在 hdmi 的 HAL 代码中进行调用以完成某些功能。 解决方法 首先将 hdmi HAL 要调用的 audio 接口函数所在的 .so 链接到最基本的 lib.primay.amlogic.so 中(其它平台上这个 .so 文件的名字也可能是…...
【DB2】事务日志满/归档占用较大问题处理记录
某DB2环境经常报错The active log is full and is held by...,并且归档磁盘占用较大 事务日志满 事务日志满可以理解为Oracle的redo追尾,即业务写入量大于redo刷盘速度,这时候其他SQL会陷入等待,容易造成性能问题 一般由两方面原…...
基于CNN-BiLSTM-GRU的深度Q网络(Deep Q-Network,DQN)求解移动机器人路径规划,MATLAB代码
一、深度Q网络(Deep Q-Network,DQN)介绍 1、背景与动机 深度Q网络(DQN)是深度强化学习领域的里程碑算法,由DeepMind于2013年提出。它首次在 Atari 2600 游戏上实现了超越人类的表现,解决了传统…...
CVE-2025-29927 Next.js 中间件鉴权绕过漏洞
Next.js Next.js 是一个基于 React 的现代 Web 开发框架,用来构建高性能、可扩展的 Web 应用和网站。 CVE-2025-29927 Next.js 中间件鉴权绕过漏洞 CVE-2025-29927是Next.js框架中的一个授权绕过漏洞,允许攻击者通过特制的HTTP请求绕过在中间件中执行…...
数据结构(五)——AVL树(平衡二叉搜索树)
目录 前言 AVL树概念 AVL树的定义 AVL树的插入 右旋转 左旋转 左右双旋 右左双旋 插入代码如下所示 AVL树的查找 AVL树的遍历 AVL树的节点个数以及高度 判断平衡 AVL树代码如下所示 小结 前言 前面我们在数据结构中介绍了二叉搜索树,其中提到了二叉搜…...
