emdadibos/nextjobzlm-dataset-v0.1.0
NextjobzLM Instruction Dataset v0.1.0 Training data for NextjobzLM, the explanation and extraction model behind NextJobz recommendations. This is the v0.1.0 release, published on its own so the dataset viewer and fine-tuning UIs can read it. Every row is generated by code in the repository; no real person's data is in here. The model this trains never scores, ranks, or decides eligibility. Those decisions come from a rule engine and a ranker; the model restates them and extracts… See the full description on the dataset page: https://huggingface.co/datasets/emdadibos/nextjobzlm-dataset-v0.1.0.
NextjobzLM Instruction Dataset v0.1.0
Training data for NextjobzLM, the explanation and extraction model behind NextJobz recommendations. This is the v0.1.0 release, published on its own so the dataset viewer and fine-tuning UIs can read it. Every row is generated by code in the repository; no real person's data is in here.
The model this trains never scores, ranks, or decides eligibility. Those decisions come from a rule engine and a ranker; the model restates them and extracts structured fields. No row in here asks it to form a judgement.
10,000 rows, split 9,000 / 500 / 500. Chat format: each row is {"id", "category", "messages", "tool_calls"} with one user turn and one assistant turn. Every message is exactly {"role", "content"}, both strings.
Tool-call rows
1,082 assistant turns across the three splits are ATS tool calls. In the canonical repository those turns carry a structured tool_calls list instead of content. Here the schema is flat so that every loader and viewer can read it: the call is serialised as compact JSON into content, and the same JSON is repeated in the row-level tool_calls column (empty string on the other 9,000-odd rows). Parse that column if you want the structured form:
import json
calls = json.loads(row["tool_calls"]) if row["tool_calls"] else []A model trained on messages as-is therefore learns to emit the tool call as JSON text. If you want native tool-call supervision, map tool_calls back onto the assistant turn before applying a chat template.
How the labels were produced
Nothing here was written by hand or by a teacher model.
Engine-written. explanation, recruiter_note and eligibility_note are produced by running a synthesised candidate/job pair through the real recommendation pipeline - the actual eligibility rules, features and reason codes - and assembling the row from what came out.
Reversed extraction. job_profile and candidate_profile sample the answer JSON first and render the prose from it, so every value in the label provably appears in the source text.
Every row then passes a validator: JSON must parse, extraction values must be quotable from the prompt, canonical skills must round-trip through the taxonomy, tool arguments must appear in the request, and candidate-facing text must be grounded - no word outside the prompt, the English stopwords, and the house vocabulary the phrasings define.
Negatives
- 328 explanation rows (14.9%) carry only gap codes; the correct answer declines to recommend.
- 118 ats_tool rows (9.8%) are answered in words, not a call - including requests for a score, where the answer is a refusal and a pointer to the tool that has one.
Limitations
Template prose. Vocabulary and sentence structure are narrow, and a model trained only on this will generalise poorly to real job ads. Grounding is defined against the same phrasings that generated the data, which makes the corpus grounded by construction - that is a guard against a model inventing things at inference time, not evidence of linguistic richness.
Everything is generated by code in the repository. People, companies and postings are invented.
See docs/datasets.md in the repository for the full account.
