DEV Community

Cover image for I Built an AI Interview Coach That Turns Any Resume Into a Personalized Prep Package — No API Keys Needed
Ansuj Kumar Meher
Ansuj Kumar Meher

Posted on

I Built an AI Interview Coach That Turns Any Resume Into a Personalized Prep Package — No API Keys Needed

Hermes Agent Challenge Submission: Build With Hermes Agent

This is a submission for the Hermes Agent Challenge

What I Built

Interview preparation is broken. You Google "top 50 interview questions," get a wall of generic prompts that have nothing to do with your background, and somehow you're supposed to feel prepared. If you've built real-time chat systems with Socket.io and trained CNNs with TensorFlow, why are you practicing questions about linked lists and nothing else?

I built AI Interview Coach — a full-stack web application that takes your resume PDF and produces a complete, personalized interview preparation package in under five seconds.

Here's what happens when you upload a resume:

  1. Resume Score (out of 10) — Your resume is scored across five dimensions: Formatting & Readability, Content Completeness, Skills Relevance, Experience Impact, and Education & Certs. Each dimension gets a score, a color-coded progress bar, and specific notes explaining the rating.

  2. Skills Summary — The engine auto-detects technologies from your resume and groups them into categories: Languages, Frameworks, ML & AI, Cloud & DevOps, Databases, and Tools & Practices. It scans against 90+ technology keywords.

  3. 20 Technical Interview Questions — These are generated based on what's actually on your resume. If you list TensorFlow, you'll get questions about batch normalization and vanishing gradients. If you list React, you'll get questions about useEffect dependency arrays and virtualization. Each question includes a "why" explanation connecting it to something specific on your resume.

  4. 10 HR & Behavioral Questions — Adapted based on whether you're a student, have internship experience, show leadership signals, or have multiple projects. Each comes with a STAR-method framing tip.

  5. Improvement Suggestions — Prioritized into High, Medium, and Low buckets. Things like "Quantify your achievements" or "Add certifications" — not vague advice, but specific actions mapped to scoring gaps.

The entire thing runs locally. No OpenAI key. No GPT calls. No cost per request. No data leaves your machine.

Why does this matter? Because most interview prep tools either cost money, require API keys, or give you the same generic output regardless of your background. This one is free, private, and genuinely personalized.

Demo

📹 Video Walkthrough:


Upload Zone — Drag & drop your resume PDF:
Drag & drop your resume PDF

Resume Score — Circular indicator + five-dimension breakdown:

Resume Score

Skills Summary — Auto-detected technologies grouped by category:

Skills Summary

Technical Questions — Searchable, filterable, with difficulty badges:

Technical Questions

HR Questions — Category-tagged with STAR-method tips:

HR Questions

Improvement Suggestions — Prioritized by impact:

Improvement Suggestions

Analysis engine output — scores, skills, and tailored questions in the terminal:

Code

AI Interview Coach

A full-stack web application that analyzes resumes and generates personalized interview preparation packages. Built with React + Express for the Hermes Agent Challenge.

Overview

Upload a resume PDF and instantly receive:

  • Resume Score — rated across 5 dimensions (formatting, completeness, skills relevance, experience impact, education)
  • Skills Summary — auto-detected and grouped by category
  • 20 Technical Interview Questions — tailored to your actual skills and projects
  • 10 HR / Behavioral Questions — with STAR-method framing tips
  • Improvement Suggestions — prioritized by impact

No API keys or external services required. Everything runs locally.

Architecture

interview-coach-app/
├── backend/
│   ├── server.js              # Express server — upload handling, analysis engine
│   ├── package.json           # Dependencies: express, multer, cors
│   └── tmp/                   # Temp directory for PDF processing
├── frontend/
│   ├── src/
│   │   ├── App.jsx            # Main app — theme toggle, upload, results orchestration
│   │   ├── main.jsx           # React

My Tech Stack

