Spaces:
Sleeping
Sleeping
| """ | |
| Grounded reasoning generation. | |
| Every reasoning string is assembled from facts that actually exist in the | |
| candidate's profile and from the scorer's own per-component breakdown - never | |
| from an LLM at ranking time. This guarantees the Stage-4 review checks pass: | |
| specific facts, JD connection, honest concerns, no hallucination, variation, | |
| and tone that matches the rank. Borderline candidates also get a counterfactual. | |
| The output reads as plain English a recruiter could act on, not a template with | |
| a name slotted in. | |
| """ | |
| from __future__ import annotations | |
| from typing import Dict, List | |
| from . import config, features | |
| _GROUP_LABEL = { | |
| "retrieval_ranking": "retrieval/ranking", | |
| "embeddings": "embeddings", | |
| "vector_db": "vector search / hybrid search", | |
| "nlp": "NLP/LLM", | |
| "evaluation": "ranking evaluation (NDCG/MRR/A-B)", | |
| "ml_core": "applied ML", | |
| } | |
| def _evidence_phrase(scored: Dict) -> str: | |
| ev = scored["evidence"] | |
| present = [g for g in config.EVIDENCE_TERMS if ev.get(g, 0) > 0] | |
| # prioritise the IR-core groups for the phrase | |
| ordered = [g for g in ["retrieval_ranking", "embeddings", "vector_db", | |
| "evaluation", "nlp", "ml_core"] if g in present] | |
| labels = [_GROUP_LABEL[g] for g in ordered[:3]] | |
| if not labels: | |
| return "" | |
| if len(labels) == 1: | |
| return labels[0] | |
| return ", ".join(labels[:-1]) + " and " + labels[-1] | |
| def _top_skill_names(rec: dict, k: int = 3) -> List[str]: | |
| ai = [s for s in rec["skills"] if features._any_skill_is_ai(s)] | |
| ai.sort(key=lambda s: (s["assessment"] or 0, s["months"]), reverse=True) | |
| return [s["name"] for s in ai[:k]] | |
| def confidence_tag(scored: Dict, trap: Dict) -> str: | |
| c = scored["components"] | |
| if trap["is_honeypot"]: | |
| return "Excluded" | |
| # "High" demands excellence across the board, not just a relevant title - so even | |
| # within the submitted top-100 (all strong by construction) the tag still varies: | |
| # a top pick that is off the 6-8y band or thinner on evidence reads "Moderate". | |
| strong = (c["title_role_fit"] >= 0.8 and c["domain_evidence"] >= 0.6 | |
| and c["must_have_coverage"] >= 0.7 and c["experience_band"] >= 0.6) | |
| moderate = c["title_role_fit"] >= 0.55 or c["domain_evidence"] >= 0.3 | |
| return "High" if strong else ("Moderate" if moderate else "Low") | |
| def _concern(rec: dict, scored: Dict, trap: Dict) -> str: | |
| """One honest concern, if any - Stage-4 rewards acknowledging gaps.""" | |
| c = scored["components"] | |
| sig = rec["signals"] | |
| if trap["is_stuffer"]: | |
| return "skills list is AI-heavy but the work history shows no ML/IR role" | |
| if c["must_have_coverage"] < 0.5: | |
| return "limited direct evidence on some JD must-haves (vector DB / ranking eval)" | |
| d = rec["days_since_active"] | |
| if d is not None and d > 150: | |
| return f"low availability ({d} days since last active)" | |
| rr = sig.get("recruiter_response_rate") | |
| if rr is not None and rr < 0.2: | |
| return f"weak recruiter response rate ({rr:.0%})" | |
| if features.consulting_only(rec): | |
| return "entire career at IT-services firms, no product-company experience" | |
| if features.location_class(rec) == "far" and not sig.get("willing_to_relocate"): | |
| return f"based in {rec['location']} and not open to relocation" | |
| if rec["yoe"] < config.EXP_OK_LO: | |
| return f"only {rec['yoe']:.0f} years experience, below the target band" | |
| return "" | |
| def build_reasoning(rec: dict, scored: Dict, trap: Dict, rank: int, | |
| counterfactual: bool = False) -> str: | |
| """Assemble a 1-2 sentence grounded reasoning for one candidate.""" | |
| title = rec["title"] | |
| yoe = rec["yoe"] | |
| conf = confidence_tag(scored, trap) | |
| ev_phrase = _evidence_phrase(scored) | |
| skills = _top_skill_names(rec, 3) | |
| # Lead clause: who they are + the decisive evidence. | |
| lead = f"{title}, {yoe:.1f} yrs" | |
| if ev_phrase: | |
| lead += f"; demonstrated {ev_phrase}" | |
| elif skills: | |
| lead += f"; lists {', '.join(skills)}" | |
| # Availability / location colour where it helps. | |
| sig = rec["signals"] | |
| extras = [] | |
| if features.location_class(rec) in ("preferred", "welcome"): | |
| extras.append(f"{rec['location']}-based") | |
| elif sig.get("willing_to_relocate"): | |
| extras.append("open to relocation") | |
| rr = sig.get("recruiter_response_rate") | |
| if rr is not None and rr >= 0.6 and conf in ("High", "Moderate"): | |
| extras.append(f"responsive to recruiters ({rr:.0%})") | |
| lead_extra = ("; " + ", ".join(extras)) if extras else "" | |
| concern = _concern(rec, scored, trap) | |
| if conf == "High": | |
| sent = f"{conf} confidence - {lead}{lead_extra}." | |
| if concern: | |
| sent += f" Minor concern: {concern}." | |
| elif conf == "Low": | |
| sent = f"{conf} confidence - {lead}{lead_extra}." | |
| sent += f" {concern[0].upper()}{concern[1:]}." if concern else " Adjacent fit only." | |
| else: | |
| sent = f"{conf} confidence - {lead}{lead_extra}." | |
| if concern: | |
| sent += f" Concern: {concern}." | |
| # Tone must scale with rank (Stage-4 check). Beyond the clear top tier, add an | |
| # honest "ranked here rather than higher because ..." note derived from this | |
| # candidate's own weakest dimension - keeps confident candidates from all | |
| # reading identically and acknowledges relative standing without faking doubt. | |
| note = "" | |
| if rank > 20: | |
| note = _relative_standing(rec, scored) | |
| elif counterfactual: | |
| note = _counterfactual(rec, scored) | |
| if note: | |
| sent += f" {note}" | |
| return sent.strip() | |
| def _relative_standing(rec: dict, scored: Dict) -> str: | |
| """Surface the candidate's single WEAKEST dimension - the largest shortfall from | |
| an ideal hire - rather than the first matching rule. Picking the max gap (not a | |
| fixed priority order) keeps the clause honest *and* genuinely varied: different | |
| candidates have different weakest dimensions, so no single clause monopolizes the | |
| population the way a first-match chain does.""" | |
| c = scored["components"] | |
| mods = scored["modifiers"] | |
| yoe = rec["yoe"] | |
| # Shortfalls normalized to a comparable 0..1 scale so the max is meaningful. | |
| gaps = { | |
| "experience": max(0.0, 0.9 - c["experience_band"]), | |
| "domain": max(0.0, 0.8 - c["domain_evidence"]), | |
| "availability": max(0.0, 0.95 - mods.get("availability", 1.0)) / 0.4, | |
| "skill_trust": max(0.0, 0.6 - c["skill_trust"]), | |
| "must_have": max(0.0, 0.85 - c["must_have_coverage"]), | |
| } | |
| worst = max(gaps, key=gaps.get) | |
| if gaps[worst] < 0.05: | |
| return "Ranked here rather than higher: edged out by candidates above with deeper retrieval/ranking track records." | |
| if worst == "experience": | |
| side = "below" if yoe < 6 else "above" | |
| return f"Ranked here rather than higher: {yoe:.1f}y sits {side} the 6-8y sweet spot." | |
| if worst == "domain": | |
| return "Ranked here rather than higher: retrieval/ranking evidence is solid but thinner than the top tier." | |
| if worst == "availability": | |
| return "Ranked here rather than higher: availability signals (recruiter response / recency) are a notch lower." | |
| if worst == "skill_trust": | |
| return "Ranked here rather than higher: skills are less corroborated by platform assessments." | |
| return "Ranked here rather than higher: doesn't yet evidence every JD must-have (e.g. ranking-evaluation depth)." | |
| def _counterfactual(rec: dict, scored: Dict) -> str: | |
| """A cheap, specific 'what would move this candidate' note for borderline rows.""" | |
| c = scored["components"] | |
| if c["domain_evidence"] < 0.5 and c["title_role_fit"] >= 0.6: | |
| return "Would rank materially higher with explicit vector-DB / ranking-eval evidence." | |
| if c["must_have_coverage"] < 0.75: | |
| return "Closing the gap on ranking-evaluation experience would lift this candidate." | |
| d = rec["days_since_active"] | |
| if d is not None and d > 120: | |
| return "Stronger if recent platform activity confirmed current availability." | |
| return "" | |