What it does
Given a job posting and a résumé (the score_v1 prompt in the repo), it emits
one JSON verdict: a calibrated fit probability, up to 5 quoted evidence
items, job-relevant gaps, or an explicit insufficient_information
abstention for unreadable input. Wrong-field candidates get low scores, not
abstentions — identity signals are not scoring features.
Evaluation (vs base Inkling, held-out synthetic val, efforts 0.3/0.8)
Table with columns: metric, base @0.3, tuned @0.3, base @0.8, tuned @0.8| metric | base @0.3 | tuned @0.3 | base @0.8 | tuned @0.8 |
|---|
| JSON validity | 0.993 | 1.000 | 0.993 | 1.000 |
| Score MAE vs rubric | 0.206 | 0.024 | 0.177 | 0.027 |
| Spearman | 0.794 | 0.949 | 0.808 | 0.958 |
| Abstention tp/fp/fn | 14/0/0 | 14/0/0 | 10/0/4 | 14/0/0 |
| Counterfactual name-swap gap | 0.0254 | 0.0189 | 0.0414 | 0.0176 |
| Completion tokens (460 calls) | 523,710 | 42,073 | — | — |
The counterfactual gap — mean absolute score change when only the candidate's
name is swapped across demographic groups (Bertrand & Mullainathan 2004 audit
names) — improved and is stable across effort. Fairness non-regression was
a hard ship gate. Details, methodology, and two honest caveats (a mis-specified
Brier criterion; rubric-mastery vs world-mastery): finetune/RESULTS.md.
Training
- Data: 100% synthetic — 5,468 examples generated by a deterministic,
open-source engine (no real personal data, reproducible byte-for-byte:
python -m finetune.build_training_data, hash 16c9ba62c5d0993e).
Three task types: rubric-target scoring (demonstrated skills weighted over
merely listed ones), abstention discipline (incl. anti-abstention for
wrong-field candidates), and counterfactual consistency (name-swapped twins
with byte-identical targets).
- LoRA rank 32, 1 epoch, lr 2e-4 linear, batch 64, trained on
Tinker (~$34 at July-2026 rates).
- Val split holds out entire (family, seniority) cells to test generalization.
Intended use & limits
Decision support for human recruiters, embedded in a pipeline that enforces
review — never automated hiring decisions. This is both the design and a
condition of Inkling's Acceptable Use Policy
(no automated employment decisions; deployer disclosure duties), which binds
derivatives including this adapter. Trained and evaluated on synthetic English
résumés across 10 job families; real-world résumé performance is not
claimed — run your own evaluation (the repo ships the audit harness to do it,
per-run and free). Base-model limitations (hallucination, training-data bias)
may persist; the counterfactual audit measures, not eliminates, name bias.
This repo ships the adapter in Tinker LoRA format (adapter_model.safetensors
adapter_config.json, ~20GB — rank 32 across all layers incl. 256 experts).
Converting to standard PEFT format requires the base model's weights on local
disk — which your serving machine needs anyway — so convert on the box that
serves it (one command, via tinker-cookbook):
from tinker_cookbook import weights
weights.build_lora_adapter(
base_model="thinkingmachines/Inkling",
adapter_path="./inkling-hire",
output_path="./inkling-hire-peft",
)
Then serve with vLLM/SGLang and point the
inkling-hire pipeline's
config.yaml at your endpoint — no candidate data leaves your infrastructure.
(On Tinker, the checkpoint is directly usable at
tinker://2b4f6b9a-9e2c-546c-a600-866e9755dbb8:train:0/sampler_weights/final.)