用 Jev 做简历初筛:快速且可复核
更新于 适用版本 Jev 1.13
TL;DR: 一份 JD(职位描述)本质是穿着段落外衣的检查清单。把每条硬性条件转成一道
judgment判断题,整体匹配度用一次scoring打 1-10 分,边界情况连同 rationale 交给招聘人员。你得到的是一轮快速、一致、而且可审计的初筛——这正是公平性审查和合规团队要看的东西。
从 JD 到问题清单
筛选决策必须可解释,所以先改写 JD:
- 硬性条件 → judgment 调用。“5 年以上后端经验""做过分布式系统""可在 X 地合法工作”。一题一问,答案 yes/no/unclear。示例数据(example fixture):
{"answer":"yes","confidence":0.97,"rationale":"工作经历部分显示其带过后端团队 7 年。"}
- **整体匹配度 → scoring 调用。**检查清单过完之后,对照 JD 写明的职责打 1-10 匹配分。示例:
{"answer":8,"scale":[1,10],"confidence":0.86,"rationale":"技术栈与级别匹配;缺少要求的金融科技背景。"}
- 不进问题的东西:年龄暗示、姓名、用作代理的学校、照片、婚姻状况等一切受保护特征(protected characteristics)。不是书面岗位要求,就不是一道题。
初筛流程图
简历 + JD 问题清单
|
v
逐条硬性条件调用 judgment(yes / no / unclear)
|
+--> 某条真实硬性条件为 no --> 淘汰,保留 rationale
|
+--> 出现 unclear 或低置信度 --> 招聘人员队列
|
+--> 全部条件通过
|
v
Jev scoring 调用(匹配度,1-10 分制)
|
+--> 分数 >= 8 且置信度高 --> 推进到面试
|
+--> 分数 6-7 或置信度低 --> 招聘人员队列
|
+--> 分数 < 6 --> 淘汰,保留 rationale
每次淘汰和每次推进都存 answer、confidence、rationale。招聘人员看得到原因,候选人问得到原因,审计方能回放原因。
最小实现
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)}
注意系统提示里的”简历没写就答 unclear”——正是这句话阻止模型对缺失信息瞎猜。官方 API 的端点与字段以 typesafe.ai 官方文档为准。
公平与合规注意事项
| 关注点 | 做法 |
|---|---|
| 问题范围 | 只问书面、与岗位相关的要求;不碰受保护特征 |
| 信息缺失 | 模型必须答 unclear,不允许从空白推断 |
| 记录留存 | 每次决策存问题、answer、confidence、rationale、模型版本 |
| 人工环节 | 所有 unclear、所有低置信度、所有最终决定 |
| 偏差检查 | 定期抽样对比不同群体的通过率 |
为什么固定格式的问题比让聊天模型”评价一下这份简历”更可靠,见 Jev 与 LLM-as-a-judge 对比指南;简历匹配度打分案例展示了完整流水线;阈值调优见置信度与兜底指南。
本文适用版本:Jev 1.13。
FAQ
- 为什么拆成多个是/否问题? 每条硬性条件都是独立的 judgment 调用,带 confidence 和 rationale,每次筛选决策都小、一致、可复核。
- 怎么保证公平合规? 只问岗位相关要求,缺信息必须答 unclear,每次决策留痕带 rationale,边界和最终决定保留人工。
- 人工复核阈值放哪? 只有全部硬性条件高置信度通过才自动推进;任何 unclear 或低置信度结果都进招聘人员队列。