内容
# AI 职业生涯副驾驶




一个多智能体的求职副驾驶:上传你的简历,从真实的职位 API 中拉取匹配的职位,查看每个职位的技能差距,生成量身定制的简历和求职信,并跟踪你的申请流程——所有这些都严格基于你的实际经验(无虚假声明)。一个核心(`src/`)暴露了三种方式:一个 Streamlit 仪表盘,一个 FastAPI REST API 和一个 MCP 服务端。
灵感来自企业级多智能体编排模式,这些模式用于生产 AI 系统,该项目将类似的架构原则应用于个人职业助理。
## 为什么我创建了这个项目
大多数求职平台严重依赖关键词匹配,使得识别与候选人实际经验和可转移技能相符的职位变得困难。
我创建了 AI 职业生涯副驾驶,以探索现代 AI 工程技术——包括 LangGraph 多智能体工作流、语义嵌入、检索增强推理和模型上下文协议(MCP)——如何改进整个申请流程。
与其成为另一个聊天机器人演示,我的目标是构建一个端到端的 AI 平台,帮助候选人发现相关机会,识别技能差距,生成量身定制的申请文件,并通过单一的统一系统跟踪他们的进度。
**[实时演示](#)** *(在此处部署后添加您的 Streamlit Cloud URL)*
## 功能
1. **上传简历**(PDF/DOCX)→ 大型语言模型将其结构化为个人资料(标题、技能、经验要点)。
2. **获取职位** 通过 LangGraph 管道,跨五个来源:**Adzuna**(英国/爱尔兰/德国),**Arbeitnow** 和 **Remotive**(免费,欧盟/远程),以及 **Greenhouse**/**Lever**(每公司公共板 API),以及手动 URL 粘贴到任何职位板——然后去重。
3. **评分和排名** 每个职位与您的简历通过 **嵌入余弦相似度**——不仅仅是标题关键词匹配,这样它可以捕捉到具有不同标题但做相同工作的职位。
4. **技能差距分析**:对于任何职位,查看匹配和缺失的技能,以及关闭差距的短期路线图。
5. **生成**:选择一个职位 → 量身定制的简历和求职信,渲染为 `.docx`,可以直接从仪表盘下载。
6. **申请跟踪器**:标记已保存/已申请/面试/报价/拒绝的职位;查看漏斗计数、接受率和已申请的顶级公司。
7. **三个接口,一个核心**:Streamlit 仪表盘、FastAPI REST API(`backend/`)和 **MCP 服务端**(`mcp_server/`),允许 Claude Desktop 或 Claude Code 直接调用 `search_jobs`、`generate_tailored_documents`、`get_skill_gap`、`track_application` 等作为智能体工具。
## 它故意不做的事
不刮取 LinkedIn 或 Indeed。两者在其 ToS 中都禁止自动刮取,而在招聘人员指向的存储库中构建这些功能并不是我想要的。这里的每个来源(Adzuna、Arbeitnow、Remotive、Greenhouse、Lever)都有一个用于此用例的真正公共 API。
## 架构
```
┌─────────────┐
简历.pdf ──►│简历解析器│──► 个人资料 JSON (SQLite)
└─────────────┘
Adzuna ─────┐
Arbeitnow ──┤ ┌───────────────────────────────────┐
Remotive ───┼──► 获取节点 ─►│ graph.py (LangGraph) │
Greenhouse ─┤ │ 获取 → 去重 → 评分 → 存储 │──► SQLite `职位`
Lever ──────┤ └───────────────────────────────────┘
手动 URL ─┘ │
▼
匹配器.py (嵌入相似度)
│
┌───────────────────────────┼───────────────────────────┐
▼ ▼ ▼
app.py (Streamlit) backend/main.py (FastAPI) mcp_server/server.py (MCP)
仪表盘,跟踪器, REST API 用于相同 Claude Desktop / 的工具
技能差距,Excel 导出 核心逻辑 Claude Code
三个接口都调用相同的 src/ 核心:
技能差距.py · 生成器.py · 应用程序.py · 缓存.py(双键)
```
### 双键缓存(`src/cache.py`)
镜像 TCS 缓存设计:一个 `match_key`(精确个人资料 + 职位的哈希)用于逐字重复,一个 `shape_key`(标题 + 公司 + 职位描述的前 40 个字)用于近似重复职位,以避免触发新的、昂贵的生成调用。用于简历定制和技能差距分析。
## 快速入门
```bash
git clone https://github.com/YOUR_USERNAME/job-hunt-copilot.git
cd job-hunt-copilot
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
# 添加 ANTHROPIC_API_KEY(生成)和 ADZUNA_APP_ID/ADZUNA_APP_KEY
# (免费,网址:https://developer.adzuna.com/)。Arbeitnow/Remotive/Greenhouse/
# Lever 不需要密钥。
streamlit run app.py
```
### 运行 FastAPI 后端
```bash
uvicorn backend.main:app --reload --port 8000
# 文档位于 http://localhost:8000/docs
```
### 运行 MCP 服务端
```bash
python mcp_server/server.py
```
将其添加到 Claude Desktop 的 `claude_desktop_config.json`(或 Claude Code 的 MCP 配置)中,以调用它作为智能体工具:
```json
{
"mcpServers": {
"job-hunt-copilot": {
"command": "python",
"args": ["/绝对路径/to/job-hunt-copilot/mcp_server/server.py"]
}
}
}
```
然后,您可以询问 Claude 类似于 *"在德国和爱尔兰搜索 GenAI 工程师职位,然后为最佳匹配生成量身定制的文档"* 的问题,它将调用 `search_jobs`、`list_top_jobs`、`generate_tailored_documents` 等。
### 使用 Docker 运行所有内容
```bash
docker compose up --build
# Streamlit:http://localhost:8501
# FastAPI: http://localhost:8000/docs
```
两个容器共享一个 `data/` 卷(SQLite 数据库 + 生成的文档),因此简历上传和获取的职位可以通过任一接口可见。
## 测试
```bash
pytest -v
```
所有测试都在离线状态下运行(假嵌入,隔离的临时 SQLite 数据库)——无需 API 密钥或 CI 中的网络调用。
## 关于职位来源的法律说明
该项目仅从 **Adzuna** 和 **Arbeitnow** 拉取数据,两者都为此用例提供免费、符合服务条款的公共 API。它不会刮取 LinkedIn、Indeed 或其他在服务条款中禁止自动刮取的职位板——手动 URL 粘贴功能用于您自己找到的特定职位发布。
## 路线图
- ✅ V1 — 简历上传,Adzuna + Arbeitnow,语义匹配,仪表盘,量身定制简历/求职信生成,Excel 导出
- ✅ V2(此版本)— Remotive/Greenhouse/Lever 来源,技能差距分析器,申请跟踪器 + 分析,FastAPI 后端,MCP 服务端,Docker Compose
- 🔜 V3 — 与 [career-rag-assistant](../career-rag-assistant) 结合:公开 RAG 职业知识库作为生成代理可以调用的工具,以实现更丰富、基于检索的定制;使用 pgvector 代替内存嵌入比较;用于多用户使用的身份验证
## 技术栈
LangGraph · LangChain · FastAPI · MCP · 基于嵌入的语义匹配 · SQLite · Streamlit · python-docx · Adzuna, Arbeitnow, Remotive, Greenhouse & Lever APIs · Docker Compose · pytest · GitHub Actions