Parse a CV into structured fields
Extraction from messy human documents, where the hard part is telling the model not to guess.
When to use it
Extraction from documents written by humans for humans, where every one is formatted differently.
What it prevents
Confident fabrication. CVs omit things constantly. Told to extract an employer, a model will happily infer one from an email domain unless you forbid it.
The prompt
Extract the candidate's work history from the CV below.
### Output format
Return JSON and nothing else: [{"employer": "string", "title": "string", "start": "YYYY-MM", "end": "YYYY-MM or null"}]
### Requirements
- Use null for a missing end date, meaning the role is current. Do not write "present".
- If a date is given only as a year, use the year with month 01.
- Do not infer an employer from an email domain or a project name.
### Example
[{"employer": "Acme", "title": "Backend Engineer", "start": "2023-04", "end": null}]
### CV
"""
Acme — Backend Engineer, Apr 2023 to now
Globex, 2021: Junior Developer
"""Instant checks
States a concrete task
PassedAvoids vague language
PassedSpecifies an output format
PassedAvoids dangling references
PassedIncludes an example
PassedSeparates data from instructions
PassedAvoids over-aggressive phrasing
Passed
Why each part is there
Every section of that prompt exists because a specific failure happens without it. These are the checks it passes, and what each one is protecting you from:
- States a concrete task — why this matters
- Avoids vague language — why this matters
- Specifies an output format — why this matters
- Avoids dangling references — why this matters
- Includes an example — why this matters
- Separates data from instructions — why this matters
- Avoids over-aggressive phrasing — why this matters
How to adapt this one
Swap the target fields and keep the two anti-guessing rules: no inferring an employer from an email domain, and a defined convention for partial dates. CVs are written by humans for humans and every one is shaped differently, so the value you add is telling the model what to do with the gaps — not the fields that are present, which it handles fine on its own.
The mistake this prompt avoids
Letting the model fill blanks from context. A CV lists a project but not the employer, and the model quietly infers one from a URL or an email domain — a fabrication that looks exactly like real data. Extraction from human documents is mostly a discipline of forbidding inference; the fields that are stated were never the hard part.
A variation
Feeding an ATS or a search index, where consistency matters more than fidelity? Add a normalisation step — “map job titles to this controlled list, null for anything that does not fit” — so “Sr. SWE”, “Senior Software Engineer”, and “Software Engineer II” do not become three separate buckets. Extract raw when a human reads it; normalise when a filter does.
Check your version
Once you have adapted it, run it through the checker. The same nine checks that graded this page will grade yours, free and in your browser — paste it in, or build one from scratch by answering a few questions.