不是那种糊弄人的AI筛选,是真正把简历拆开、对照代码库、给出一份带证据链的评估报告
上个月帮朋友团队看简历,几十份PDF翻得眼花。后来发现他们内部其实有个叫Hiring Agent的开源项目,能把简历解析、结构化、再结合GitHub信息给出一份评分报告。我本地跑了一遍,觉得挺有意思,干脆写篇文章详细拆解一下。
这玩意儿到底在干什么
简单说,你把一份简历PDF丢进去,它做四件事:
把PDF转成Markdown文本(保留了标题层级和段落) 用LLM按模块提取JSON(教育背景、工作经历、技能、奖项……每一个模块单独调用) 如果简历里有GitHub链接,它会去抓profile和最近的项目代码库 最后生成一份评估报告:每个维度有评分、有证据引用、有加分项和扣分项
而且它支持本地跑(Ollama)或者用Google Gemini,不需要把简历上传到某些不可控的云服务。
代码结构长什么样
项目是Python写的,核心模块分得挺清楚:
pymupdf_rag.py—— PDF转Markdown的工具,依赖PyMuPDF。pdf.py—— 用Jinja模板组装提示词,按章节逐个调用LLM。github.py—— 获取GitHub个人资料和仓库列表,把项目分类,让LLM挑出最相关的7个。evaluator.py—— 严格执行评分规则,有公平性约束(比如不能因为性别、学校名字给加分)。score.py—— 端到端的入口,开发模式下会写CSV方便调试。
还有几个辅助文件:
models.py—— Pydantic数据模型,定义了LLM返回的JSON结构。llm_utils.py—— 处理不同提供商的初始化和返回结果清洗。transform.py—— 把LLM偶尔抽风输出的非标准JSON转成标准格式。prompts/目录 —— 全是Jinja模板,每个模块(basics.jinja、education.jinja、work.jinja……)都有自己的提示词模板,方便调优。
工作流一步步走
第一步:PDF解析
pymupdf_rag.py 把PDF每一页的内容转成类似Markdown的纯文本,保留标题和段落结构。这一步不依赖LLM,纯本地处理。
第二步:分模块解析
pdf.py 拿到文本后,会按章节切分,然后逐个调用LLM。比如先解析基本信息(姓名、邮箱、GitHub链接),再解析教育经历、工作经历、项目、技能、奖项。每个模块都有独立的Jinja模板,提示词里明确要求返回JSON格式。
好处是每个模块可以独立调优,某个模块抽风不会影响其他模块。
第三步:GitHub增强
如果解析出来的基本信息里有GitHub个人主页链接,github.py 就去抓:
用户公开资料(bio、location、公司等) 仓库列表(按语言分类,过滤掉fork) 然后让LLM根据项目描述和技术栈,选最相关的7个项目
这一步不是为了堆数量,而是筛选出最能代表候选人能力的项目。
第四步:综合评估
evaluator.py 把上面所有数据汇总,用一套严格的评分规则打分。规则写在提示词里,包括:
每个维度(技术深度、项目复杂度、代码质量、文档习惯等)有明确的评分标准 必须有证据引用(比如“GitHub上XX项目的commit记录显示……”) 加分项和扣分项要具体说明原因 禁止使用性别、年龄、学校排名等偏见过滤
最后生成一份可读的Markdown报告。
第五步:输出与缓存
score.py 是总入口,跑完会打印报告。开发模式(config.py里DEVELOPMENT_MODE = True)下,还会把提取的中间结果缓存到cache/目录,并在resume_evaluations.csv里追加一行,方便批量对比调试。
本地安装和配置
前提是Python 3.11.13(项目里锁了这个版本,建议保持一致)。
第一步:克隆并建虚拟环境
git clone https://github.com/interviewstreet/hiring-agent
cd hiring-agent
python -m venv .venv
source .venv/bin/activate # Windows用 .venv\Scripts\activate
pip install -r requirements.txt
第二步:选LLM后端
用Ollama(本地):去官网安装,然后拉模型,比如 ollama pull gemma3:4b。配置低的机器可以拉1b版,配置高的可以拉12b。用Google Gemini:得有API key。
第三步:配置环境变量
cp .env.example .env
编辑.env,设置LLM_PROVIDER(ollama或gemini)和对应的DEFAULT_MODEL、GEMINI_API_KEY(如果用的话)。
GITHUB_TOKEN是可选的,但建议填上,不然GitHub API有频率限制。
第四步:跑起来
python score.py /path/to/resume.pdf
如果简历里有GitHub链接,它会自动抓取并缓存,第一次可能会慢一点。
几个让我觉得设计得好的地方
缓存机制 —— 开发模式下,PDF解析结果和GitHub数据都会缓存,调试的时候不用反复请求LLM和GitHub API,省时间省钱(如果是付费API)。 模块化提示词 —— 每个章节单独模板,改提示词不用动代码,还能针对不同岗位类型(比如前端/后端/算法)调整模板。 严格评分+证据链 —— 不是只给一个总分,而是每条评分都写了“为什么给这个分”,比如“该候选人在XX仓库中有完善的单元测试,代码注释清晰,因此加分”。 本地运行支持 —— 用Ollama的话,所有数据不出本地,对数据敏感的公司特别友好。
可能踩的坑
PDF格式要规范 —— 如果是扫描件或图片型PDF, pymupdf_rag提取出来是乱码,目前项目没有集成OCR,所以只能用文字型PDF。GitHub Token限流 —— 不填token的话,匿名请求一小时只能60次,如果有多个简历要跑,建议填上。 大模型输出不稳定 —— 虽然用了Pydantic约束,但有些模型(尤其是小尺寸的)偶尔返回格式不对, transform.py会尽力修复,但偶尔还是会失败,这时候可以换个模型试试。内存占用 —— 用12b模型本地跑,建议16G以上内存,4b模型相对友好。
适合谁用
小团队想自动化初筛简历,但又不想把数据交给第三方SaaS。 对候选人的GitHub代码质量有要求的岗位(技术岗)。 想批量评估简历、做横向对比的HR或技术负责人。 对AI提示词工程感兴趣,想拿这个项目当样例来学习。
最后说两句
这个项目不是那种“一键淘汰90%简历”的黑盒工具,它更像一个结构化的信息汇总器 + 初步评估助手。最终决策权还是在你手上,但它能帮你把简历里的信息跟实际代码产出联系起来,减少拍脑袋打分。
我本地跑了几份简历,发现它真的会去读你的commit message和代码文件结构,有些细节自己写简历都忘了,它倒给扒出来了。挺实在的。
项目地址:https://github.com/interviewstreet/hiring-agent
有兴趣的可以自己clone下来跑跑看,记得改改提示词模板里的评分标准,匹配自己的岗位要求。
题外话:如果你跑通了,可以试着把prompts/templates/resume_evaluation_criteria.jinja里的评分维度改成你团队最看重的几点,效果会更贴切。
夜雨聆风