grounding-firewall
An answer-or-ABSTAIN gate for RAG / agent answers, driven by grounding-drop sensitivity instead of confidence. Zero dependencies (Python stdlib only).
v0.3 adds --bench (and gf.bench(cfg)): reproduce "drop-sensitivity beats confidence" on your own
(logprob-capable) model in mixed clean+poison retrieval - don't take our numbers on faith, re-run them.
v0.2 adds gate_freeform() for open-ended (free-form) RAG answers, not just A/B multiple choice -
this is the mode for real RAG. (Free-form was validated on glm-5.2 in a smaller pilot; the hardened
headline numbers below are the n=101 multiple-choice measurement.)
Why
A model's confidence is blind exactly when it is confidently wrong: when a retrieved document is poisoned (asserts a plausible-but-false answer), frontier models follow it at full confidence. The firewall instead measures how much the answer depends on the retrieved doc:
sensitivity = | p(answer | context) - p(answer | context dropped) |
An answer that flips when you remove its evidence is grounded in the doc, not in the model's knowledge - so if the doc is wrong, the answer is wrong, and confidence won't warn you. The firewall abstains on high-sensitivity answers.
Measured (frontier models, n = 101 factual questions)
101 factual questions, each given once a clean doc and once a poisoned doc (50/50, strong direct-assertion poison), 3 samples each, on glm-5.2 and deepseek-v4-flash (202 items per model):
| signal | glm-5.2 | deepseek-v4-flash |
|---|---|---|
| model fooled by poison (base wrong-rate) | 29% | 40% |
| confidence corr with correctness | +0.30 (weak) | +0.23 (weak) |
| drop-sensitivity corr with correctness | -0.93 | -0.95 |
| confidence: wrong-rate @ 50% coverage | 18.8% | 35.6% |
| firewall: wrong-rate @ 50% coverage | 0.0% (0/101, 95% CI ≤ 3.7%) | 0.0% (0/101, ≤ 3.7%) |
Drop-sensitivity correlates negatively with correctness - the more an answer depends on the retrieved doc, the more likely it's wrong - while confidence barely correlates at all. Ranking by lowest drop-sensitivity, the firewall keeps the half of answers grounded in the model's own knowledge and ships 0 wrong of 101 on both models (Wilson 95% upper bound 3.7%), where confidence-gating ships 19-36% wrong.
Honest scope: strong direct-assertion poison, 2-option factual questions; the coverage you keep tracks the fraction of clean docs in your retrieval. The real deploy cost is one extra (context-dropped) query. (This n=101 measurement supersedes an earlier n=16 pilot.)
Install
pip install grounding-firewall
Use
import grounding_firewall as gf
cfg = {"endpoint": "https://your-llm/v1", "model": "<model>", "api_key": "<key>", "logprobs": True, "k": 5}
# free-form (real RAG) — v0.2:
gf.gate_freeform(cfg, question="What is the capital of Australia?",
context="Doc: the capital is Sydney.")
# -> {'answer': 'Sydney', 'answer_without_doc': 'Canberra', 'sensitivity': 1.0, 'decision': 'ABSTAIN', ...}
# multiple-choice:
gf.gate(cfg, question="What is the capital of Australia?",
context="Doc: the capital is Sydney.", a="Canberra", b="Sydney")
# -> {'answer': 'Sydney', 'confidence': 1.0, 'sensitivity': 1.0, 'decision': 'ABSTAIN', ...}
CLI:
# reproduce the poisoning self-test on your own model:
grounding-firewall --endpoint <url> --model <m> --demo
# gate one answer:
grounding-firewall --endpoint <url> --model <m> \
--question "What is the capital of Australia?" --context "Doc: the capital is Sydney." \
--a Canberra --b Sydney
Part of Agora - see the verification ledger / Folklore Index. License: MIT.
Metadata
Release files for grounding-firewall 0.3.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| grounding_firewall-0.3.1.tar.gz | 9.2 kB | Without provenance | Details for grounding_firewall-0.3.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| grounding_firewall-0.3.1-py3-none-any.whl | Python 3 | none | any | Details for grounding_firewall-0.3.1-py3-none-any.whl |
Total release size: 18.5 kB
Release files / grounding_firewall-0.3.1.tar.gz
| Download URL | grounding_firewall-0.3.1.tar.gz |
|---|---|
| Size | 9.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
19f1a04002b7835b1958fe94231dc49e868f7c2462b92c280ae28e823778ef27
|
|
BLAKE2b-256 checksum How to use checksums |
788f6494a362cac863b7c0fc08ce25aefb224a8166ea5c5ed0f63c611ecbf39c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|
Release files / grounding_firewall-0.3.1-py3-none-any.whl
| Download URL | grounding_firewall-0.3.1-py3-none-any.whl |
|---|---|
| Size | 9.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ac6452c9c4f3b4dd3a1bacdb97997f20781ac331df3db5f97f5f3b5be000a92e
|
|
BLAKE2b-256 checksum How to use checksums |
dc7dfcbfa087a9f3d5047475ebdb53486574bf53c92ec3d6ade6304f8a7a701d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|
Security for grounding-firewall 0.3.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.