Intelligent job search assistant with RAG-based semantic matching, automated applications, and data-driven tracking.
Run the setup script to install dependencies and initialize the vector database:
bash
cd {SKILL_DIR}
pip install -r scripts/requirements.txt
python3 scripts/setup_rag.py --init
Then create your profile:
bash
cp assets/profile_template.json ~/job_profile.json
# Edit ~/job_profile.json with your info
Import your resume (PDF or DOCX):
bash
python3 scripts/rag_engine.py --import-resume ~/path/to/resume.pdf
When user says "find jobs for me" or "match my resume":
Load user profile from ~/job_profile.json
Run RAG matching engine: bash
python3 {SKILL_DIR}/scripts/rag_engine.py \
--mode search \
--platforms linkedin,boss \
--min-score 0.75 \
--max-results 20
Present results sorted by match score
For each job, show: title, company, match score, top matching skills, missing skills
Ask user which jobs to apply to, or auto-apply if configured
When user says "apply to these jobs" or "auto-apply":
For each selected job: bash
python3 {SKILL_DIR}/scripts/apply_pipeline.py \
--job-id <id> \
--mode dry-run \
--generate-cover-letter \
--optimize-ats
In dry-run mode: show generated cover letter and ATS-optimized resume highlights for review
After user confirms, switch to --mode submit
Log result to tracker database
When user says "track my applications" or "job search report":
bash
python3 {SKILL_DIR}/scripts/tracker.py --report daily
Status flow: Discovered → Applied → Screening → Interview → Offer / Rejected
When user says "I like this job" or "not interested":
bash
python3 {SKILL_DIR}/scripts/rag_engine.py \
--mode feedback \
--job-id <id> \
--signal like|dislike
This adjusts the RAG query vectors to improve future recommendations.
User config lives at ~/job_profile.json. Skill config in OpenClaw:
json
{
"skills": {
"ai-job-hunter-pro": {
"enabled": true,
"profile_path": "~/job_profile.json",
"default_platforms": ["linkedin", "boss"],
"max_daily_applications": 20,
"min_match_score": 0.75,
"require_confirmation": true,
"dry_run": true
}
}
}