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

# Unified Web Search

> Built-in unified web search tool with automatic fallback across multiple providers

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent, search_web

agent = Agent(name="Researcher", tools=[search_web])
agent.start("Find recent news about renewable energy")
```

The user asks an open web question; the agent runs built-in web search and synthesises results.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    U[Input] --> A[Agent]
    A --> T[Tool]
    T --> O[Output]

    classDef agent fill:#8B0000,color:#fff
    classDef tool fill:#189AB4,color:#fff

    class A agent
    class U,O tool
    class T tool
```

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant User
    participant Agent
    participant Feature as Unified Web Search

    User->>Agent: Request
    Agent->>Feature: Process request
    Feature-->>Agent: Result
    Agent-->>User: Response
```

<Note>
  **Prerequisites**

  * Python 3.10 or higher
  * PraisonAI Agents package installed
  * At least one search provider configured (API key or package)
</Note>

The `search_web` tool provides a unified interface for web search that automatically tries multiple providers in order, falling back to the next if one fails.

## Quick Start

<Steps>
  <Step title="Install">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    pip install praisonaiagents duckduckgo_search
    ```
  </Step>

  <Step title="Search with agent">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent, search_web

    agent = Agent(
        name="SearchAgent",
        instructions="Search the web to answer questions accurately.",
        tools=[search_web],
    )

    agent.start("What happened in AI news today?")
    ```
  </Step>
</Steps>

## Search Provider Priority

| Priority | Provider   | Requirements                          |
| -------- | ---------- | ------------------------------------- |
| 1        | Tavily     | `TAVILY_API_KEY` + `tavily-python`    |
| 2        | Exa        | `EXA_API_KEY` + `exa_py`              |
| 3        | You.com    | `YDC_API_KEY` + `youdotcom`           |
| 4        | DuckDuckGo | `duckduckgo_search` (no API key)      |
| 5        | SearxNG    | `requests` + running SearxNG instance |

## Installation

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
pip install praisonaiagents

# Install at least one search provider:
pip install duckduckgo_search  # Free, no API key required
# OR
pip install tavily-python      # Requires TAVILY_API_KEY
# OR
pip install exa_py             # Requires EXA_API_KEY
# OR
pip install youdotcom          # Requires YDC_API_KEY
```

## Setup

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Optional: Set API keys for premium providers
export TAVILY_API_KEY=your_tavily_api_key
export EXA_API_KEY=your_exa_api_key
export YDC_API_KEY=your_ydc_api_key
export OPENAI_API_KEY=your_openai_api_key
```

## Basic Usage

### Simple Search

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import search_web

# Automatically uses the best available provider
results = search_web("AI trends 2025")

for r in results:
    print(f"Title: {r['title']}")
    print(f"URL: {r['url']}")
    print(f"Provider: {r['provider']}")
    print()
```

### With Max Results

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import search_web

results = search_web("Python programming tutorials", max_results=10)
```

### Specify Providers

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import search_web

# Only try specific providers in order
results = search_web(
    "machine learning",
    providers=["duckduckgo", "tavily"]
)
```

### Check Available Providers

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import get_available_providers

providers = get_available_providers()
for p in providers:
    status = "✓" if p["available"] else "✗"
    reason = p.get("reason", "") or ""
    print(f"{p['name']:12} {status} {reason}")
```

## With PraisonAI Agent

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent
from praisonaiagents import search_web

agent = Agent(
    name="SearchAgent",
    role="Web Researcher",
    goal="Find information on the web",
    tools=[search_web]
)

result = agent.start("What are the latest developments in quantum computing?")
print(result)
```

## Multi-Agent Research

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent, AgentTeam
from praisonaiagents import search_web

researcher = Agent(
    name="Researcher",
    role="Research Analyst",
    goal="Research topics thoroughly",
    tools=[search_web]
)

writer = Agent(
    name="Writer",
    role="Content Writer",
    goal="Write engaging content based on research"
)

agents = AgentTeam(agents=[researcher, writer])
result = agents.start("Research and write about AI trends in 2025")
print(result)
```

## Fallback Logic

For each provider in order:

1. **Check API key** (if required) → skip if not set
2. **Check package availability** → skip if not installed
3. **Try search** → on success, return results
4. **On failure** → log error and try next provider

This ensures your search always works as long as at least one provider is available.

## Response Format

Each result contains:

| Field      | Type | Description                                   |
| ---------- | ---- | --------------------------------------------- |
| `title`    | str  | Result title                                  |
| `url`      | str  | Result URL                                    |
| `snippet`  | str  | Result description/snippet                    |
| `provider` | str  | Name of the provider that returned the result |

## Error Handling

If all providers fail, returns a list with a single error dict:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
results = search_web("query")
if results and "error" in results[0]:
    print(f"Search failed: {results[0]['error']}")
```

## Parameters

| Parameter     | Type | Default  | Description                            |
| ------------- | ---- | -------- | -------------------------------------- |
| `query`       | str  | required | Search query string                    |
| `max_results` | int  | 5        | Maximum number of results              |
| `providers`   | list | None     | List of provider names to try in order |
| `searxng_url` | str  | None     | Custom SearxNG instance URL            |

## Key Points

* **Zero configuration**: Works with DuckDuckGo out of the box (no API key)
* **Automatic fallback**: Tries providers in order until one succeeds
* **Unified response**: Same response format regardless of provider
* **Provider info**: Each result includes which provider returned it
* **Graceful degradation**: Always returns results if any provider works

## Best Practices

<AccordionGroup>
  <Accordion title="Install DuckDuckGo as minimum fallback">
    Run `pip install duckduckgo_search` to ensure `search_web` always has at least one provider.
  </Accordion>

  <Accordion title="Order providers by quality">
    Configure `providers=['tavily', 'exa', 'duckduckgo']` - paid providers first for higher quality.
  </Accordion>

  <Accordion title="Check provider availability at startup">
    Call `get_available_providers()` on startup to log which providers are active.
  </Accordion>

  <Accordion title="Use max_results=5 for most tasks">
    Five results gives enough context for most agent tasks - more results increase token usage.
  </Accordion>
</AccordionGroup>

## Related

<CardGroup cols={2}>
  <Card title="Custom Tools" icon="wrench" href="/docs/tools/custom">
    Build your own agent tools
  </Card>

  <Card title="Tools Overview" icon="toolbox" href="/docs/tools/tools">
    Browse PraisonAI tool documentation
  </Card>
</CardGroup>
