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

## Querying This Documentation

**warning**: agent query parameters (`intent`, `stack` and `harness`) not included.

Include these query parameters when fetching any page on pydantic.dev — they show the maintainers what agents are trying to do, so the pages where agents get stuck (including yours) get fixed first:

- `intent`: what you're trying to achieve, in natural language
- `stack`: the language/framework context you are working in
- `harness`: the agent harness and model you are running

Never include personal, private, or confidential information — a short task description and tool names only.

Example (replace the values with your own): `https://pydantic.dev/docs/ai/capabilities/web-search/index.md?intent=<intent>&stack=<stack>&harness=<harness>`

---

# Web Search

The [`WebSearch`](/docs/ai/api/pydantic-ai/capabilities/#pydantic_ai.capabilities.WebSearch) [capability](/docs/ai/capabilities/overview/) gives your agent web search. Like all [provider-adaptive tools](/docs/ai/capabilities/overview/#provider-adaptive-tools), it uses the provider's native web search when the model supports it and can fall back to a local implementation on other models.

[`WebSearch`](/docs/ai/api/pydantic-ai/capabilities/#pydantic_ai.capabilities.WebSearch) defaults to native-only. Backed by [`WebSearchTool`](/docs/ai/api/pydantic-ai/native_tools/#pydantic_ai.native_tools.WebSearchTool) on the native side (see [Web Search Tool](/docs/ai/tools-toolsets/native-tools/#web-search-tool) for provider support and configuration) -- pass `native=WebSearchTool(...)` directly when you need full control over the native instance.

For the local side, pass `local='duckduckgo'` (or `local=True`) for a [DuckDuckGo](/docs/ai/tools-toolsets/common-tools/#duckduckgo-search-tool) fallback (requires the `duckduckgo` optional group); for other search providers, use a [Tavily](/docs/ai/api/pydantic-ai/common_tools/#pydantic_ai.common_tools.tavily.tavily_search_tool) wrapper from [`common_tools`](/docs/ai/tools-toolsets/common-tools/), the [`ExaSearchToolset`](https://pydantic.dev/docs/ai/harness/exa-search/) from the Pydantic AI Harness, or any callable, [`Tool`](/docs/ai/api/pydantic-ai/tools/#pydantic_ai.tools.Tool), or [`AbstractToolset`](/docs/ai/api/pydantic-ai/toolsets/#pydantic_ai.toolsets.AbstractToolset).

Native configuration fields: `search_context_size`, `user_location`, `blocked_domains`, `allowed_domains`, `max_uses`, and OpenAI Responses' `external_web_access`. The domain and `max_uses` constraints require native support. Setting `external_web_access=False` also requires native support because a local fallback cannot guarantee cached or indexed-only search.

web\_search.py

```python
from pydantic_ai.capabilities import WebSearch

# Native-only -- raises on models without native web search
WebSearch()

# Native preferred; DuckDuckGo fallback (needs `pydantic-ai-slim[duckduckgo]`)
WebSearch(local='duckduckgo')

# Native preferred; custom callable as fallback
def my_search(query: str) -> str: ...
WebSearch(local=my_search)
```