Frontend:

  • React 18 — Functional components with hooks (useState, useRef, useCallback). Five purpose-built components: FileUpload, ResumeScore, SkillsSummary, QuestionsList, and Suggestions.
  • Vite 5 — Dev server with API proxy to the backend, plus production builds served directly by Express.
  • CSS Custom Properties — A complete dark and light theme system with 25+ CSS variables. No Tailwind, no CSS framework — every style is hand-written with transitions for smooth theme switching.

Backend:

  • Node.js + Express 4 — Handles file uploads via Multer (disk storage, PDF-only filter, 10MB limit), spawns the Python extraction process, runs the analysis engine, and serves the built frontend in production.
  • Custom request logger — Every request gets a unique ID and timing for debugging.

PDF Extraction:

  • Python 3 + pymupdf — Extracts raw text from PDF resumes with proper Unicode handling. The script outputs structured JSON including page-level text, page count, and document metadata.

Analysis Engine:

  • A custom rule-based engine written entirely in JavaScript — no external API calls. It includes:
    • A multi-dimensional scoring system with regex-based pattern matching
    • Skill extraction across 90+ technology keywords organized into 6 categories
    • Conditional question generation with 30+ templates spanning Deep Learning, NLP, Computer Vision, React, Node.js, Databases, Cloud, Security, and more
    • HR question adaptation based on inferred career stage
    • Priority-ranked improvement suggestions mapped to scoring gaps

Build & Dev Tooling:

  • Vite for frontend bundling
  • Express serves the production build from frontend/dist/
  • uv for Python virtual environment and dependency management

How I Used Hermes Agent

Hermes Agent was involved at every stage of building this project — not as a magic "generate my app" button, but as a collaborative development partner that I could iterate with in real time.

Hermes Agent CLI

Architecture Decisions

The first thing I worked through with Hermes was the fundamental architecture question: should the analysis engine call an external LLM, or should it be rule-based?

Hermes helped me reason through the tradeoffs. An LLM-based approach would generate more varied questions, but it would require API keys (friction for users), add latency (seconds per request), introduce cost (real money per upload), and make the output non-deterministic. Hermes helped me design a rule-based engine that's fast, free, deterministic, and transparent. Every score has an explanation. Every question has a "why."

Hermes also helped me decide on the three-layer architecture — React frontend, Express backend, Python extraction subprocess. The alternative was doing PDF extraction in Node.js, but Hermes pointed out that pymupdf has significantly better handling of ligatures, embedded fonts, and Unicode edge cases compared to the Node.js PDF libraries available.

Here's Hermes planning the approach and setting up the Python environment:

Architecture Decisions

Implementation: The Analysis Engine

Hermes scaffolded all 16 source files, installed dependencies, and verified the frontend build — all in a single session:

Implementation: The Analysis Engine

The heart of the application is the analyzeResume() function in server.js — around 300 lines of scoring, extraction, and question generation logic. Hermes helped me build this incrementally.

For the scoring system, I started with a basic keyword count approach, but Hermes helped me evolve it into a five-dimension model. Take the Experience Impact dimension:

let impact = 3;
if (/\d+%/.test(text)) impact += 2;
if (/\d+\+ (users|requests|events|bugs|projects|modules)/i.test(text)) impact += 1.5;
if (/reduced|improved|increased|optimized|accelerated/i.test(text)) impact += 1.5;
if (/led|owned|driven|spearheaded|initiated/i.test(text)) impact += 1;
if (/\d+K\+|\d+M\+|\d+TB|\$[\d,]+/i.test(text)) impact += 1;
impact = Math.min(Math.round(impact), 10);
Enter fullscreen mode Exit fullscreen mode

Hermes helped me identify which regex patterns actually correlate with strong resumes — looking for quantified achievements, scale indicators, and action verbs that signal ownership. We iterated on the weights until the scores felt calibrated against real resumes.

For question generation, Hermes helped me design the conditional template system. Instead of random questions, each template is gated on what's actually in the resume:

