Guides

Guardrails & Policies

Policies are rules the Niitaka SDK evaluates in real time as your agent runs — cost limits, step caps, retries, and fallbacks — without touching your agent code.

Where to configure policies

Dashboard

Create and edit policies in the Policies page. Changes take effect on the next session — no redeploy needed.

YAML file

Define policies in a local file and pass policy_file= to configure(). File policies take priority over DB policies for matching agents.

Policy types

cost_limit

Emit a warning or abort when accumulated session cost crosses a threshold. Each entry is one threshold — use two entries (warn + abort) for a soft and hard limit.

FieldDescription
condition.cost_exceededDollar amount (USD). Triggers when total session cost exceeds this value.
action.type"warn" emits a signal and lets the session continue. "abort" raises AgentExecutionStopped before the next LLM call.
step_limit

Abort or warn when the number of completed LLM + tool calls in a session reaches a cap. Catches runaway loops before they drain budget.

FieldDescription
condition.steps_exceededInteger. Triggers when step count reaches or exceeds this value.
action.type"warn" emits a signal and continues. "abort" halts before the next call.
retry

Automatically retry failed LLM calls with configurable backoff. Scope to specific error types so unrecoverable errors (auth, bad request) propagate immediately.

FieldDescription
condition.on_errorAlways true — condition is met whenever any LLM/tool call raises an error.
action.max_retriesMaximum number of retry attempts before giving up.
action.backoff_secondsBase delay in seconds between retries.
action.backoff"exponential" (default) doubles delay each attempt. "linear" waits backoff_seconds each time.
action.on_errorsOptional list of error class names to retry on. Omit to retry on any error.
fallback

Switch to an alternate model after all retry attempts are exhausted. Pairs with retry to form the full resilience stack.

FieldDescription
condition.on_errorAlways true — condition is met on any error after retries are exhausted.
action.fallback_modelModel ID to switch to (e.g. "gpt-4o-mini").
action.on_errorsOptional list of error class names that trigger the fallback. Omit to fall back on any error.

Full YAML example

A complete policy file with all four policy types configured for one agent. Each cost_limit or step_limit threshold is its own entry — create two entries (warn + abort) to get both a signal and a hard stop:

yaml
# policies.yaml — load with niitaka.configure(policy_file="policies.yaml")
version: "1"

policies:
  # Warn at $0.30
  - agent_id: my-agent
    type: cost_limit
    priority: 5
    condition:
      cost_exceeded: 0.30
    action:
      type: warn

  # Hard abort at $0.50
  - agent_id: my-agent
    type: cost_limit
    priority: 10
    condition:
      cost_exceeded: 0.50
    action:
      type: abort

  # Cap the number of LLM + tool call steps
  - agent_id: my-agent
    type: step_limit
    priority: 10
    condition:
      steps_exceeded: 20
    action:
      type: abort

  # Retry transient errors with exponential backoff
  - agent_id: my-agent
    type: retry
    priority: 8
    condition:
      on_error: true
    action:
      max_retries: 3
      backoff_seconds: 2
      backoff: exponential
      on_errors:
        - RateLimitError
        - APITimeoutError
        - InternalServerError

  # Fall back to a cheaper model after retries are exhausted
  - agent_id: my-agent
    type: fallback
    priority: 7
    condition:
      on_error: true
    action:
      fallback_model: gpt-4o-mini
      on_errors:
        - RateLimitError
        - APITimeoutError
python
import os
import niitaka

niitaka.configure(
    api_key=os.getenv("NIITAKA_API_KEY"),
    policy_file="policies.yaml",      # file policies take priority over DB policies
)

Accessing guardrail values in code

The SDK enforces guardrails automatically — you don't need to check thresholds manually. If you need to read the active policy values from your agent (e.g. for logging or adaptive behaviour), use get_runtime_config():

python
import niitaka

# The SDK enforces guardrails automatically — no manual checks needed.
# To inspect active policy values from your agent code:
with niitaka.start_session(agent_id="my-agent"):
    result = niitaka.get_runtime_config()
    cfg = result.get("config", {})

    # Guardrail thresholds from the active shipped version / experiment variant:
    guardrails = cfg.get("guardrails", {})
    cost_limit = guardrails.get("cost_limit_usd")    # e.g. 0.50  (None if not set)
    max_steps  = guardrails.get("max_steps")          # e.g. 20    (None if not set)

    # Use for observability / logging — enforcement is handled by the SDK.
    print(f"Active cost limit: {cost_limit}, step limit: {max_steps}")

How guardrails fire

Cost and step guardrails are pre-call gates. Before each LLM call the SDK checks accumulated totals from previous calls against the configured limits. If a threshold is crossed:

  • warn — emits a guardrail signal in the session timeline and lets the call proceed.
  • abort — raises AgentExecutionStopped before the next call starts. The current call always completes and is logged — limits prevent the next call from running, not the one that just finished.

Policy evaluation order

Higher priority numbers are evaluated first. When multiple policies of the same type match, the highest-priority action wins. A common pattern: abort at priority 10, warn at priority 5 — if both thresholds are crossed, the abort fires first, as intended. All policy changes are versioned and logged in the Policy Audit Log in the dashboard.