> [!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

简历转评分流水线(Resume-to-Score pipeline),可从 PDF 提取结构化数据,结合 GitHub 信号进行增强,并输出公平、可解释的评价结果。

Python License: MIT Code style: Black

--- ## 目录 - [概述](#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。 --- ## 架构
**流程** 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。 **核心模块** - `models.py` Pydantic 模式(schema)与 LLM 提供商接口。 - `llm_utils.py` 提供商初始化与响应清理。 - `transform.py` 将松散的 LLM JSON 规范化为 JSON Resume 风格。 - `prompts/` 用于提取与评分的全部 Jinja 模板。
--- ## 安装与配置 ### 前置要求 - **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 ``` 迭代期间可保持开启。详见下一节。 --- ## 工作原理
1) PDF 提取 - `pymupdf_rag.py` 与 `pdf.py` 使用 PyMuPDF 读取 PDF,并将页面转换为类 Markdown 文本。 - `to_markdown` 例程处理标题、链接、表格及基本格式。
2) 基于模板的章节解析 - `prompts/templates/*.jinja` 为各章节定义严格指令 Basics、Work、Education、Skills、Projects、Awards。 - `pdf.PDFHandler` 按章节调用 LLM,并组装 `JSONResume` 对象(见 `models.py`)。
3) GitHub 增强 - `github.py` 从简历 profiles 中提取用户名,获取个人资料与仓库,并对每个项目进行分类。 - 它让 LLM 恰好选出 7 个不重复的项目,要求达到最低作者提交阈值,并优先选择有意义的贡献。
4) 评价 - `evaluator.py` 使用编码了公平性与评分规则的模板。 - 得分包括 `open_source`、`self_projects`、`production` 与 `technical_skills`,以及加分与扣分,随后为证据提供说明。
5) 输出与 CSV 导出 - `score.py` 向 stdout 打印可读摘要。 - 当 `DEVELOPMENT_MODE=True` 时,会创建或追加 `resume_evaluations.csv`(包含关键字段),并在 `cache/` 下缓存中间 JSON。
--- ## CLI 用法 ### 端到端评分 提供简历 PDF 的路径。 ```bash $ python score.py /path/to/resume.pdf ``` 执行过程: 1. 若开发模式开启,PDF 提取结果会缓存到 `cache/resumecache_.json`。 2. 若在简历中找到 GitHub 个人资料,会获取仓库并缓存到 `cache/githubcache_.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