refactor: generic system prompt — dumps full JSON profiles, no hardcoded criteria
This commit is contained in:
@@ -19,53 +19,22 @@ export function loadProfile(profilePath) {
|
||||
}
|
||||
|
||||
function buildSystemPrompt(jobProfile, candidateProfile) {
|
||||
const tr = jobProfile.target_role;
|
||||
const exp = jobProfile.experience || {};
|
||||
const highlights = (exp.highlights || []).map(h => `- ${h}`).join('\n');
|
||||
return `You are a job relevance scorer. Score each job listing 0-10 based on how well it matches the candidate profile below.
|
||||
|
||||
return `You are a job relevance scorer. Score each job 0-10 based on how well it matches this candidate.
|
||||
## Candidate Profile
|
||||
${JSON.stringify(candidateProfile, null, 2)}
|
||||
|
||||
## Candidate
|
||||
- Name: ${candidateProfile.name?.first} ${candidateProfile.name?.last}
|
||||
- Location: ${candidateProfile.location?.city}, ${candidateProfile.location?.state} (remote only, will not relocate)
|
||||
- Years in sales: ${candidateProfile.years_experience}
|
||||
- Desired salary: $${(candidateProfile.desired_salary || 0).toLocaleString()}
|
||||
- Background: ${(candidateProfile.cover_letter || '').substring(0, 300)}
|
||||
## Target Job Profile
|
||||
${JSON.stringify(jobProfile, null, 2)}
|
||||
|
||||
## Target Role Criteria
|
||||
- Titles: ${(tr.titles || []).join(', ')}
|
||||
- Industries: ${(exp.industries || []).join(', ')}
|
||||
- Company stage: ${(tr.company_stage || []).join(', ') || 'any'}
|
||||
- Company size: ${tr.company_size || 'any'}
|
||||
- Salary minimum: $${(tr.salary_min || 0).toLocaleString()}
|
||||
- Remote only: ${tr.remote ? 'Yes' : 'No'}
|
||||
- Excluded keywords: ${(tr.exclude_keywords || []).join(', ')}
|
||||
## Instructions
|
||||
- Use the candidate profile and target job profile above as your only criteria
|
||||
- Score based on title fit, industry fit, experience match, salary range, location/remote requirements, and any exclude_keywords
|
||||
- 10 = perfect match, 0 = completely irrelevant
|
||||
- If salary is unknown, do not penalize
|
||||
- If a posting is from a staffing agency but the role itself matches, score the role — not the agency
|
||||
|
||||
## Experience Highlights
|
||||
${highlights}
|
||||
|
||||
## Scoring Guide
|
||||
10 = Perfect match (exact title, right company stage, right industry, right salary range)
|
||||
7-9 = Strong match (right role type, maybe slightly off industry or stage)
|
||||
5-6 = Borderline (relevant but some mismatches — wrong industry, seniority, or vague posting)
|
||||
3-4 = Weak match (mostly off target but some overlap)
|
||||
0-2 = Not relevant (wrong role type, wrong industry, recruiter spam, part-time, etc.)
|
||||
|
||||
Penalize heavily for:
|
||||
- Part-time roles
|
||||
- Wrong industry (insurance, healthcare PR, construction, retail, K-12 education, utilities)
|
||||
- Wrong role type (SDR/BDR, customer success, partnerships, marketing, coordinator)
|
||||
- Junior or entry-level positions
|
||||
- Staffing agency posts with NO discernible real role or company (pure spam) — if the role and responsibilities are clearly described, DO NOT penalize for being posted by a recruiter/agency
|
||||
- Salary clearly below minimum
|
||||
- Geographic mismatch (non-remote, requires relocation)
|
||||
|
||||
Do NOT penalize for:
|
||||
- Company size or funding stage (this is an enterprise AE role — large companies are fine)
|
||||
- SMB or mid-market segments (these are valid AE roles)
|
||||
- Staffing agency postings where the actual role is clearly described
|
||||
|
||||
Return ONLY a JSON object: {"score": <0-10>, "reason": "<one line>"}`;
|
||||
Return ONLY a JSON object: {"score": <0-10>, "reason": "<one concise line>"}`;
|
||||
}
|
||||
|
||||
function sanitize(str) {
|
||||
|
||||
Reference in New Issue
Block a user