BURNFIR3/LobberRedrob
GitHub: BURNFIR3/LobberRedrob
一款基于两阶段流水线的可解释 AI 简历排名工具,从大规模候选人池中自动筛选、评分并生成排名与自然语言解释。
Stars: 0 | Forks: 0
# Lobber — 智能简历排名工具
一个为 Redrob 黑客松构建的多阶段、完全可解释的 AI 排名流水线。给定一个 JSONL 格式的候选人资料池,该系统会输出一份最适合高级 NLP/IR 工程师职位的前 100 名候选人排名列表。输出结果中的每位候选人都会获得一段自然语言解释字符串,其中引用了直接来自其个人资料的具体事实:雇主、任期、指定技能和信号值。
该简历排名工具托管在 https://huggingface.co/spaces/Burnfir3/LobberRedrob
## 架构
该流水线分为两个连续的阶段,每个阶段都实现为一个独立的 Python 脚本,除了写入 `artifacts/` 目录的文件外,没有其他进程间状态。
```
candidates.jsonl
│
▼
┌─────────────────────┐
│ precompute.py │ Stage 1 — Deterministic hard filters + embedding generation
│ │
│ • Honeypot check │
│ • Title filter │
│ • Location filter │
│ • Inactivity gate │
│ • Keyword gate │
│ • Encode embeddings│
└──────────┬──────────┘
│ artifacts/stage1_shortlist.jsonl
│ artifacts/embeddings.npy
│ artifacts/id_index.json
▼
┌─────────────────────┐
│ rank.py │ Stage 2 — Composite scoring, ranking, reasoning
│ │
│ • Semantic sim. │
│ • Keyword bonus │
│ • Skill depth │
│ • YoE / tenure │
│ • Notice period │
│ • Redrob signals │
│ • Reasoning gen. │
└──────────┬──────────┘
│
▼
submission.csv (top 100, ranked)
```
### 阶段 1 — 硬过滤 (`precompute.py`)
按顺序应用五个确定性关卡。候选人如果在某个关卡失败就会被立即淘汰;不再评估该候选人的后续关卡。
| 过滤器 | 逻辑 |
|---|---|
| **蜜罐检测** | 标记具有零持续时间的专家级技能、存在大量未记录的职业空档期(`>= HONEYPOT_UNRECORDED_GAP_PCT` 的声称 YoE),或者技能月数超过职业生涯总月数 4 倍以上的个人资料 |
| **硬性职位取消资格** | 拒绝包含 `jd.py` 中定义的明确取消资格片段的职位(例如 `qa engineer`、`frontend developer`、`android developer`) |
| **地理位置** | 要求个人资料的国家或地理位置字段包含“india”,除非候选人明确表示愿意搬迁 |
| **不活跃状态** | 拒绝最后一次活动时间超过 `MAX_INACTIVE_DAYS_IF_NOT_OPEN` 天且未标记为开放找工作状态的候选人 |
| **领域关键词存在** | 要求完整的个人资料文本中(所有职位、标题、摘要、描述)至少出现一次 `MUST_HAVE_SKILL_KEYWORDS` 或 `JD_RELEVANT_ROLE_KEYWORDS` 中的术语 |
通过筛选的候选人会被写入 `artifacts/stage1_shortlist.jsonl`。随后,他们的完整资料文本将使用 `sentence-transformers/all-MiniLM-L6-v2`(384维密集向量)进行编码,并保存到 `artifacts/embeddings.npy`,同时将匹配的候选人 ID 索引保存在 `artifacts/id_index.json`。
### 阶段 2 — 评分与排名 (`rank.py`)
加载预计算的产出物,并为每位通过筛选的候选人分配一个复合浮点数分数。该分数根据候选人 embedding 和 JD embedding 之间的语义相似度(余弦相似度)进行初始化,随后通过附加奖励和惩罚进行调整。
**评分组件:**
| 组件 | 方向 | 描述 |
|---|---|---|
| **语义相似度** | 基础 | 候选人与 JD embedding 之间的余弦相似度 |
| **关键词奖励** | + | 对完整资料文本中精确匹配的 JD 关键词命中次数进行缩放计入 |
| **技能深度奖励** | + | 与匹配的 JD 技能数量成正比;最多计算 15 个匹配技能 |
| **语义错觉惩罚** | − | 当语义得分较高但关键词命中数较低时应用 — 捕捉那些听起来符合 JD 但并未明确展示所需技能的资料 |
| **YoE 惩罚** | − | 对经验年限少于职位最低要求的候选人进行分级惩罚 |
| **YoE 空档惩罚** | − | 对声称的经验与可验证的经验之间存在显著差距的情况进行额外惩罚 |
| **频繁跳槽惩罚** | − | 当平均职业任期低于 18 个月时应用 |
| **离职通知期** | − | 分级计算:≤ 30 天无惩罚,31–60 天轻微惩罚,61–90 天中度惩罚,> 90 天严重惩罚 |
| **GitHub 活跃度奖励** | + | 辅助信号;奖励权重上限为 0.06。缺失 GitHub(`github == -1`)视为中性 — 不应用惩罚 |
| **招聘人员回复率** | +/− | 高回复率给予奖励;低回复率或信号缺失则进行惩罚 |
| **顶级公司奖励** | + | 对职业生涯中出现 FAANG/一线公司的情况给予额外奖励 |
| **初级不匹配惩罚** | − | 惩罚声称拥有高 YoE 但仅有初级职位的资料 |
| **纯咨询惩罚** | − | 对纯粹在代理/咨询机构任职的职业经历给予轻微惩罚 |
| **无背书的专家技能** | − | 对零背书的专家级自我评估技能按单个技能进行惩罚 |
**解释生成:**
排名前 100 的候选人每位都会获得一个确定性生成的自然语言解释字符串。每个字符串都以事实前缀开头,并指出具体的个人资料数据:
```
Recent: {Title} @ {Company} ({Tenure}mo). Matched JD skills: {skill_1}, {skill_2}, ...
```
字符串的其余部分会根据占主导地位的评分组件从模板库中进行选择。模板根据排名区间(排名 1–20 与 21–100)进行区分,并直接引用具体的信号值(语义得分、离职通知期天数、YoE、公司名称)。
## 仓库结构
```
.
├── app.py # Streamlit UI for hosted reproduction
├── precompute.py # Stage 1: hard filters + embedding generation
├── rank.py # Stage 2: scoring, ranking, reasoning, CSV output
├── jd.py # Job description constants (keywords, thresholds, tier lists)
├── validate_submission.py # Submission format validator per spec sections 2–3
├── requirements.txt # Python dependencies
├── sample_data.jsonl # 100-candidate extract for hosted reproduction
├── submission.csv # Latest ranked output (top 100)
├── submission_metadata.yaml # Submission metadata for the Redrob portal
├── Main/
│ ├── candidates.jsonl # NOT included — competition dataset (place here manually)
│ └── rules.yaml
├── artifacts/ # Runtime-generated; not committed
│ ├── embeddings.npy
│ ├── id_index.json
│ └── stage1_shortlist.jsonl
└── problem_statements/ # Competition documents; not committed
```
## 复现
### 前置条件
- Python 3.11+
- ~4 GB RAM(用于对全量 10 万名候选人池进行 embedding)
- 无需 GPU
- 排名期间无需网络访问
### 安装
```
pip install -r requirements.txt
```
### 数据准备
如果您有比赛数据集的访问权限,请按以下方式放置:
```
LobberRedrob/
└── Main/
└── candidates.jsonl ← place the file here
```
如果您想使用内置的 100 名候选人样本进行快速测试(无需下载),请跳过上述步骤,并在运行命令中使用 `sample_data.jsonl`:
```
# 使用包含的 100-candidate 样本进行快速测试
python precompute.py --candidates ./sample_data.jsonl
python rank.py
```
### 运行全流程(完整比赛数据集)
一旦 `Main/candidates.jsonl` 准备就绪:
```
# Stage 1:应用 hard filters 并生成 embeddings(在 CPU 上约 4-5 分钟)
python precompute.py --candidates ./Main/candidates.jsonl
# Stage 2:评分、排名并写入 submission.csv(约 35 秒)
python rank.py
```
在 CPU(16 核,16 GB RAM)上完成完整的 10 万级运行大约需要 **5–6 分钟**。
### 验证输出
```
python validate_submission.py submission.csv
```
## 复现命令
```
# PowerShell
python precompute.py --candidates .\Main\candidates.jsonl ; python rank.py
```
输出将写入工作目录下的 `submission.csv`。
标签:Kubernetes, 人工智能, 招聘科技, 数据流水线, 用户模式Hook绕过, 简历解析, 逆向工具