Home / AI-Assisted CV Screening, Part 2: Sharper Requirements, a Council of Models

AI-Assisted CV Screening, Part 2: Sharper Requirements, a Council of Models

Follow-up to AI-Assisted CV Screening: A Research Prototype (February 2026).

In February, we asked how AI could assist with CV screening while keeping human judgment firmly in the decision-making seat. Since then, the prototype has evolved in three important ways. It now interprets job requirements more precisely. It fails visibly rather than silently: anything it cannot read, calculate, or reconcile is flagged, together with a clear path for review, rather than absorbed into a plausible-looking number. And it no longer asks reviewers to rely on the opinion of a single model.

One principle connects these changes and extends the Python-based scoring approach introduced in February: the model proposes, code verifies, and the human decides. Language models are valuable readers and writers, but they are not dependable calculators or consistent rule engines. Wherever a calculation or rule must produce a reliable result every time, the prototype now handles it deterministically in ordinary code. Anything that cannot be guaranteed is made visible for human review.

Together, these changes make the results more transparent, explainable, and dependable than they were in February. Here is what changed, and why the prototype is now ready for wider testing across UNU.

Precision: “and” is not “or”, and the code now enforces it

Job postings are full of quiet logic. “PHP, JavaScript, and CSS” means all three. “MS SQL or MySQL” means either. “(e.g., Laravel, ReactJS)” means these are examples, not a checklist. The parser has always been instructed to read these signals, but instructions to a language model are hopes, not guarantees.

So, the checking moved into code. Every skill category now carries an explicit threshold (“any 1 of 3”, “all 7”). After each evaluation the system recounts, in plain Python rather than by asking the model, how many of a category’s skills the candidate actually demonstrated and compares that count against the threshold. Where the model’s own claim disagrees with the recount, the evaluation is flagged for review rather than silently trusted. The dashboard’s ranking follows the same logic: a candidate who has AWS scores 100% on an “any one of AWS, Azure, GCP” requirement, instead of being punished for the two alternatives they never needed.

Getting here was arguably the most challenging engineering problem in the prototype so far. The same posting, parsed twice with the same model and the same instructions, can produce three broad skill categories in one run and twelve fine-grained categories in the next. A rule the model follows perfectly today may be ignored tomorrow. At one point, a contradiction between two parts of our own prompt caused the strongest candidates, those matching more alternatives than a category required, to be silently excluded from the results altogether.

The lesson has been a recurring one: a language model’s compliance is a probability, not a guarantee. Anything that must be true every time now lives in ordinary code. Anything that cannot be guaranteed is surfaced as a flag for review rather than silently assumed.

Which is where the February post’s core principle, human-in-the-loop by designmoves from principle to practice. Because the parse itself can misread a posting, two safety nets sit in front of all this. An optional second, independent reading re-derives every threshold and flags disagreements, down to naming the specific skill it found that the first pass missed. And everything is directly editable in the interface before any candidate is evaluated: skills, categories, thresholds, education, and experience lines. Ten seconds of human review on the parsed requirements is the highest-leverage quality check in the whole pipeline, so the tool now makes that review effortless.

Alternative pathways, tested in both directions

UN job postings often provide more than one way to qualify: “Master’s degree … OR Bachelor’s degree … in combination with two additional years of qualifying experience may be accepted in lieu of the advanced university degree.” If a screening tool treats the Master’s degree as mandatory, it can silently reject every candidate who legitimately qualifies through the Bachelor’s degree pathway.

The parser now preserves each pathway as a complete combination of education and experience requirements. The interface displays the two pathways with an explicit OR between them, and the evaluator is given this exact structure as a worked example. Meeting either pathway satisfies the education requirement; any standalone experience requirements still apply to everyone.

Figure 1: Parsed requirements for a real UNU posting. The two education pathways are labeled and joined by an explicit OR, meaning either one satisfies the education requirement, while the two lines marked “must meet” always apply. Every line is editable before any candidate is evaluated.

We verified this live against a real UNU posting, in both directions. A synthetic candidate with a Bachelor’s degree and nine years of experience was marked qualified, and the model’s own summary read “qualified through the bachelor’s-degree alternative pathway”. The same candidate with only seven years was rejected for precisely the two-year shortfall, not for “missing a Master’s”.

