A System One decision model with open weights. Give it a document (text, email, ticket, log or JSON) and typed questions; it returns typed answers (yes/no, a choice between options you describe, or a score on levels you define) with a calibrated probability for every option, in one pass. It never generates text, so there is nothing to parse and nothing to hallucinate. It runs on your own machines: your documents never leave them.
398.2M parameters (ModernBERT-large plus a 3.5M-parameter decision network), English, up to 4,096 input tokens; runs on a laptop CPU or GPU, an edge box, or any GPU.
| Model | Size | Runs on | Best for | Status |
|---|---|---|---|---|
| Beveridge-Large-C | 0.4B (ModernBERT-large base) | laptop CPU/GPU, edge boxes, any GPU | operations documents, logs and alerts, counting, amounts and limits, ticket routing, request safety | available |
| Beveridge-Pro-C | 26B (Gemma 4 26B-A4B base) | one GPU with about 60 GB | knowledge-heavy decisions: contracts, finance topics, large intent sets, dates and payment status | available |
Installation
python -m pip install bev-decisions
Python 3.10 or newer. Optional extras: bev-decisions[serve] (HTTP server), bev-decisions[mcp] (MCP server for AI
assistants and agents), bev-decisions[structured] (Pydantic schemas), bev-decisions[all]. The first bev.load()
downloads the model from this repository and caches it; after that it works offline.
Quickstart
import bev
model = bev.load("sathiskumarjothi0/Beveridge-Large-C")
answers = model.decide(
"Subject: Charged twice for order 88412. I was billed $49.99 twice on 3 October. Please refund one payment today.",
{
"team": {"type": "choice", "instructions": "Which team should handle this ticket?",
"criteria": {"billing": "payments, invoices, refunds", "tech": "bugs, outages, errors", "sales": "pricing and plans"}},
"urgent": {"type": "noul", "instructions": "Does the customer ask for urgent handling?"},
"severity": {"type": "score", "instructions": "How severe is the problem for the customer?", "criteria": ["low", "medium", "high"]},
},
)
answers["team"] # {"choice": ..., "confidence": ..., "probabilities": {...}}
Run with or without a GPU
bev.load() picks the best device it finds: an NVIDIA GPU (cuda), an Apple Silicon GPU (mps), otherwise the CPU.
Choose one yourself with device=:
model = bev.load("sathiskumarjothi0/Beveridge-Large-C", device="cpu") # no GPU needed
model = bev.load("sathiskumarjothi0/Beveridge-Large-C", device="cuda") # NVIDIA GPU
model = bev.load("sathiskumarjothi0/Beveridge-Large-C", device="mps") # Apple Silicon GPU
Command line: bev "I was charged twice, please refund" --noul "Does the customer ask for a refund?" --device cpu.
| Device | First load | One document with 3 questions |
|---|---|---|
| Apple M4 Pro laptop, CPU only | about 25 s | about 0.18 s |
Apple M4 Pro laptop, GPU (mps) |
about 22 s | about 0.05 s |
One NVIDIA H200 GPU (cuda) |
about 32 s | about 0.015 s |
The first load includes reading the 1.6 GB weights; after that, use decide_batch for many documents.
Use cases
| Use case | Example questions | Where the evidence is |
|---|---|---|
| Support inbox triage | which team (choice), urgent? (yes/no), customer sentiment (score) | Beveridge-Bench ticket questions; support intents |
| Request safety and guardrails | is this request harmful? is it a jailbreak attempt? | Aegis 2.0 and JailbreakBench |
| AI agents: tool dispatch and checks | does this need a tool? which tool? is this action risky? (MCP server: bev mcp) |
typed decisions |
| Model routing | which handler: rules, a small model, a large LLM or a person? how hard is this request? | typed decisions |
| Security and operations logs | attack category, failed logins above a number, severity, outage root cause | Beveridge-Bench security and alert questions |
| Back office documents | invoice total over the approval limit? how many items above a price? | Beveridge-Bench invoice questions |
| Contract and policy review | does this clause look unfair to the customer? which policy rule applies? | unfair contract terms; Rules-Bench |
| Reviews and content moderation | review sentiment, toxic comment? | product reviews; toxic comments |
Check any use case on a few hundred labelled examples of your own first (bev eval my_cases.jsonl).
Voice examples
Beveridge reads text, so it pairs well with open speech models: a caller's voice note is transcribed, Beveridge answers typed questions about it, fixed reply rules turn the answers into a reply, and a text-to-speech model speaks it. Same model, different questions: 23 use cases, from customer service, IT helpdesk and agentic AI to engineering, lab notes and robotics.
Speech to text: Whisper / faster-whisper (MIT). Text to speech: Kokoro-82M (Apache-2.0), stock voices only; no real person's voice is used. Use cases outside the areas Beveridge was tested on are illustrations. Runnable script: examples/14_voice_reply.py. Beveridge can make mistakes; keep a person in the loop for important decisions.
| Type | Use it for | Answer |
|---|---|---|
noul |
yes or no | noul: probability of yes |
choice |
one of the options you define (criteria: key → description, up to 300) |
choice, confidence, probabilities |
score |
ordered levels (criteria: list or key → description, lowest first) |
label, score (expected level), confidence, probabilities |
Up to 16 questions per call share one read of the document.
Confidence gating
sure, review = bev.gate(answers, threshold=0.8) # act on `sure`, send `review` to a person
Route mode
Route mode sends every question to Beveridge-Large-C first and only the unsure answers to Beveridge-Pro-C:
router = bev.Router(load_strong=True, threshold=0.8)
result = router.decide(text, questions)
result["answers"], result["routing"] # routing: {"team": "fast", "urgent": "strong"}
Schema-driven decisions
from typing import Literal
from pydantic import BaseModel, Field
class Ticket(BaseModel):
urgent: bool = Field(description="Does the customer ask for urgent handling?")
team: Literal["billing", "tech", "sales"] = Field(description="Which team should handle this ticket?")
ticket = bev.decide_as(model, text, Ticket) # Ticket(urgent=True, team='billing')
Self-hosting: HTTP and MCP
pip install "bev-decisions[serve]"
bev serve --model sathiskumarjothi0/Beveridge-Large-C --port 8000 # POST /v1/decide, /v1/batch; GET /v1/presets, /health
pip install "bev-decisions[mcp]"
bev mcp --model sathiskumarjothi0/Beveridge-Large-C # tools: decide, decide_preset, list_presets
The server listens on 127.0.0.1 without authentication; put it behind your own gateway before exposing it. Docker files and examples are in the GitHub repository.
Benchmarks
Accuracy (%) = correct answers ÷ questions on held-out test sets; the same cases for every system (October 2026). Bold = best in the row; – = not run. * = an area Beveridge was not built for.
Decisions on documents
| Test | Beveridge-Large-C | Beveridge-Pro-C | Jev | Mistral Large 4 | Mistral Large 3 | gpt-oss 120B | Gemma 4 31B | Nemotron 3 Super |
|---|---|---|---|---|---|---|---|---|
| Beveridge-Bench (operations documents) | 93.0 | 91.9 | 87.9 | 83.7 | 74.6 | 91.1 | 88.9 | 70.6 |
| Typed decisions | 75.8 | 79.2 | 73.8 | 72.0 | 68.0 | 68.8 | 75.0 | 62.7 |
| Rules-Bench (rules shown) | 85.6 | 92.0 | 92.3 | 83.1 | 81.4 | 94.5 | 91.6 | 82.7 |
| JailbreakBench refusal | 84.5 | 84.0 | 83.5 | 77.5 | 62.0 | 68.0 | 87.5 | 65.0 |
| Aegis 2.0 request safety | 82.3 | 78.2 | 71.5 | 70.5 | 66.9 | 69.5 | 73.1 | 69.3 |
Public classification tests
| Test | Beveridge-Large-C | Beveridge-Pro-C | Jev | Mistral Large 4 | Mistral Large 3 | gpt-oss 120B | Gemma 4 31B | Nemotron 3 Super |
|---|---|---|---|---|---|---|---|---|
| AG News | 86.6 | 90.6 | 91.8 | 90.8 | 88.8 | 88.8 | 91.8 | 87.8 |
| Emotion | 53.2 | 56.2 | 57.6 | 55.8 | 55.6 | 57.8 | 55.4 | 50.2 |
| Banking77 (77 intents) | 63.6 | 70.6 | 79.2 | 75.8 | 71.2 | 81.0 | 78.8 | 69.2 |
| SST-5 (5-level sentiment) | 33.2 | 51.8 | 56.8 | 51.4 | 49.4 | 49.6 | 53.2 | 46.8 |
| XNLI (English) | 84.6 | 86.4 | 89.2 | 84.8 | 77.6 | 80.2 | 89.2 | 75.0 |
| MASSIVE intents | 59.4 | 74.8 | 80.8 | 78.4 | 75.2 | 81.6 | 83.8 | 69.4 |
Areas Beveridge was not built for
| Test | Beveridge-Large-C | Beveridge-Pro-C | Jev | Mistral Large 4 | Mistral Large 3 | gpt-oss 120B | Gemma 4 31B | Nemotron 3 Super |
|---|---|---|---|---|---|---|---|---|
| Product reviews* | 93.2 | 96.4 | 96.4 | 96.4 | 96.6 | 95.4 | 97.2 | 94.8 |
| Unfair contract terms* | 65.6 | 76.0 | 62.0 | 54.6 | 52.8 | 47.6 | 74.4 | 44.0 |
| Financial-news sentiment* | 69.8 | 59.2 | 66.4 | 64.0 | 50.4 | 68.4 | 71.2 | 64.0 |
| Poem sentiment* | 71.8 | 65.1 | 44.5 | 42.6 | 32.1 | 59.8 | 62.7 | 45.5 |
| Support intents* | 85.6 | 88.0 | 89.8 | 85.4 | 86.2 | 90.0 | 90.4 | 76.6 |
| Toxic comments* | 63.0 | 79.2 | 78.8 | 68.0 | 73.0 | 80.8 | 76.4 | 69.6 |
| Financial-news topics* | 37.8 | 69.8 | 65.0 | 61.8 | 61.6 | 63.4 | 64.2 | 57.2 |
| Legal case holdings* | 42.0 | 71.2 | 77.6 | 69.2 | 72.2 | 61.2 | 71.6 | 55.0 |
Size and speed
Accuracy on the same 10,238 answers against total parameters (log scale), for every system with a published size: Beveridge-Large-C (0.4B) and Beveridge-Pro-C (25.8B) are more accurate than LLMs of 31B to 675B.
| Beveridge, one document with 3 questions (package from PyPI) | Per decision | In batches of 64 |
|---|---|---|
| Beveridge-Large-C, one NVIDIA H200 GPU | 4.9 ms | 3.4 ms |
| Beveridge-Large-C, Apple M4 Pro laptop GPU | 17 ms | |
| Beveridge-Large-C, Apple M4 Pro laptop CPU | 60 ms | |
| Beveridge-Pro-C, one NVIDIA H200 GPU | 22 ms | 7.8 ms |
The LLMs and Jev were measured through their cloud APIs (median response time per decision, including network and queueing): Jev 98 ms, the five LLMs 4.1 to 7.0 s.
How much of the work can you automate?
Sort every answer from most to least confident and hand over the most confident ones first. The share you can hand over while those decisions stay at least 95% (or 90%) correct is the automation rate. Example: "76% at 95%" means 3 of every 4 decisions are taken automatically and at least 95% of them are right; the rest go to a person. Answers given with the same confidence are handed over together, so a system whose "100% sure" answers are only 94% right reaches 0% at the 95% target. Held-out tests: Beveridge-Bench, typed decisions and Aegis 2.0 request safety, 10,238 answers per system.
| System | Automated at 95% accuracy | Automated at 90% accuracy | Accuracy on all answers |
|---|---|---|---|
| Beveridge-Large-C | 76% | 93% | 87.0% |
| Beveridge-Pro-C | 69% | 90% | 86.0% |
| Jev | 59% | 77% | 81.1% |
| gpt-oss 120B | 0% | 74% | 81.4% |
| Gemma 4 31B | 0% | 71% | 82.2% |
| Mistral Large 4 | 0% | 0% | 78.1% |
| Mistral Large 3 | 0% | 0% | 71.4% |
| Nemotron 3 Super | 0% | 0% | 68.7% |
Beveridge-Bench, question by question
Averages hide weak spots. Bold = within 10 points of always answering the most common label, i.e. little or no skill.
| Question (300 cases each) | Beveridge-Large-C | Always-most-common baseline |
|---|---|---|
| Invoice: total over a limit? | 100.0% | 51.3% |
| Security log: attack category | 100.0% | 20.7% |
| Security log: severity | 100.0% | 39.0% |
| Security log: failed-login count | 100.0% | 59.7% |
| Outage alert: root cause | 100.0% | 5.3% |
| Outage alert: SLO breached? | 100.0% | 82.0% |
| Ticket: which department | 100.0% | 16.0% |
| Ticket: urgent? | 100.0% | 66.0% |
| Ticket: sentiment | 100.0% | 24.3% |
| Which date is earlier | 100.0% | 50.0% |
| Comparing two amounts | 100.0% | 52.0% |
| Choosing among many options | 100.0% | 0.7% |
| Invoice: items above a price | 99.7% | 14.7% |
| Counting items in a list | 96.3% | 10.0% |
| Long log: intrusion? | 84.0% | 52.7% |
| Invoice: payment status vs due date | 64.7% | 38.3% |
Calibration
| Test | Accuracy | Answered at confidence ≥ 0.8 | Accuracy of those | ECE |
|---|---|---|---|---|
| Beveridge-Bench (operations documents) | 93.0% | 86.9% | 98.9% | 0.029 |
| Rules-Bench (rules shown) | 85.6% | 76.8% | 94.7% | 0.034 |
| Aegis 2.0 request safety | 82.3% | 57.0% | 94.2% | 0.034 |
| Product reviews | 93.2% | 84.2% | 96.9% | 0.024 |
| Support intents | 85.6% | 72.6% | 95.0% | 0.031 |
| Typed decisions | 75.8% | 14.0% | 97.1% | 0.170 |
ECE (expected calibration error) = Σ over 10 confidence bins of (share of answers in the bin × |accuracy − mean confidence|); 0 is perfect. Example: a bin holding 40% of the answers at mean confidence 0.95 with 90% of them right adds 0.4 × 0.05 = 0.02. Calibration temperatures: noul 1.5, choice 1.2, score 1.0. Option-order flips: 103 of 3,035 answers (3.4%) change when options are shuffled.
Package check
The bev-decisions package was checked against the official evaluation run on 3,000 questions: 100.0% identical answers.
Honest limits
- Knowledge-heavy decisions are weak: legal case holdings 42.0%, financial-news topics 37.8%; use Beveridge-Pro-C for these.
- How late an invoice is paid, judged against today's date, is not reliable: compute due dates and lateness in your own code.
- Very large intent sets and five-level sentiment are weaker than the operations questions.
- With very many options (hundreds), the top answer is often right but its probability is low (on a 250-option question: right every time, at about 14% confidence); choose that question's threshold on your own data.
- Option order matters for a small share of questions: 3.4% of answers change when the options are shuffled, so keep the order stable between calls.
- English only; text beyond 4,096 tokens is cut; no images.
- Not for medical, legal or financial advice. For decisions with serious consequences, validate on your own data
(
bev eval my_cases.jsonl) and keep a person in the loop.
Files
| File | Contents |
|---|---|
model.safetensors |
weights (fp32), SHA-256 f89e53122b39f0fe… |
config.json |
settings and calibration temperatures |
encoder/ |
ModernBERT-large config and tokenizer (loads offline) |
eval/ |
test results and the package check |
assets/ |
the logo and the charts on this page |
Links
- Package: pypi.org/project/bev-decisions
- Code and examples: github.com/sathiskumarjothi0-oss/bev-decisions-pypi
- Beveridge-Pro-C: huggingface.co/sathiskumarjothi0/Beveridge-Pro-C
Support
If Beveridge is useful to you, you can support its development: buymeacoffee.com/sjothi
Licence and credit
Apache-2.0, © 2026 Dr. Sathiskumar JOTHI. Built on ModernBERT-large (Apache-2.0) by Answer.AI and LightOn.
About the name
Beveridge is named after Sir William Beveridge (1879–1963), the British economist, born in British India and educated in England, whose 1942 Beveridge Report laid the foundations of the modern welfare state and of the National Health Service (NHS), built for the good of future generations. The name is a reminder of what we want from the model: dependable, fair decisions that serve people, made carefully and checked against the facts.
Other models on Hugging Face are called Bev; they are not related to this model. The Python package keeps its short
name: pip install bev-decisions, import bev.
- Downloads last month
- 29
Model tree for sathiskumarjothi0/Beveridge-Large-C
Base model
answerdotai/ModernBERT-largeEvaluation results
- accuracy on Beveridge-Bench (operations documents)self-reported0.930
- accuracy on Typed decisionsself-reported0.758
- accuracy on Rules-Bench (rules shown)self-reported0.856
- accuracy on JailbreakBench refusalself-reported0.845
- accuracy on Aegis 2.0 request safetyself-reported0.824







