Back to all posts

Building Evidence Guard: Preventing LLM Hallucinations in Automated Resume Tailoring

How we architected a deterministic verification engine to audit LLM-generated bullet points against candidate factual records, eliminating fabricated metrics and hallucinated skills.

6 min read

When we started building ResumeFit, our goal was simple: help engineers reframe their authentic experience to match target role descriptions without spending hours rewriting bullet points. But in LLM-assisted document generation, generative models possess an inherent liability: they love to invent facts to sound persuasive.

Ask an unconstrained model to "optimize a bullet point for a Senior Distributed Systems Engineer role," and it will happily change "Assisted with Redis cluster migrations" into "Architected global multi-region Raft consensus layer serving 500,000 QPS with 99.999% availability."

While impressive on paper, this destroys candidate credibility in an interview. To solve this, we architected Evidence Guard—a deterministic verification engine that audits every modified phrase against a grounded candidate knowledge graph before any output reaches the final resume.

The Problem: Why Generative Resumes Fail

Large Language Models are probabilistic token predictors, not factual database engines. When tasked with matching a job specification that demands Kubernetes, eBPF, and Kafka, conventional prompt engineering like:

Flawed Naive Prompt

"Rewrite the following resume bullet point to highlight distributed systems skills. Do not lie or add skills the candidate does not have."

This naive constraint fails in three repeatable failure modes:

  • Metric Inflation: Turning "Reduced latency by optimizing SQL queries" into "Achieved 87% p99 latency reduction" without empirical benchmark data.
  • Technology Smuggling: Introducing adjacent technologies (e.g., if Docker was mentioned, the model casually adds Kubernetes and Helm).
  • Scope Escalation: Elevating contributor roles into owner/architect designations (e.g., "contributed to PR review" becomes "headed organizational migration").

System prompts alone cannot prevent this reliably because the temperature and attention distribution prioritize fluent token sequences over strict factual containment. We needed an adversarial system that treats every model generation as untrusted input.

The Architecture: Two-Phase Generation & Audit

Rather than relying on a single monolithic generation step, Evidence Guard separates content generation from factual verification in an asymmetric pipeline:

Verification Pipeline Flow
Step 1

Ground Truth Extraction

Parse original resume into canonical claim entities: verified tools, quantitative deltas, roles, and action verbs.

Step 2

Constrained Generation

Fast inference LLM (Groq / NVIDIA NIM Llama 3.3) drafts tailored variations targeting specific ATS keywords.

Step 3

Evidence Guard Audit

Deterministic AST-like token validator cross-checks claim entities. Flagged claims trigger surgical regenerations.

By decoupling the creative phrasing engine from the factual verification engine, we can run high-throughput LLM generation at low cost while guaranteeing zero hallucinated claims.

Implementing Evidence Guard: Grounding & Verification

The core verification engine inspects three distinct claim types: Hard Technical Entities, Numeric Claims, and Action Scope Hierarchy.

Here is a simplified TypeScript implementation demonstrating how entity grounding and numeric containment checks are performed on generated candidates:

evidence-guard.ts TypeScript
interface GroundTruthRecord {
  canonicalSkills: Set<string>;
  metrics: Array<{ rawValue: string; magnitude: number; unit: string }>;
  originalText: string;
}

interface AuditResult {
  passed: boolean;
  violations: Array<{
    type: 'ILLEGAL_SKILL' | 'FABRICATED_METRIC' | 'SCOPE_ESCALATION';
    token: string;
    explanation: string;
  }>;
}

export function auditBulletPoint(
  candidateDraft: string,
  groundTruth: GroundTruthRecord
): AuditResult {
  const violations: AuditResult['violations'] = [];

  // 1. Entity boundary extraction & whitelist validation
  const extractedSkills = extractTechEntities(candidateDraft);
  for (const skill of extractedSkills) {
    if (!groundTruth.canonicalSkills.has(skill.toLowerCase())) {
      violations.push({
        type: 'ILLEGAL_SKILL',
        token: skill,
        explanation: `Skill "${skill}" does not exist in candidate profile history.`,
      });
    }
  }

  // 2. Numeric delta containment
  const candidateNumbers = extractQuantifiableDeltas(candidateDraft);
  for (const num of candidateNumbers) {
    const isVerified = groundTruth.metrics.some(
      (m) => m.unit === num.unit && Math.abs(m.magnitude - num.magnitude) < 0.01
    );

    if (!isVerified) {
      violations.push({
        type: 'FABRICATED_METRIC',
        token: num.rawValue,
        explanation: `Metric "${num.rawValue}" was not present in the original experience evidence.`,
      });
    }
  }

  return {
    passed: violations.length === 0,
    violations,
  };
}

When an audit fails, the pipeline does not discard the candidate and retry blind. Instead, the violation array is converted into a structured negative feedback constraint: "The previous draft introduced unverified skill [Kubernetes]. Regenerate without mentioning Kubernetes." This convergence loop typically resolves in a single additional sub-200ms pass.

Benchmarking Accuracy & Guardrail Latency

Safety mechanisms often introduce unacceptable user-facing latency. To assess the cost of Evidence Guard, we benchmarked 500 bullet point transformations using Llama 3.3 70B hosted on Groq inference engines:

Strategy Hallucination Rate P90 Latency Factual Integrity
Unconstrained Baseline 24.6% 340ms Poor
Detailed System Prompting 11.2% 420ms Unreliable
Evidence Guard Architecture < 0.2% 485ms Deterministic

For an overhead of roughly 145ms (running fast Groq LPUs with deterministic regex/AST token filters), hallucination incidence dropped from nearly 1-in-4 bullets to essentially zero. In production, this was the difference between candidates feeling anxious about resume accuracy versus confidently exporting their LaTeX document.

Key Takeaways for Production LLM Pipelines

Building ResumeFit reinforced several core patterns that apply to any engineer building production LLM products:

1. Never trust prompt instructions alone for factual boundaries

Prompts are steering wheels, not guardrails. When factual precision matters (finance, career records, healthcare, legal), layer an external programmatic validator over the output.

2. Prefer fast models with audit loops over slow monolithic models

Running a high-token/sec model (like Llama 3.3 70B on Groq or Cerebras) with an automated correction loop is faster and dramatically cheaper than relying on a slow multi-second reasoning model to self-police.

3. Deliver actionable feedback to the regeneration loop

When an audit fails, tell the model specifically which token violated the contract and why. Targeted surgical corrections converge in a single retry instead of oscillating randomly.

Published in AI Engineering & System Architecture By Kalpit Jare