Detecting prompt injection in production
benchmark
Detecting prompt injection in production
Our first public benchmark for AgentGuard's detection runtime: recall, false positives and latency for each layer, measured against a corpus mapped to the OWASP Top 10 for LLM Applications.
September 26, 2026 · benchmark v1.0.0 · reproducible corpus and hashes below
91.5%
recall — regex only
98.1%
recall — regex + ML
0%
false positives — regex only
Short version: the deterministic `regex` layer catches 91.5% of the attacks in our corpus with 0% false positives, under a millisecond. Adding a ML layer pushes recall to 98.1%, at the cost of \~450ms latency and false positive rates that still need work.
We're publishing this first because the deterministic layer is already solid, fast and fully reproducible. The ML false-positive work is in progress — the "Known limitations" section below is part of this post, not a footnote.
Methodology
The corpus contains 106 malicious prompts, 20 ordinary benign prompts, and 12 hard negatives — benign prompts worded to resemble attacks (e.g. "write a blog post explaining prompt injection and how to defend against it"), designed to trip up an over-eager detector.
SDK 0.4.2
Python 3.14.2
Platform Windows 10
Corpus hashes (for reproduction):
attacks — 7775a3e8326df3c71fdd478587e126bc5d733ce5327181305d1d61ec8213c5aa benign — f967bf6d22d18c4fa764f864286cc0f2e960265066c51ba1039beff0e2a4bf60 hard\_negatives — 54e96f408e696b8bfda7aaa8cf8dee305af6c678dfdf1a06c924fab3f83dae99
The actual run
No cherry-picking — this is the real CLI output.
benchmarks/run\_public\_benchmark.py
Results by configuration
| Layers | Recall | FP benign | FP hard-neg. | p50 | p95 | | ---------------- | ------ | --------- | ------------ | ------ | ------ | | regex | 91.5% | 0.0% | 0.0% | 0.29ms | 1.48ms | | regex + ML | 98.1% | 5.0% | 33.3% | 0.20ms | 448ms | | regex + ML + LLM | 98.1% | 5.0% | 33.3% | 0.22ms | 442ms |
Recall by category — regex only
dangerous\_commands12/12
exfiltration15/15
indirect\_injection10/10
system\_extraction13/14
direct\_injection24/27
jailbreak16/18
encoded\_obfuscated7/10
Obfuscation — character-spaced text, invisible characters, HTML-comment tricks — is the hardest category for regex alone. It's exactly where the ML layer helps most (7/10 → 8/10), at the cost of the false positives described below.
Mapping to the OWASP Top 10 for LLM Applications (2025)
LLM01
Prompt Injection
direct\_injection, indirect\_injection, jailbreak, encoded\_obfuscated
LLM02
Sensitive Information Disclosure
exfiltration
LLM06
Excessive Agency
dangerous\_commands
LLM07
System Prompt Leakage
system\_extraction
Known limitations
ML false positives: On hard negatives — benign prompts worded to look like attacks — the ML layer wrongly blocks 4 out of 12 (33.3%). Typically requests that talk about security or API keys without exposing any. This is the current top priority.
ML latency: p95 sits around 450ms versus under 2ms for regex alone — a real cost to weigh against the recall gain depending on the use case.
LLM layer: Depends on an external API, so results vary by environment. On this corpus it adds no measurable recall over regex+ML.
Obfuscation: Still the hardest category (80% even with ML) — character-spaced text, invisible characters and HTML-comment tricks are the next target.
Code and benchmark are reproducible on GitHub. Feedback and failure cases welcome — this is an actively iterated project.

