生活与工具
#api
job-hunter
Automated job hunting skill that searches jobs via JobSpy (LinkedIn guest API, free) and JSearch (RapidAPI/Google Jobs, 200 req/month free), matches them to your resume using scoring, generates personalized cover letters, and saves results to Obsidian. Triggers: /job-hunt, "find jobs", "job search", "hunt for jobs"
DeepseekModel
官方收录技能
质量 良好 · 64
v1.0.0
获取
https://deepseekmodel.com/api/download.php?id=donzhu2020-job-tracker-skill-md&format=skill
下载 .skill
标准格式,含 system_prompt 与 model_config,导入任意 Agent 框架即可使用
.skill 文件中 system_prompt 字段的实际内容。
name job-hunter description Automated job hunting skill that searches jobs via JobSpy (LinkedIn guest API, free) and JSearch (RapidAPI/Google Jobs, 200 req/month free), matches them to your resume using scoring, generates personalized cover letters, and saves results to Obsidian. Triggers: /job-hunt, "find jobs", "job search", "hunt for jobs" Job Hunter Skill Automates your job search: scrapes LinkedIn, Indeed, and 100+ job boards daily, scores every posting against your resume, and saves a ranked tracker to Obsidian. No LinkedIn account needed. Quick Start First-Time Setup Set up virtual environment: bash ~/.claude/skills/job-hunter/scripts/setup_venv.sh Configure preferences: ~/.venv/job-hunter/bin/python3 ~/.claude/skills/job-hunter/scripts/setup_config.py Set your resume path (PDF, DOCX, or TXT) Set Obsidian vault path Usage Run the job hunt: /job-hunt Or with specific options: /job-hunt --keywords "software engineer" --location "San Francisco" How It Works Two complementary providers run on a smart schedule: Provider Source Cost Schedule JobSpy LinkedIn guest API + Indeed Free, no key Every day JSearch Google Jobs aggregator (100+ boards) 200 req/month free Every 2 days On days both run, results are merged and deduplicated. On off-days, JobSpy runs alone. Workflow When invoked, the skill executes these steps: 1. Load Configuration Read config from ~/.config/job-hunter/config.json Validate paths and optional API keys 2. Read Resume Load resume from configured path Extract key skills for matching 3. Search Jobs — JobSpy (daily) + JSearch (every 2 days) JobSpy hits LinkedIn's undocumented public guest API — no login, no API key, returns full job descriptions (~60 results/run). JSearch queries Google Jobs via RapidAPI, aggregating postings from LinkedIn, Indeed, Dice, Remotive, and 100+ company career pages (~100 results/run). The scheduler uses a state file ( ~/.job-hunter-jsearch-last-run ) to decide whether JSearch runs. If both run, their outputs are merged and deduplicated: JobSpy ~60 jobs ─┐ ├─ deduplicate → ~130–160 unique jobs JSearch ~100 jobs─┘ 4. Score against resume Each job is scored 0–100 based on skill keyword matching: +5 per skill match (Python, SQL, machine learning, etc.) Bonus: role alignment (+15), healthcare domain (+10), EHR tools (+8), remote (+5) Skills are extracted automatically from your resume (PDF/DOCX/TXT) 4b. AI Re-rank (interactive runs only) Keyword scoring is literal — it can't distinguish "we use Python for Excel macros" from "ML platform team". When the skill runs interactively (not via cron), Claude re-ranks the top jobs by actually reading them: Prep — build a compact packet of the top ~30 keyword-scored jobs + resume: ~/.venv/job-hunter/bin/python3 ~/.claude/skills/job-hunter/scripts/rerank.py prep \ -i /tmp/scored.json -o /tmp/rerank_packet.md --top 30 Judge — Claude reads /tmp/rerank_packet.md and scores every job 0–100 for holistic fit (seniority, domain, day-to-day work vs. resume — not keyword counts). Claude writes the result to /tmp/rerank_scores.json as: { "<job id>" : { "ai_score" : 88 , "ai_reason" : "Strong healthcare + Python overlap" } } Every job id from the packet must appear. Keep reasons under 80 chars. Apply — merge scores back and re-sort: ~/.venv/job-hunter/bin/python3 ~/.claude/skills/job-hunter/scripts/rerank.py apply \ -i /tmp/scored.json -r /tmp/rerank_scores.json Each job gains final_score (AI score when present, keyword score otherwise) and the tracker sorts/filters by it, adding a Why column. Cron runs skip this step automatically — write_tracker.py falls back to keyword scores. 5. Save Job Tracker to Obsidian Writes Job Tracker - YYYY-MM-DD.md with all jobs scoring > 70 , sorted by score descending. Idempotent — skips if today's file already exists. | # | Score | Title | Company | Salary | Remote | Source | Link | |---|-------|-------|---------|--------|--------|--------|------| | 1 | 100 | Data Engineer II | Dana-Farber Cancer Institute | - | Yes | Indeed | [ Apply ]( url ) | | 2 | 100 | Senior Health Data Informaticist | Veeva Systems | - | Yes | Linkedin | [ Apply ]( url ) | 6. Wait for User Selection — STOP HERE After saving the tracker: "Saved X jobs to Job Tracker - YYYY-MM-DD.md in Obsidian. Review the file and tell me which numbers you'd like cover letters for (e.g. '1, 3')." Never auto-generate cover letters. Always wait for user to select. 7. Generate Cover Letters ~/.venv/job-hunter/bin/python3 ~/.claude/skills/job-hunter/scripts/generate_cover_letters.py \ -- jobs /path/to/scored_jobs.json \ --indices "1,3" Saves to Cover Letters/YYYY-MM-DD/Company - Title.md in your Obsidian vault. Configuration Reference Config file: ~/.config/job-hunter/config.json { "jsearch_api_key" : "your-rapidapi-key" , "search_provider" : "jobspy" , "resume_path" : "/path/to/resume.pdf" , "obsidian_vault" : "~/Documents/Obsidian Vault/job-hunter" , "user_name" : "Your Name" , "min_score" : 70 , "search" : { "keywords" : [ "data analyst" , "healthcare data analyst" , "research analyst" ] , "location" : "Boston, MA" , "remote" : true , "time_range" : "week" , "max_results_per_query" : 20 , "job_domains" : [ "linkedin.com" , "indeed.com" ] , "linkedin_fetch_description" : true , "request_delay" : 3 , "proxies" : [ ] , "user_agent" : "" , "country_indeed" : "USA" } } Key Fields Field Description jsearch_api_key RapidAPI key for JSearch (free tier: 200 req/month) search_provider "jobspy" (default) or "jsearch" for manual override min_score Tracker only includes jobs scoring above this (default 70) search.max_results_per_query Max 20 for JobSpy, max 10 for JSearch search.job_domains Used by JobSpy; maps to linkedin , indeed , glassdoor , zip_recruiter . Glassdoor is off by default (upstream 400 errors) search.linkedin_fetch_description Full LinkedIn descriptions (1 extra request/job). Set false if you hit 429 rate limits search.request_delay Seconds between JobSpy calls (default 3) — reduces rate-limiting search.proxies Proxy list ["user:pass@host:port"] — JobSpy round-robins through them; the reliable fix for persistent LinkedIn 429s search.user_agent Override JobSpy's default browser user-agent if it gets blocked search.country_indeed Indeed/Glassdoor country (default "USA" ) Scripts Script Purpose scripts/jobspy_scraper.py LinkedIn/Indeed via guest API (no key) scripts/jsearch_scraper.py Google Jobs via RapidAPI scripts/run_search.py Provider-switching search CLI scripts/score_jobs.py Score jobs against resume (keyword-based) scripts/rerank.py Prep/apply AI re-ranking by Claude (interactive runs) scripts/generate_cover_letters.py Generate cover letter templates scripts/write_tracker.py Write ranked Job Tracker markdown to Obsidian scripts/daily_job_hunt.sh Full pipeline orchestration (cron) scripts/setup_config.py Interactive config setup scripts/setup_venv.sh Virtual environment setup scripts/common/ Shared modules (config, scoring, dedup) Obsidian Structure job-hunter/ ├── Job Tracker - 2026-02-28.md # Today's tracker ├── Job Tracker - 2026-02-27.md # Yesterday's tracker ├── Cover Letters/ │ ├── 2026-02-28/ │ │ ├── Dana-Farber - Data Engineer II.md │ │ └── Veeva Systems - Senior Health Data Informaticist.md │ └── 2026-02-27/ Scheduling Set up a daily cron to run the full pipeline automatically: # Run job hunt daily at 10am 0 10 * * * bash ~/.claude/skills/job-hunter/scripts/daily_job_hunt.sh The script decides internally whether to also run JSearch (every 2 days). To force a JSearch run: rm ~/.job-hunter-jsearch-last-run API Usage & Cost Provider Free Tier Usage per run Monthly (daily cron) JobSpy Unlimited 0 requests $0 JSearch 200 req/month 7–14 requests ~98 req/month ✓ Troubleshooting No jobs found Check ~/.job-hunter.log — the run now prints per-site totals ( Per-site totals: linkedin=0, indeed=25 ) so you can see which board failed Broaden search keywords in config Each site is scraped independently, so one board failing no longer wipes out the others' results LinkedIn returns 0 results / 429 errors LinkedIn aggressively rate-limits (~100 results per IP, then blocks). In config: Set search.linkedin_fetch_description: false (biggest win — cuts requests by ~95%) Lower search.max_results_per_query Increase search.request_delay (e.g. 10) Add search.proxies — per JobSpy maintainers, proxies are the only durable fix Indeed has no rate limiting and full descriptions — results still flow while LinkedIn cools down (blocks typically clear within hours) JSearch API errors Verify key at rapidapi.com Check monthly usage (200 free requests) Delete ~/.job-hunter-jsearch-last-run to retry Glassdoor 400 errors in logs Known upstream issue in JobSpy — Glassdoor is now excluded from default sites; remove glassdoor.com from job_domains if you added it Virtual environment issues Re-run bash ~/.claude/skills/job-hunter/scripts/setup_venv.sh Requires Python 3.10+
Agent 识别该技能的关键词,点击任意一个即可复制。
该技能未提供触发词。
下载的 .skill 包内含以下字段。
| 字段 | 说明 |
|---|---|
| format | 格式标识(skill/v1) |
| skill_id | 技能唯一 ID |
| name | 技能名称 |
| version | 版本号 |
| description | 技能描述 |
| category | 所属分类(数组) |
| trigger_words | 触发词列表 |
| tags | 标签列表 |
| source | 来源标识 |
| source_url | 来源链接(本页地址) |
| exported_at | 导出时间(每次下载生成) |
| system_prompt | 系统提示词正文 |
| model_config | 模型参数:provider / model / temperature / max_tokens / top_p |
| examples | 示例 |
| install_guide | 各平台导入说明(Coze / Dify / Claude / 自定义框架) |