Skip to content

Latest commit

 

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VUS Copilot

Decision-support for interpreting variants of uncertain significance (VUS) in regulatory, non-coding regions of the genome.

Give it one variant, or drop in a whole VCF. VUS Copilot checks every variant against five evidence sources in parallel, ranks the list with a deterministic, fully-visible triage score, and uses Claude as a reasoning layer that reconciles the evidence into a clinician-readable, fully-cited report. It targets the gap where coding-variant interpretation is mature but regulatory interpretation is not: the evidence is scattered, and most variants land in "uncertain significance" by default.

The architecture is code ranks, Claude explains. The ranking is deterministic, so it is reproducible and auditable, and the model cannot move a row. Claude reads the finished ranking and writes the summary on top of it.

⚕️ Triage / decision-support assistant, not a diagnostic tool. For genetic counselors and clinical geneticists to prioritize and contextualize regulatory VUS, not to make clinical calls. Every conclusion traces to a real source, not model authority.

Built for Built with Claude: Life Sciences (Anthropic × Cerebral Valley × Gladstone Institutes), Builder Track.


Two ways in

One variant (chr/pos/ref/alt or an rsID) gives you the full source-cited report: what each source said, where they agree, where they conflict, and what is simply missing.

A cohort. VCF is the universal genomics interchange format, every sequencing pipeline emits one. Drop in a VCF (or a CSV/TSV, or a pasted list of rsIDs) and every variant is checked against all five sources, scored, and ranked by which ones a human should open first. Claude then makes exactly one call to summarize the whole cohort. The parser tells you what it skipped and why, rather than silently dropping rows.

one variant  ─┐                             ┌─► report: every claim cited to its source
              ├─►  five sources, in parallel ┤
a VCF / CSV  ─┘    RegulomeDB · Ensembl VEP  │
                   Open Targets · gnomAD     │
                   Myint 2020 MPRA           │
                          │                  │
                          ▼                  │
              deterministic triage score ────┤
              (no model in this loop)        │
                          │                  │
                          ▼                  ▼
              ranked cohort  ──────►  ONE Claude call: which rows to open first

Evidence sources

Five sources, four predictive / annotation / database, one experimental:

Source Contributes
RegulomeDB Core regulatory impact score (rank 1a to 7)
Ensembl VEP Regulatory consequence / feature & motif overlap
Open Targets Annotation, nearest-gene distances, ClinVar precedent
gnomAD Population allele frequency
Myint et al. 2020 MPRA Experimental corroboration/contradiction of the predicted signal

Full rationale, and the sources we rejected with reasons, is in docs/data-sources.md.

The triage score, and what it is not

The ranking is produced by backend/app/services/triage.py: pure, offline, deterministic. Every point it awards is shown with its plain-English label, the source it came from, and the raw value it was computed from, so any row can be taken apart by hand. The rubric is served verbatim at GET /api/rubric and printed under every cohort table.

It is a heuristic triage prior for human review. The weights are hand-picked. It is NOT a validated pathogenicity classifier, and it has NOT been benchmarked against a labelled truth set. It answers "which of these does a human need to look at first", nothing more.

Two rules in it are worth knowing:

  • Absence of data is never a penalty. A variant the MPRA never tested, or that RegulomeDB never scored, is listed as not assessed, not scored down. "We did not look" and "we looked and found nothing" are different facts and are kept apart.
  • The ACMG/AMP BA1 frequency cap is the one rule we did not invent. An allele frequency above 5% is stand-alone evidence against a Mendelian disease role (Richards et al., Genet Med 2015), so a common variant is capped out of "Review first" no matter what else it scores. Be precise about what that means: "not your rare-disease answer", NOT "not real". A common allele can still have a real, measured regulatory effect. The cap moves the band, states its reason on the row, and retracts no evidence.

The grounding benchmark

backend/bench/ measures the one thing this tool actually claims: grounding. Does the generated prose contain a gene, a number, a rank, a count or an experimental result that is not in the evidence bundle that produced it? It runs the real pipeline over 24 real variants and exits non-zero on any ungrounded claim.

