How to Use Jev for Resume Screening (Fair, Fast First Pass)
TL;DR: A job description is a checklist wearing a paragraph costume. Convert each hard requirement into a
judgmentquestion, use ascoringcall for overall fit on a 1-10 scale, and send anything borderline to a recruiter with the rationale attached. You get a fast, consistent first pass that is also auditable — which is exactly what fairness reviewers and compliance teams will ask for.
From JD to question list
Screening decisions must be explainable, so start by rewriting the JD:
- Hard requirements → judgment calls. “5+ years backend”, “worked with distributed systems”, “authorized to work in X”. One question each, answered yes/no/unclear. Example fixture:
{"answer":"yes","confidence":0.97,"rationale":"Led backend teams for 7 years per the work history section."}
- Overall fit → scoring call. After the checklist, ask for a 1-10 fit score against the JD’s stated responsibilities. Fixture:
{"answer":8,"scale":[1,10],"confidence":0.86,"rationale":"Matches stack and seniority; missing the stated fintech background."}
- What stays out: age proxies, names, schools used as proxies, photo, marital status, or any protected characteristic. If it is not a written job requirement, it is not a question.
Screening flow
Resume + JD question list
|
v
Judgment call per hard requirement (yes / no / unclear)
|
+--> any "no" on a true hard requirement --> reject, keep rationale
|
+--> any "unclear" or low confidence --> recruiter queue
|
+--> all requirements pass
|
v
Jev scoring call (fit, scale 1-10)
|
+--> score >= 8 and confidence high --> advance to interview
|
+--> score 6-7 or lower confidence --> recruiter queue
|
+--> score < 6 --> reject, keep rationale
Every reject and every advance stores answer, confidence, and rationale. Recruiters see why, candidates can be told why, and auditors can replay why.
Minimal implementation
import os, json, requests
URL = "https://openrouter.ai/api/v1/chat/completions"
# Confirm the exact model slug on the OpenRouter model page.
MODEL = "typesafe/jev-1.13"
def ask(question: str, resume: str) -> dict:
resp = requests.post(
URL,
headers={"Authorization": f"Bearer {os.environ['OPENROUTER_API_KEY']}"},
json={"model": MODEL, "temperature": 0, "messages": [
{"role": "system", "content":
"Answer strictly from the resume. yes, no, or unclear. "
"If the resume does not state it, answer unclear."},
{"role": "user", "content": f"Requirement: {question}\n\n{resume[:6000]}"}]},
timeout=30,
)
resp.raise_for_status()
# example fixture:
# {"answer":"yes","confidence":0.97,"rationale":"..."}
return json.loads(resp.json()["choices"][0]["message"]["content"])
def screen(resume: str, requirements: list[str], low=0.85):
for req in requirements:
r = ask(req, resume)
if r["answer"] == "no":
return {"stage": "rejected", "requirement": req, **r}
if r["answer"] == "unclear" or r["confidence"] < low:
return {"stage": "recruiter-queue", "requirement": req, **r}
return {"stage": "checklist-pass", **ask("Overall fit 1-10.", resume)}
Note the “answer unclear if not stated” instruction — it is what stops the model from guessing on missing information.
Fairness and compliance notes
| Concern | Practice |
|---|---|
| Question scope | Only written, job-relevant requirements; no protected characteristics |
| Missing data | Model must answer unclear, never infer from gaps |
| Record keeping | Store question, answer, confidence, rationale, model version per decision |
| Human in the loop | All unclear results, all low-confidence results, all final decisions |
| Bias checks | Periodically sample decisions across groups and compare pass rates |
Why fixed-format questions beat asking a chat model to “evaluate this resume” is covered in the Jev vs. LLM-as-a-judge comparison, and the resume fit scoring case study shows the full pipeline. Threshold tuning details are in the confidence and fallback guide.
Applies to Jev 1.13.
FAQ
- Why separate yes/no questions instead of one prompt? Each hard requirement becomes its own judgment call with confidence and rationale, so every screen decision is small, consistent, and reviewable.
- How do I keep it fair and compliant? Score only job-relevant criteria, require
unclearinstead of inference, log every decision with rationale, and keep humans in the loop for borderline and final calls. - Where does the human review threshold sit? Auto-advance only when every hard requirement passes with high confidence; everything else — any
unclearor low-confidence result — goes to a recruiter queue.