关于 job-auto-apply
job-auto-apply 是用于管理求职搜索、申请材料准备和提交流程的 Claude 技能。它将职位筛选与调研、定制简历、申请跟踪以及可配置的人工审核或自主提交结合起来。
主要功能
- 01搜索职位并筛选资格
- 02记录公司与职位调研
- 03生成定制简历和求职信
- 04检查 ATS 与文档格式
- 05跟踪申请及提交状态
- 06支持人工审核或自主模式
适用场景
- 01按每日目标寻找并筛选职位
- 02准备针对职位的申请材料
- 03在浏览器提交前审核申请
- 04跟踪已提交和待处理申请
MCP 相关
该技能可使用 Playwright MCP 搜索职位并通过浏览器执行申请步骤。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ liruihan000/ claude-job-auto-apply --skill job-auto-apply安装后在 Claude Code 中输入/job-auto-apply确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.md.gitignoreSETUP.mdconfig.example.jsonpackage.jsonpackage-lock.jsonats-handlers/generic.mdjobvite.mdindeed.mdlever.mdashby.mdgreenhouse.mdsap.mdoracle.mdtaleo.mdworkday.mdevals/test-bootstrap.shtest-config-change.mdtest-tailoring.mdreferences/filing-guide.mdcover-letter-guide.mdresume-format-spec.mduser-profile.example.mdselection-strategy.mdtemplate-guide.mdtailoring-guide.mdsearch-guide.mdscripts/ats_score.jscreate_cover_letter.jsbootstrap.js详细介绍
自动申请职位
配置:启动时,运行
node ${CLAUDE_SKILL_DIR}/scripts/bootstrap.js以加载所有运行时参数。 以下所有以config.*为前缀的值均来自config.json。 如果bootstrap.js返回ready: false,请读取${CLAUDE_SKILL_DIR}/SETUP.md并引导用户完成设置。 每个 Playwright 实例可用的工具:browser_snapshot、browser_navigate、browser_click、browser_type、browser_fill_form、browser_select_option、browser_file_upload、browser_press_key、browser_evaluate、browser_take_screenshot、browser_wait_for、browser_tabs、browser_hover
阶段 -1:启动时自动检查(必须执行)
每次调用此技能时:
- 检查用户意图:
- 如果用户询问职位相关问题,或表示要“讨论”/“分析”/“审查”/“看看”某个职位 → 进入讨论模式(见下文)。
- 如果用户针对特定职位 URL 或职位表示“申请”/“提交”/“投” → 进入单次申请模式:针对该职位执行阶段 1 的调研步骤(获取职位描述、提取关键词、调研公司、创建文件夹),然后直接进入该职位的阶段 2 → 阶段 2.5 → 阶段 3。
- 否则 → 继续自动申请流程。
- 运行
node ${CLAUDE_SKILL_DIR}/scripts/bootstrap.js→ 加载配置并检查准备状态- 如果
ready: false→ 读取${CLAUDE_SKILL_DIR}/SETUP.md,并引导用户补齐缺失项。不要进入任何阶段。不要尝试变通方案或使用替代工具。 - bootstrap.js 会自动创建目录和 TRACKER.md
- 如果
- 读取
applications/TRACKER.md - 统计「已提交」列中日期为今天的条目数 →
today_submitted - 列出材料已准备好的 ⬜ 未提交条目
- 报告:“今天:已提交 X/{config.daily_target},待处理 Y”
- 如果
today_submitted >= config.daily_target→ 报告已完成并停止 - 否则 → 立即进入自动申请工作流
自主性:如果 config.automation.manual_review: false → 完全自主执行,绝不询问用户,也绝不中途停止循环。如果为 true → 每个阶段之间暂停,等待用户审核后再继续。
讨论模式
当用户想讨论某个职位,而不是自动申请时:
- 读取职位信息(通过 WebFetch、Playwright 或用户提供的文本)
- 分析:职位要求、技术栈、团队、公司信息
- 对照用户在
uploaded-resumes/中的简历和user-profile.md - 与用户讨论:匹配度评估、优缺点、简历策略、需要询问的问题
- **不要进入自动申请工作流。**继续对话,直到用户表示要申请或结束讨论。
- 如果用户表示“申请”或“提交” → 将该职位添加到 TRACKER.md,并仅针对该职位继续执行阶段 2。
自动申请工作流
阶段 1:搜索 + 调研
持续查找职位,直到 pending + today_submitted >= config.daily_target。
按照 ${CLAUDE_SKILL_DIR}/references/search-guide.md 中的说明,并行搜索 config.search.platforms。
搜索可使用 Playwright MCP、WebSearch 或 WebFetch 来发现职位。
按照 ${CLAUDE_SKILL_DIR}/references/selection-strategy.md 进行筛选。去重。
对每个候选职位,必须完成所有步骤后才能继续处理下一个职位:
-
获取完整的职位描述文本(此时不要添加到 TRACKER)
-
应用
${CLAUDE_SKILL_DIR}/references/selection-strategy.md中的所有筛选条件——尤其要检查担保和公民身份要求。如果职位未通过任何一项筛选 → 完全跳过,不创建文件夹,也不添加到 TRACKER -
只有职位通过所有筛选后,才完成以下所有事项,然后再继续处理下一个职位: a. 在 TRACKER.md 中添加一行,状态为 ⬜ NOT SUBMITTED b. 创建文件夹
applications/YYYY-MM-DD_Company_Role/c. 将完整的职位描述文本保存到{APP_FOLDER}/jd.mdd. 提取职位描述中的关键词 →{APP_FOLDER}/jd-keywords.json(格式:{"required_skills":[], "preferred_skills":[], "keywords":[]}) e. 查找并阅读公司的 About/Mission 页面;将摘要保存到{APP_FOLDER}/notes.md(包括:行业、产品、规模、阶段、文化、职位描述 URL) f. 将{APP_FOLDER}/STATUS.md写为⬜ NOT SUBMITTED只有在 6 项文件均已存在时,职位才算在阶段 1 中“完成”:TRACKER 行 + 文件夹 + jd.md + jd-keywords.json + notes.md + STATUS.md。部分完成 = 未完成。
审核检查点(若 config.automation.manual_review: true):
向用户展示找到的职位列表(公司、职位、平台、URL)。等待用户确认要继续处理哪些职位。从 TRACKER.md 和相应文件夹中移除任何被拒绝的职位。
阶段 1.5:人脉扫描(可选——需要在 Playwright 配置文件中登录 LinkedIn)
针对 TRACKER.md 中状态为 ⬜ 的每家公司:
- 前往 LinkedIn:
linkedin.com/search/results/people/?keywords={COMPANY}&network=%5B%22F%22%5D(筛选一级人脉) - 如果在该公司找到人脉 → 在 TRACKER.md 中该职位的 Notes 列添加对方姓名和职位(例如:“🤝 John Doe - SWE @ Company”)
- 将有人脉的职位提高优先级
如果未登录 LinkedIn 或访问被拦截,则跳过此阶段。每家公司处理时间不得超过 30 秒。
阶段 2:准备(仅简历 + 求职信)
针对 STATUS.md 中包含 ⬜ NOT SUBMITTED 且文件夹中包含 jd.md 的每个职位。所有调研均已完成——仅阅读本地文件,无需发送网络请求。
- 阅读
{APP_FOLDER}/jd.md— 完整的职位描述文本 - 阅读
{APP_FOLDER}/jd-keywords.json— 提取的关键词 - 阅读
{APP_FOLDER}/notes.md— 公司信息 - 按照
${CLAUDE_SKILL_DIR}/references/template-guide.md从uploaded-resumes/中选择模板 - 阅读
user-profile.md获取个人信息(联系方式、工作授权、EEO) - 按照
${CLAUDE_SKILL_DIR}/references/tailoring-guide.md定制简历 - 按照
${CLAUDE_SKILL_DIR}/references/cover-letter-guide.md生成求职信(如果config.prepare.cover_letter_required) - 生成 DOCX + PDF
- 将
STATUS.md写为📁 PREPARED — NOT SUBMITTED
可通过子 Agent 并行处理(无需浏览器)。使用下方的准备子 Agent 提示词模板。
所有准备子 Agent 完成后——同步 TRACKER.md:
扫描所有 applications/*/STATUS.md。对于状态为 📁 PREPARED 或 ✅ SUBMITTED 的每个文件夹,确保对应的 TRACKER.md 行反映了该状态。
第 2.5 阶段:自动审核(强制 — 始终运行)
准备好所有材料后,主 Agent 会审核每份申请。运行以下检查:
- 内容:应用
${CLAUDE_SKILL_DIR}/references/tailoring-guide.md中的相同规则,确认内容符合要求。 - 格式:阅读生成的 PDF 并检查渲染问题 — 多余的 Markdown 字符(
*、**、#)、格式错误、乱码、缺失章节。 - 页面适配:确认正好 1 页 — 不溢出,也不要太短。
- AI 写作检测 + ATS 关键词评分:运行
node ${CLAUDE_SKILL_DIR}/scripts/ats_score.js {APP_FOLDER}/resume.md {APP_FOLDER}/jd-keywords.json。(jd-keywords.json已在第 1 阶段创建 — 不要重新生成。)检查结果:ats_score < 60→ 在简历中自然地补充缺失的关键词,然后重新生成ai_phrases_found→ 将标记的短语替换为建议的替代表达ai_patterns_found→ 重写受影响的句子
- ATS 解析检查:运行
node ${CLAUDE_SKILL_DIR}/scripts/ats_parse_check.js {APP_FOLDER}/resume.pdf。检查结果:status: FAIL→ 修复错误(缺失章节、格式错误),然后重新生成status: WARN→ 查看警告,尽可能修复
自动修复发现的问题;如有更改,重新生成 DOCX + PDF。
审核检查点(如果 config.automation.manual_review: true):
自动审核后,向用户展示每份已准备申请的摘要,以及发现或修复的问题。等待用户确认要提交哪些申请。将被拒绝的申请标记为 TRACKER.md 中的 ❌ SKIPPED。
第 3 阶段:提交
根据 config.automation.manual_review 分为两种模式:
人工审核模式(manual_review: true)— 并行子 Agent,由用户手动提交
子 Agent 仍会在 N 个 Playwright 实例中并行运行。每个子 Agent 的任务在审核页面结束 — 用户在浏览器中手动提交。
子 Agent 行为(manual_review: true):
1. Navigate to job URL (opens a new tab in the assigned Playwright browser instance)
2. Fill all forms and upload tailored resume as normal
3. Navigate to the final review/confirmation page — do NOT click Submit
4. Take screenshot → {APP_FOLDER}/review-screenshot.png
5. Return "REVIEW_READY: {COMPANY} — {ROLE} | screenshot: {APP_FOLDER}/review-screenshot.png"
(Task is complete — browser tab stays open at the review page)
主 Agent 行为(manual_review: true):
active_subagents = 0
WHILE today_submitted < config.daily_target OR active_subagents > 0:
// Dispatch up to N subagents (N = config.submit.parallel_instances)
WHILE active_subagents < N AND more jobs with 📁 PREPARED:
Launch next subagent (run_in_background: true, mode=REVIEW_ONLY)
active_subagents++
// Handle incoming results (non-blocking — process as they arrive)
When a subagent returns REVIEW_READY:
active_subagents--
Show user: "✋ {COMPANY} — {ROLE} ready. Screenshot: {APP_FOLDER}/review-screenshot.png
Submit in browser → reply 'submitted {COMPANY}' | 'skip {COMPANY}' | 'stop'"
When user replies:
"submitted {COMPANY}" → update TRACKER.md ✅, today_submitted++
"skip {COMPANY}" → update TRACKER.md ❌ SKIPPED
"stop" → drain active subagents then exit loop
END WHILE
自主模式(manual_review: false)— 并行子 Agent
WHILE today_submitted < config.daily_target:
1. Pick up to N jobs whose STATUS.md contains `📁 PREPARED` (N = config.submit.parallel_instances)
2. Launch N subagents (run_in_background: true), each assigned a unique Playwright prefix
3. Wait for ALL subagents in this batch to complete
4. For EACH completed subagent — immediately update TRACKER.md:
SUCCESS → change Status to ✅ SUBMITTED, fill Submitted date column, today_submitted++
FAILED → change Status to ❌ SKIPPED, add reason to Notes column
Do NOT batch these updates — update one row at a time as each result comes in.
5. After updating TRACKER.md, verify the row was written correctly by re-reading it.
6. If more pending → repeat. If none → back to Phase 1.
END WHILE
TRACKER.md 更新规则:TRACKER.md 由主 Agent 负责。每次结果出现后立即更新 — 不要批量更新或跳过。
第 4 阶段:回顾(达到每日目标或会话结束后)
检查子 Agent 的返回消息中是否有 FRICTION: 行:
- 新的 ATS + 摩擦问题 → 使用变通方法创建
${CLAUDE_SKILL_DIR}/ats-handlers/{platform}.md - 已知 ATS + 摩擦问题 → 将修复方法作为一个项目追加到现有处理文档中
- 没有摩擦问题行 → 跳过,无需更新
准备子 Agent 提示词模板
替换 {variables},传递给 Agent 工具:
Prepare application materials for {COMPANY} — {ROLE}.
**Application folder**: {APP_FOLDER}
Start from the research already saved in {APP_FOLDER}. You may do additional web research if needed (e.g. deeper company info, product details for cover letter).
**Input files (already exist in {APP_FOLDER}):**
- `jd.md` — full job description text
- `jd-keywords.json` — extracted JD keywords
- `notes.md` — company info (industry, product, size, culture)
**Steps:**
1. Read `{APP_FOLDER}/jd.md`, `{APP_FOLDER}/jd-keywords.json`, `{APP_FOLDER}/notes.md`
**JD completeness check**: If `jd.md` is missing, empty, or clearly truncated (< 300 words, no responsibilities/requirements section), re-fetch the full JD from the URL in `notes.md` and overwrite `jd.md` and `jd-keywords.json`.
2. Select the best matching template from `uploaded-resumes/` per `${CLAUDE_SKILL_DIR}/references/template-guide.md` — read its full content for experience/skills
3. Read `user-profile.md` for personal info (contact, work auth, EEO)
4. Tailor resume per `${CLAUDE_SKILL_DIR}/references/tailoring-guide.md`
**Format**: follow `${CLAUDE_SKILL_DIR}/references/resume-format-spec.md` exactly. `create_resume.js` enforces this automatically.
5. Write `resume-config.json` (structured data for DOCX generation)
6. Generate DOCX: `node ${CLAUDE_SKILL_DIR}/scripts/create_resume.js {APP_FOLDER}/resume-config.json {APP_FOLDER}/resume.docx`
7. Generate PDF: `libreoffice --headless --convert-to pdf --outdir {APP_FOLDER} {APP_FOLDER}/resume.docx`
8. **Page check**: Read the generated PDF and verify exactly 1 page. If not, reduce bullets per role (min 1) and regenerate. Repeat until exactly 1 full page.
9. If `config.prepare.cover_letter_required`: write `cover-letter-config.json`, generate cover_letter.docx + PDF — reference specific company details from notes.md
10. Write `STATUS.md` as `📁 PREPARED — NOT SUBMITTED`
11. Do NOT submit anything — only prepare materials
12. Do NOT fabricate experience — only use info from the resume template
13. Return "PREPARED: {COMPANY} — {ROLE}" when done
提交子 Agent 提示词模板
替换 {variables},传递给 Agent 工具:
Submit application to {COMPANY} — {ROLE}.
**Mode:** {SUBMIT_MODE} (either "AUTO_SUBMIT" or "REVIEW_ONLY")
**Goal:**
- AUTO_SUBMIT: Fill all forms, upload resume, and click Submit.
- REVIEW_ONLY: Fill all forms, upload resume, navigate to review/confirmation page — do NOT click Submit. Take screenshot and return "REVIEW_READY".
**Tools:** ONLY use `{PLAYWRIGHT_PREFIX}*` tools. Never use other playwright instances.
**Data sources:**
- `user-profile.md` — personal info, contact, work auth, EEO defaults
- `secrets.md` — credentials for login/registration
- Resume: {RESUME_PATH}
- Cover letter: {COVER_LETTER_PATH} (if exists)
- Additional documents: {ADDITIONAL_DOCS}
- ATS strategies: `${CLAUDE_SKILL_DIR}/ats-handlers/` (read matching platform file if recognized)
**Approach:** Observe the page at each step, decide what to do next. Every ATS is different — adapt to what you see rather than following a fixed sequence. General flow: navigate → find apply button → fill forms → upload files → review → submit. But let the page guide you.
**Constraints:**
- Auto-agree all terms/cookies/eSignatures (if config.automation.auto_agree_terms)
- Auto-register accounts if needed (if config.automation.auto_register_accounts)
- Fill ALL required fields — never leave a field empty or on "Select..."
- **Resume upload**: ALWAYS upload {RESUME_PATH} — never use a previously saved resume from the ATS profile, even if one is already shown. Actively replace it.
- Screening questions: authorized=Yes, sponsorship=Yes (+explanation), 18+=Yes, background=Yes, previously worked=No. Check for follow-up fields after each answer.
- Experience/Education dates must match the tailored resume exactly — never guess
- Before submitting: verify all required fields are filled
- Screenshot before submit → {APP_FOLDER}/review-screenshot.png (if config.submit.screenshot_review)
- Screenshot after submit → {APP_FOLDER}/confirmation-screenshot.png (if config.submit.screenshot_confirmation)
- If stuck on any interaction for >config.submit.max_retries_per_form retries, skip and report why
**Output:**
- AUTO_SUBMIT: Write {APP_FOLDER}/STATUS.md as ✅ SUBMITTED. Return "SUCCESS" or "FAILED: [reason]"
- REVIEW_ONLY: Take screenshot → {APP_FOLDER}/review-screenshot.png. Do NOT write STATUS.md. Return "REVIEW_READY: {COMPANY} — {ROLE}"
- If friction encountered, append: "FRICTION: [what happened] → [what worked]"
参考资料
- 求职搜索:
${CLAUDE_SKILL_DIR}/references/search-guide.md— 平台方法、去重 - 职位选择:
${CLAUDE_SKILL_DIR}/references/selection-strategy.md— 筛选条件、优先级排序 - 简历定制:
${CLAUDE_SKILL_DIR}/references/tailoring-guide.md— 8 步检查清单 - 简历格式:
${CLAUDE_SKILL_DIR}/references/resume-format-spec.md— Times New Roman、黑色标题、2 行公司格式、项目符号技能 - 求职信:
${CLAUDE_SKILL_DIR}/references/cover-letter-guide.md— 结构、规则 - 模板选择:
${CLAUDE_SKILL_DIR}/references/template-guide.md— 不同 JD 应选用哪个模板 - 归档与跟踪:
${CLAUDE_SKILL_DIR}/references/filing-guide.md— 文件夹结构、TRACKER 格式 - 用户档案:
user-profile.md— 个人信息、联系方式、工作授权、EEO - 凭据:
secrets.md— ATS 登录、注册、Google Sign-In
关键规则
- 浏览器工具规则:
- 搜索职位:WebSearch、WebFetch 和 Playwright 均可使用。
- 所有与网页交互的操作(填写表单、点击、上传、提交、登录、注册):只能使用 Playwright MCP(
mcp__playwright*)。 切勿使用 BrowserMCP、Claude-in-Chrome 或其他浏览器工具。 - 如果 Playwright 不可用,停止并运行 SETUP——不要尝试使用其他浏览器工具。
- 为每份简历量身定制。 切勿直接提交模板。
- 切勿捏造经历——只能使用
uploaded-resumes/中简历模板里的信息。 - 提交前验证——点击提交前,使用 JS 检查所有必填字段。
- 发生错误时:最多重试
config.submit.max_retries_per_form次,然后跳过并记录原因。 - 每日目标达成前绝不停止。
- 使用与用户相同的语言(参见
config.preferences.response_language)。 - 自动更新:用户要求添加新的搜索平台、ATS 处理程序或更改配置时,立即更新相应文件(
config.json、${CLAUDE_SKILL_DIR}/references/search-guide.md、${CLAUDE_SKILL_DIR}/ats-handlers/*.md)——不要让用户手动编辑。