Jev 案例:简历与 JD 匹配打分(完整代码)

更新于 适用版本 Jev 1.13 示例数据(example fixture)

TL;DR: 本示例用 Jev 1.13 上的一道打分题完成简历与 JD 的匹配打分:返回 1-10 的分数、置信度,以及招聘人员可以直接审计的一句话依据。完整请求体、示例数据(example fixture)响应和可运行 Python 脚本见下文。

场景

我们公司一个职位开放后能收到两百多份简历。招聘人员的第一遍筛选——打开简历、对照 JD、写一句备注——每人要花十分钟,而且到了周五下午,筛选质量会明显漂移。我们并不想把招聘决策自动化,只想把”第一遍备注”自动化:每份申请在人工过目之前,先拿到一个匹配分和一句解释。

我们选的工具是 Jev——TypeSafe AI 发布的 System One 判断模型,2026 年 9 月上线——把它当打分题用:

给这份简历与这份 JD 的匹配程度打分,1 到 10 分。

返回的是类型化 JSON:answer(分数)、scaleconfidencerationale。与让通用聊天模型做同一件事相比(差异在Jev 与 LLM-as-a-judge 对比指南里有展开),区别在工程层面:答案以固定结构返回并带置信度,兜底规则(“低置信度 → 人工再看一遍”)就是一次数值比较,而不是一次文本解析练习。我们要的不是求职信,而是一个能排序的数字,附带证据。

一个比任何提示词都重要的政策说明:分数不自动淘汰任何人。它只负责给队列排序、标记明显不匹配的申请。决策永远由人来做。

请求

{
  "model": "typesafe/jev-1.13",
  "messages": [
    {
      "role": "system",
      "content": "Scoring question. Score how well the resume fits the job description, on a scale of 1 to 10. Reply with JSON only: {\"answer\": <1-10>, \"scale\": [1, 10], \"confidence\": <0-1>, \"rationale\": <one sentence>}"
    },
    {
      "role": "user",
      "content": "Job description:\nSenior Backend Engineer: 5+ years of Python, PostgreSQL, Kubernetes. Owns payment services. Remote-friendly, EU time zones.\n\nResume:\n8 years backend, mostly Python and Go. Ran the billing platform at a fintech: PostgreSQL at 2TB, deployed on Kubernetes. Based in Berlin. Last role: Staff Engineer, payments."
    }
  ]
}

响应

示例数据(example fixture)——用于说明格式,不是线上实测抓包:

{
  "answer": 8,
  "scale": [1, 10],
  "confidence": 0.86,
  "rationale": "Exceeds the Python and payments-service requirements and matches the Kubernetes and EU-location criteria, with less evidence of day-to-day PostgreSQL ownership at scale."
}

rationale 才是招聘人员真正读的部分。它同时说清了加分项和扣分项——这本来就是一份好的初筛备注该有的样子。

复现脚本

保存为 fit.py,设置环境变量 OPENROUTER_API_KEY 后运行 python3 fit.py

import json, os, urllib.request

URL = "https://openrouter.ai/api/v1/chat/completions"
MODEL = "typesafe/jev-1.13"  # confirm exact slug on the OpenRouter model page

JD = """Senior Backend Engineer: 5+ years of Python, PostgreSQL,
Kubernetes. Owns payment services. Remote-friendly, EU time zones."""

RESUME = """8 years backend, mostly Python and Go. Ran the billing
platform at a fintech: PostgreSQL at 2TB, deployed on Kubernetes.
Based in Berlin. Last role: Staff Engineer, payments."""

SYSTEM = ('Scoring question. Score how well the resume fits the job '
          'description, on a scale of 1 to 10. Reply with JSON only: '
          '{"answer": <1-10>, "scale": [1, 10], "confidence": <0-1>, '
          '"rationale": <one sentence>}')

body = {"model": MODEL, "messages": [
    {"role": "system", "content": SYSTEM},
    {"role": "user", "content": "Job description:\n" + JD + "\n\nResume:\n" + RESUME}]}

req = urllib.request.Request(URL, data=json.dumps(body).encode(),
    headers={"Authorization": "Bearer " + os.environ["OPENROUTER_API_KEY"],
             "Content-Type": "application/json"})

with urllib.request.urlopen(req) as res:
    payload = json.load(res)

result = json.loads(payload["choices"][0]["message"]["content"])
print(result["answer"], result["confidence"])
print(result["rationale"])

关键参数

字段取值说明
modeltypesafe/jev-1.13固定版本,整批候选人的分数才有可比性。准确 slug 请以 OpenRouter 模型页为准。
messages[0](system)打分题 + 量程 + JSON 结构固定标尺(1-10)加固定输出结构,分数才能排序。
messages[1](user)先 JD 后简历,各自带标签两个文本块都要显式标注;不标注就是让模型猜哪段是哪段。
answer(响应)8申请队列的排序键。
scale(响应)[1, 10]回显标尺,每次调用顺手做个哨兵检查。
confidence(响应)0.86(示例数据)低置信度的分数回到人工 pile 的顶部,而不是底部。
rationale(响应)一句话可审计的初筛备注。
价格$0.0462 / 1M input tokens每份申请一次调用;预算前请在 OpenRouter 核对当前价格。

注意事项

继续阅读