291 lines
8.2 KiB
Markdown
291 lines
8.2 KiB
Markdown
<!-- WEHUB_ZH_README -->
|
||
> [!NOTE]
|
||
> 本文档由 WeHub 基于上游 README 翻译整理,属于社区翻译,非官方中文文档。
|
||
> [English](./README.en.md) · [原始项目](https://github.com/interviewstreet/hiring-agent) · [上游 README](https://github.com/interviewstreet/hiring-agent/blob/HEAD/README.md)
|
||
> 原作者、版权与许可证归属以原始项目及本仓库 LICENSE 文件为准。
|
||
|
||
# Hiring Agent
|
||
|
||
<p align="center"><strong>简历转评分流水线(Resume-to-Score pipeline)</strong>,可从 PDF 提取结构化数据,结合 GitHub 信号进行增强,并输出公平、可解释的评价结果。</p>
|
||
|
||
<p align="center">
|
||
<a href="https://www.python.org/downloads/release/python-3110/">
|
||
<img alt="Python" src="https://img.shields.io/badge/python-3.11%2B-blue.svg">
|
||
</a>
|
||
<a href="https://github.com/interviewstreet/hiring-agent/blob/master/LICENSE">
|
||
<img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-yellow.svg">
|
||
</a>
|
||
<a href="https://github.com/psf/black">
|
||
<img alt="Code style: Black" src="https://img.shields.io/badge/code%20style-Black-000000.svg">
|
||
</a>
|
||
</p>
|
||
|
||
---
|
||
|
||
## 目录
|
||
|
||
- [概述](#overview)
|
||
- [架构](#architecture)
|
||
- [安装与配置](#installation-and-setup)
|
||
- [前置要求](#prerequisites)
|
||
- [使用 pip 快速安装](#quick-setup-with-pip)
|
||
- [Ollama 模型](#ollama-models)
|
||
- [配置](#configuration)
|
||
- [工作原理](#how-it-works)
|
||
- [CLI 用法](#cli-usage)
|
||
- [目录结构](#directory-layout)
|
||
- [提供商详情](#provider-details)
|
||
- [贡献](#contributing)
|
||
- [许可证](#license)
|
||
|
||
---
|
||
|
||
## 概述
|
||
|
||
Hiring Agent 将简历 PDF 解析为 Markdown,使用本地或托管 LLM 提取分节 JSON,并用 GitHub 个人资料与仓库信号增强数据,最终生成客观评价,包含分类得分、证据、加分项与扣分项。你可以通过 Ollama 完全在本地运行,或使用 Google Gemini。
|
||
|
||
---
|
||
|
||
## 架构
|
||
|
||
<table>
|
||
<tr>
|
||
<td>
|
||
|
||
**流程**
|
||
|
||
1. `pymupdf_rag.py` 将 PDF 页面转换为类 Markdown 文本。
|
||
2. `pdf.py` 使用 `prompts/templates` 下的 Jinja 模板,按章节调用 LLM。
|
||
3. `github.py` 获取个人资料与仓库,对项目进行分类,并让 LLM 选出前 7 个。
|
||
4. `evaluator.py` 在公平性约束下执行严格评分评价。
|
||
5. `score.py` 端到端编排整个流程,并在开发模式开启时写入 CSV。
|
||
|
||
</td>
|
||
<td>
|
||
|
||
**核心模块**
|
||
|
||
- `models.py`
|
||
Pydantic 模式(schema)与 LLM 提供商接口。
|
||
|
||
- `llm_utils.py`
|
||
提供商初始化与响应清理。
|
||
|
||
- `transform.py`
|
||
将松散的 LLM JSON 规范化为 JSON Resume 风格。
|
||
|
||
- `prompts/`
|
||
用于提取与评分的全部 Jinja 模板。
|
||
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
|
||
---
|
||
|
||
## 安装与配置
|
||
|
||
### 前置要求
|
||
|
||
- **Python 3.11+**
|
||
|
||
本仓库将 `.python-version` 固定为 3.11.13。
|
||
|
||
- **一个 LLM 后端**(二选一)
|
||
|
||
- **Ollama** 用于本地模型
|
||
从[官方网站](https://ollama.com/), 安装,然后运行 `ollama serve`。
|
||
- **Google Gemini**:如果你有 API 密钥,可从[此处](https://aistudio.google.com/api-keys). 获取。
|
||
|
||
### 使用 pip 快速安装
|
||
|
||
```bash
|
||
$ git clone https://github.com/interviewstreet/hiring-agent
|
||
$ cd hiring-agent
|
||
|
||
$ python -m venv .venv
|
||
# Linux or macOS
|
||
$ source .venv/bin/activate
|
||
# Windows
|
||
# .venv\Scripts\activate
|
||
|
||
$ pip install -r requirements.txt
|
||
```
|
||
|
||
### Ollama 模型
|
||
|
||
拉取你想使用的模型。例如:
|
||
|
||
```bash
|
||
$ ollama pull gemma3:4b
|
||
```
|
||
|
||
如果想要不同结果,可以拉取其他模型,例如:
|
||
|
||
```bash
|
||
# For higher system configuration
|
||
$ ollama pull gemma3:12b
|
||
|
||
# For lower system configuration
|
||
$ ollama pull gemma3:1b
|
||
```
|
||
|
||
---
|
||
|
||
## 配置
|
||
|
||
复制模板并设置环境变量。
|
||
|
||
```bash
|
||
$ cp .env.example .env
|
||
```
|
||
|
||
**环境变量**
|
||
|
||
| Variable | Values | Description |
|
||
| ---------------- | ------------------------------------------- | ---------------------------------------------------------------------- |
|
||
| `LLM_PROVIDER` | `ollama` or `gemini` | 选择提供商。默认为 Ollama。 |
|
||
| `DEFAULT_MODEL` | for example `gemma3:4b` or `gemini-2.5-pro` | 传递给提供商的模型名称。 |
|
||
| `GEMINI_API_KEY` | string | 当 `LLM_PROVIDER=gemini` 时为必填项。 |
|
||
| `GITHUB_TOKEN` | optional | 继承自 shell 环境,可改善 GitHub API 速率限制。 |
|
||
|
||
提供商映射位于 `prompt.py` 与 `models.py`。`config.py` 文件包含一个标志:
|
||
|
||
```python
|
||
# config.py
|
||
DEVELOPMENT_MODE = True # enables caching and CSV export
|
||
```
|
||
|
||
迭代期间可保持开启。详见下一节。
|
||
|
||
---
|
||
|
||
## 工作原理
|
||
|
||
<details>
|
||
<summary><b>1) PDF 提取</b></summary>
|
||
|
||
- `pymupdf_rag.py` 与 `pdf.py` 使用 PyMuPDF 读取 PDF,并将页面转换为类 Markdown 文本。
|
||
- `to_markdown` 例程处理标题、链接、表格及基本格式。
|
||
|
||
</details>
|
||
|
||
<details>
|
||
<summary><b>2) 基于模板的章节解析</b></summary>
|
||
|
||
- `prompts/templates/*.jinja` 为各章节定义严格指令
|
||
Basics、Work、Education、Skills、Projects、Awards。
|
||
- `pdf.PDFHandler` 按章节调用 LLM,并组装 `JSONResume` 对象(见 `models.py`)。
|
||
|
||
</details>
|
||
|
||
<details>
|
||
<summary><b>3) GitHub 增强</b></summary>
|
||
|
||
- `github.py` 从简历 profiles 中提取用户名,获取个人资料与仓库,并对每个项目进行分类。
|
||
- 它让 LLM 恰好选出 7 个不重复的项目,要求达到最低作者提交阈值,并优先选择有意义的贡献。
|
||
|
||
</details>
|
||
|
||
<details>
|
||
<summary><b>4) 评价</b></summary>
|
||
|
||
- `evaluator.py` 使用编码了公平性与评分规则的模板。
|
||
- 得分包括 `open_source`、`self_projects`、`production` 与 `technical_skills`,以及加分与扣分,随后为证据提供说明。
|
||
|
||
</details>
|
||
|
||
<details>
|
||
<summary><b>5) 输出与 CSV 导出</b></summary>
|
||
|
||
- `score.py` 向 stdout 打印可读摘要。
|
||
- 当 `DEVELOPMENT_MODE=True` 时,会创建或追加 `resume_evaluations.csv`(包含关键字段),并在 `cache/` 下缓存中间 JSON。
|
||
|
||
</details>
|
||
|
||
---
|
||
|
||
## CLI 用法
|
||
|
||
### 端到端评分
|
||
|
||
提供简历 PDF 的路径。
|
||
|
||
```bash
|
||
$ python score.py /path/to/resume.pdf
|
||
```
|
||
|
||
执行过程:
|
||
|
||
1. 若开发模式开启,PDF 提取结果会缓存到 `cache/resumecache_<basename>.json`。
|
||
2. 若在简历中找到 GitHub 个人资料,会获取仓库并缓存到 `cache/githubcache_<basename>.json`。
|
||
3. 评价器打印报告;在开发模式下,会向 `resume_evaluations.csv` 追加一行 CSV。
|
||
|
||
---
|
||
|
||
## 目录结构
|
||
|
||
```text
|
||
.
|
||
├── .env.example
|
||
├── .python-version
|
||
├── config.py
|
||
├── evaluator.py
|
||
├── github.py
|
||
├── llm_utils.py
|
||
├── models.py
|
||
├── pdf.py
|
||
├── prompt.py
|
||
├── prompts/
|
||
│ ├── template_manager.py
|
||
│ └── templates/
|
||
│ ├── awards.jinja
|
||
│ ├── basics.jinja
|
||
│ ├── education.jinja
|
||
│ ├── github_project_selection.jinja
|
||
│ ├── projects.jinja
|
||
│ ├── resume_evaluation_criteria.jinja
|
||
│ ├── resume_evaluation_system_message.jinja
|
||
│ ├── skills.jinja
|
||
│ ├── system_message.jinja
|
||
│ └── work.jinja
|
||
├── pymupdf_rag.py
|
||
├── requirements.txt
|
||
├── score.py
|
||
└── transform.py
|
||
```
|
||
|
||
---
|
||
|
||
## 提供商详情
|
||
|
||
### Ollama
|
||
|
||
- 设置 `LLM_PROVIDER=ollama`
|
||
- 将 `DEFAULT_MODEL` 设为任意已拉取的模型,例如 `gemma3:4b`
|
||
- `models.OllamaProvider` 中的提供商封装会调用 `ollama.chat`
|
||
|
||
### Gemini
|
||
|
||
- 设置 `LLM_PROVIDER=gemini`
|
||
- 将 `DEFAULT_MODEL` 设为受支持的 Gemini 模型,例如 `gemini-2.0-flash`
|
||
- 提供 `GEMINI_API_KEY`
|
||
- `models.GeminiProvider` 中的封装会将响应适配为统一格式
|
||
|
||
---
|
||
|
||
## 贡献
|
||
|
||
请阅读 [CONTRIBUTING.md](./CONTRIBUTING.md),了解提交 issue、提出变更与提交 pull request 的详细指南。核心原则包括:
|
||
|
||
- 保持 prompt 声明式且与提供商无关。
|
||
- 在不同提供商下用几份真实简历验证变更。
|
||
- 添加或调整无单元测试的冒烟测试(smoke test),以最小输入调用各阶段。
|
||
|
||
---
|
||
|
||
|
||
## 许可证
|
||
|
||
[MIT](https://github.com/interviewstreet/hiring-agent/blob/master/LICENSE) © HackerRank
|