Exa Search Plugin
AI-powered semantic web search and URL similarity search for agents. Built on the Exa API.
#Installation
Install with the Exa extra:
bash
pip install 'daita-agents[exa]'Or install the SDK dependency directly:
bash
pip install exa-py#Quick Start
python
import os
from daita import Agent
from daita.plugins import exa_search
# Uses EXA_API_KEY from the environment
search = exa_search()
agent = Agent(
name="Research Assistant",
prompt="You are a research assistant. Use search when current or sourced information matters.",
tools=[search],
model="gpt-4o-mini",
)
await agent.start()
result = await agent.run("Find recent research on agent evaluation systems.")
await agent.stop()#Getting Started with Exa
- Create an Exa account at exa.ai
- Get an API key from the dashboard
- Set the environment variable:
bash
export EXA_API_KEY=your-key- Create the plugin with
exa_search()
#Direct Usage
Use the plugin directly when you need programmatic search without an agent:
python
from daita.plugins import exa_search
async with exa_search(num_results=5, search_type="auto") as search:
results = await search.search(
"Python async best practices",
include_highlights=True,
include_summary=True,
)
for result in results["results"]:
print(result["title"])
print(result["url"])
print(result["snippet"])#Connection Parameters
python
exa_search(
api_key: Optional[str] = None,
num_results: int = 5,
search_type: str = "auto",
include_text: bool = False,
include_highlights: bool = True,
include_summary: bool = False,
max_text_chars: int = 1000,
category: Optional[str] = None,
include_domains: Optional[List[str]] = None,
exclude_domains: Optional[List[str]] = None,
**kwargs,
)#Parameters
api_key(str): Exa API key. Defaults toEXA_API_KEY.num_results(int): Default number of results to return. Defaults to5.search_type(str): Search mode. One of"auto","neural","fast", or"keyword".include_text(bool): Include full page text in each result. Defaults toFalse.include_highlights(bool): Include Exa-generated highlights. Defaults toTrue.include_summary(bool): Include Exa-generated summaries. Defaults toFalse.max_text_chars(int): Maximum text characters per result wheninclude_text=True.category(str): Optional default category filter.include_domains(List[str]): Optional default domain allowlist.exclude_domains(List[str]): Optional default domain blocklist.
#Search
python
async with exa_search() as search:
results = await search.search(
query="latest vector database benchmarks",
num_results=10,
search_type="neural",
category="research paper",
include_domains=["arxiv.org"],
start_published_date="2025-01-01",
include_highlights=True,
include_summary=True,
)search() returns:
python
{
"success": True,
"query": "latest vector database benchmarks",
"results": [
{
"title": "...",
"url": "...",
"snippet": "...",
"score": 0.91,
"published_date": "...",
"author": "...",
"text": "...",
"highlights": ["..."],
"summary": "...",
}
],
"count": 1,
}#Find Similar Pages
Use find_similar() when you have one useful source and want related pages:
python
async with exa_search(num_results=5) as search:
related = await search.find_similar(
"https://example.com/reference-article",
include_highlights=True,
include_summary=True,
)#Using with Agents
Exa exposes search operations as tools that agents can call autonomously:
python
import os
from daita import Agent
from daita.plugins import exa_search
search = exa_search(
api_key=os.getenv("EXA_API_KEY"),
num_results=6,
search_type="auto",
include_highlights=True,
include_summary=True,
)
agent = Agent(
name="Market Researcher",
prompt="""You are a careful research agent.
Use search_web for current information and find_similar when a source looks useful.
Prefer authoritative sources, compare multiple results, and include URLs in the answer.
""",
tools=[search],
model="gpt-4o-mini",
)
await agent.start()
result = await agent.run("Research recent adoption trends for lakehouse architectures.")
await agent.stop()#Available Tools
| Tool | Description | Parameters |
|---|---|---|
| search_web | Semantic web search with optional content fields | query (required), num_results, search_type, category, include_domains, exclude_domains, start_published_date, end_published_date |
| find_similar | Find pages semantically similar to a URL | url (required), num_results, include_text, include_highlights, include_summary |
Tool Category: search
Tool Source: plugin
Plugin Name: ExaSearch
#Search Types
| Type | Use when |
|---|---|
auto | You want Exa to choose the best search mode for the query. |
neural | You want semantic ranking for conceptual or research-heavy questions. |
fast | You want lower-latency search for straightforward lookups. |
keyword | You need lexical matching for exact terms, names, identifiers, or codes. |
#Category Filters
Supported categories:
companyresearch papernewspersonal sitefinancial reportpeople
#Domain and Date Filters
python
async with exa_search() as search:
results = await search.search(
"OpenAI structured outputs",
include_domains=["openai.com"],
exclude_domains=["community.example.com"],
start_published_date="2025-01-01",
end_published_date="2026-01-01",
)Domain filters are useful when an agent should stay close to primary sources or avoid low-signal sites. Date filters are useful for news, market research, and rapidly changing technical topics.
#Error Handling
The plugin maps Exa/API failures into Daita's error hierarchy:
| Condition | Error type |
|---|---|
| Rate limit or HTTP 429 | RateLimitError |
| Invalid or missing API key | AuthenticationError |
| Forbidden or bad request | PermanentError |
| Request timeout | TimeoutError |
| Network or connection issue | ConnectionError |
| Temporary service issue | TransientError |
| Other search execution error | RetryableError |
#Best Practices
- Use
EXA_API_KEYinstead of hardcoding secrets. - Keep
include_text=Falseunless the agent needs full page content. - Use
include_highlights=Truefor concise source evidence. - Use domain filters for trusted-source research.
- Use
find_similar()to expand from a high-quality source. - Prefer
search_type="auto"unless you know the query needs semantic or exact matching.
#Related
- WebSearch Plugin - Tavily-backed web search, news search, and URL fetching
- Agent - Adding plugins to agents
- Error Handling - Daita exception types and retry behavior