Skip to main content

Documentation Index

Fetch the complete documentation index at: https://browseruse-0aece648-codex-deterministic-rerun-docs.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Deterministic rerun lets you run a task once with the full agent, save the learned workflow as a Python script, then rerun that script with new parameters. Cache hits skip the full agent and can drop LLM cost to zero when the script succeeds without auto-healing or explicit LLM calls. The cached script still fetches the website or API again. It does not replay the first run’s output, so updated page/API content is reflected on reruns.

Quick start

Use @{{double brackets}} around values that can change between runs. The first call runs the full agent and creates a script in your workspace. Every subsequent call with the same template runs that script with the new parameter values.
from browser_use_sdk.v3 import AsyncBrowserUse

client = AsyncBrowserUse()
workspace = await client.workspaces.create(name="my-scraper")

# First call: agent explores, creates scripts/<hash>.py
result = await client.run(
    "Fetch https://httpbin.org/anything?item=@{{alpha}} and return args.item, url, and response date as JSON",
    workspace_id=str(workspace.id),
)

# Second call: same template, new parameter, cached script path
result2 = await client.run(
    "Fetch https://httpbin.org/anything?item=@{{beta}} and return args.item, url, and response date as JSON",
    workspace_id=str(workspace.id),
    auto_heal=False,  # optional: disables validation/healing LLM calls
)
On the cached run, result2.output comes from a new request to httpbin.org with item=beta. In live testing this path returned 0 input tokens, 0 output tokens, and llmCostUsd: 0.

How it works

1

You send a task with @{{brackets}}

The brackets mark which parts are parameters:
"Get prices from @{{example.com}} for @{{electronics}}"
  • @{{example.com}} → parameter 1
  • @{{electronics}} → parameter 2
The system strips the values to create a template: "Get prices from @{{}} for @{{}}".
2

System hashes the template

Template "Get prices from @{{}} for @{{}}" is normalized, hashed, and stored as a 16-character script filename like scripts/a7f3b2c19d4e8f01.py.The cache key ignores parameter values. It is based on the template after values are replaced with @{{}}, whitespace is collapsed, and the template is lowercased.
3

Cache miss → agent creates script

If no script exists, the full agent runs your task. After completing it, the agent saves a standalone Python script that can reproduce the workflow with new parameters.
4

Cache hit → script executes directly

If the script exists, it runs directly with the new parameter values. This skips the full browser agent. The script can use a browser, or it can use Browser Use’s fetch helper for direct HTTP requests when a browser is unnecessary.
Keep each @{{...}} value on one line, and do not put }} inside a parameter value. Changing only parameter values reuses the script; changing the wording or the number/order of parameters creates a different script.

Auto-detection

Caching activates automatically when both conditions are met:
  • The task contains @{{ and }}
  • A workspace_id is provided
No extra flags needed. You can override with cache_script:
ValueBehavior
None (default)Auto-detect from @{{brackets}} + workspace
TrueForce-enable, even without brackets
FalseForce-disable, even if brackets are present
cacheScript applies to create-and-run calls. Follow-up dispatches to an existing sessionId currently run as normal agent tasks, even if the task contains @{{...}}.

Examples

Parameterized scraping

Run once, then loop over different keywords. Cache hits skip the full agent:
# Agent figures out how to scrape intro.co on first call
result = await client.run(
    "Go to @{{https://intro.co/marketplace}} and get all @{{logistics}} experts as JSON",
    workspace_id=str(workspace.id),
)

# Reruns with different keywords use the cached script
for keyword in ["CEO", "marketing", "finance", "e-commerce"]:
    result = await client.run(
        f"Go to @{{{{https://intro.co/marketplace}}}} and get all @{{{{{keyword}}}}} experts as JSON",
        workspace_id=str(workspace.id),
    )
    print(f"{keyword}: {result.output}, LLM cost: ${result.llm_cost_usd}")

Fresh content on rerun

The cached script fetches the source again. It is useful for extraction jobs where the target page or API changes over time.
result = await client.run(
    "Fetch https://httpbin.org/anything?mode=@{{first}}&value=@{{red}} "
    "and return JSON with mode, value, url, and response date",
    workspace_id=str(workspace.id),
    auto_heal=False,
)

result2 = await client.run(
    "Fetch https://httpbin.org/anything?mode=@{{second}}&value=@{{blue}} "
    "and return JSON with mode, value, url, and response date",
    workspace_id=str(workspace.id),
    auto_heal=False,
)

