缘起
招聘是一个经典的信息不对称场景。
HR 看不懂技术栈,技术负责人又没时间逐份细读。大量简历躺在邮箱里,其中可能有合适的人,但”找到他们”的成本高得不成比例。
ResumeAgent(芙小娜简历助手)就是为这个痛点而生的——一个完全用自然语言驱动的简历筛选工具。你只需要告诉它岗位要求是什么、简历在哪里,剩下的解析、匹配、评分、报告全由它自动完成。
技术栈
| 层级 | 技术选型 |
|---|---|
| 语言 | Python 3.10+ |
| Agent 框架 | LangChain (LangGraph) |
| LLM | DeepSeek V4 Flash(OpenAI 兼容端点) |
| 数据模型 | Pydantic v2 |
| 文档解析 | pdfplumber + python-docx |
| 配置管理 | python-dotenv |
核心理念
ResumeAgent 并不是一个传统的”关键词匹配”工具。它让 LLM 扮演招聘初筛官的角色——理解岗位描述中的隐性需求、评估简历中的项目含金量、动态分配各维度的评分权重,最后给出有推理过程的打分而不是一个黑盒数字。
工作流程
整个筛选过程被设计为五个步骤的流水线:
加载 JD → 解析简历 → 匹配 → 评分 → 生成报告
每一步都有对应的 LangChain 工具,由 Agent 根据用户的自然语言指令自动编排调用。
1. 解析(Parser)
支持 PDF 和 DOCX 两种格式。先用 pdfplumber / python-docx 提取原始文本,再通过 LLM 将非结构化的简历文本转换为结构化的字段:姓名、学历、技能列表、工作经历、项目经验等。对格式怪异的简历也有很好的鲁棒性。
2. 匹配(Matcher)
将结构化后的简历数据与 JD 文本一同发送给 LLM。LLM 会:
- 逐技能比对:每个 JD 要求是否被满足
- 动态分配权重:技能匹配、工作经验、教育背景、项目质量各占多少
- 标注缺失项:候选人缺什么、差多远
3. 评分(Scorer)
基于匹配结果中的权重分析,LLM 在各维度上打分,汇总为 0-100 的总分,并给出四档建议:强烈推荐 / 推荐 / 待定 / 不推荐。每一项都附带推理过程,让你知道这个分数是怎么来的。
4. 报告(Reporter)
生成一份结构化的 Markdown 报告:
- 排名概览表
- 每位候选人的完整档案(简历摘要 → 匹配详情 → 评分明细 → 工作经历 → 项目经验)
- 按总分降序排列
- 文件名使用内容哈希避免覆盖
5. 对话(Conversation)
报告生成后,你还可以继续追问:
- “把排名前三的候选人对比一下”
- “第二位候选人的项目经验具体是什么?”
- “有没有 Java 经验特别突出的?”
Agent 会记住上下文,调用对应的工具来回答。
架构亮点
- 9 个 LangChain 工具,覆盖了从文件查找、解析、匹配、评分到报告生成的完整链路。每个工具职责单一,可被 Agent 灵活组合
- LLM 承担核心逻辑:与传统的规则引擎或嵌入向量方案不同,ResumeAgent 把理解、比对、打分全交给 LLM——这意味着它能捕捉 JD 中的”隐性偏好”,而不仅仅是关键词命中
- 内存态对话:所有状态(JD、候选人列表、报告路径)保持在
ConversationState这个 Pydantic 模型中,无数据库依赖,启动零成本 - 可插拔 LLM 后端:通过
.env即可切换模型或 API 提供商,架构与 OpenAI 生态完全兼容 - 批量优先:单份和批量操作都有专用工具,处理几十份简历也只需一句话
快速开始
# 安装依赖
pip install -r requirements.txt
# 配置 .env
# DEEPSEEK_API_KEY=your-key
# DEEPSEEK_BASE_URL=https://api.deepseek.com
# DEEPSEEK_MODEL=deepseek-v4-flash
# 把 JD 放到 jd/ 目录,简历放到 resume/ 目录
# 启动对话
python main.py
然后你只需要说:
“加载 Java 后端开发的 JD,把 resume 文件夹里的简历都解析了,帮我全部匹配一遍,然后评分出报告。”
剩下的事,芙小娜会帮你做完。
后记
ResumeAgent 的灵感来自一个朴素的观察:第一轮简历筛选其实是一道阅读理解题——而 LLM 天生擅长阅读理解。
它不是要取代 HR 的判断力,而是把那些机械的、重复的、需要逐字比对的初筛工作自动化,让人的精力能花在更值得的地方:面试、沟通、判断一个人是否真的适合团队。
从这个意义上说,ResumeAgent 不是”筛选器”,它是一个”放大器”——放大那些真正重要的信号,过滤掉格式和措辞的噪声。
—— March7th-OvO
Comments
Join the conversation — sign in to leave a comment.
Login with GitHub