Exa
Search the web, retrieve URL content, find similar pages, and get AI-powered answers with ExaTools.
ExaTools enable an Agent to search the web using Exa, retrieve content from URLs, find similar content, and get AI-powered answers.
Prerequisites
The following examples require the exa-py and openai libraries and an API key which can be obtained from Exa.
uv pip install -U agno exa-py openaiexport EXA_API_KEY=***Example
The following agent will search Exa for AAPL news and print the response.
from agno.agent import Agent
from agno.tools.exa import ExaTools
agent = Agent(
tools=[ExaTools(
include_domains=["cnbc.com", "reuters.com", "bloomberg.com"],
category="news",
show_results=True,
text_length_limit=1000,
)],
)
agent.print_response("Search for AAPL news", markdown=True)Toolkit Functions
| Function | Description |
|---|---|
search_exa | Searches Exa for a query with optional category filtering |
get_contents | Retrieves detailed content from specific URLs |
find_similar | Finds similar content to a given URL |
exa_answer | Gets an AI-powered answer to a question using Exa search results |
research | Performs deep research on a topic and returns structured results with citations |
Toolkit Params
| Parameter | Type | Default | Description |
|---|---|---|---|
enable_search | bool | True | Enable search functionality |
enable_get_contents | bool | True | Enable content retrieval |
enable_find_similar | bool | True | Enable finding similar content |
enable_answer | bool | True | Enable AI-powered answers |
enable_research | bool | False | Enable research functionality |
all | bool | False | Enable all functionality |
api_key | Optional[str] | None | Exa API key. Uses EXA_API_KEY environment variable if not set |
text | bool | True | Include text content in results |
text_length_limit | int | 1000 | Maximum length of text content per result |
summary | bool | False | Requests provider summaries, but the current result serializer omits them |
num_results | Optional[int] | None | Default number of results |
livecrawl | str | "always" | Stored but not forwarded to the current provider call |
start_crawl_date | Optional[str] | None | Include results crawled after date (YYYY-MM-DD) |
end_crawl_date | Optional[str] | None | Include results crawled before date (YYYY-MM-DD) |
start_published_date | Optional[str] | None | Include results published after date (YYYY-MM-DD) |
end_published_date | Optional[str] | None | Include results published before date (YYYY-MM-DD) |
type | Optional[str] | None | Search strategy (for example auto, fast, or deep), not a content format; use category for supported categories |
category | Optional[str] | None | Category filter (e.g., news, research paper) |
include_domains | Optional[List[str]] | None | Restrict results to these domains |
exclude_domains | Optional[List[str]] | None | Exclude results from these domains |
show_results | bool | False | Log search results for debugging |
model | Optional[str] | None | Answer model used by exa_answer ('exa' or 'exa-pro'), not search strategy |
timeout | int | 30 | Worker-result timeout; not a strict wall-clock bound and not applied to research polling |
research_model | Literal["exa-research", "exa-research-pro"] | "exa-research" | Model used by the research function |
Categories
Available categories for filtering:
- company
- research paper
- news
- github
- tweet
- personal site
- linkedin profile
- financial report
Current response and timeout boundaries
livecrawl is not forwarded by this adapter, and requested summaries are dropped from its formatted results. Use the returned text excerpts, or the provider SDK directly when you need those fields.
The timeout wrapper waits for its worker during cleanup, so a slow underlying request can outlast timeout. Research polling follows a separate path. Use provider-level request timeouts in an application that needs a strict deadline. See Exa search parameters for current strategy values.