Runtime safety proxy for multi-agent AI systems
Project description
pyguardops
Runtime safety proxy for multi-agent AI systems. Intercepts agent outputs in real-time — before bad values (or bad decisions) cascade downstream — and auto-corrects or halts the pipeline based on rules you define.
What it does
- DATA_OVERRIDE — detects a breach, corrects the unsafe field, pipeline continues
- SHORT_CIRCUIT — raises
GuardOpsRefusalIntercept, halts the pipeline immediately - Telemetry (optional) — every breach can be logged to Langfuse (live spans) and MLflow (retraining artifacts)
Install
pip install pyguardops==0.0.1
The command-line tool and the Python import both remain guardops:
guardops init
from guardops import guard_runtime
Quickstart
guardops init
This creates two files in your current directory:
guard_manifest.json— your rulescustom_guards.py— starter custom check/recovery functions
Edit guard_manifest.json to describe your real rules, then decorate your agent function:
from guardops import guard_runtime
@guard_runtime(node_name="PricingAgent") # must match a key in guard_manifest.json
async def pricing_agent(payload: dict) -> dict:
payload["price"] = compute_price(payload)
return payload # GuardOps checks the return value before it goes further
@guard_runtime works on both async def and plain def functions — no separate decorator needed for sync code.
Validate your manifest any time:
guardops validate --manifest guard_manifest.json
Manifest basics
Three built-in condition types need no custom Python at all:
{
"PricingAgent": [
{
"metric_key": "price",
"condition_type": "UNDER_FLOOR",
"boundary_limit": 5.00,
"fallback_value": 5.00,
"strategy": "DATA_OVERRIDE",
"breach_tag": "PRICE_UNDER_FLOOR"
}
]
}
UNDER_FLOOR, OVER_CEILING, and REGEX_MISMATCH cover most simple checks. For anything more — comparing fields to each other, semantic similarity, LLM-as-judge — use CUSTOM_CHECK, which points at a function in custom_guards.py:
{
"condition_type": "CUSTOM_CHECK",
"boundary_limit": "custom_guards.check_my_condition",
"fallback_value": "custom_guards.recover_my_value",
"breach_tag": "MY_CUSTOM_BREACH",
"parameters": { "threshold": 0.85 }
}
Custom functions receive (value, rule_config). rule_config always includes metric_key, condition_type, boundary_limit, fallback_value, strategy, breach_tag, parameters (whatever you defined above — free-form), and payload (the full agent output for this call, so you can read sibling fields alongside value).
Telemetry — fully optional, off by default
GuardOps runs completely standalone with zero telemetry setup. Turning it on requires two things together:
1. Install the extra:
pip install "pyguardops[telemetry]"
2. Set these in your app's environment (via your own .env, loaded by your own app before your first @guard_runtime call — GuardOps does not load .env files itself):
LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_SECRET_KEY=sk-lf-...
MLFLOW_TRACKING_URI=http://localhost:5000
Both steps are required. Installing the extra without setting the variables leaves telemetry off. Setting the variables without installing the extra also leaves it off (the import fails gracefully). Neither half alone does anything — and that's intentional, so a bare pip install pyguardops never pulls in mlflow/langfuse for anyone who doesn't want them.
If you already run Langfuse and/or MLflow elsewhere in your stack, point these variables at your existing setup — GuardOps logs into your existing project/experiment, it doesn't spin up a separate instance.
Optional extras
pip install "pyguardops[embeddings]" # semantic similarity in custom guards (sentence-transformers)
pip install "pyguardops[llm]" # LLM-as-judge custom guards (openai)
pip install "pyguardops[pydantic]" # Pydantic BaseModel payload support
pip install "pyguardops[all]" # everything above
Payloads can be plain dict or Pydantic BaseModel instances — GuardOps detects and round-trips both automatically.
Development
git clone <this-repo>
cd pyguardops
pip install -e ".[dev]"
pytest tests/ -v
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyguardops-0.0.1.tar.gz.
File metadata
- Download URL: pyguardops-0.0.1.tar.gz
- Upload date:
- Size: 27.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a2315a270fda75b02c6c7624bc16ff3b687593dc07ae330595f55ceb478f2e22
|
|
| MD5 |
b367612e24e81ac257b806868c8dcde7
|
|
| BLAKE2b-256 |
c08198cc2b8482dfb68bab4219734e77767e080f8893288a10a9e155c961c3bd
|
File details
Details for the file pyguardops-0.0.1-py3-none-any.whl.
File metadata
- Download URL: pyguardops-0.0.1-py3-none-any.whl
- Upload date:
- Size: 27.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b45aaad79b7f00a9a778a75515991b434dc51b95e594381946cf367095fcdf51
|
|
| MD5 |
d5f3276bfb70718354f6eea15f6bdcfe
|
|
| BLAKE2b-256 |
3fa06e2f16f4a7e5757180f1c31988afe30ef416fa88684c304e927863e7e176
|