智能简历筛选系统——AI 能替代 HR 的初筛工作吗
智能简历筛选系统——AI 能替代 HR 的初筛工作吗
适读人群:做HR科技/企业内部效率工具的工程师 | 阅读时长:约16分钟 | 核心价值:简历筛选AI系统完整案例,包含系统设计、Prompt工程、效果评估和真实局限
去年有个客户找我,HR总监,一脸愁容。
她说:"我们现在招聘量很大,每个岗位投简历的有几百个,初筛全靠HR手工看,一个人每天看200份简历,看完眼睛要瞎。你能不能做个AI帮我初筛?"
我问她,初筛的标准是什么。
她想了想说:"就看学历、工作年限、之前做过类似岗位不,感觉符合就发邀请面试。"
我心里咯噔了一下。"感觉符合"——这四个字意味着初筛标准是非结构化的、依赖经验的、有时候连HR自己都说不清楚的。
但项目最终还是做了。这篇把整个系统的设计、效果和真实局限写出来,结论可能和你预期的不一样。
系统设计思路
初筛任务拆解下来,有几类工作:
结构化信息提取(AI擅长):
- 教育背景(学校、专业、学历层次)
- 工作年限计算
- 历任公司和职位
- 技能关键词提取
匹配度评估(AI部分擅长):
- 技能匹配:候选人技能是否覆盖JD要求
- 行业经验相关性:是否有类似行业背景
- 成长轨迹:职位是否在上升
综合判断(AI不擅长):
- 候选人是否"有潜力但经验不足"
- 简历描述是否可信(项目描述是否夸大)
- 文化匹配感(很多HR凭直觉判断)
系统架构:
简历文件(PDF/Word)
|
v
[简历解析器]
- 提取文本
- 识别各部分(教育/工作/技能/自我介绍)
|
v
[结构化提取模块]
- LLM提取为标准JSON格式
- 解析学历、年限、技能
|
v
[JD匹配评估模块]
- 读取该岗位的JD
- 逐维度打分
|
v
[综合报告生成]
- 汇总分数
- 输出通过/待定/不通过建议
- 高亮匹配亮点和主要差距简历解析:比想象中更难
简历格式没有标准,这是最大的工程挑战。
我见过的简历格式包括:
- 标准Word格式(有各章节标题)
- PDF版设计简历(多栏布局,表格嵌套)
- 纯文本简历
- 从招聘网站导出的格式化文件
- 扫描版PDF(需要OCR)
针对不同格式,解析策略不同:
import pdfplumber
from docx import Document
from pathlib import Path
from typing import Optional
class ResumeParser:
def parse(self, filepath: str) -> str:
"""
解析简历文件,返回清理后的文本
"""
path = Path(filepath)
suffix = path.suffix.lower()
if suffix == '.pdf':
return self._parse_pdf(filepath)
elif suffix in ['.docx', '.doc']:
return self._parse_docx(filepath)
elif suffix == '.txt':
return path.read_text(encoding='utf-8')
else:
raise ValueError(f"不支持的文件格式: {suffix}")
def _parse_pdf(self, filepath: str) -> str:
"""解析PDF,处理多栏布局"""
texts = []
with pdfplumber.open(filepath) as pdf:
for page in pdf.pages:
# 尝试提取表格
tables = page.extract_tables()
if tables:
for table in tables:
for row in table:
row_text = ' | '.join(
cell if cell else '' for cell in row
)
texts.append(row_text)
# 提取普通文本
text = page.extract_text(layout=True)
if text:
texts.append(text)
return '\n'.join(texts)
def _parse_docx(self, filepath: str) -> str:
"""解析Word文档"""
doc = Document(filepath)
texts = []
for paragraph in doc.paragraphs:
if paragraph.text.strip():
texts.append(paragraph.text)
# 处理表格(很多Word简历用表格布局)
for table in doc.tables:
for row in table.rows:
row_text = ' | '.join(
cell.text.strip() for cell in row.cells
)
if row_text.strip(' |'):
texts.append(row_text)
return '\n'.join(texts)提取出文本之后,才能送给LLM做结构化解析。
核心Prompt:结构化信息提取
EXTRACT_PROMPT = """请从以下简历文本中提取结构化信息。
简历文本:
{resume_text}
请提取以下信息并以JSON格式输出:
{{
"basic_info": {{
"name": "姓名(如无则null)",
"current_location": "所在城市",
"phone": "电话(如无则null)",
"email": "邮箱(如无则null)"
}},
"education": [
{{
"school": "学校名称",
"degree": "学历层次(专科/本科/硕士/博士)",
"major": "专业",
"start_year": 2018,
"end_year": 2022,
"is_985_211": true/false
}}
],
"work_experience": [
{{
"company": "公司名称",
"position": "职位",
"start_date": "2022-07",
"end_date": "2024-03",
"duration_months": 20,
"industry": "行业(如能判断)",
"responsibilities": ["主要职责描述1", "主要职责描述2"],
"achievements": ["量化成果1", "量化成果2"]
}}
],
"skills": ["技能1", "技能2"],
"total_work_years": 3.5,
"self_summary": "自我评价原文(如有)"
}}
注意:
- 日期格式统一为YYYY-MM,在职则end_date填"至今"
- duration_months根据start_date和end_date计算
- is_985_211根据学校名称判断,不确定填false
- total_work_years是所有工作经验的总年限(不含空窗期重叠)
- 如果信息不存在,对应字段填null"""这个Prompt在测试中跑了500份简历,结构化提取的准确率约91%。主要失败场景:
- 简历格式特别乱,文字顺序被打乱(PDF多栏)
- 日期格式非常奇特(比如"2020年7月-2022年初")
- 工作经历描述和教育背景混在一起
JD匹配评估:打分逻辑
有了结构化简历数据,下一步是和岗位要求对比:
JD_MATCH_PROMPT = """你是一名专业的招聘顾问。请评估以下候选人简历与岗位要求的匹配程度。
岗位名称:{job_title}
岗位要求:
{job_description}
候选人信息:
{candidate_info}
请从以下4个维度打分(1-10分),并给出打分理由:
1. 技能匹配度(权重30%)
- 必要技能是否具备
- 加分技能有多少
2. 经验相关度(权重35%)
- 工作年限是否达标
- 过往行业/职能是否相关
- 核心工作内容是否match
3. 学历匹配(权重15%)
- 学历层次是否满足要求
- 学校背景
4. 成长潜力(权重20%)
- 职位轨迹是否上升
- 有无量化的工作成果
- 稳定性(工作时长是否太短)
输出JSON格式:
{{
"scores": {{
"skill_match": 8,
"experience_relevance": 7,
"education_match": 9,
"growth_potential": 7
}},
"weighted_total": 7.65,
"highlights": ["候选人的主要亮点1", "亮点2"],
"concerns": ["主要顾虑1", "顾虑2"],
"recommendation": "推荐面试/待定/不推荐",
"recommendation_reason": "推荐或不推荐的核心理由(50字以内)"
}}
注意:weighted_total = skill_match×0.3 + experience_relevance×0.35 + education_match×0.15 + growth_potential×0.2"""效果评估
系统上线后跑了两个月,我们做了一个"AI推荐 vs 人工复核"的对比研究:
取500份简历,HR先不看AI结果,做人工判断(通过/不通过/待定),然后和AI结果对比。
| 指标 | 数据 |
|---|---|
| AI推荐"通过",HR也认为"通过" | 76% |
| AI推荐"不通过",HR也认为"不通过" | 89% |
| AI推荐"通过"但HR认为"不通过" | 24% |
| AI推荐"不通过"但HR认为"通过" | 11% |
关键指标:漏掉好候选人(假阴性)的比例是11%。也就是说,每100个HR认为值得面试的候选人里,AI把11个排除在外了。
这个数字在HR眼里是不可接受的——如果用AI完全替代初筛,有11%的好候选人被错误淘汰。
AI筛选的真实局限
局限1:无法判断"潜力型"候选人
有一份简历,候选人学历普通(二本),工作年限不足(3年),但在小公司独立主导过一个有100万DAU的产品从0到1。这种候选人,有经验的HR会说"值得聊一聊",AI会打低分然后不推荐——因为学历和年限不达标。
局限2:无法验证简历真实性
AI完全基于简历文字打分。简历上写"主导XX项目,用户增长300%",AI会把这当成亮点打高分,但这个数据是不是真的,AI没有能力判断。
经验丰富的HR在面试中会通过追问细节来验证,AI在初筛阶段完全做不到这个。
局限3:行业变化导致JD词汇失效
我们遇到过一个案例:招Python工程师,JD写的是"熟悉Flask框架"。但有个优秀候选人用的是FastAPI,简历里根本没提Flask。AI技能匹配分低,差点被错误过滤。
局限4:文化匹配无法量化
客户HR说了一句话让我印象深刻:"有些候选人简历上一切都符合,但聊十分钟你就知道他不适合我们团队。"
这种判断来自多年积累的人际直觉,不是规则可以覆盖的,AI做不到。
最终建议:AI做辅助,不做决策
基于这些局限,我最终给客户的方案不是"AI替代初筛",而是:
AI做分层处理:
明显不符合(不通过率 > 85%的候选人):
AI过滤后,HR做5%比例抽检,验证AI的准确性
中等匹配(待定区间):
AI给HR一份结构化摘要和打分依据,HR基于摘要快速决策
每份简历HR时间从15分钟降到3分钟
明显优秀(AI高分):
AI汇总亮点,HR全看,但看的是AI预先整理好的摘要版
HR完全自主决定的比例:100%
AI的角色是"信息整理助手",不是"筛选决策者"这个方案上线后,HR的工作效率提升了60%(每天能处理的简历从200份提升到320份),同时没有增加漏看优秀候选人的风险,因为AI没有替代HR的判断权。
AI能替代HR的初筛工作吗?
不能替代,能大幅辅助。替代会带来法律风险(用AI过滤候选人在某些地区有合规要求)、质量风险(漏掉潜力型候选人)和信任风险(候选人如果知道自己被AI淘汰,感受很差)。
辅助则不同——AI把信息结构化、把明显不符合的快速过滤、把匹配信息清晰呈现给HR,HR的决策更有依据、速度更快。这才是AI在这个场景的正确位置。
