Library / Job Extractor
ExtractionJob Extractor
Job postings hide structured data in prose: a salary written as "$80k–$100k", remote work described as "work from anywhere", skills buried in a paragraph, and experience asked as "3+ years". This prompt parses a posting into a strict object — job title and company exactly as written, a remote boolean that is only true when the posting says so explicitly, salary min and max as yearly numbers (or null when the posting stays silent), the required skills as an array, and years of experience. The null rule matters: a missing salary is null, never zero and never invented, so your salary filters never show a $0 job. Use it to build a job board, to compare offers, or to feed a matching engine that ranks candidates against real postings.
Optimized System Prompt
You are a job posting extraction engine. Read the posting and return ONLY a valid JSON object matching the schema below. job_title and company are strings exactly as written. remote is true only if the posting explicitly says remote, work from home, or fully distributed; otherwise false. salary_min and salary_max are yearly numbers in the posting's currency, or null if not stated. required_skills is an array of skill names exactly as written. years_experience is a number, or null if not stated. Do not add explanations, markdown, or extra fields. Never invent values that are not in the posting.
Raw JSON Schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "JobPosting",
"type": "object",
"additionalProperties": false,
"required": [
"job_title",
"company",
"remote",
"salary_min",
"salary_max",
"required_skills",
"years_experience"
],
"properties": {
"job_title": {
"type": "string",
"minLength": 1
},
"company": {
"type": "string",
"minLength": 1
},
"remote": {
"type": "boolean"
},
"salary_min": {
"type": [
"number",
"null"
],
"description": "Yearly salary minimum, or null if not stated."
},
"salary_max": {
"type": [
"number",
"null"
],
"description": "Yearly salary maximum, or null if not stated."
},
"required_skills": {
"type": "array",
"items": {
"type": "string"
}
},
"years_experience": {
"type": [
"number",
"null"
]
}
}
}
Validation Code — Zod (TypeScript)
import { z } from "zod";
export const JobPostingSchema = z.object({
job_title: z.string().min(1),
company: z.string().min(1),
remote: z.boolean(),
salary_min: z.number().nullable(),
salary_max: z.number().nullable(),
required_skills: z.array(z.string()),
years_experience: z.number().nullable(),
});
export type JobPosting = z.infer<typeof JobPostingSchema>;
Validation Code — Pydantic v2 (Python)
from pydantic import BaseModel, Field
class JobPosting(BaseModel):
job_title: str = Field(..., min_length=1)
company: str = Field(..., min_length=1)
remote: bool
salary_min: float | None = None
salary_max: float | None = None
required_skills: list[str] = []
years_experience: float | None = None