A grounding firewall for biomedical LLMs: verifies biological identifiers and claims against authoritative databases, and flags fabrications.
Project description
bioclaim
A grounding firewall for biomedical LLMs. Wrap it around any model's output and it verifies the biological identifiers against authoritative databases — UniProtKB, Ensembl, and EBI's Ontology Lookup Service — flagging the ones that are fabricated.
Large language models constantly emit identifiers that look real but don't exist
(GO:9999999, HP:9999999), alongside false gene–function and gene–disease claims. In
research and clinical settings that is a documented safety risk. bioclaim is a
deterministic, low-latency layer that catches it.
Real-model finding: across three models, 48–68% of specialist biology answers contained a wrong biomedical identifier (Llama-3.1-8B 68%, gpt-oss-120B 60%, Llama-3.3-70B 48%). The dominant error is a real, valid accession pointing at the wrong gene — invisible to existence checks, independently verified. Full study: RESULTS.md.
Benchmark result
On a labeled set of 500 LLM-style answers (394 injected fabrications):
| Metric | Score |
|---|---|
| Precision (flagged that were truly fake) | 100.0% |
| Recall (fabrications caught) | 95.7% (377 / 394) |
| F1 | 0.978 |
| False accusations | 0 |
Every uncaught fabrication was a network-throttled lookup that safely returned
UNVERIFIED — not a single fake was checked and missed. Reproduce with:
python scripts/generate_benchmark.py 500
python scripts/benchmark.py data/benchmark_large.jsonl
How it works
Two layers, both designed to never falsely accuse (if a claim can't be verified it is
marked UNVERIFIED, never NOT_FOUND):
- FORMAT — offline, deterministic. Rejects malformed identifiers.
- EXISTS — live existence check against the source database. Well-formed but absent
identifiers are flagged
NOT_FOUND. Rate-limit/network errors are retried with backoff, then degrade toUNVERIFIED. - CLAIM (v0.5) — label consistency. A real identifier with a wrong description
(
GO:0006281 (photosynthesis), actually "DNA repair") is flaggedSUPPORTED_LABEL_MISMATCH. Synonym-aware, so paraphrases aren't falsely flagged. - ENTITY (v0.6) — correspondence. A real UniProt/Ensembl ID attached to the
wrong gene ("the UniProt for TP53 is P38398", actually BRCA1) is flagged
SUPPORTED_ENTITY_MISMATCH— the hardest class, invisible to existence checks.
Supported identifier types: GO, HP, MONDO, DOID, CHEBI, Ensembl gene (ENSG), UniProtKB.
Every lookup is cached to disk ($BIOCLAIM_CACHE, else ~/.cache/bioclaim/), so
after a warm-up bioclaim runs fast, offline-capable, and immune to rate limits.
Install & use
pip install -e . # from a clone; PyPI release: pip install bioclaim
One-call API:
from bioclaim import check
result = check("TP53 (P04637) is annotated with GO:9999999 (apoptosis).")
print(result.ok) # False
for p in result.problems:
print(p) # GO:9999999: fabricated (does not exist)
Guard any model call (raises if a fabrication slips through):
from bioclaim import Firewall
guarded = Firewall(raise_on_flag=True).guard(call_my_llm)
answer = guarded(prompt) # BioclaimFlag raised if the answer cites a fake ID
Command line:
bioclaim "TP53 is P04637 and the fake GO:9999999"
echo "some model output" | bioclaim --entity BRCA1
Project layout
bioclaim/ core package (patterns, live sources, validator)
scripts/ runnable CLIs: demo, batch, benchmark, generate_benchmark
data/ sample_answers.jsonl (labeled demo set)
tests/ offline unit tests
Run the pieces (from the repo root):
python scripts/demo.py # catch fakes in one example answer
python scripts/benchmark.py # precision/recall on the sample set
python scripts/batch.py your_answers.jsonl # scan your own AI answers
python -m pytest # run tests
Roadmap (land-and-expand)
- v0.1–0.3 Identifier validation across ontologies, genes, and proteins (done)
- v0.4 Local database snapshots — microsecond lookups, fully offline, true 100% recall
- v0.5 Claim verification — relationships, not just IDs (gene–disease, gene–function)
- v0.6 Calibrated confidence per claim
- v1.0 Public leaderboard + LLM-framework integrations
Why this design wins
Generality (all identifier types, one layer) · Deployability (pure standard library, 3-line integration) · Speed (deterministic lookups, not agent loops) · Trust (never a false accusation).
License
MIT — see LICENSE.
Project details
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 bioclaim-0.7.5.tar.gz.
File metadata
- Download URL: bioclaim-0.7.5.tar.gz
- Upload date:
- Size: 19.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c43010af98781fd362e2b37a3aed18a697a33651a518d7c8fbdad090bc701b92
|
|
| MD5 |
3fc74d3ef3cda6cda3b2006dc3c912f5
|
|
| BLAKE2b-256 |
85bdae73bb633724b34dc4fa8bb1fee57649b0ea8e0ba6886a3c6a9b3ecaa277
|
File details
Details for the file bioclaim-0.7.5-py3-none-any.whl.
File metadata
- Download URL: bioclaim-0.7.5-py3-none-any.whl
- Upload date:
- Size: 17.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
833eabc0cabc079813d838a26eb4b36e3f2527f850c40d23c4a27038b21be965
|
|
| MD5 |
51affae0ca1a8f55c46d28288dd7982a
|
|
| BLAKE2b-256 |
43945c843ee6390c852cd34f6d557e9aaaca0b34f038902fff805b3253169ad0
|