> ## Documentation Index
> Fetch the complete documentation index at: https://exa.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> The Exa API is served at https://api.exa.ai. Authenticate with `Authorization: Bearer $EXA_API_KEY` (or `x-api-key: $EXA_API_KEY`); create keys at https://dashboard.exa.ai/api-keys?utm_source=docs&utm_medium=docs&utm_campaign=markdown_instructions. Every way an agent can get access to Exa is described at https://exa.ai/auth.md.
> Prefer the official SDKs, `exa-py` (`pip install exa-py`) and `exa-js` (`npm install exa-js`); both read `EXA_API_KEY` from the environment.
> Tool-using agents can call Exa without writing code through the hosted MCP server at https://mcp.exa.ai/mcp, or install the Exa agent skill with `npx skills add exa-labs/agent-skills` (skill file: https://exa.ai/docs/skill.md).
> The OpenAPI specs at https://exa.ai/docs/exa-spec.yaml and https://exa.ai/docs/team-management-spec.yaml are the source of truth for request and response schemas.

# CrewAI

> Learn how to add Exa retrieval capabilities to your CrewAI agents.

> [card] [Coding Agent Quickstart](https://dashboard.exa.ai/onboarding?utm_source=docs\&utm_medium=docs\&utm_campaign=coding_agent_quickstart_card)
>
> New to Exa? Get started in under a minute.

***

[CrewAI](https://crewai.com/) is a framework for orchestrating AI agents that work together to accomplish complex tasks.
In this guide, we'll create a crew of two agents that generate a newsletter based on Exa's search results. We'll go over how to:

1. Create a custom Exa-powered CrewAI tool
2. Set up agents and assign them specific roles that use the Exa-powered search tool
3. Organize the agents into a crew that will write a newsletter

> [!NOTE]
>
> CrewAI also ships a built-in [`ExaSearchTool`](https://docs.crewai.com/en/tools/search-research/exasearchtool) you can drop in without writing a custom wrapper. The custom tool below is useful if you want full control over how results are formatted; either approach works.

***

## Get started

**1. Prerequisites and installation**

Install the crewAI core, crewAI tools and Exa Python SDK libraries.

```bash Python theme={null}
pip install crewai 'crewai[tools]' exa_py

# Or, if using uv:
uv add crewai 'crewai[tools]' exa_py
```

**2. Defining a custom Exa-based tool in crewAI**

We set up a [custom tool](https://docs.crewai.com/concepts/tools) using the crewAI [@tool decorator ](https://docs.crewai.com/concepts/tools#utilizing-the-tool-decorator). Within the tool, we can initialize the Exa class from the [Exa Python SDK](https://github.com/exa-labs/exa-py), make a request, and return a parsed out result.

```Python Python theme={null}
from crewai_tools import tool
from exa_py import Exa
import os

exa_api_key = os.getenv("EXA_API_KEY")

@tool("Exa search and get contents")
def search_and_get_contents_tool(question: str) -> str:
    """Tool using Exa's Python SDK to run semantic search and return result highlights."""

    exa = Exa(api_key=exa_api_key)

    response = exa.search(
        question,
        type="auto",
        num_results=10,
        contents={"highlights": True}
    )

    parsedResult = ''.join([
      f'<Title id={idx}>{eachResult.title}</Title>'
      f'<URL id={idx}>{eachResult.url}</URL>'
      f'<Highlight id={idx}>{"".join(eachResult.highlights)}</Highlight>'
      for (idx, eachResult) in enumerate(response.results)
    ])

    return parsedResult
```

> [!NOTE]
>
> Make sure your API keys are initialized properly. For this demonstration, the environment variable names are `OPENAI_API_KEY` and `EXA_API_KEY` for OpenAI and Exa keys respectively.

> [card] [Get your Exa API key](https://dashboard.exa.ai/api-keys?utm_source=docs\&utm_medium=docs\&utm_campaign=get_key_card)
>
> Create a key in the dashboard. New accounts start with free credits.

**3. Setting up a crewAI agent**

Import the relevant crewAI modules. Then, define `exa_tools` to reference the custom search method we defined above.

```Python Python theme={null}
from crewai import Task, Crew, Agent

exa_tools = search_and_get_contents_tool
```

We then set up[ two agents](https://docs.crewai.com/concepts/Agents/) and place them in a [crew together](https://docs.crewai.com/concepts/Crews/):

* One to research with Exa (providing the custom tool defined above)
* Another to write a newsletter as an output (using an LLM)

```Python Python theme={null}
# Creating a senior researcher agent with memory and verbose mode
researcher = Agent(
  role='Researcher',
  goal='Get the latest research on {topic}',
  verbose=True,
  memory=True,
  backstory=(
    "Driven by curiosity, you're at the forefront of"
    "innovation, eager to explore and share knowledge that could change"
    "the world."
  ),
  tools=[exa_tools],
  allow_delegation=False
)

article_writer = Agent(
  role='Writer',
  goal='Write a great newsletter article on {topic}',
  verbose=True,
  memory=True,
  backstory=(
    "Driven by a love of writing and passion for"
    "innovation, you are eager to share knowledge with"
    "the world."
  ),
  tools=[exa_tools],
  allow_delegation=False
)
```

**4. Defining tasks for the agents**

Next, we'll define [tasks](https://docs.crewai.com/concepts/Tasks/) for each agent and create the crew overall using all of the components we've set up above.

```Python Python theme={null}
research_task = Task(
  description=(
    "Identify the latest research in {topic}."
    "Your final report should clearly articulate the key points,"
  ),
  expected_output='A comprehensive 3 paragraphs long report on the {topic}.',
  tools=[exa_tools],
  agent=researcher,
)

write_article = Task(
  description=(
    "Write a newsletter article on the latest research in {topic}."
    "Your article should be engaging, informative, and accurate."
    "The article should address the audience with a greeting to the newsletter audience \"Hi readers!\", plus a similar signoff"
  ),
  expected_output='A comprehensive 3 paragraphs long newsletter article on the {topic}.',
  agent=article_writer,
)

crew = Crew(
  agents=[researcher, article_writer],
  tasks=[research_task, write_article],
  memory=True,
  cache=True,
  max_rpm=100,
  share_crew=True
)
```

**5. Kicking off the crew**

Finally, we kick off the crew by providing a research topic as our input query.

```Python Python theme={null}
response = crew.kickoff(inputs={'topic': 'Latest AI research'})

print(response)
```

The crew writes the newsletter from the content the Exa search tool returned.