if (has(["tensorflow","keras"])) {
  add("Deep Learning", "Hard",
    "You used transfer learning with MobileNetV2. Explain why you'd freeze early layers vs fine-tune them all.",
    "Your EarthSense-AI project used transfer learning — interviewers will probe the reasoning.");
}
Enter fullscreen mode Exit fullscreen mode

This produces questions that reference the user's actual projects and explain why an interviewer would ask this. Hermes helped me write templates for 15+ technology areas.

Debugging: The Unicode Incident

The first real-world resume I uploaded crashed the app. The error:

UnicodeEncodeError: 'charmap' codec can't encode character '\ufb01'
Enter fullscreen mode Exit fullscreen mode

That's the "fi" ligature — common in PDFs generated by LaTeX. On Windows, Python's default stdout uses cp1252 encoding, which doesn't support it.

Hermes immediately identified the root cause and proposed a two-layer fix. On the Node.js side, force the spawned Python process to use UTF-8:

const proc = spawn(pythonExe, [scriptPath, pdfPath, "--json"], {
  env: { ...process.env, PYTHONIOENCODING: "utf-8" },
});
Enter fullscreen mode Exit fullscreen mode

On the Python side, wrap stdout if the console encoding isn't UTF-8:

if sys.stdout.encoding.casefold() != "utf-8":
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")
Enter fullscreen mode Exit fullscreen mode

This fixed the crash without losing any text content. Hermes knew exactly where to intervene because it understood both the Node.js child process API and Python's encoding stack.

Feature Refinement

Hermes drove several UX improvements that I wouldn't have prioritized on my own. Here's Hermes refactoring the FileUpload component to add progress tracking and cancel support — you can see the diff of what changed:

Feature Refinement

  • Duplicate detection — When multiple skill categories triggered similar questions, Hermes suggested the deduplication step with normalized comparison, then padding with fallback questions to guarantee exactly 20 technical and 10 HR.
  • AbortController integration — Hermes wired up the upload cancel button to actually abort the in-flight fetch request and clean up state, rather than just hiding the progress bar.
  • Export formatting — The "Download Report" feature generates a structured text file with headers, scores, and all questions. Hermes helped format the output so it reads well in any text editor.
  • CSS custom properties for theming — Instead of class-based theme switching, Hermes designed a CSS variable system with 25+ tokens that made adding the light theme a one-block-of-CSS addition rather than rewriting every component.

Development Velocity

Working with Hermes, I went from an empty directory to a functioning full-stack app in a single development session. The agent handled the scaffolding — Vite config, Express boilerplate, Multer setup — while I focused on the analysis logic and UI design decisions.

After writing the files, Hermes automatically verified the build and ran syntax checks before moving on:

Hermes build verification

When I hit the Unicode bug, Hermes fixed it in minutes rather than the hour I'd have spent reading Python encoding documentation. When I wanted to add search and filtering to the questions list, Hermes built the entire QuestionsList component with search, difficulty filter, topic filter, copy-per-question, and copy-all in one pass.

That's the real value: Hermes doesn't replace thinking, but it removes the friction between having an idea and seeing it work.

Technical Challenges

PDF Extraction Is Messier Than You Think

PDF is a page layout format, not a document format. Text inside a PDF can be fragmented across drawing commands, use arbitrary fonts with custom ligature tables, and contain Unicode characters that look normal on screen but break when piped through a process boundary. The "fi" ligature is just the most common offender — there are dozens more in PDFs generated by professional typesetting tools.

The fix required interventions at two layers: the Node.js process spawner (setting PYTHONIOENCODING) and the Python script itself (wrapping sys.stdout). A single-layer fix wouldn't have been robust.

Deduplication Without Losing Personality

When a resume lists React, Node.js, and TypeScript, the question generator might fire templates from the "React" bucket, the "Backend" bucket, and the "TypeScript" bucket — some of which produce overlapping questions. Simple string deduplication would miss near-duplicates, so I normalize the text (lowercase, collapse whitespace) before comparison:

