mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-05-05 09:12:39 +00:00
feat(crewai-tools): add highlights to ExaSearchTool, rename from EXASearchTool
Some checks failed
Some checks failed
* feat(crewai-tools): add highlights to ExaSearchTool, rename from EXASearchTool - Add a highlights init param so agents can get token-efficient excerpts instead of full pages - Rename EXASearchTool to ExaSearchTool; keep EXASearchTool as a deprecated alias so existing imports keep working - Update the docs and example to use highlights as the recommended option - Add a small note that says Exa is the fastest and most accurate web search API - Add tests for the new highlights param and the deprecation alias * fix(crewai-tools): import order and module-level Exa for tests - Reorder std-lib imports so ruff is happy with force-sort-within-sections. - Import Exa at module level (with a fallback) so the existing test mocks resolve. The lazy install prompt still works if exa_py is missing. - Allow content and summary to be a dict, matching highlights. - Trim test file to the cases this PR introduces (highlights param and the EXASearchTool deprecation alias). Existing init-shape tests stay. Co-Authored-By: ishan <ishan@exa.ai> * chore(crewai-tools): drop self-explanatory comment on schema alias Co-Authored-By: ishan <ishan@exa.ai> * docs(crewai-tools): default highlights to True, drop summary from examples Co-Authored-By: ishan <ishan@exa.ai> * docs(crewai-tools): simplify highlights examples to highlights=True Co-Authored-By: ishan <ishan@exa.ai> * feat(crewai-tools): add x-exa-integration header for usage tracking Co-Authored-By: ishan <ishan@exa.ai> * docs(crewai-tools): add Exa MCP section and resources links Co-Authored-By: ishan <ishan@exa.ai> --------- Co-authored-by: ishan <ishan@exa.ai> Co-authored-by: Greyson LaLonde <greyson.r.lalonde@gmail.com> Co-authored-by: Lorenze Jay <63378463+lorenzejay@users.noreply.github.com>
This commit is contained in:
@@ -133,7 +133,7 @@ crew.kickoff()
|
||||
| **DirectorySearchTool** | أداة RAG للبحث في المجلدات، مفيدة للتنقل في أنظمة الملفات. |
|
||||
| **DOCXSearchTool** | أداة RAG للبحث في مستندات DOCX، مثالية لمعالجة ملفات Word. |
|
||||
| **DirectoryReadTool** | تسهّل قراءة ومعالجة هياكل المجلدات ومحتوياتها. |
|
||||
| **EXASearchTool** | أداة مصممة لإجراء عمليات بحث شاملة عبر مصادر بيانات متنوعة. |
|
||||
| **ExaSearchTool** | أداة مصممة لإجراء عمليات بحث شاملة عبر مصادر بيانات متنوعة. |
|
||||
| **FileReadTool** | تُمكّن قراءة واستخراج البيانات من الملفات، مع دعم تنسيقات ملفات متنوعة. |
|
||||
| **FirecrawlSearchTool** | أداة للبحث في صفحات الويب باستخدام Firecrawl وإرجاع النتائج. |
|
||||
| **FirecrawlCrawlWebsiteTool** | أداة لزحف صفحات الويب باستخدام Firecrawl. |
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
---
|
||||
title: "أداة بحث Exa"
|
||||
description: "ابحث في الويب باستخدام Exa Search API للعثور على النتائج الأكثر صلة لأي استعلام، مع خيارات لمحتوى الصفحة الكامل والمقتطفات والملخصات."
|
||||
description: "ابحث في الويب باستخدام Exa Search API للعثور على النتائج الأكثر صلة لأي استعلام، مع خيارات لمحتوى الصفحة الكامل والمقتطفات."
|
||||
icon: "magnifying-glass"
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
تتيح أداة `EXASearchTool` لوكلاء CrewAI البحث في الويب باستخدام [Exa](https://exa.ai/) search API. تُرجع النتائج الأكثر صلة لأي استعلام، مع خيارات لمحتوى الصفحة الكامل والملخصات المولّدة بالذكاء الاصطناعي.
|
||||
تتيح أداة `ExaSearchTool` لوكلاء CrewAI البحث في الويب باستخدام [Exa](https://exa.ai/) search API. تُرجع النتائج الأكثر صلة لأي استعلام، مع خيارات لمحتوى الصفحة الكامل والمقتطفات الموفرة للرموز.
|
||||
|
||||
## التثبيت
|
||||
|
||||
@@ -27,15 +27,15 @@ export EXA_API_KEY='your_exa_api_key'
|
||||
|
||||
## مثال على الاستخدام
|
||||
|
||||
إليك كيفية استخدام `EXASearchTool` مع وكيل CrewAI:
|
||||
إليك كيفية استخدام `ExaSearchTool` مع وكيل CrewAI:
|
||||
|
||||
```python
|
||||
import os
|
||||
from crewai import Agent, Task, Crew
|
||||
from crewai_tools import EXASearchTool
|
||||
from crewai_tools import ExaSearchTool
|
||||
|
||||
# Initialize the tool
|
||||
exa_tool = EXASearchTool()
|
||||
exa_tool = ExaSearchTool()
|
||||
|
||||
# Create an agent that uses the tool
|
||||
researcher = Agent(
|
||||
@@ -66,11 +66,11 @@ print(result)
|
||||
|
||||
## خيارات التكوين
|
||||
|
||||
تقبل أداة `EXASearchTool` المعاملات التالية أثناء التهيئة:
|
||||
تقبل أداة `ExaSearchTool` المعاملات التالية أثناء التهيئة:
|
||||
|
||||
- `type` (str، اختياري): نوع البحث المستخدم. الافتراضي هو `"auto"`. الخيارات: `"auto"`، `"instant"`، `"fast"`، `"deep"`.
|
||||
- `highlights` (bool أو dict، اختياري): إرجاع مقتطفات موفرة للرموز أكثر صلة بالاستعلام بدلاً من الصفحة الكاملة. الافتراضي هو `True`. مرر قاموسًا مثل `{"max_characters": 4000}` للتكوين، أو `False` للتعطيل.
|
||||
- `content` (bool، اختياري): ما إذا كان يجب تضمين محتوى الصفحة الكامل في النتائج. الافتراضي هو `False`.
|
||||
- `summary` (bool، اختياري): ما إذا كان يجب تضمين ملخصات مولّدة بالذكاء الاصطناعي لكل نتيجة. يتطلب `content=True`. الافتراضي هو `False`.
|
||||
- `api_key` (str، اختياري): مفتاح Exa API الخاص بك. يعود إلى متغير البيئة `EXA_API_KEY` إذا لم يتم تقديمه.
|
||||
- `base_url` (str، اختياري): عنوان URL مخصص لخادم API. يعود إلى متغير البيئة `EXA_BASE_URL` إذا لم يتم تقديمه.
|
||||
|
||||
@@ -86,25 +86,52 @@ print(result)
|
||||
يمكنك تكوين الأداة بمعاملات مخصصة للحصول على نتائج أغنى:
|
||||
|
||||
```python
|
||||
# Get full page content with AI summaries
|
||||
exa_tool = EXASearchTool(
|
||||
content=True,
|
||||
summary=True,
|
||||
# Use 'deep' for thorough, multi-step searches
|
||||
exa_tool = ExaSearchTool(
|
||||
highlights=True,
|
||||
type="deep"
|
||||
)
|
||||
|
||||
# Use it in an agent
|
||||
agent = Agent(
|
||||
role="Deep Researcher",
|
||||
goal="Conduct thorough research with full content and summaries",
|
||||
goal="Conduct thorough research",
|
||||
tools=[exa_tool]
|
||||
)
|
||||
```
|
||||
|
||||
## استخدام Exa عبر MCP
|
||||
|
||||
يمكنك أيضًا ربط وكيلك بخادم MCP المستضاف من Exa. مرّر مفتاح API الخاص بك عبر ترويسة `x-api-key`:
|
||||
|
||||
```python
|
||||
from crewai import Agent
|
||||
from crewai.mcp import MCPServerHTTP
|
||||
|
||||
agent = Agent(
|
||||
role="Research Analyst",
|
||||
goal="Find and analyze information on the web",
|
||||
backstory="Expert researcher with access to Exa's tools",
|
||||
mcps=[
|
||||
MCPServerHTTP(
|
||||
url="https://mcp.exa.ai/mcp",
|
||||
headers={"x-api-key": "YOUR_EXA_API_KEY"},
|
||||
),
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
احصل على مفتاح API من [لوحة تحكم Exa](https://dashboard.exa.ai/api-keys). لمزيد من المعلومات حول MCP في CrewAI، راجع [نظرة عامة على MCP](/ar/mcp/overview).
|
||||
|
||||
## الميزات
|
||||
|
||||
- **مقتطفات موفرة للرموز**: الحصول على المقتطفات الأكثر صلة من كل نتيجة، باستخدام رموز أقل بكثير من النص الكامل
|
||||
- **البحث الدلالي**: العثور على نتائج بناءً على المعنى، وليس الكلمات المفتاحية فقط
|
||||
- **استرجاع المحتوى الكامل**: الحصول على النص الكامل لصفحات الويب مع نتائج البحث
|
||||
- **ملخصات الذكاء الاصطناعي**: الحصول على ملخصات موجزة مولّدة بالذكاء الاصطناعي لكل نتيجة
|
||||
- **تصفية التاريخ**: تقييد النتائج لفترات زمنية محددة باستخدام فلاتر تاريخ النشر
|
||||
- **تصفية النطاقات**: تقييد عمليات البحث على نطاقات محددة
|
||||
- **تصفية النطاقات**: تقييد عمليات البحث على نطاقات محددة
|
||||
|
||||
## موارد
|
||||
|
||||
- [توثيق Exa](https://exa.ai/docs)
|
||||
- [لوحة تحكم Exa — إدارة مفاتيح API والاستخدام](https://dashboard.exa.ai)
|
||||
@@ -133,7 +133,7 @@ Here is a list of the available tools and their descriptions:
|
||||
| **DirectorySearchTool** | A RAG tool for searching within directories, useful for navigating through file systems. |
|
||||
| **DOCXSearchTool** | A RAG tool aimed at searching within DOCX documents, ideal for processing Word files. |
|
||||
| **DirectoryReadTool** | Facilitates reading and processing of directory structures and their contents. |
|
||||
| **EXASearchTool** | A tool designed for performing exhaustive searches across various data sources. |
|
||||
| **ExaSearchTool** | Search the web with Exa, the fastest and most accurate web search API. Supports token-efficient highlights and full page content. |
|
||||
| **FileReadTool** | Enables reading and extracting data from files, supporting various file formats. |
|
||||
| **FirecrawlSearchTool** | A tool to search webpages using Firecrawl and return the results. |
|
||||
| **FirecrawlCrawlWebsiteTool** | A tool for crawling webpages using Firecrawl. |
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
---
|
||||
title: "Exa Search Tool"
|
||||
description: "Search the web using the Exa Search API to find the most relevant results for any query, with options for full page content, highlights, and summaries."
|
||||
description: "Search the web with Exa, the fastest and most accurate web search API. Get token-efficient highlights and full page content."
|
||||
icon: "magnifying-glass"
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
The `EXASearchTool` lets CrewAI agents search the web using the [Exa](https://exa.ai/) search API. It returns the most relevant results for any query, with options for full page content and AI-generated summaries.
|
||||
The `ExaSearchTool` lets CrewAI agents search the web using [Exa](https://exa.ai/), the fastest and most accurate web search API. It returns the most relevant results for any query, with options for token-efficient highlights and full page content.
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -27,15 +27,15 @@ Get an API key from the [Exa dashboard](https://dashboard.exa.ai/api-keys).
|
||||
|
||||
## Example Usage
|
||||
|
||||
Here's how to use the `EXASearchTool` within a CrewAI agent:
|
||||
Here's how to use the `ExaSearchTool` within a CrewAI agent:
|
||||
|
||||
```python
|
||||
import os
|
||||
from crewai import Agent, Task, Crew
|
||||
from crewai_tools import EXASearchTool
|
||||
from crewai_tools import ExaSearchTool
|
||||
|
||||
# Initialize the tool
|
||||
exa_tool = EXASearchTool()
|
||||
exa_tool = ExaSearchTool()
|
||||
|
||||
# Create an agent that uses the tool
|
||||
researcher = Agent(
|
||||
@@ -66,11 +66,11 @@ print(result)
|
||||
|
||||
## Configuration Options
|
||||
|
||||
The `EXASearchTool` accepts the following parameters during initialization:
|
||||
The `ExaSearchTool` accepts the following parameters during initialization:
|
||||
|
||||
- `type` (str, optional): The search type to use. Defaults to `"auto"`. Options: `"auto"`, `"instant"`, `"fast"`, `"deep"`.
|
||||
- `highlights` (bool or dict, optional): Return token-efficient excerpts most relevant to the query instead of the full page. Defaults to `True`. Pass a dict like `{"max_characters": 4000}` to configure, or `False` to disable.
|
||||
- `content` (bool, optional): Whether to include full page content in results. Defaults to `False`.
|
||||
- `summary` (bool, optional): Whether to include AI-generated summaries of each result. Requires `content=True`. Defaults to `False`.
|
||||
- `api_key` (str, optional): Your Exa API key. Falls back to the `EXA_API_KEY` environment variable if not provided.
|
||||
- `base_url` (str, optional): Custom API server URL. Falls back to the `EXA_BASE_URL` environment variable if not provided.
|
||||
|
||||
@@ -83,28 +83,70 @@ When calling the tool (or when an agent invokes it), the following search parame
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
You can configure the tool with custom parameters for richer results:
|
||||
For most agent workflows we recommend `highlights` — it returns the most relevant excerpts from each result and uses far fewer tokens than full page content:
|
||||
|
||||
```python
|
||||
# Get full page content with AI summaries
|
||||
exa_tool = EXASearchTool(
|
||||
content=True,
|
||||
summary=True,
|
||||
type="deep"
|
||||
# Get token-efficient excerpts most relevant to the query
|
||||
exa_tool = ExaSearchTool(
|
||||
highlights=True,
|
||||
type="auto",
|
||||
)
|
||||
|
||||
# Use it in an agent
|
||||
agent = Agent(
|
||||
role="Deep Researcher",
|
||||
goal="Conduct thorough research with full content and summaries",
|
||||
role="Researcher",
|
||||
goal="Answer questions with current web data",
|
||||
tools=[exa_tool]
|
||||
)
|
||||
```
|
||||
|
||||
For thorough, multi-step searches, use `type="deep"`:
|
||||
|
||||
```python
|
||||
exa_tool = ExaSearchTool(
|
||||
highlights=True,
|
||||
type="deep",
|
||||
)
|
||||
```
|
||||
|
||||
For more on choosing between highlights and full content, see the [Exa search best practices](https://exa.ai/docs/reference/search-best-practices).
|
||||
|
||||
## Using Exa via MCP
|
||||
|
||||
You can also connect your agent to Exa's hosted MCP server. Pass your API key with the `x-api-key` header:
|
||||
|
||||
```python
|
||||
from crewai import Agent
|
||||
from crewai.mcp import MCPServerHTTP
|
||||
|
||||
agent = Agent(
|
||||
role="Research Analyst",
|
||||
goal="Find and analyze information on the web",
|
||||
backstory="Expert researcher with access to Exa's tools",
|
||||
mcps=[
|
||||
MCPServerHTTP(
|
||||
url="https://mcp.exa.ai/mcp",
|
||||
headers={"x-api-key": "YOUR_EXA_API_KEY"},
|
||||
),
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
Get your API key from the [Exa dashboard](https://dashboard.exa.ai/api-keys). For more on MCP in CrewAI, see the [MCP overview](/en/mcp/overview).
|
||||
|
||||
## Features
|
||||
|
||||
- **Token-Efficient Highlights**: Get the most relevant excerpts from each result, ~10x fewer tokens than full text
|
||||
- **Semantic Search**: Find results based on meaning, not just keywords
|
||||
- **Full Content Retrieval**: Get the full text of web pages alongside search results
|
||||
- **AI Summaries**: Get concise, AI-generated summaries of each result
|
||||
- **Date Filtering**: Limit results to specific time periods with published date filters
|
||||
- **Domain Filtering**: Restrict searches to specific domains
|
||||
|
||||
<Note>
|
||||
`EXASearchTool` is a deprecated alias for `ExaSearchTool`. Existing imports continue to work but will emit a deprecation warning; please migrate to `ExaSearchTool`.
|
||||
</Note>
|
||||
|
||||
## Resources
|
||||
|
||||
- [Exa documentation](https://exa.ai/docs)
|
||||
- [Exa dashboard — manage API keys and usage](https://dashboard.exa.ai)
|
||||
|
||||
@@ -132,7 +132,7 @@ crew.kickoff()
|
||||
| **DirectorySearchTool** | 디렉터리 내에서 검색하는 RAG 도구로, 파일 시스템을 탐색할 때 유용합니다. |
|
||||
| **DOCXSearchTool** | DOCX 문서 내에서 검색하는 데 특화된 RAG 도구로, Word 파일을 처리할 때 이상적입니다. |
|
||||
| **DirectoryReadTool** | 디렉터리 구조와 그 내용을 읽고 처리하도록 지원하는 도구입니다. |
|
||||
| **EXASearchTool** | 다양한 데이터 소스를 폭넓게 검색하기 위해 설계된 도구입니다. |
|
||||
| **ExaSearchTool** | 다양한 데이터 소스를 폭넓게 검색하기 위해 설계된 도구입니다. |
|
||||
| **FileReadTool** | 다양한 파일 형식을 지원하며 파일에서 데이터를 읽고 추출할 수 있는 도구입니다. |
|
||||
| **FirecrawlSearchTool** | Firecrawl을 이용해 웹페이지를 검색하고 결과를 반환하는 도구입니다. |
|
||||
| **FirecrawlCrawlWebsiteTool** | Firecrawl을 사용해 웹페이지를 크롤링하는 도구입니다. |
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
---
|
||||
title: EXA 검색 웹 로더
|
||||
description: EXASearchTool은 인터넷 전반에 걸쳐 텍스트의 내용에서 지정된 쿼리에 대한 시맨틱 검색을 수행하도록 설계되었습니다.
|
||||
description: ExaSearchTool은 인터넷 전반에 걸쳐 텍스트의 내용에서 지정된 쿼리에 대한 시맨틱 검색을 수행하도록 설계되었습니다.
|
||||
icon: globe-pointer
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
# `EXASearchTool`
|
||||
# `ExaSearchTool`
|
||||
|
||||
## 설명
|
||||
|
||||
EXASearchTool은 텍스트의 내용을 기반으로 지정된 쿼리를 인터넷 전반에 걸쳐 의미론적으로 검색하도록 설계되었습니다.
|
||||
ExaSearchTool은 텍스트의 내용을 기반으로 지정된 쿼리를 인터넷 전반에 걸쳐 의미론적으로 검색하도록 설계되었습니다.
|
||||
사용자가 제공한 쿼리를 기반으로 가장 관련성 높은 검색 결과를 가져오고 표시하기 위해 [exa.ai](https://exa.ai/) API를 활용합니다.
|
||||
|
||||
## 설치
|
||||
@@ -25,15 +25,15 @@ pip install 'crewai[tools]'
|
||||
다음 예제는 도구를 초기화하고 주어진 쿼리로 검색을 실행하는 방법을 보여줍니다:
|
||||
|
||||
```python Code
|
||||
from crewai_tools import EXASearchTool
|
||||
from crewai_tools import ExaSearchTool
|
||||
|
||||
# Initialize the tool for internet searching capabilities
|
||||
tool = EXASearchTool()
|
||||
tool = ExaSearchTool()
|
||||
```
|
||||
|
||||
## 시작 단계
|
||||
|
||||
EXASearchTool을 효과적으로 사용하려면 다음 단계를 따르세요:
|
||||
ExaSearchTool을 효과적으로 사용하려면 다음 단계를 따르세요:
|
||||
|
||||
<Steps>
|
||||
<Step title="패키지 설치">
|
||||
@@ -47,7 +47,35 @@ EXASearchTool을 효과적으로 사용하려면 다음 단계를 따르세요:
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## MCP를 통한 Exa 사용
|
||||
|
||||
Exa가 호스팅하는 MCP 서버에 에이전트를 연결할 수도 있습니다. API 키는 `x-api-key` 헤더로 전달하세요:
|
||||
|
||||
```python
|
||||
from crewai import Agent
|
||||
from crewai.mcp import MCPServerHTTP
|
||||
|
||||
agent = Agent(
|
||||
role="Research Analyst",
|
||||
goal="Find and analyze information on the web",
|
||||
backstory="Expert researcher with access to Exa's tools",
|
||||
mcps=[
|
||||
MCPServerHTTP(
|
||||
url="https://mcp.exa.ai/mcp",
|
||||
headers={"x-api-key": "YOUR_EXA_API_KEY"},
|
||||
),
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
API 키는 [Exa 대시보드](https://dashboard.exa.ai/api-keys)에서 발급받을 수 있습니다. CrewAI에서의 MCP 사용에 대한 자세한 내용은 [MCP 개요](/ko/mcp/overview)를 참고하세요.
|
||||
|
||||
## 결론
|
||||
|
||||
`EXASearchTool`을 Python 프로젝트에 통합함으로써, 사용자는 애플리케이션 내에서 실시간으로 인터넷을 직접 검색할 수 있는 능력을 얻게 됩니다.
|
||||
`ExaSearchTool`을 Python 프로젝트에 통합함으로써, 사용자는 애플리케이션 내에서 실시간으로 인터넷을 직접 검색할 수 있는 능력을 얻게 됩니다.
|
||||
제공된 설정 및 사용 지침을 따르면, 이 도구를 프로젝트에 포함하는 과정이 간편하고 직관적입니다.
|
||||
|
||||
## 참고 자료
|
||||
|
||||
- [Exa 공식 문서](https://exa.ai/docs)
|
||||
- [Exa 대시보드 — API 키 및 사용량 관리](https://dashboard.exa.ai)
|
||||
|
||||
@@ -133,7 +133,7 @@ Aqui está uma lista das ferramentas disponíveis e suas descrições:
|
||||
| **DirectorySearchTool** | Ferramenta RAG para busca em diretórios, útil para navegação em sistemas de arquivos. |
|
||||
| **DOCXSearchTool** | Ferramenta RAG voltada para busca em documentos DOCX, ideal para processar arquivos Word. |
|
||||
| **DirectoryReadTool** | Facilita a leitura e processamento de estruturas de diretórios e seus conteúdos. |
|
||||
| **EXASearchTool** | Ferramenta projetada para buscas exaustivas em diversas fontes de dados. |
|
||||
| **ExaSearchTool** | Ferramenta projetada para buscas exaustivas em diversas fontes de dados. |
|
||||
| **FileReadTool** | Permite a leitura e extração de dados de arquivos, suportando diversos formatos. |
|
||||
| **FirecrawlSearchTool** | Ferramenta para buscar páginas web usando Firecrawl e retornar os resultados. |
|
||||
| **FirecrawlCrawlWebsiteTool** | Ferramenta para rastrear páginas web utilizando o Firecrawl. |
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
---
|
||||
title: Carregador Web EXA Search
|
||||
description: O `EXASearchTool` foi projetado para realizar uma busca semântica para uma consulta especificada a partir do conteúdo de um texto em toda a internet.
|
||||
description: O `ExaSearchTool` foi projetado para realizar uma busca semântica para uma consulta especificada a partir do conteúdo de um texto em toda a internet.
|
||||
icon: globe-pointer
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
# `EXASearchTool`
|
||||
# `ExaSearchTool`
|
||||
|
||||
## Descrição
|
||||
|
||||
O EXASearchTool foi projetado para realizar uma busca semântica para uma consulta especificada a partir do conteúdo de um texto em toda a internet.
|
||||
O ExaSearchTool foi projetado para realizar uma busca semântica para uma consulta especificada a partir do conteúdo de um texto em toda a internet.
|
||||
Ele utiliza a API da [exa.ai](https://exa.ai/) para buscar e exibir os resultados de pesquisa mais relevantes com base na consulta fornecida pelo usuário.
|
||||
|
||||
## Instalação
|
||||
@@ -25,15 +25,15 @@ pip install 'crewai[tools]'
|
||||
O exemplo a seguir demonstra como inicializar a ferramenta e executar uma busca com uma consulta determinada:
|
||||
|
||||
```python Code
|
||||
from crewai_tools import EXASearchTool
|
||||
from crewai_tools import ExaSearchTool
|
||||
|
||||
# Initialize the tool for internet searching capabilities
|
||||
tool = EXASearchTool()
|
||||
tool = ExaSearchTool()
|
||||
```
|
||||
|
||||
## Etapas para Começar
|
||||
|
||||
Para usar o EXASearchTool de forma eficaz, siga estas etapas:
|
||||
Para usar o ExaSearchTool de forma eficaz, siga estas etapas:
|
||||
|
||||
<Steps>
|
||||
<Step title="Instalação do Pacote">
|
||||
@@ -47,7 +47,35 @@ Para usar o EXASearchTool de forma eficaz, siga estas etapas:
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Usando o Exa via MCP
|
||||
|
||||
Você também pode conectar seu agente ao servidor MCP hospedado pelo Exa. Passe sua chave de API no cabeçalho `x-api-key`:
|
||||
|
||||
```python
|
||||
from crewai import Agent
|
||||
from crewai.mcp import MCPServerHTTP
|
||||
|
||||
agent = Agent(
|
||||
role="Research Analyst",
|
||||
goal="Find and analyze information on the web",
|
||||
backstory="Expert researcher with access to Exa's tools",
|
||||
mcps=[
|
||||
MCPServerHTTP(
|
||||
url="https://mcp.exa.ai/mcp",
|
||||
headers={"x-api-key": "YOUR_EXA_API_KEY"},
|
||||
),
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
Obtenha sua chave de API no [painel da Exa](https://dashboard.exa.ai/api-keys). Para mais informações sobre MCP no CrewAI, consulte a [visão geral do MCP](/pt-BR/mcp/overview).
|
||||
|
||||
## Conclusão
|
||||
|
||||
Ao integrar o `EXASearchTool` em projetos Python, os usuários ganham a capacidade de realizar buscas relevantes e em tempo real pela internet diretamente de suas aplicações.
|
||||
Seguindo as orientações de configuração e uso fornecidas, a incorporação desta ferramenta em projetos torna-se simples e direta.
|
||||
Ao integrar o `ExaSearchTool` em projetos Python, os usuários ganham a capacidade de realizar buscas relevantes e em tempo real pela internet diretamente de suas aplicações.
|
||||
Seguindo as orientações de configuração e uso fornecidas, a incorporação desta ferramenta em projetos torna-se simples e direta.
|
||||
|
||||
## Recursos
|
||||
|
||||
- [Documentação do Exa](https://exa.ai/docs)
|
||||
- [Painel do Exa — gerenciar chaves de API e uso](https://dashboard.exa.ai)
|
||||
@@ -26,7 +26,7 @@ CrewAI provides an extensive collection of powerful tools ready to enhance your
|
||||
- **Web Scraping**: `ScrapeWebsiteTool`, `SeleniumScrapingTool`
|
||||
- **Database Integrations**: `MySQLSearchTool`
|
||||
- **Vector Database Integrations**: `MongoDBVectorSearchTool`, `QdrantVectorSearchTool`, `WeaviateVectorSearchTool`
|
||||
- **API Integrations**: `SerperApiTool`, `EXASearchTool`
|
||||
- **API Integrations**: `SerperApiTool`, `ExaSearchTool`
|
||||
- **AI-powered Tools**: `DallETool`, `VisionTool`, `StagehandTool`
|
||||
|
||||
And many more robust tools to simplify your agent integrations.
|
||||
|
||||
@@ -76,7 +76,7 @@ from crewai_tools.tools.e2b_sandbox_tool import (
|
||||
E2BFileTool,
|
||||
E2BPythonTool,
|
||||
)
|
||||
from crewai_tools.tools.exa_tools.exa_search_tool import EXASearchTool
|
||||
from crewai_tools.tools.exa_tools.exa_search_tool import EXASearchTool, ExaSearchTool
|
||||
from crewai_tools.tools.file_read_tool.file_read_tool import FileReadTool
|
||||
from crewai_tools.tools.file_writer_tool.file_writer_tool import FileWriterTool
|
||||
from crewai_tools.tools.files_compressor_tool.files_compressor_tool import (
|
||||
@@ -258,6 +258,7 @@ __all__ = [
|
||||
"E2BPythonTool",
|
||||
"EXASearchTool",
|
||||
"EnterpriseActionTool",
|
||||
"ExaSearchTool",
|
||||
"FileCompressorTool",
|
||||
"FileReadTool",
|
||||
"FileWriterTool",
|
||||
|
||||
@@ -65,7 +65,7 @@ from crewai_tools.tools.e2b_sandbox_tool import (
|
||||
E2BFileTool,
|
||||
E2BPythonTool,
|
||||
)
|
||||
from crewai_tools.tools.exa_tools.exa_search_tool import EXASearchTool
|
||||
from crewai_tools.tools.exa_tools.exa_search_tool import EXASearchTool, ExaSearchTool
|
||||
from crewai_tools.tools.file_read_tool.file_read_tool import FileReadTool
|
||||
from crewai_tools.tools.file_writer_tool.file_writer_tool import FileWriterTool
|
||||
from crewai_tools.tools.files_compressor_tool.files_compressor_tool import (
|
||||
@@ -242,6 +242,7 @@ __all__ = [
|
||||
"E2BFileTool",
|
||||
"E2BPythonTool",
|
||||
"EXASearchTool",
|
||||
"ExaSearchTool",
|
||||
"FileCompressorTool",
|
||||
"FileReadTool",
|
||||
"FileWriterTool",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# EXASearchTool Documentation
|
||||
# ExaSearchTool Documentation
|
||||
|
||||
## Description
|
||||
This tool is designed to perform a semantic search for a specified query from a text's content across the internet. It utilizes the `https://exa.ai/` API to fetch and display the most relevant search results based on the query provided by the user.
|
||||
This tool lets CrewAI agents search the web using [Exa](https://exa.ai/), the fastest and most accurate web search API. By default the tool returns token-efficient highlights of the most relevant results for any query; you can also opt in to full page content.
|
||||
|
||||
## Installation
|
||||
To incorporate this tool into your project, follow the installation instructions below:
|
||||
@@ -10,21 +10,23 @@ uv add crewai[tools] exa_py
|
||||
```
|
||||
|
||||
## Example
|
||||
The following example demonstrates how to initialize the tool and execute a search with a given query:
|
||||
The following example demonstrates how to initialize the tool and run a search:
|
||||
|
||||
```python
|
||||
from crewai_tools import EXASearchTool
|
||||
from crewai_tools import ExaSearchTool
|
||||
|
||||
# Initialize the tool for internet searching capabilities
|
||||
tool = EXASearchTool(api_key="your_api_key")
|
||||
# Default: results with token-efficient highlights
|
||||
tool = ExaSearchTool(api_key="your_api_key", highlights=True)
|
||||
```
|
||||
|
||||
## Steps to Get Started
|
||||
To effectively use the `EXASearchTool`, follow these steps:
|
||||
To effectively use the `ExaSearchTool`, follow these steps:
|
||||
|
||||
1. **Package Installation**: Confirm that the `crewai[tools]` package is installed in your Python environment.
|
||||
2. **API Key Acquisition**: Acquire a `https://exa.ai/` API key by registering for a free account at `https://exa.ai/`.
|
||||
3. **Environment Configuration**: Store your obtained API key in an environment variable named `EXA_API_KEY` to facilitate its use by the tool.
|
||||
2. **API Key Acquisition**: Get an Exa API key from the [Exa dashboard](https://dashboard.exa.ai/api-keys).
|
||||
3. **Environment Configuration**: Store your API key in an environment variable named `EXA_API_KEY` so the tool can pick it up automatically.
|
||||
|
||||
## Conclusion
|
||||
By integrating the `EXASearchTool` into Python projects, users gain the ability to conduct real-time, relevant searches across the internet directly from their applications. By adhering to the setup and usage guidelines provided, incorporating this tool into projects is streamlined and straightforward.
|
||||
For details on choosing between highlights and full content, see the [Exa search best practices](https://exa.ai/docs/reference/search-best-practices).
|
||||
|
||||
## Note
|
||||
`EXASearchTool` is a deprecated alias for `ExaSearchTool`. Existing imports continue to work but emit a deprecation warning; please migrate to `ExaSearchTool`.
|
||||
|
||||
@@ -3,12 +3,19 @@ from __future__ import annotations
|
||||
from builtins import type as type_
|
||||
import os
|
||||
from typing import Any, TypedDict
|
||||
import warnings
|
||||
|
||||
from crewai.tools import BaseTool, EnvVar
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
from typing_extensions import Required
|
||||
|
||||
|
||||
try:
|
||||
from exa_py import Exa
|
||||
except ImportError:
|
||||
Exa = None # type: ignore[assignment,misc]
|
||||
|
||||
|
||||
class SearchParams(TypedDict, total=False):
|
||||
"""Parameters for Exa search API."""
|
||||
|
||||
@@ -18,7 +25,7 @@ class SearchParams(TypedDict, total=False):
|
||||
include_domains: list[str]
|
||||
|
||||
|
||||
class EXABaseToolSchema(BaseModel):
|
||||
class ExaBaseToolSchema(BaseModel):
|
||||
search_query: str = Field(
|
||||
..., description="Mandatory search query you want to use to search the internet"
|
||||
)
|
||||
@@ -31,14 +38,20 @@ class EXABaseToolSchema(BaseModel):
|
||||
)
|
||||
|
||||
|
||||
class EXASearchTool(BaseTool):
|
||||
EXABaseToolSchema = ExaBaseToolSchema
|
||||
|
||||
|
||||
class ExaSearchTool(BaseTool):
|
||||
model_config = ConfigDict(arbitrary_types_allowed=True)
|
||||
name: str = "EXASearchTool"
|
||||
description: str = "Search the internet using Exa"
|
||||
args_schema: type_[BaseModel] = EXABaseToolSchema
|
||||
name: str = "ExaSearchTool"
|
||||
description: str = (
|
||||
"Search the web with Exa, the fastest and most accurate web search API."
|
||||
)
|
||||
args_schema: type_[BaseModel] = ExaBaseToolSchema
|
||||
client: Any | None = None
|
||||
content: bool | None = False
|
||||
summary: bool | None = False
|
||||
content: bool | dict[str, Any] | None = False
|
||||
summary: bool | dict[str, Any] | None = False
|
||||
highlights: bool | dict[str, Any] | None = True
|
||||
type: str | None = "auto"
|
||||
package_dependencies: list[str] = Field(default_factory=lambda: ["exa_py"])
|
||||
api_key: str | None = Field(
|
||||
@@ -68,17 +81,17 @@ class EXASearchTool(BaseTool):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
content: bool | None = False,
|
||||
summary: bool | None = False,
|
||||
content: bool | dict[str, Any] | None = False,
|
||||
summary: bool | dict[str, Any] | None = False,
|
||||
highlights: bool | dict[str, Any] | None = True,
|
||||
type: str | None = "auto",
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
super().__init__(
|
||||
**kwargs,
|
||||
)
|
||||
try:
|
||||
from exa_py import Exa
|
||||
except ImportError as e:
|
||||
global Exa
|
||||
if Exa is None:
|
||||
import click
|
||||
|
||||
if click.confirm(
|
||||
@@ -88,12 +101,13 @@ class EXASearchTool(BaseTool):
|
||||
|
||||
subprocess.run(["uv", "add", "exa_py"], check=True) # noqa: S607
|
||||
|
||||
# Re-import after installation
|
||||
from exa_py import Exa
|
||||
from exa_py import Exa as _Exa
|
||||
|
||||
Exa = _Exa # type: ignore[misc]
|
||||
else:
|
||||
raise ImportError(
|
||||
"You are missing the 'exa_py' package. Would you like to install it?"
|
||||
) from e
|
||||
"You are missing the 'exa_py' package. Please install it to use ExaSearchTool."
|
||||
)
|
||||
|
||||
client_kwargs: dict[str, str] = {}
|
||||
if self.api_key:
|
||||
@@ -101,8 +115,10 @@ class EXASearchTool(BaseTool):
|
||||
if self.base_url:
|
||||
client_kwargs["base_url"] = self.base_url
|
||||
self.client = Exa(**client_kwargs)
|
||||
self.client.headers["x-exa-integration"] = "crewai"
|
||||
self.content = content
|
||||
self.summary = summary
|
||||
self.highlights = highlights
|
||||
self.type = type
|
||||
|
||||
def _run(
|
||||
@@ -126,10 +142,31 @@ class EXASearchTool(BaseTool):
|
||||
if include_domains:
|
||||
search_params["include_domains"] = include_domains
|
||||
|
||||
contents_kwargs: dict[str, Any] = {}
|
||||
if self.content:
|
||||
results = self.client.search_and_contents(
|
||||
search_query, summary=self.summary, **search_params
|
||||
contents_kwargs["text"] = self.content
|
||||
if self.highlights:
|
||||
contents_kwargs["highlights"] = self.highlights
|
||||
if self.summary:
|
||||
contents_kwargs["summary"] = self.summary
|
||||
|
||||
if contents_kwargs:
|
||||
return self.client.search_and_contents(
|
||||
search_query, **contents_kwargs, **search_params
|
||||
)
|
||||
else:
|
||||
results = self.client.search(search_query, **search_params)
|
||||
return results
|
||||
return self.client.search(search_query, **search_params)
|
||||
|
||||
|
||||
class EXASearchTool(ExaSearchTool):
|
||||
"""Deprecated alias for :class:`ExaSearchTool`. Kept for backwards compatibility."""
|
||||
|
||||
name: str = "ExaSearchTool"
|
||||
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
||||
warnings.warn(
|
||||
"EXASearchTool is deprecated and will be removed in a future release; "
|
||||
"use ExaSearchTool instead.",
|
||||
DeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import os
|
||||
from unittest.mock import patch
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from crewai_tools import EXASearchTool
|
||||
from crewai_tools import EXASearchTool, ExaSearchTool
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def exa_search_tool():
|
||||
return EXASearchTool(api_key="test_api_key")
|
||||
return ExaSearchTool(api_key="test_api_key")
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
@@ -22,11 +22,12 @@ def test_exa_search_tool_initialization():
|
||||
"crewai_tools.tools.exa_tools.exa_search_tool.Exa"
|
||||
) as mock_exa_class:
|
||||
api_key = "test_api_key"
|
||||
tool = EXASearchTool(api_key=api_key)
|
||||
tool = ExaSearchTool(api_key=api_key)
|
||||
|
||||
assert tool.api_key == api_key
|
||||
assert tool.content is False
|
||||
assert tool.summary is False
|
||||
assert tool.highlights is True
|
||||
assert tool.type == "auto"
|
||||
mock_exa_class.assert_called_once_with(api_key=api_key)
|
||||
|
||||
@@ -36,7 +37,7 @@ def test_exa_search_tool_initialization_with_env(mock_exa_api_key):
|
||||
with patch(
|
||||
"crewai_tools.tools.exa_tools.exa_search_tool.Exa"
|
||||
) as mock_exa_class:
|
||||
EXASearchTool()
|
||||
ExaSearchTool()
|
||||
mock_exa_class.assert_called_once_with(api_key="test_key_from_env")
|
||||
|
||||
|
||||
@@ -47,12 +48,13 @@ def test_exa_search_tool_initialization_with_base_url():
|
||||
) as mock_exa_class:
|
||||
api_key = "test_api_key"
|
||||
base_url = "https://custom.exa.api.com"
|
||||
tool = EXASearchTool(api_key=api_key, base_url=base_url)
|
||||
tool = ExaSearchTool(api_key=api_key, base_url=base_url)
|
||||
|
||||
assert tool.api_key == api_key
|
||||
assert tool.base_url == base_url
|
||||
assert tool.content is False
|
||||
assert tool.summary is False
|
||||
assert tool.highlights is True
|
||||
assert tool.type == "auto"
|
||||
mock_exa_class.assert_called_once_with(api_key=api_key, base_url=base_url)
|
||||
|
||||
@@ -67,7 +69,7 @@ def test_exa_search_tool_initialization_with_env_base_url(
|
||||
mock_exa_api_key, mock_exa_base_url
|
||||
):
|
||||
with patch("crewai_tools.tools.exa_tools.exa_search_tool.Exa") as mock_exa_class:
|
||||
EXASearchTool()
|
||||
ExaSearchTool()
|
||||
mock_exa_class.assert_called_once_with(
|
||||
api_key="test_key_from_env", base_url="https://env.exa.api.com"
|
||||
)
|
||||
@@ -79,8 +81,33 @@ def test_exa_search_tool_initialization_without_base_url():
|
||||
"crewai_tools.tools.exa_tools.exa_search_tool.Exa"
|
||||
) as mock_exa_class:
|
||||
api_key = "test_api_key"
|
||||
tool = EXASearchTool(api_key=api_key)
|
||||
tool = ExaSearchTool(api_key=api_key)
|
||||
|
||||
assert tool.api_key == api_key
|
||||
assert tool.base_url is None
|
||||
mock_exa_class.assert_called_once_with(api_key=api_key)
|
||||
|
||||
|
||||
def test_exa_search_tool_highlights_uses_search_and_contents():
|
||||
with patch("crewai_tools.tools.exa_tools.exa_search_tool.Exa") as mock_exa_class:
|
||||
mock_client = MagicMock()
|
||||
mock_exa_class.return_value = mock_client
|
||||
tool = ExaSearchTool(
|
||||
api_key="test_api_key", highlights={"max_characters": 4000}
|
||||
)
|
||||
|
||||
tool._run(search_query="hello world")
|
||||
|
||||
mock_client.search_and_contents.assert_called_once_with(
|
||||
"hello world",
|
||||
highlights={"max_characters": 4000},
|
||||
type="auto",
|
||||
)
|
||||
mock_client.search.assert_not_called()
|
||||
|
||||
|
||||
def test_exasearchtool_alias_is_deprecated():
|
||||
with patch("crewai_tools.tools.exa_tools.exa_search_tool.Exa"):
|
||||
with pytest.warns(DeprecationWarning, match="ExaSearchTool"):
|
||||
tool = EXASearchTool(api_key="test_api_key")
|
||||
assert isinstance(tool, ExaSearchTool)
|
||||
|
||||
@@ -774,7 +774,7 @@ def calculator(expression: str) -> str:
|
||||
```
|
||||
|
||||
### Built-in Tools (install with `uv add crewai-tools`)
|
||||
Web/Search: SerperDevTool, ScrapeWebsiteTool, WebsiteSearchTool, EXASearchTool, FirecrawlSearchTool
|
||||
Web/Search: SerperDevTool, ScrapeWebsiteTool, WebsiteSearchTool, ExaSearchTool, FirecrawlSearchTool
|
||||
Documents: FileReadTool, DirectoryReadTool, PDFSearchTool, DOCXSearchTool, CSVSearchTool, JSONSearchTool, XMLSearchTool, MDXSearchTool
|
||||
Code: CodeInterpreterTool, CodeDocsSearchTool, GithubSearchTool
|
||||
Media: DALL-E Tool, YoutubeChannelSearchTool, YoutubeVideoSearchTool
|
||||
|
||||
Reference in New Issue
Block a user