匹配度一跑分就崩 - JD与简历匹配AI的失败路径复盘
写给独立开发者和小团队:先看别人怎么翻车,再动手。
一、业务痛点
求职平台的刚需场景:用户投递简历后,希望系统能自动给出「这份JD和你的匹配度」,并推荐合适的岗位。听起来简单,实际坑很多:
- JD和简历都是非结构化文本,格式五花八门,PDF简历、Word简历、直接粘贴的文本都有;
- 匹配不是相似度,“熟悉Java"和"五年Java开发经验”语义相近,但要求不同;
- 时效性要求高,匹配结果要在用户投递的瞬间给出,不能等三分钟;
- 成本敏感,一个中型平台每天可能有几万次匹配请求,全用顶级大模型跑长文本,账单会失控。
二、常见的失败做法(反例)
反例一:直接把JD和简历全塞给大模型
# 失败示范
prompt = f"以下是职位描述:\n{jd_full_text}\n以下是简历:\n{resume_full_text}\n请给出匹配度分数。"
response = llm.call(prompt)后果:一份JD 1500字,一份简历 3000字,每次调用输入上万token。匹配质量没提升多少(大模型在长文本对比任务里容易遗漏细节),但延迟和账单先爆了。长文本场景下,模型经常只关注开头结尾,硬性要求(比如“必须持有某证书”)恰恰藏在中间。
反例二:用Embedding余弦相似度当匹配分
把两段文本向量化,算个余弦相似度就返回"匹配度78%"。这更是灾难:相似度反映的是“文本话题像不像”,不是“候选人满不满足要求”。一个“熟悉Python”的应届生和“精通Python、5年经验”的岗位,余弦相似度可能高达0.9。用户被误导,投诉接踵而至。
反例三:规则引擎写死关键词
if "Java" in resume and "Java" in jd: score += 20。三个月后需求变成“Java相关但接受转Go的岗位也要匹配”,规则表越写越长,最后没人敢动。
三、正确的路径:分层混合架构
核心思路:把“抽取”和“判断”拆开,各用最合适的手段。
简历入库 → 解析/结构化(一次性)
JD入库 → 解析/结构化(一次性)
匹配请求 → 粗筛(向量检索)→ 精排(LLM逐条比对)→ 输出结构化结果架构分层
- 解析层:简历PDF转文本,用开源解析库+小模型抽取结构化字段(技能、年限、学历、证书)。JD同样抽成结构化的“要求清单”,区分硬性要求和加分项。这一步在简历/JD入库时做一次,不要在每次匹配时重复做。
- 粗筛层:用Embedding做召回,但目的不是打分,而是从几千个岗位里筛出Top 50候选。允许漏一些,精排会兜底一部分。
- 精排层:用LLM逐条比对。关键改动是不要喂全文,只喂结构化字段:
def build_match_prompt(jd_reqs, resume_struct):
req_lines = "\n".join(
f"- {r['type']}: {r['content']}" for r in jd_reqs # 硬性/加分
)
return f"""你是招聘匹配专家。逐条判断候选人是否满足以下要求。
职位要求:
{req_lines}
候选人结构化信息:
{json.dumps(resume_struct, ensure_ascii=False)}
以JSON输出:
{{"hard_reqs": [{{"req": "...", "met": true/false, "evidence": "简历中的依据"}}],
"bonus_reqs": [...],
"match_score": 0-100,
"missing": ["未满足项"],
"summary": "一句话评价"}}"""输入从上万token降到几百token,延迟从十几秒降到两秒内,准确率反而更高——因为模型在逐条判断,而不是在长文本里“凭印象”。
- 输出层:把匹配结果落库,同一份简历对同一JD的结果缓存。用户改简历才重新计算。
四、为什么统一AI API网关能降低维护成本
这套方案要调用至少三类模型能力:小模型做解析抽取、Embedding模型做召回、中档模型做精排。如果每个能力各接一家厂商的SDK,你会遇到:
- 三套鉴权、三套SDK、三套错误处理,某家限流了、某家改了返回格式,你分别改三处代码;
- 模型升级即事故,厂商下线旧版本模型,硬编码的模型名直接报错;
- 账单分散在多个控制台,成本归因困难,没法知道匹配一次到底花多少钱。
统一走一个AI API网关后:
- 所有调用统一协议,切换或灰度新模型只改一个参数,不动业务代码;
- 抽取用便宜的模型、精排用能力强的模型,成本策略集中配置,不用在代码里到处写模型名;
- 调用日志、失败率、token消耗集中在一张报表里,成本可归因、事故可回溯。
对小团队来说,这意味着AI层的维护工作从“每个项目盯N家厂商”变成“维护一条统一通道”,人手省下来去做业务本身。
五、落地清单
- 选定简历/JD解析方案,产出结构化Schema(技能、年限、学历、证书、硬性要求标记);
- 建Embedding索引,实现Top 50粗筛;
- 按上文模板实现精排Prompt,强制JSON输出并做schema校验,解析失败自动降级重试;
- 接入统一AI网关,抽取/精排配置不同模型与预算上限;
- 上线前用50组人工标注的JD-简历对做评测,匹配结论与人工判断一致率达标(建议≥85%)再放量;
- 加缓存与结果落库,监控单次匹配成本与P95延迟。
结语
匹配系统的本质不是“让AI读两段文本打分”,而是把非结构化问题拆解成AI擅长的逐条判断。做好结构化这一步,再配一个统一网关把多模型管理收拢,独立开发者也能在两三周内跑出一个可用的匹配服务。
如果你也准备动手搭这套方案,可以先在 https://api.thistoken.ai/register 注册一个统一AI网关,把抽取、召回、精排三类调用跑通——落地成本比想象中低得多。
---
不想折腾多家供应商的接入差异?在 https://api.thistoken.ai/register 注册,用一个 base_url 调用所有模型。