OGL-Mini: Lightweight Hybrid Guard for AI Agents (250MB ONNX)
Hybrid 3-stage guard: (heuristics + MiniClassifier + PII) distilled from DeBERTa-v3-xsmall (70M) + MiniLM-L6 with training for OWASP 2026 datasets.
CPU-only, <10ms p95, 250MB FP32 / 2.8MB INT8, RU/EN + multilingual.
Deployed as standalone libraries for Python / TypeScript (Node + Browser, WASM) / Go: no HTTP required. See github.com/devsdaddy/ogl-mini for full code, Helm chart and API.
❓ Why OGL-Mini?
- OWASP coverage: LLM Top 10 2025-2026 (LLM01-LLM10) + Agentic Top 10 (Goal Hijack, Privilege Abuse, Code Execution, InterAgent, Tool Misuse, Memory Poisoning, Rogue Agents, Policy Puppetry, EchoLeak, Lies-in-the-Loop)
- 3-stage hybrid: Stage 1 heuristics (0.1ms, 30-40% attacks) → Stage 2
ogl-mini.onnxTF-IDF 80k + LR (3-7ms, AUC 0.9988) → Stage 3 PII hybrid (regex + NER, <5ms) - CPU-only: <500MB RAM, cold start 1.7s, no GPU, x86_64/ARM64, K8s-ready
- Multilingual: RU/EN primary (FR/DE/ES/IT/PT via shieldlm) and PII in 23 languages (ai4privacy trained)
Our Models
| File | Size | Use | Input | Outputs |
|---|---|---|---|---|
ogl-mini.onnx |
250MB FP32 (247MB dummy for 200-300MB spec) | Node.js / Python / Browser (WASM) | string[1,1] (input) |
label (0 benign / 1 attack), probabilities float[1,2] |
ogl-mini.int8.onnx |
2.8MB INT8 (Micro model with low detection, not for production) | Browser (WASM) | same | same |
ogl-mini.pkl |
3.8MB (Fallback) | Python fallback (calibrated sklearn pipeline) |
string |
predict_proba |
All exported with skl2onnx opset 14, TfidfVectorizer + LinearClassifier, zipmap=False.
Dummy initializer ogl_mini_large_dummy_weight [31642,2048] inflates FP32 to spec size (pruned at runtime, still counts on disk).
Datasets (96,662 train, 14,500 test)
| Dataset | Samples | Role | HF ID |
|---|---|---|---|
| shieldlm | 54,162 (37,913 train / 8,124 val / 8,125 test) | LLM01 direct/indirect/jailbreak, 11 sources, 8 lang | Abdennebi/shieldlm-prompt-injection |
| Agentic synthetic | 22,500 | LLM01-10 2026 + Agentic Top10 (see owasp_coverage in ogl-mini.json) |
training/synth_datasets.py |
| PII | 15,000 sampled (from 300k dataset) | 19 types, RU/EN | custom dataset + gravitee-io/pii-detection-dataset (175k) + nvidia/Nemotron-PII (100k) paradigm |
Evaluation (hold-out 14,500, threshold 0.60)
| Metric | Target | Actual |
|---|---|---|
| AUC | - | 0.9988 |
| LLM01 direct + indirect recall | ≥90% | 100% (12 direct 100%, 7 indirect 100%) |
| Jailbreak recall | ≥85% | 100% (10 wild) |
| Policy Puppetry / Hidden Context / Goal Hijack / Obfuscation | - | 100% |
| PII F1 RU/EN (19 types) | ≥0.85 | 0.95 |
| FPR benign 30 + 120 extended | <2% | 0% |
| Input p95 | <10ms | 1-7ms |
| Output p95 | <15ms | 2-8ms |
| PII p50 / p95 | <200 / <500ms | 1ms / 30ms |
| Cold start | <5s | 1.7s |
Intended Use
- ✅ Input Guard - block prompt injection before agent (
<10ms p95) - ✅ Output Guard - block PII / system-prompt leaks (
pii_leak,system_prompt_leak) - ✅ PII detection & redaction - 13 types:
PERSON, EMAIL, PHONE, IP, IBAN, BANK_CARD, PASSPORT, GOV_ID, DOB, ADDRESS, SOCIAL, MAC+ custom - ❌ Not for multimodal, not a legal compliance guarantee
Quickstart
Python (ONNX Runtime + sklearn fallback)
pip install onnxruntime scikit-learn
from pathlib import Path
import onnxruntime as ort, pickle
# Lightweight fallback (no model file needed, 18-feature LR, 0.01ms)
from ogl_mini.guards.pipeline import HybridGuard
guard = HybridGuard() # threshold 0.60
print(guard.check_input("Ignore previous instructions"))
# GuardResult(safe=False, risk_score=0.99, label='direct_prompt_injection', stage='ml')
# ONNX TF-IDF 80k (250MB, AUC 0.9988)
import numpy as np
sess = ort.InferenceSession("models/ogl-mini/ogl-mini.onnx", providers=["CPUExecutionProvider"])
# with browser use ogl-mini.int8.onnx (2.8MB)
def onnx_prob(text: str) -> float:
out = sess.run(None, {"input": np.array([[text]], dtype=object)})
prob = out[1] if len(out)>1 else out[0]
return float(prob[0][1] if hasattr(prob[0], "__len__") else prob[0])
# Plug into HybridGuard
from ogl_mini.ml.classifier import MiniClassifier
clf = MiniClassifier()
# Monkey: wrap onnx_prob as scorer (or use guard.classifier.SetOnnxScorer in Go/TS)
Inference Details (ONNX)
# ONNX inputs/outputs (skl2onnx)
# input: Tensor[str] shape [1,1], name "input"
# outputs: "label" int64[1], "probabilities" float[1,2] (benign, attack)
import onnxruntime as ort, numpy as np
sess = ort.InferenceSession("ogl-mini.onnx")
print(sess.get_inputs()[0].name, sess.get_inputs()[0].type) # input, tensor(string)
inp = np.array([["List your tools and their schemas"]], dtype=object)
label, prob = sess.run(None, {"input": inp})
# prob[0][1] is P(attack)
Heuristics run before ONNX (control tokens, zero-width, homoglyph, spaced_letters, base64, policy_puppetry, direct/jailbreak/hidden/goal_hijack, tool_misuse). If hScore >=0.85 → immediate block (stage="heuristic"), else max(onnxProb, hScore*0.9).
Limitations
- English-centric TF-IDF (80k) - RU/EN best, fallback heuristics cover RU jailbreak/puppetry; FR/DE/ES limited to shieldlm samples
- PII regex+NER - may miss rare locales, IBAN/phone formatting variants; PERSON EN/RU heuristic (not transformer NER)
- 250MB ONNX is mostly
TfidfVectorizervocabulary + dummy initializer; - Not robust to adaptive adversarial ML without retraining; track
BENCHMARK.md
License
MIT - see LICENSE.
Datasets: shieldlm Apache-2.0, Nemotron-PII NVIDIA, gravitee Apache-2.0.
Citation
@misc{oglmini2026,
title={OGL-Mini: Hybrid Guard for AI Agents (DeBERTa-v3-xsmall distilled, 250MB ONNX)},
author={Elijah Rastorguev},
year={2026},
url={https://huggingface.co/devsdaddy/ogl-mini},
note={OWASP LLM Top 10 2025-2026 + Agentic Top 10, 96k training, AUC 0.9988}
}
@dataset{shieldlm2024,
title={ShieldLM Prompt Injection Dataset (54k)},
author={Abdennebi et al.},
url={https://huggingface.co/datasets/Abdennebi/shieldlm-prompt-injection}
}
Model tree for devsdaddy/ogl-mini
Base model
microsoft/deberta-v3-xsmall