AI简历筛选配置:从零搭建可运行的自动筛选流程
AI简历筛选配置的核心,是把简历文件变成可检索的文本,再按岗位关键词和评分规则自动排序。
适合没有采购商业招聘系统、但希望用开源工具快速跑通筛选流程的小团队。
下面按环境准备、脚本编写、规则配置、结果验证的顺序讲一遍,命令和路径都可以直接照做。
先确认运行环境和文件格式
这套流程不需要GPU,普通Linux服务器或本地电脑都能跑。
建议准备Python 3.8以上版本,简历统一放在一个目录里,优先使用PDF和DOCX格式。
先检查版本:
python3 --version
pip3 --version
如果版本低于3.8,先升级Python。
接着安装解析和匹配要用的依赖库:
pip3 install pdfplumber python-docx jieba scikit-learn
pdfplumber负责读取PDF文字,python-docx读取Word文档,jieba做中文分词,scikit-learn用来计算文本相似度。
安装完成后用pip3 list确认这几个包都在列表里。
简历目录建议这样组织,避免中文路径和空格带来的读取问题:
/data/resumes/
├── zhangsan.pdf
├── lisi.docx
└── wangwu.pdf
编写简历解析与筛选脚本
在/data/ai_resume/下新建filter.py,核心逻辑分三步:读取文件、提取文本、按岗位描述打分。
下面是一个可运行的最小示例:
import os, pdfplumber, jieba
from docx import Document
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
RESUME_DIR = "/data/resumes"
JOB_DESC = "熟悉Linux运维,掌握Nginx、MySQL,有自动化脚本经验"
def read_pdf(path):
text = ""
with pdfplumber.open(path) as pdf:
for page in pdf.pages:
text += page.extract_text() or ""
return text
def read_docx(path):
doc = Document(path)
return "\n".join(p.text for p in doc.paragraphs)
def load_resumes():
results = []
for name in os.listdir(RESUME_DIR):
path = os.path.join(RESUME_DIR, name)
if name.lower().endswith(".pdf"):
text = read_pdf(path)
elif name.lower().endswith(".docx"):
text = read_docx(path)
else:
continue
results.append((name, text))
return results
def score(resumes):
corpus = [JOB_DESC] + [t for _, t in resumes]
vec = TfidfVectorizer(tokenizer=jieba.lcut)
matrix = vec.fit_transform(corpus)
sims = cosine_similarity(matrix[0:1], matrix[1:]).flatten()
ranked = sorted(zip([n for n, _ in resumes], sims), key=lambda x: x[1], reverse=True)
for name, s in ranked:
print(f"{name}\t{s:.4f}")
if __name__ == "__main__":
score(load_resumes())
保存后执行python3 filter.py,终端会按相似度从高到低输出文件名和分数。
分数只是排序参考,不代表录用结论。
配置评分规则和关键词权重
只用相似度容易把“岗位描述写得像”的简历排前面,实际筛选时建议叠加硬性条件。
可以在脚本里增加关键词命中检查,例如:
MUST_HAVE = ["Linux", "Nginx", "MySQL"]
BONUS = ["Docker", "Kubernetes", "Python"]
def rule_score(text):
base = sum(1 for k in MUST_HAVE if k.lower() in text.lower())
extra = sum(1 for k in BONUS if k.lower() in text.lower())
return base * 2 + extra
把rule_score的结果和相似度相加或加权,再排序。
硬性关键词建议控制在3到5个,太多会把正常简历误杀。
权重可以放在单独的config.json里,方便HR调整而不用改代码:
{
"must_have": ["Linux", "Nginx", "MySQL"],
"bonus": ["Docker", "Python"],
"must_weight": 2,
"bonus_weight": 1
}
脚本读取配置后重新计算,改规则时只动JSON文件。
容易踩的坑和检查点
PDF扫描件没有文字层,pdfplumber提取出来是空字符串,这类简历需要先做OCR,否则会被当成空文件跳过。
检查方法是打开PDF尝试选中文字,选不中就是扫描件。
中文分词对英文技术词不友好,jieba可能把Nginx切碎,关键词匹配前统一转小写并保留英文原词。
另外,简历里常见表格排版,python-docx默认只读段落不读表格,如果简历用表格写经历,需要额外遍历doc.tables。
文件权限也要注意,脚本运行用户必须对/data/resumes有读权限,否则os.listdir直接报PermissionError。
建议先手动ls确认目录可读再跑脚本。
验证筛选结果是否可信
跑完脚本后,抽3到5份简历人工对照:排名靠前的简历是否真的包含岗位硬性技能,排名靠后的是否确实不匹配。
如果发现明显错排,先检查关键词是否被分词切断,再检查简历文本是否提取完整。
可以在脚本末尾增加一条汇总输出,打印每份简历的文本长度和命中关键词,方便快速定位空文本或解析异常:
print(name, len(text), [k for k in MUST_HAVE if k.lower() in text.lower()])
文本长度低于100字符的基本可以判定为解析失败,需要单独处理。
验证通过后,再把脚本放进定时任务或接入招聘系统,不要跳过人工抽检直接全自动淘汰。
常见疑问
没有编程基础能配置吗? 可以照抄本文脚本,但需要会使用终端执行命令和编辑文本文件。
如果完全没接触过命令行,建议先让运维同事协助跑通一次。
筛选结果能直接决定面试名单吗? 不建议。
AI筛选适合做初筛排序和关键词提醒,最终判断仍要人工复核,尤其是涉及年龄、学历等敏感条件时,要遵守当地招聘合规要求。
简历量很大时脚本会慢吗? 几百份以内通常可以接受。
上千份时建议把解析结果缓存成文本文件,避免每次重复读取PDF。
整套AI简历筛选配置的关键不在模型多复杂,而在简历文本提取是否完整、关键词规则是否合理、结果是否经过人工抽检。
先把小批量跑通,再逐步扩大范围,比一次性上全自动更稳妥。