When 14 years becomes 19: deriving experience from dates

One figure on every screening sheet turned out to be quietly unreliable: total years of experience. Models derive it from the free-text dates and durations in a CV, but they often add overlapping roles together. A candidate who consulted from 2010 to 2024 while also holding an advisory role from 2015 to 2020 has 14 years of experience, yet a model may report 19.

The prototype now calculates this figure independently. It extracts the date range for each role, merges overlapping periods rather than adding them together, and counts only the time covered by the combined timeline. When the model’s estimate differs meaningfully from the date-derived figure, the candidate’s card displays both, together with a warning. The dashboard also uses the date-derived figure when calculating its median.

Dates that cannot be parsed are never guessed. Instead, the candidate’s card flags, for example, “Dates unreadable for 2 of 4 roles,” identifies the affected roles, and links the reviewer to the built-in raw CV view for manual verification. Once checked, the reviewer can enter the verified figure directly on the card. The correction is saved with the run, and the rankings and statistics update accordingly, while the model’s original estimate remains preserved for the record.

A flag without a path to resolution is little more than decoration. Here, the reviewer knows what to verify, where to find the evidence, and how to record the correction.

A dashboard that ranks by what matters for this role

Overall scores can obscure the distinctions that matter most to a hiring panel. The new Dashboard tab lets reviewers choose which criteria should count for a particular role, including individual skills, skill groups, key responsibility areas, and score components. Candidates are then re-ranked instantly using only those selected criteria.

The job posting’s AND/OR logic carries through to the dashboard. A skill group applies the posting’s original rule, so one matching skill earns full credit for an “any 1 of 3” requirement. An individual skill, by contrast, acts as an exact-skill filter for cases where the reviewer specifically wants to assess Azure, even if the posting also accepts other cloud platforms.

Each row shows how many selected criteria were actually assessed, distinguishing rankings based on partial data from those based on complete data. A coverage heatmap makes candidate-to-criterion matches easy to scan, multi-column sorting supports tiebreakers, and each batch is saved as a named run that can be reopened and, where several models were used, filtered by model.

Figure 2: The Dashboard tab, shown with synthetic candidates. The skill group checkboxes on the left score the posting’s own logic (“any 1 of 3”, “all 3”), candidates re-rank live by the selected criteria, and the small 6/6 next to each match score shows how many of those criteria the evaluation actually assessed.

A council of models, one human decision

Different models can reach genuinely different conclusions about the same CV. Rather than hiding those differences, the prototype makes them visible. Council mode evaluates each candidate using two or more models against the same parsed requirements, then brings the cases with the greatest disagreement to the top, where human review matters most.

Figure 3: The Council tab, shown with synthetic candidates. Three models evaluated the same two candidates. The split verdict is flagged and brought to the top for review; the consensus column is clearly labelled as the raw average of the models that returned a score; and the reviewer’s decision, in this case Hold, is recorded alongside the model outputs.

The table presents each model’s score, verdict, and recommendation side by side, together with the spread between their scores. It also shows a consensus figure, clearly labelled for what it is: a raw average, not a calibrated measure of truth or confidence. If a model fails during an evaluation, the result appears as failed, never as an artificial zero that could unfairly lower a candidate’s ranking.

The reviewer then records a decision of Advance, Hold, or Reject, together with any supporting notes. That decision is saved with the run and included in the exported report. The models provide different perspectives; the decision remains human.

Numbers that mean what they say

A series of less visible changes supports one important principle: a number should never look more reliable than the process that produced it.

  • A failed evaluation now appears as a visible failure, not a plausible-looking 0% that quietly pushes the candidate to the bottom of the ranking.
  • CVs and screening questionnaires are matched by filename and presented in an editable pairing table, preventing candidates from being evaluated against someone else’s answers simply because files were uploaded in a different order.
  • Every evaluation is stamped with its model, evaluation depth, and time of creation, so an original result and a later re-run can never be confused.

What this work reinforces

The prototype’s development has reinforced a simple lesson: better AI assistance doesn’t remove the need for human judgement—it makes clear where that judgement is needed most.

This remains experimental research, not a production system, and it isn’t connected to any actual UNU recruitment process. The goal is not automated decision-making, but a process in which evidence can be examined, results challenged, and decisions explained.