Scope, stated exactly. It measures grounding, not clinical accuracy. We have no labelled truth set for regulatory VUS and we make no accuracy claim: no AUROC, no sensitivity, no specificity. A report can be perfectly grounded and still be clinically wrong.

The part worth your attention is that the benchmark ships with an adversarial self-test, so you do not have to take the check on faith. It runs 64 deliberate fabrications through the real audit functions and asserts they are caught: 57 are, 7 are not, and all 7 are disclosed in bench/README.md, each with a test asserting it still slips so a hole cannot quietly stop being disclosed. Seven paragraphs of legitimately grounded prose are then fed in, and the audit must flag nothing. A check that flags everything is as useless as one that flags nothing. The measured rate at which an arbitrary number grounds by coincidence (8.8%) is printed next to every zero it qualifies.

Two adversarial reviews of this benchmark found, in order, that 16 of 17 and then 7 of 23 fabricated claims sailed through it. bench/README.md is the record of what that cost and what is still missing.

Run it

Prerequisites: Python 3.10+, Node 18+, and an Anthropic API key.

# Backend (terminal 1)
cd backend
python -m venv .venv && source .venv/bin/activate    # Windows: .venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env                                  # then set ANTHROPIC_API_KEY in .env
uvicorn app.main:app --reload                         # http://localhost:8000

# Frontend (terminal 2)
cd frontend
npm install
npm run dev                                           # http://localhost:5173

Open http://localhost:5173. Try rs2439202 (sources disagree, Claude reconciles), rs2736100 (ClinVar precedent), or rs6983267 (strong regulatory signal). For cohort mode, hit "Try the sample cohort", or drop in backend/data/examples/demo_cohort.vcf (24 real variants, including one indel and one multi-allelic site that are supposed to be skipped, so you can see the parser say so). The Vite dev server proxies /api to the backend.

Tests and the benchmark

cd backend
python -m pytest -q                              # backend test suite
python -m pytest bench/test_audit.py -q          # the adversarial self-test: 82 tests, offline, no API key
python -m bench.grounding_audit                  # the full benchmark: live APIs, needs ANTHROPIC_API_KEY

The self-test needs no network and no key: it is the fastest way to see what the grounding check does and does not catch. The full benchmark writes bench/results/grounding.md (the table a human reads) and bench/results/grounding.json, and exits 1 on any ungrounded claim.

cd frontend && npm run typecheck                 # frontend types

API

GET  /api/variant?chr=8&pos=127401060&ref=G&alt=T     one variant, full cited report
GET  /api/variant?rsid=rs2439202                      the same, by rsID
POST /api/batch                                       a cohort: multipart "file", or JSON {"text": "..."}
GET  /api/rubric                                      the scoring rubric, verbatim

Synthesis model: claude-fable-5 declines this clinical-genomics task (stop_reason: refusal); the default is claude-sonnet-5 (override via SYNTHESIS_MODEL). Without an API key the five sources, the triage score and the ranking all still run; only the Claude summary is skipped, and the app says so rather than degrading quietly.

Data

The Myint 2020 MPRA dataset (backend/data/myint_2020_mpra.csv) is not committed: it is third-party data whose redistribution rights we have not confirmed. See backend/data/README.md for provenance and one-step reproduction from MPRAVarDB. Without it, the other four sources are unaffected and the MPRA source reports "not tested."

The demo cohort is a synthetic file of real, published variants. No individual was sequenced. Every coordinate in it was read out of a file in this repo or resolved live from Ensembl and checked against the GRCh38 reference; the provenance of each row, and a genuine data error we found in the upstream MPRA export and did not paper over, are in backend/data/examples/README.md.

Docs

Doc What's in it
docs/system.md What it is, who it's for, hackathon rules & judging criteria
docs/architecture.md Architecture, both pipelines, verified API contracts, schemas
docs/data-sources.md Every source, chosen, secondary, and rejected with reasons
backend/bench/README.md The grounding benchmark: what it catches, what it misses
docs/checklist.md Running task list
docs/submission-summary.md 100 to 200 word written submission summary

License

MIT, open source, per the hackathon requirement. Only data and code we have explicit rights to use are included (see Data for the Myint dataset).

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages