Launch offer+40%Claim →

Jev phishing detection: five signals beat one verdict

Jev's single raw verdict lost on accuracy to a cheap LLM in an independent test — but combining five cheap signal questions from the same call beat it decisively.

Run this example

5 questions · no key needed

The problem

Phishing classification is high volume and latency-sensitive, which makes the speed and cost profile attractive. But security is exactly where you should not take a vendor's accuracy claim on faith.

How Jev handles it

Rather than asking one "is this phishing?" question, ask several orthogonal signal questions in the same call — sender plausibility, urgency pressure, credential solicitation, link/domain mismatch — and combine them in your own classifier.

python
def signal(instructions, yes, no):
    return Noul(instructions=instructions,
                criteria=NoulCriteria(true=yes, false=no))

response = client.system_one(
    model="jev-latest",
    state=email_text,
    questions={
        "urgency": signal("Does this create artificial time pressure?",
                          "Deadlines or threats of loss", "No time pressure"),
        "credentials": signal("Does this ask for credentials?",
                              "Requests login, password or MFA code", "No credential request"),
        "sender_odd": signal("Is the sender identity inconsistent?",
                             "Display name conflicts with address", "Sender looks coherent"),
        "link_mismatch": signal("Does link text disagree with its destination?",
                                "Anchor text and href point elsewhere", "Links are consistent"),
        "unusual_ask": signal("Is an unusual financial action requested?",
                              "Wire transfer, gift cards, payment change", "No financial request"),
    },
)

# Five probabilities in, your own classifier decides
features = [response.answers[k].noul for k in
            ("urgency", "credentials", "sender_odd", "link_mismatch", "unusual_ask")]
is_phishing = my_logistic_model.predict_proba([features])[0][1]
Measured outputtypesafe/jev-1.13 · 2026-09-18

State sent the example loaded in Run this example above, as it first appears.

Answers returned

urgency0.97
credentials0.86
sender_odd0.81
link_mismatch0.37
unusual_ask0.02
Latency (median of 3)
498.9ms
Minus network floor (198.8ms)
≈300ms
Input tokens
533
Cost
$0.00002239

Five signals in one call — the pattern the phishing benchmark found beats a single verdict question.

Does it actually work?

Independent evidence

Across 2,000 phishing emails, Jev's own verdict was statistically worse than Claude Haiku 4.5 (McNemar p < 0.0001) while winning on speed and cost. A cross-validated logistic regression over five signal questions asked in the same call reached 95.1% accuracy, AUROC 0.988, ECE 0.027. Controls added after review narrow that: a two-line regex over link hosts scored 91.6% on the same emails, and on held-out mail Claude Haiku 4.5 asked the same five questions reached 93.2% against Jev's 95.0%, a gap that is not significant. Jev's edge is price, about 27 times cheaper for signals of similar quality. Latency was measured wall-clock from France against US-hosted services.

anisselbd/jev-phishing-bench

Choosing the signals for Jev phishing detection

Good Jev phishing detection starts with signals an analyst would check one at a time, so each carries information the others do not: pressure to act fast, a request for credentials, a sender that does not add up, a link that lies about its destination, an unusual payment ask. Each is a Noul whose instruction and criteria point the same way, with true meaning suspicious. Keep a catch-all "is this phishing?" out of the decision path — in the independent benchmark, that single verdict is the part that lost.

Fit the combiner on your own labelled mail and on the model you will actually run. Our head-to-head of 2026-09-20 found the same five questions producing a different profile per model: asked whether the measured email requests credentials, Jev answered 0.86 or 0.87 on every run, GPT-5 nano stayed between 0.0 and 0.2, and Gemini 2.5 Flash Lite said 1.0. Weights learned on one model's signals do not transfer to another's.

What to put in the state

A Jev phishing detection call can only judge what the state shows, so give each signal something concrete to read. Put the From display name and address on separate labelled lines, add Reply-To when it differs, and extract every link as its anchor text and its real href — rendering HTML to plain text throws away exactly the pair the link question needs. The measured email shows the cost: its link appeared as a bare URL after "Verify now", so there was no anchor to compare, and link_mismatch came back at 0.37.

Anything you can compute — SPF and DKIM results, the age of the sending domain, a lookalike match against your own domains — belongs in the state as a plain statement, or straight into the combiner as a feature. Jev reads text; it cannot resolve a domain or query a reputation list.

What one decision costs

Jev phishing detection has two costs worth knowing: screening live mail, and building the labelled set that makes the combiner trustworthy. First line: the measured email with five questions. Second: a 2,000-email evaluation — the independent benchmark's size — at that token count. Third: 50,000 emails a day for 30 days.

arithmetic
# the measured email, five questions
533 tokens × $0.042 / 1M = $0.0000224

# a 2,000-email labelled evaluation at that size
2,000 × 533 = 1,066,000 tokens × $0.042 / 1M = $0.0448

# 50,000 emails a day for 30 days
1,500,000 × 533 = 799,500,000 tokens × $0.042 / 1M = $33.58

The evaluation line is the one to notice. Scoring five signals across two thousand of your own labelled emails costs under five cents, so there is no budget reason to ship on vendor numbers.

Jev's answers on the measured call — urgency: 0.97; credentials: 0.86; sender odd: 0.81; link mismatch: 0.37; unusual ask: 0.02, $22.39 per million calls

When not to use Jev for this

Where it fits in your stack

In a mail pipeline, the Jev phishing detection call happens after the gateway's authentication checks and before delivery: code parses headers and links, the call asks the five questions, and the five probabilities join your computed features in a small logistic regression that makes the decision. That model is cheap to refit whenever you add a signal.

Quarantine rather than delete on a high score, show a warning banner in the middle band, and feed every user report back as a label — reports are the ground truth this pipeline improves on.

Notes from the field

Common questions

Is Jev phishing detection accurate enough to use on its own?

Not on the published evidence. Across 2,000 emails the single verdict lost to Claude Haiku 4.5 (McNemar p < 0.0001). What worked was combining: a cross-validated logistic regression fitted on the five signal probabilities reached 95.1% accuracy (AUROC 0.988, ECE 0.027). Build that, not the one verdict.

How fast is a Jev phishing detection call?

The five-question call measured 267 ms median against the first-party API, 74 ms of it server time — about the same as a single-question call, because the questions run in parallel. The benchmark's own latencies were taken from France against US-hosted services, so measure from where your mail servers sit.

Can I add a sixth signal later?

Yes: it is one more entry in the questions dict and barely changes latency or cost, since the email is sent once. Refit the combiner afterwards — a signal the model was never trained on is just noise to it.