Skip to content

Quickstart

pip install riskgate            # once published; until then: pip install -e .   (from a clone)

The complete runnable file is examples/quickstart.py. It walks through five steps on a toy problem: an agent tops up a tank that may have a hidden leak.

1. A consequence model: what would this action do?

import riskgate as rg

class TankModel:
    version = "tank-model-v1"            # bump on every change: old calibrations become VOID
    def predict(self, action, hyp, ctx):
        return {"level": ctx["level"] + action.args["v"] - hyp.params["leak"]}

In a real deployment this is your digital twin, simulator, --dry-run, a dry-run on a database clone, or a learned model.

2. Hypotheses: what could be going on?

class LeakDiagnoser:
    version = "leak-diag-v1"
    def hypotheses(self, ctx):          # lower score = explains the evidence better
        return [rg.Hypothesis(f"leak={l}", family=f"leak{l}", params={"leak": l},
                              score=abs(ctx["flow"] - l) / 8) for l in (0, 15, 30)]

3. The safety spec and the gate

spec = rg.Spec(rg.Envelope("level", lo=10, hi=100, scale=10))    # margin > 0 means safe
gate = rg.Gate(TankModel(), spec, LeakDiagnoser(), alpha=0.05)

4. Calibrate on labelled episodes

episodes = [rg.Episode(ctx, ranked_actions, unsafe_labels, true_family="leak15"), ...]
cal = gate.calibrate(episodes)               # sets tau, lambda-hat; status -> VALID
cal.save("tank.cal.json", key=SECRET)        # signed, fingerprinted artefact

5. Use it

Check proposals directly:

d = gate.check(rg.Action("add", {"v": 40}), {"level": 80, "flow": 15.0})
d.verdict, d.reason, d.plausible, d.score, d.status

Real output from the example:

calibrated: lambda=-1.76, tau=1.89, n=420, status=valid
CERTIFY  add(5) at level=30, flow=0.0: plausible=['leak=0', 'leak=15'], robust margin=1.00
         reason: robust margin above calibrated threshold
REJECT   add(40) at level=80, flow=0.0: plausible=['leak=0', 'leak=15'], robust margin=-2.00
         reason: unsafe under every plausible hypothesis (binding constraint: 10<=level<=100)
ASK      add(40) at level=80, flow=15.0: plausible=['leak=0', 'leak=15', 'leak=30'], robust margin=-2.00
         reason: cannot certify: best robust margin -2.000 < threshold -1.763; worst case under hypothesis 'leak=0'

Or guard the function your agent framework calls as a tool:

@rg.guard(gate, context=lambda: current_state(), on_ask=page_human)   # on_ask returns True to approve
def add(v: float) -> str:
    ...

add(20)   # certified -> runs and returns "added 20 L"
add(80)   # -> {'status': 'rejected', 'reason': 'unsafe under every plausible hypothesis ...', 'guarantee': 'valid'}

The dict is returned to the agent as the tool result, so it can re-plan. With the OpenAI Agents SDK, LangGraph, Google ADK or MCP, see Integrations.

Next steps