MadsLorentzen/ai-job-search — 本地运行的 AI 求职申请框架
评估岗位、定制简历和求职信、准备面试。
本周新增 Star 9,073 | 仓库 Star 总数 63,937 | Forks 19,797⚠️ 仓库已迁移:原
MadsLorentzen/ai-job-search现重定向至ai-job-search-dev/ai-job-search。下方命令已按新路径给出。
| 项目 | 信息 |
|---|---|
| 官方仓库 | https://github.com/ai-job-search-dev/ai-job-search (旧地址 https://github.com/MadsLorentzen/ai-job-search 自动跳转) |
| 社区分叉讨论 | https://github.com/MadsLorentzen/ai-job-search/discussions/78 |
| 语言 / 许可 | Python / MIT |
| 默认分支 | master |
| 最新提交 | 2026-10-21 |
| 一句话定位 | 跑在你自己机器上 的求职申请框架:基于 Claude Code,评估岗位 → 定制简历 → 写求职信 → 准备面试。全链路本地,简历不被上传到第三方 SaaS |

▲ 图 0:AI Job Search 官方吉祥物演示(官方截图)
一、前置条件
| 依赖 | 要求 |
|---|---|
| Claude Code(CLI) | 必须。无免费层:需要 Claude Pro / Max / Team 订阅,或 Anthropic API 额度(按 token 计费,偶尔使用通常更便宜) |
| Python | 3.10+ |
| Bun | 用于求职门户 CLI 工具(https://bun.sh) |
| LaTeX 发行版 | 需含 lualatex 与 xelatex:TeX Live / MacTeX / TinyTeX / MiKTeX |
| pypdf(可选) | pip install pypdf,用于 /apply 的 ATS 可解析性检查(BSD,无需 Poppler) |
LaTeX 引擎选择的坑(官方明确提示):
- CV 用
lualatex编译 —— 现代 MiKTeX 上的pdflatex常因fontawesome5字体扩展报错。 - 求职信用
xelatex编译 ——cover.cls需要fontspec。 - 使用 TinyTeX / BasicTeX 等精简发行版时,需按
SETUP.md#minimal-tex-install-tinytexbasictex安装额外宏包。
Poppler(可选回退方案): pdftotext 是 pypdf 的替代方案 —— macOS brew install poppler;Debian/Ubuntu apt install poppler-utils;Windows choco install poppler。两者都缺失时,检查降级为目视关键词复核。
使用其他智能体(Codex / Antigravity / Gemini CLI): 从 AGENTS.md 开始 —— 门户搜索 skills 开箱即用;完整工作流可参考社区分叉自行适配。
二、部署方式
方式 A:Fork + 克隆(官方推荐流程)
gh repo fork MadsLorentzen/ai-job-search --clone
cd ai-job-search
[!IMPORTANT]
公开仓库的 fork 永远是公开的 —— GitHub 不允许把公开仓库 fork 成私有。而/setup(第 3 步)会把你的个人数据(姓名、联系方式、工作经历、薪资预期)写进 被 git 跟踪的文件。如果这份副本只是你自己用来找工作、不打算回馈贡献,请改用 私有仓库 并把本仓库设为
upstream:
# 1. 在 GitHub 上新建一个空的私有仓库
# 2. 把它设为 upstream 并推送
git remote add upstream https://github.com/ai-job-search-dev/ai-job-search.git
git push -u origin main
完整的两分钟配方见
SETUP.md第 8 节,所有更新流程完全一致。只有打算贡献代码时才用 Fork。
方式 B:直接克隆(不打算改代码时)
git clone https://github.com/ai-job-search-dev/ai-job-search.git
cd ai-job-search
方式 C:安装求职门户 CLI 工具
python3 tools/install_portal_clis.py # Windows: python tools\install_portal_clis.py
它会在 .agents/skills/*/cli/ 下的 每一个 门户 CLI 中运行 bun install —— 这些目录是 自动发现 的而非写死的,所以你后来用 /add-portal 添加的、或从别的分叉复制来的门户,在全新克隆后也会被纳入。
package.json中声明了安装期生命周期脚本的 CLI 会被 跳过并报告,而不是执行。- 加
--dry-run可预览将要安装什么。 - 对
linkedin-search与freehire-search,安装是可选的:两者 零运行时依赖,直接用bun即可运行;bun install只会拉取 TypeScript 开发类型。
方式 D:安装 LaTeX 工具链
# macOS
brew install --cask mactex
# 或轻量版
brew install --cask basictex
# Debian / Ubuntu
sudo apt install texlive-full
# Windows:安装 MiKTeX(https://miktex.org/),并在安装器中勾选额外宏包
三、使用方法
3.1 标准五步工作流
第 1 步:Fork 并克隆(见部署方式 A)
第 2 步:安装求职门户工具
python3 tools/install_portal_clis.py
第 3 步:建立个人档案
claude
# 然后在 Claude Code 内:
/setup
/setup 提供 三条路径:
- 路径 A:读取你的
documents/文件夹(CV 的 PDF、LinkedIn 导出、学历证书、推荐信、过往申请记录) - 路径 B:直接粘贴一份 CV 到聊天窗口
- 路径 C:通过问答式访谈逐项建立
它会自动检测你已有什么并主动询问。路径 A 是幂等的,你持续补充材料时可以安全重复运行。documents/ 目录布局见 documents/README.md。
第 4 步:搜索岗位
/scrape
跨多个招聘门户搜索与你档案匹配的岗位,去重后 按匹配度排序 呈现。
- 选一个岗位 → 直接对它运行
/apply - 岗位太多看不过来 → 先运行
/rank批量打分,拿到排序后的短名单
第 5 步:申请
/apply https://jobindex.dk/job/1234567
若 URL 抓不到(部分招聘门户屏蔽自动访问),直接粘贴职位描述:
/apply <在此粘贴完整职位描述>
3.2 全部命令速查
| 命令 | 作用 |
|---|---|
/setup |
建立个人档案(documents / CV 导入 / 访谈三选一) |
/scrape |
跨门户搜索岗位 |
/apply |
评估岗位 → 起草 CV 与求职信 → 复审 → 定稿 |
/rank |
批量给新抓取的岗位打分,输出排序短名单 |
/interview |
为已投递岗位准备阶段特定的面试包 + 模拟面试 |
/outcome |
记录申请结果(面试阶段、offer、拒绝、沉默);/outcome followup 跟进长期无回音的申请 |
/upskill |
分析技能差距,产出优先级热力图与学习计划 |
/expand |
从公开来源(GitHub、作品集、Kaggle、Scholar、课程大纲)补全能力项 |
/html-report |
生成自包含的 HTML 求职看板(纯离线,无外部依赖) |
/notion-sync |
把求职管道以 单向只读 视图发布到 Notion 数据库 |
/gmail-sync |
读 Gmail 识别申请状态(面试邀请、笔试、offer、拒绝),批量提议后需你批准 |
/add-template |
注册你自己的 CV / 求职信模板(LaTeX、Typst 或其他工具链) |
/add-portal |
为你所在市场的招聘网站生成搜索 skill |
/reset |
清空档案数据或 documents 文件夹 |
3.3 /apply 内部做了什么(核心机制)
- 解析职位公告(URL 或文本)
- 评估匹配度:技能、经验、文化、地点、职业方向
- 起草定制的 CV 与求职信(LaTeX)
- 派生复审智能体:调研公司并批判草稿
- 根据反馈修订
- 编译并逐页检视 PDF:CV 用
lualatex,求职信用xelatex。Claude 会 读取渲染后的页面 并迭代修改 LaTeX,直到 CV 恰好 2 页且无孤立标题、求职信恰好 1 页且签名可见、字体一致 - ATS 检查 CV:用
pdftotext抽取 PDF 文本层,按 ATS 解析器的方式验证(联系方式是否为字面文本、无乱码字形、阅读顺序合理),再计算职位关键词覆盖率。档案真正支持的关键词才会被加入;真实缺口保持可见,绝不硬塞 - 呈现最终产出与核对清单
四个关键设计:
- PDF 验证闭环 —— 多数 LaTeX 简历模板在
.tex里看着正常,编译出来就崩:职位标题跑到下一页、求职信溢出到第 2 页、项目符号字体静默回退。/apply每次都编译并 目视检查,再用\needspace、\enlargethispage、字体匹配包装器逐项修复。 - ATS 校验 PDF 文本层 —— ATS 读的是嵌入文本而非渲染页面。LaTeX 可能产出文本抽取为乱码的 PDF(邮箱位置变成图标字形、多栏布局行序交错)。
- 相关性加权裁剪 —— CV 超 2 页时,不机械地从"最老"的部分砍。而是按 (a) 与目标职位的相关性、(b) 文档内独特性、(c) 求职信是否依赖它 三项打分,先砍总分最低的行。命中职位关键词的 老岗位 要点能排在不命中的 近期岗位 要点之前。
- 起草者-复审者分离 —— 起草者写,第二个 全新上下文 的 Claude 智能体调研公司并批判草稿,起草者再修订。这能抓出一遍生成常漏掉的关键词缺失、定位薄弱与套话。
诚实性底线: CV 与求职信中的所有主张都会对照你的真实档案核验,系统绝不编造技能或经历。
3.4 自定义
手动编辑档案文件
| 文件 | 改什么 |
|---|---|
CLAUDE.md |
你的完整档案(姓名、教育、经历、技能、目标) |
01-candidate-profile.md |
CV 数据的结构化版本 |
02-behavioral-profile.md |
行为测评或自评 |
04-job-evaluation.md |
技能匹配领域、职业目标、动机筛选项 |
05-cv-templates.md |
不同岗位类型的个人陈述模板 |
07-interview-prep.md |
你真实经历中的 STAR 案例 |
search-queries.md |
按技能与地点编写的搜索查询 |
只更新搜索配置
/setup --section search
重新运行搜索配置访谈:目标岗位、搜索技能、地点、门户;还会基于你的档案推荐你可能没想到的岗位类型。
使用自己的简历模板
/add-template # 注册新模板
/add-template --list # 查看已注册模板
/add-template --use # 切换
/add-template --use default # 恢复内置 moderncv / cover.cls
流程:指向源文件(.tex + .cls/.sty/字体,或 .typ + 本地包)→ 访谈采集模板说明(源扩展名、编译命令、字体位置、需保留的样式规则、硬性页数上限)→ 存入 templates/ → 强制执行一次测试编译 → 激活。模板中用 [PLACEHOLDER] 占位符而非真实数据,因此 可安全提交与分享。
添加本地招聘门户
/add-portal
给它本地招聘网站的 URL。该命令会 调研 门户(搜索 URL 规律、结果页结构、robots.txt / 访问规则),用与内置 skill 相同的结构生成 CLI skill,并在注册前 先跑一次真实查询测试。需要登录的门户会被拒绝;条款限制严格的门户会在生成的 skill 里加上醒目的"仅供个人使用"警告。
从别的分叉借用门户 skill(推荐方式):在门户索引找到 → 打开那个分叉 → 把那一个文件夹复制进你自己的 .agents/skills/。复制前务必:
- 通读代码 —— 这些 CLI 会在你的机器上 预授权运行(
.claude/settings.json已放行),且接触你的职业数据。检查:网络请求是否只去它声称搜索的招聘网站、package.json是否无dependencies与生命周期脚本(postinstall等)、是否读写自身目录以外的东西 - 离线跑它的测试 —— 在 skill 的
cli/目录执行bun test,好 skill 的测试应当无需联网即通过 - 检查
enabled:标志与 skill 自带的 ToS 说明
复制步骤故意保持手动。因为你的设置已放行已安装的门户 skill 免询问运行 —— 一个替你从第三方仓库自动抓取 skill 的安装器,会跳过唯一重要的检查:你自己先读代码。
薪资对标
薪资工具支持 任何你提供的数据(工会统计、Glassdoor 导出、个人调研)。格式与设置见 tools/README_SALARY_TOOL.md。没有数据则跳过该步骤。
重置
/reset profile # 清空 skill 文件,保留框架规则
/reset documents # 删除 documents/ 下的文件
/reset all # 两者都做
/reset 会 明确列出将删除的内容,并要求你输入 RESET 确认,不确认则什么都不删。
保持更新
# 预览上游更新会触及你哪些个性化文件
python3 tools/check_upstream_updates.py
# 把落后的提交分类为"值得审阅" vs "大概可跳过"
python3 tools/upstream_triage.py
上游节奏很快。更新你的副本时,请拉取带 tag 的 release(经过审核的检查点,变更见 CHANGELOG.md),而不是直接拉 master。完整流程见 SETUP.md 第 8 节。
3.4.1 提高质量的建议
档案深度决定输出质量。 档案单薄 → 申请函千篇一律;档案详实 → 才能真正定制化。
- 岗位描述别只列职位名:写清你实际做了什么 —— 具体项目、用到的工具、职责、可量化的成果
- 技能要有上下文:"用 Python + scikit-learn 搭建了客户流失预测的 ML 管道" 远比 "Python、机器学习" 更有用
两种求职模式:
- 明确目标型:你已知想去的岗位或行业,系统帮你细化与排序
- 潜在机会发现型:通过分析你的完整履历(不只是职位名,而是实际做的事),发现你没想到的职业路径 —— 可迁移技能到意外行业、你乐在其中或擅长的模式、领域 expertise 与新技术结合的新兴岗位
第二种模式需要在 /setup 时额外投入:不仅描述经历,也描述 什么让你兴奋、什么让你耗竭、你还想做什么更多。这些上下文直接影响 /scrape 浮现哪些岗位。
四、安全说明
- 招聘公告被视为 不可信输入 —— 工作流 不遵循 公告中嵌入的任何指令,也 不抓取 其正文中的链接
- 但智能体层的防护是 指令级 的,不是沙箱级 —— 在陌生招聘网站上,发送前请先扫一眼抓取和写入了什么
- 详情见
SECURITY.md
内置工具:
| 工具 | 作用 |
|---|---|
tools/posting_guard.py |
完整性闸门:剥离隐藏文本、标记形似注入的行 |
tools/security_guards.py |
CI 守卫:权限 allow/ask/deny、skill 授权、gitignore、清单 |
tools/robots_check.py |
对 robots.txt 做门控,配合浏览器头重试 |
tools/fetch_page.py |
仅 GET 的浏览器头重试(强制遵守 robots.txt) |
tools/verify_layout.py |
测量编译后 PDF 的版面(空洞、孤行、页脚碰撞) |
tools/verify_pdf.py |
验证编译后 PDF 的页数与可提取文本 |
参考链接
- 仓库:https://github.com/ai-job-search-dev/ai-job-search
- 详细设置指南:https://github.com/ai-job-search-dev/ai-job-search/blob/master/SETUP.md
- 安全策略:https://github.com/ai-job-search-dev/ai-job-search/blob/master/SECURITY.md
- 贡献指南:https://github.com/ai-job-search-dev/ai-job-search/blob/master/CONTRIBUTING.md
- 社区分叉与门户索引:https://github.com/MadsLorentzen/ai-job-search/discussions/78
- 演示视频:https://www.youtube.com/watch?v=HoVxjMNFYv4