Skip to main content

Overview

Synthetic Worlds let you develop and test agents that use tools — without calling the real tools. Instead of hitting live APIs, databases, or services, your tool calls get realistic responses generated on the fly. This is useful when:
  • Real tools are slow or expensive — external APIs, database writes, third-party services
  • You need deterministic behavior — reproducible runs for debugging and CI
  • The real service doesn’t exist yet — build your agent against the contract, not the implementation
  • You want to test failure handling — simulate timeouts, errors, and rate limits

How it works

You create a world — an isolated session that intercepts your tool calls and returns generated responses. Define your tools as normal Python functions with type hints. The SDK extracts the schema automatically and sends it to the backend, which generates a realistic response that matches the return type.
When the with block exits, the world is destroyed and resources are freed.

Setup

1. Set environment variables

2. Create a world and register tools

Or use the context manager (recommended):

Registering tools

Using the @world.tool decorator

The simplest way. Your function’s type hints and docstring become the tool schema automatically:
The SDK extracts:
  • name from the function name (search_products)
  • description from the docstring (Search the product catalog.)
  • parameters from the type hints (query: str required, limit: int optional with default)
  • return type from the return annotation (dict)
Calling search_products("shoes", limit=5) routes through the synthetic backend and returns a generated response.

Using register_tool

For cases where you need manual control over the schema:

Generation modes

Control how responses are generated by setting the mode parameter:

Deterministic output

Pass a seed for reproducible responses. The same seed, tool, and input produce the same output every time:

Simulating failures

Test your agent’s error handling by injecting failures:
Failures are deterministic when a seed is set — the same step always produces the same failure or success. Available error codes: timeout, internal_error, rate_limit, not_found, bad_request.

Idempotency

Pass an idempotency_key to cache responses. Repeated calls with the same key return the cached result without hitting the backend:

Resetting a world

Reset the step counter and optionally clear all cached and stateful data:

Choosing a model

By default, the backend picks the generation model. You can override it:

Full example

See Also