Daita Logo

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

  1. Create an Exa account at exa.ai
  2. Get an API key from the dashboard
  3. Set the environment variable:
bash
export EXA_API_KEY=your-key
  1. 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 to EXA_API_KEY.
  • num_results (int): Default number of results to return. Defaults to 5.
  • search_type (str): Search mode. One of "auto", "neural", "fast", or "keyword".
  • include_text (bool): Include full page text in each result. Defaults to False.
  • include_highlights (bool): Include Exa-generated highlights. Defaults to True.
  • include_summary (bool): Include Exa-generated summaries. Defaults to False.
  • max_text_chars (int): Maximum text characters per result when include_text=True.
  • category (str): Optional default category filter.
  • include_domains (List[str]): Optional default domain allowlist.
  • exclude_domains (List[str]): Optional default domain blocklist.
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

ToolDescriptionParameters
search_webSemantic web search with optional content fieldsquery (required), num_results, search_type, category, include_domains, exclude_domains, start_published_date, end_published_date
find_similarFind pages semantically similar to a URLurl (required), num_results, include_text, include_highlights, include_summary

Tool Category: search Tool Source: plugin Plugin Name: ExaSearch

#Search Types

TypeUse when
autoYou want Exa to choose the best search mode for the query.
neuralYou want semantic ranking for conceptual or research-heavy questions.
fastYou want lower-latency search for straightforward lookups.
keywordYou need lexical matching for exact terms, names, identifiers, or codes.

#Category Filters

Supported categories:

  • company
  • research paper
  • news
  • personal site
  • financial report
  • people

#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:

ConditionError type
Rate limit or HTTP 429RateLimitError
Invalid or missing API keyAuthenticationError
Forbidden or bad requestPermanentError
Request timeoutTimeoutError
Network or connection issueConnectionError
Temporary service issueTransientError
Other search execution errorRetryableError

#Best Practices

  • Use EXA_API_KEY instead of hardcoding secrets.
  • Keep include_text=False unless the agent needs full page content.
  • Use include_highlights=True for 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.