> This page is for version 0.7.0.
> For other versions, use one of these documentation indexes:
> - Main (default): https://docs.nvidia.com/nemo/gym/main/llms.txt
> - 0.7.0: https://docs.nvidia.com/nemo/gym/v0.7.0/llms.txt
> - 0.6.0: https://docs.nvidia.com/nemo/gym/v0.6.0/llms.txt
> - 0.5.1: https://docs.nvidia.com/nemo/gym/v0.5.1/llms.txt
> - 0.5.0: https://docs.nvidia.com/nemo/gym/v0.5.0/llms.txt
> - 0.4.0: https://docs.nvidia.com/nemo/gym/v0.4.0/llms.txt
> - 0.3.0: https://docs.nvidia.com/nemo/gym/v0.3.0/llms.txt
> - 0.2.1: https://docs.nvidia.com/nemo/gym/v0.2.1/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/nemo/gym/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nemo/gym/_mcp/server.

# Tavily Search Access and Setup

> Configure search credentials, an exclusion policy, and evaluation inputs for Tavily search.

# Tavily Search Access and Setup

The [Tavily resources server](https://github.com/NVIDIA-NeMo/Gym/tree/main/resources_servers/tavily_search)
requires a Tavily key, a local domain-exclusion policy, and a policy model.
Judge-enabled configs also need a judge model.

## Access requirements

Before running the resources server, arrange authorized access to:

* A Tavily API key and sufficient quota; see the [Tavily quickstart](https://docs.tavily.com/documentation/quickstart).
* An exclusion-policy artifact approved for your use case, with its version,
  checksum, and refresh requirements.
* Policy-model and judge-model endpoints and credentials.

Obtain credentials and policy artifacts through your organization's approved
access processes. The server host needs network access to each service. Keep
credentials separate and out of source control and logs.

> **Note**
>
> For general setup questions, [contact the maintainers](https://github.com/NVIDIA-NeMo/Gym/issues/new/choose).
> Use approved private channels to exchange credentials or restricted policy contents.

## Exclusion policy

Obtain the approved JSON from its owner and place it at an absolute path readable
by the resources-server process, including inside its container if applicable.
Set `TAVILY_EXCLUDE_DOMAINS_FILE` to that path and compare its SHA-256 with the
owner-provided checksum. Record the version and follow the owner's instructions
for downloading and refreshing this file.

The [parser](https://github.com/NVIDIA-NeMo/Gym/blob/main/resources_servers/tavily_search/app.py)
reads a `notices` list containing `properties` entries with `type: "domain"`
and `value`. Use the complete, unmodified approved policy. If the file is missing
or fails to load, request a compatible approved artifact from its owner.

## Configure services

Add these references to the repo-root, gitignored `env.yaml`, matching the
[shipped vLLM-judge config](https://github.com/NVIDIA-NeMo/Gym/blob/main/resources_servers/tavily_search/configs/tavily_search_judge_vllm_model.yaml):

```yaml
tavily_api_key: ${oc.env:TAVILY_API_KEY}
exclude_domains_file_path: ${oc.env:TAVILY_EXCLUDE_DOMAINS_FILE}
search_judge_model_base_url: ${oc.env:SEARCH_JUDGE_MODEL_BASE_URL}
search_judge_model_api_key: ${oc.env:SEARCH_JUDGE_MODEL_API_KEY}
search_judge_model_name: Qwen/Qwen3-235B-A22B-Instruct-2507
```

Supply the environment variables through your credential workflow. The endpoint
must serve the named judge model; leave its key empty only if the operator confirms
unauthenticated access. Configure the policy model separately using the
[vLLM guide](/main/model-server/vllm).

## Datasets

For a small setup check, use the committed
[example dataset](https://github.com/NVIDIA-NeMo/Gym/blob/main/resources_servers/tavily_search/data/example.jsonl).
For larger evaluations, provide a dataset you are authorized to use and pass
its local JSONL path to `gym eval run --input`.

The shipped vLLM-judge config also declares train and validation datasets with
registry metadata. Those entries require separately provisioned data and access;
they are not prerequisites for running the committed example. For your own
training setup, update the dataset paths and source metadata to match your data.
See [dataset configuration](/main/reference/configuration#dataset-configuration).

## Run

With Gym installed and the prerequisites configured:

```bash
gym env start \
    --resources-server tavily_search/tavily_search_judge_vllm_model \
    --model-type vllm_model
```

In another terminal, run the committed example against those servers:

```bash
gym eval run --no-serve \
    --agent tavily_search_simple_agent \
    --input resources_servers/tavily_search/data/example.jsonl \
    --output results/tavily_search_example_rollouts.jsonl \
    --num-repeats 1 \
    --concurrency 1
```

Before scaling up, run a small [evaluation](/main/evaluation/benchmarks) and inspect
the search response, policy exclusions, and judge result to validate the workflow.

## Tool-service behavior and compatibility

The same resource exposes `web_search`, `find_in_page`, and `scroll_page` to native
harnesses when `expose_tools_over_mcp: true`. Credentials remain in the resource
process. `tavily_api_key` accepts one key, a list, or a comma-separated pool;
requests and retries rotate through the pool.

Search defaults to 10 results, advanced search, and 2,000-character snippets,
configured through `max_results`, `search_depth`, and `max_result_chars`.
Exclusion JSON uses `notices[].properties[]` entries of type `domain` or
`url_substring`; domain matches include subdomains. Provider error bodies are
neither forwarded to models nor logged.

These behaviors apply to all Tavily configurations:

* Search requests disable Tavily's aggregate answer, and returned aggregate answers
  are discarded. The former `Search Answer` output section is removed because its
  sources cannot be checked against the local policy; agents receive source results.
* Requested and returned URLs, including reported extraction redirects, are checked
  against domain and `url_substring` exclusions. Author/publisher metadata is not
  enforced. A finite exclusion list cannot prevent all online answer exposure.
  Invalid exclusion domains reject the policy at startup with the file and domain
  identified; entries are never silently dropped.
* Rate-limit retries are bounded rather than indefinite. `max_http_attempts` defaults
  to 3 total attempts; retryable HTTP failures, connection errors, incomplete response
  bodies, and timeouts share this budget. Retries use exponential delays starting at
  one second and rotate keys. `http_timeout_s` defaults to 60 seconds per attempt; a shorter
  SDK timeout takes precedence. Exhaustion raises a tool-service error instead of
  returning an empty search. Under sustained rate limits, reduce concurrency or
  explicitly increase the attempt budget.
* Invalid-key (401) and exhausted-quota (432/433) responses try another configured
  key within that same attempt budget. A rejected key is skipped for the rest of
  the current call; if no alternative remains, the call fails immediately.
  Keys are reconsidered on subsequent calls so replenished quota or restored
  access does not require restarting the server. Other non-retryable client errors
  still fail immediately. See [Tavily's error codes](https://help.tavily.com/articles/8645538886-understanding-http-errors).
* The page cache evicts the least recently used page at `max_cached_pages`
  (default 128); zero disables it.
  `max_cached_page_chars` limits stored page content and applies only when caching
  is enabled (including the initial response). `max_scroll_words` caps each response
  independently of caching.