function deduplicateQuestions(questions) {
  const seen = new Set();
  const result = [];
  for (const q of questions) {
    const key = q.question.trim().toLowerCase().replace(/\s+/g, " ");
    if (!seen.has(key)) {
      seen.add(key);
      result.push(q);
    }
  }
  return result;
}
Enter fullscreen mode Exit fullscreen mode

After deduplication, I pad with fallback questions to guarantee the target count. The fallbacks are intentionally generic ("Describe a challenging bug you encountered") so they never feel redundant with the skill-specific ones.

Making a Rule-Based Engine Feel Intelligent

The hardest design challenge wasn't technical — it was making a rule-based system produce output that feels genuinely tailored rather than randomly selected. Three things made the difference:

  1. Every question explains why it's being asked — "You have TensorFlow and Keras on your resume" or "Your EarthSense-AI project used transfer learning — interviewers will probe the reasoning." This transparency makes the output feel personalized even though it's template-driven.

  2. HR questions adapt to career stage — The engine checks whether the text matches student patterns, internship signals, leadership keywords, or project count — and selects different question variants accordingly.

  3. Suggestions map to scoring gaps — If the Experience Impact score is low, the suggestion to "Quantify your achievements" appears in the High Priority bucket. The suggestions aren't random — they're tied to the dimensions that scored weakest.

Frontend UX: Small Touches, Big Difference

  • Collapsible sections — Let you focus on what matters. When you're practicing technical questions, you don't need the suggestions panel open.
  • Search and filter on questions — Type a keyword, filter by difficulty (Easy, Medium, Hard), filter by topic (React, Databases, Security). The filter count updates in real time.
  • Copy to clipboard — Per question or all at once, useful for pasting into a study doc or sharing with a friend.
  • Progress simulation — The progress bar advances in random increments during the server round-trip, creating the feel of active processing rather than a dead spinner.

Lessons Learned

  1. Rule-based doesn't mean dumb — A well-designed rule engine with good templates produces output that's consistent, explainable, and free. For structured tasks like scoring and question generation, you don't always need an LLM.

  2. Cross-process encoding is a minefield — Node.js spawning Python on Windows has encoding assumptions at every layer: the child process environment, Python's stdout wrapper, and Node's buffer-to-string decoding. You need to control all of them.

  3. Frontend polish is what separates a demo from a tool — Search, filter, copy, download, dark mode, collapsible sections — none of these are technically hard, but together they make the difference between "interesting prototype" and "I'd actually use this."

  4. Error messages are user experience — Every error in this app tells you what went wrong and what to do: "Only PDF files are allowed," "File too large (max 10 MB)," "Could not extract meaningful text — it may be image-based." No stack traces in the browser.

Future Improvements

  • LLM-powered question generation — Integrate an optional local LLM (via Ollama or similar) to generate more varied, context-aware questions while keeping the API-free default.
  • Answer scaffolding — For each question, generate a starter answer outline based on the resume content.
  • Job description matching — Upload a job description alongside your resume and get a gap analysis: skills you have vs. skills they want, plus targeted questions for the gaps.
  • PDF report export — Generate a formatted PDF report instead of plain text, with the score visualization and color-coded question cards.
  • Session history — Save past analyses to localStorage so you can track how your resume improves over time.
  • ATS keyword checker — Compare your resume against common ATS keyword databases for specific job titles.

Conclusion

AI Interview Coach is a focused tool that solves a real problem: turning a generic resume PDF into a personalized interview preparation package — with scoring, skill extraction, tailored questions, and prioritized improvement suggestions. It runs entirely locally, requires no API keys, and produces results in seconds.

Hermes Agent was instrumental throughout development. It helped me make the right architecture decisions (rule-based over LLM, Python for PDF extraction), built the analysis engine incrementally with proper scoring weights and conditional templates, solved the cross-platform Unicode encoding bug in minutes, and drove UX refinements like deduplication, abort handling, and the CSS theming system. The collaboration wasn't about generating boilerplate — it was about making better design decisions faster and shipping a more polished product than I would have built alone.

The project is open source under MIT. Upload your resume and see what comes back — I'd love to hear whether the questions actually match your background.

Top comments (0)