Skip to main content

Introduction

WebToolset gives an agent web_search and web_fetch tools without tying your environment to a particular search provider. Which provider actually answers is process configuration, not code:
The environment stays identical either way. Input validation, the citation envelope the model sees, the fetch cache and the error contract all live in the SDK and are shared by every backend — so a task written against one backend behaves the same against another. Only the sources differ.
Requires openreward >= 0.1.148. The Tavily backend also needs pip install 'openreward[search]'; the default backsearch backend needs nothing beyond the base install.

Which toolset should I use?

BackSearchToolset deliberately ignores OPENREWARD_SEARCH_BACKEND. A toolset whose whole value is the leakage-free guarantee should not be silently redirected to the live web by an environment variable.

Configuration

A backend that is missing its key is not a startup failure — the session still opens, and the problem surfaces on the first tool call. What happens then depends on whether the agent could plausibly recover; see below.

Fatal vs recoverable errors

WebToolset splits tool failures in two, and the distinction matters for training data:
  • Recoverable — a blocked domain, an unparseable URL, an empty result set. These come back to the model as ordinary tool output with the code in metadata["error"], because the agent can act on them by searching differently or picking another source. An empty result set is a real answer to the query, not a failure.
  • Fatalnot-configured (no API key) or quota-exceeded. These raise SearchBackendUnavailable.
The reason for raising: handed back as text, the agent re-issues a dead call until it hits the turn cap, never reaches the terminal tool, and the rollout scores 0.0 — indistinguishable from a model that answered wrongly. Raising lets the platform retry the tool call and, if it still fails, end the rollout with a blank reward, which is excluded from training rather than poisoning it. Pass raise_on_fatal=False to get the everything-is-soft behaviour. BackSearchToolset is unchanged and always soft-errors.

Backends

Tavily searches the live web, so as_of is ignored. Tavily does offer publish-date filters, but they filter a live index by claimed publish date rather than serving a frozen crawl, so they cannot give the leakage-free guarantee an evaluation or prediction task needs. Rather than imply a guarantee we cannot keep, the cutoff is dropped and a warning is logged the first time one is requested. If post-cutoff leakage would invalidate your task, stay on backsearch.
allowed_domains is not a hard guarantee on Tavily. It maps to Tavily’s include_domains, which filters correctly for indexed domains — but when the requested domain is absent from Tavily’s index, Tavily silently returns unfiltered results rather than an empty set. Asking for reuters.com, for example, comes back with results from other sites entirely. If your task depends on sources being restricted to a domain, verify the hostnames yourself, or use backsearch, where the filter is applied by the index.
The tool descriptions the model sees follow the configured backend: on a live-web backend the “results are limited to documents published on or before the cutoff date” wording is removed, so the model is never told about a bound that will not hold.

Using the toolset in an environment

Declare WebToolset at class level. Like BackSearchToolset it is not sandbox-backed — it talks to a search provider over HTTP — so your environment does not need a self.sandbox.
The agent then sees two tools:

Selecting it by name in a session

WebToolset is a registered built-in, so a client can attach it to a session by name:

Passing credentials as session secrets

Environments conventionally receive API keys through the session secrets mapping rather than the server’s process environment. Expose them to the toolset with a search_secrets hook and the configured backend picks out the key it needs — tavily_api_key for Tavily, api_key for backsearch:
Without the hook the backend falls back to the process environment. See Keeping Secrets Secret for how secret values reach a hosted environment.

Choosing the backend per environment

OPENREWARD_SEARCH_BACKEND is the usual control, but an environment can pin or override it with a search_backend hook — read live on every tool call, like web_as_of:
Resolution order for each call: an explicit backend= passed to the toolset constructor, then env.search_backend, then OPENREWARD_SEARCH_BACKEND, then backsearch.

Composing with other toolsets

Because it needs no sandbox, WebToolset composes cleanly with sandbox-backed toolsets:
Do not declare WebToolset and BackSearchToolset together — they expose the same tool names and the framework rejects duplicates.

Standalone usage

The same search and fetch are available without an environment:
Both run(...) calls return a WebToolResult: Error codes are the same on every backend, so calling code can branch on them without knowing which provider is configured:

Adding your own backend

Backends live in a registry, so a new provider does not require changes to the engine or to any environment:
Two rules make backends interchangeable:
  • Render through the shared helpers (format_search_output, render_fetch_text) and validate through the shared validators (validate_search_input, validate_fetch_url). Models are trained on the exact output shape, and identical inputs must produce identical error codes.
  • Never raise for a recoverable problem. Return WebToolResult.error(code, message) so the agent can read it and try something else.

Notes

  • Citations. Search output is formatted so the model is reminded to cite the returned URLs as markdown links in its final answer.
  • Caching. Fetches are cached in-process for 15 minutes. Cache keys are namespaced per backend (and, for backdated backends, per cutoff), so a live page is never served out of a backdated fetch’s entry or vice versa.
  • Soft errors. Bad inputs come back as a normal result with .ok == False and a clear message rather than as an exception.

Next Steps

Backdated Web Tools

The point-in-time corpus, and the toolset pinned to it

Using Toolsets

Compose document toolsets and build custom ones

Backdated Search API

Call the search and fetch endpoints directly over HTTP

Keeping Secrets Secret

How API keys and secrets reach your environment