print(result2.output["mode"])   # "second"
print(result2.llm_cost_usd)     # "0" when the cached script succeeds
For browser-required pages, parameterize the URL or search terms:
result = await client.run(
    "Go to @{{https://example.com/}} in the browser. Return the final URL, title, H1, and first paragraph as JSON.",
    workspace_id=str(workspace.id),
)

result2 = await client.run(
    "Go to @{{https://www.iana.org/domains/reserved}} in the browser. Return the final URL, title, H1, and first paragraph as JSON.",
    workspace_id=str(workspace.id),
)
The second run returns content from the new URL, not a replay of the first page.

No parameters — cache the exact task

Append empty brackets @{{}} to signal “cache this exact task”:
result = await client.run(
    "Get the current Bitcoin price from coinmarketcap.com @{{}}",
    workspace_id=str(workspace.id),
)

# Same task again — cached
result2 = await client.run(
    "Get the current Bitcoin price from coinmarketcap.com @{{}}",
    workspace_id=str(workspace.id),
)

Multiple parameters

result = await client.run(
    "Go to https://help.netflix.com/en/node/24926/ax and get subscription prices for @{{Germany,France,Japan}}",
    workspace_id=str(workspace.id),
)

# Different countries — cached
result2 = await client.run(
    "Go to https://help.netflix.com/en/node/24926/ax and get subscription prices for @{{US,UK,Brazil}}",
    workspace_id=str(workspace.id),
)

Force enable / disable

# Force-enable without brackets
result = await client.run(
    "Get the top stories from Hacker News",
    workspace_id=str(workspace.id),
    cache_script=True,
)

# Force-disable even with brackets
result = await client.run(
    "Explain what @{{templates}} means in Jinja",
    workspace_id=str(workspace.id),
    cache_script=False,
)

Inspecting cached scripts

You can download and inspect the scripts the agent created:
files = await client.workspaces.files(workspace.id, prefix="scripts/")
for f in files.files:
    print(f"{f.path}  ({f.size} bytes)")

# Download a script to inspect it
await client.workspaces.download(workspace.id, "scripts/a7f3b2c19d4e8f01.py", to="./my_script.py")

Auto-healing

Cached scripts can break when a website changes its layout, adds new elements, or alters its structure. Auto-healing detects these failures and automatically regenerates the script.

How it works

When a cached script runs, the system validates its output:
  1. Fast checks (no LLM) — detects empty results, error fields in JSON, or exception keywords in output.
  2. LLM judge — if fast checks pass, a lightweight model validates whether the output looks correct for the original task.
  3. Heal — if validation fails, the full agent re-runs the task and saves an updated script.
Auto-healing is limited to 1 attempt per run to prevent runaway costs. If the healed script also fails, the output is returned as-is.

Disable auto-healing

If you want the cached path to return the raw script output and avoid validation/healing LLM calls, disable auto-healing:
result = await client.run(
    "Fetch https://httpbin.org/anything?item=@{{alpha}} and return JSON",
    workspace_id=str(workspace.id),
    auto_heal=False,
)

Cost impact

ScenarioFull agent LLMOther LLM
Cache hit, autoHeal: false, script does not call LLM helpers$0$0
Cache hit, default autoHeal: true$0Lightweight validation may run
Cache hit, script calls an LLM helper$0Per-call LLM cost
Cache hit fails and auto-healsFull agent costValidation cost
Auto-healing is enabled by default for all cached scripts.

Browser, fetch, and recordings

Cached scripts do not always use a browser. During the first run, the agent may discover that the fastest reliable implementation is a direct HTTP request with Browser Use’s fetch helper instead of browser navigation. That is expected for JSON APIs and many data-extraction tasks. If you pass enableRecording: true, recordingUrls are returned only when a browser session actually records and the MP4 is ready. Direct-HTTP cached runs may have no recording because there was no useful browser interaction to record. On cache hits, isTaskSuccessful can be null even when status is stopped and output is correct, because the full agent success judge was skipped. For deterministic reruns, treat the returned output and your own validation/schema checks as the source of truth.

Cost comparison

Full agent LLMBrowser/proxyTypical time
First call (agent)~$0.05–1.00If needed~30–120s
Cached call$0 unless auto-heal regeneratesIf needed~3–15s
Cached calls can still have small infrastructure cost. If the script uses direct HTTP only, there may be no browser recording even with recording enabled.