DEV Community

Cover image for One More Try: A Private AI Interview Coach Built for a Friend
Navodhya Fernando
Navodhya Fernando

Posted on

One More Try: A Private AI Interview Coach Built for a Friend

Hacktoberfest Weekend Challenge: Build for a Friend Submission 🤝

This is a submission for the Hacktoberfest Weekend Challenge: Build for a Friend.

What I Built

I built One More Try, a privacy-first AI interview practice app for a friend who is preparing for job interviews.

The idea came from something simple: when someone practises an interview question, their first answer usually isn't their best one.

They know the experience. They know what happened. But the first answer might be too vague, miss an important result, lack evidence, or simply not explain their contribution clearly enough.

Most interview tools generate questions.

I wanted to build something focused on what happens after you answer.

So One More Try follows this loop:

CV + Job Description
        ↓
Personalised Interview
        ↓
Answer a Question
        ↓
AI Feedback
        ↓
What Worked
+
Make It Stronger
        ↓
One More Try
        ↓
Compare the Improvement
Enter fullscreen mode Exit fullscreen mode

The user uploads their real CV and pastes the job description they are preparing for.

Gemma then uses both to create five personalised interview questions.

For every answer, the app evaluates things like:

  • relevance to the question
  • specificity
  • evidence
  • individual contribution
  • results and impact
  • STAR-style structure
  • alignment with the role

Instead of just giving a score, the interface separates feedback into What worked and Make it stronger.

Then comes the feature the whole project is built around:

One More Try.

The candidate answers the same question again while the feedback is still fresh.

At the end of the five-question interview, the app produces a final practice summary showing strengths and patterns to continue improving.

And importantly, the core AI runs locally.

Your CV and interview answers don't need to be sent to a hosted LLM API.


Demo

The flow

  1. Upload a CV
  2. Paste the target job description
  3. Select interview difficulty
  4. Gemma creates five personalised questions
  5. Answer one question at a time
  6. Review specific feedback
  7. Hit One More Try
  8. Improve the answer
  9. Continue through the interview
  10. Receive a final practice summary

The UI was intentionally designed to feel more like a focused coaching environment than a traditional dashboard.


Code

GitHub:

One More Try on GitHub

The project contains:

one-more-try/
├── backend/
│   └── FastAPI + Ollama integration
│
├── frontend/
│   └── React + Vite interface
│
├── run-local.sh
├── README.md
└── LICENSE
Enter fullscreen mode Exit fullscreen mode

Running the application locally is intentionally simple:

ollama pull gemma3:1b
chmod +x run-local.sh
./run-local.sh
Enter fullscreen mode Exit fullscreen mode

How I Built It

The application has a React frontend and a Python FastAPI backend.

AI Layer

The main AI stack is:

  • Gemma 3 1B
  • Ollama
  • local inference
  • structured model outputs

When a session begins, the backend extracts text from the CV and combines it with the job description.

Gemma analyses that context and prepares the interview.

Instead of generating generic questions like:

Tell me about yourself.

the model can ask questions grounded in the candidate's actual experience and the requirements of the role.

The interview context is kept compact after the initial preparation so later evaluations do not need to resend the full CV and job description every time.

Answer Evaluation

When an answer is submitted, Gemma receives:

  • the interview question
  • the candidate's answer
  • relevant candidate evidence
  • role priorities
  • the selected interview style

It returns structured feedback containing:

What worked
Make it stronger
Follow-up
Next focus
Enter fullscreen mode Exit fullscreen mode

This makes the AI output predictable enough to build an actual product interface around instead of simply dumping model text into a chat box.

The Retry Loop

One of my favourite parts of the project is that the second attempt is not treated as another unrelated answer.

The system compares it with the previous response.

That makes the experience closer to coaching:

Attempt 1
   ↓
Feedback
   ↓
Attempt 2
   ↓
Improvement comparison
Enter fullscreen mode Exit fullscreen mode

Frontend

The interface was built with React and Vite.

I also used several open-source React Bits components to make the experience more interactive without turning it into a visually noisy dashboard.

These included:

  • ColorBends
  • TextPressure
  • SpotlightCard
  • WakeSlider
  • FlipCard
  • ThoughtLine
  • FuseButton

The animated ColorBends background uses Three.js/WebGL while the rest of the interface stays intentionally restrained.


Why Does Open Innovation Matter?

This project would be very different if the only option were a closed hosted AI API.

Using Gemma 3 as an open-weight model with Ollama allowed me to make local inference a fundamental part of the product rather than an afterthought.

That matters especially for this use case.

A CV can contain:

  • employment history
  • education
  • personal projects
  • achievements
  • technical skills
  • and other personal career information

Interview answers can be even more personal.

With local inference, the core workflow becomes:

CV
 +
Job Description
        ↓
Local FastAPI Application
        ↓
Ollama
        ↓
Gemma 3
        ↓
Questions + Feedback
Enter fullscreen mode Exit fullscreen mode

There is no requirement to send the candidate's CV to a commercial LLM endpoint just to practise an interview.

Open innovation also gave me much more control over the product.

I could:

  • choose the model
  • control the context size
  • keep the model loaded between turns
  • optimise prompts for local hardware
  • inspect inference behaviour
  • swap models later
  • and build without per-request API costs

There were trade-offs.

Running Gemma locally on CPU forced me to think much more carefully about prompt size, output length, inference time, and how many model calls the experience actually needed.

But that constraint improved the architecture.

Instead of treating the LLM as unlimited infrastructure, I had to decide:

What actually needs AI, and what doesn't?

That was probably one of the most useful lessons from the weekend.


Built in Three Days

This is deliberately an MVP.

I wanted to finish one complete experience rather than build ten half-working features.

The scope became:

CV + Job Description → personalised interview → feedback → One More Try

That meant saying no to a few tempting features during the weekend.

One of those was voice.

I experimented with turning the experience into a full spoken interview, but adding speech-to-text, text-to-speech, microphone handling, latency management, and another set of dependencies would have increased the failure surface significantly.

For a three-day build, I chose to keep the working typed interview experience and make the core loop reliable.


Where I'd Take It Next

The next version would turn One More Try into a more complete mock-interview environment.

Voice Interviews

The first addition would be local speech-to-text using something like Whisper.

AI Question
     ↓
Candidate Speaks
     ↓
Local Speech-to-Text
     ↓
Gemma Evaluation
     ↓
Coaching Feedback
Enter fullscreen mode Exit fullscreen mode

This would preserve the privacy-first direction while making the practice experience much closer to a real interview.

Speech Delivery Coaching

Beyond the meaning of the answer, the application could analyse observable speech signals such as:

  • speaking pace
  • long pauses
  • filler words
  • repeated phrases
  • response length
  • clarity
  • answer structure

That would let the system coach both what you say and how you deliver it.

Multimodal Practice

An optional camera mode could later provide feedback on observable presentation behaviours such as:

  • gaze toward the camera
  • excessive movement
  • posture changes
  • consistency of visual engagement

I would keep this focused on observable behaviours rather than trying to infer someone's personality or emotional state from their face.

Adaptive Interviews

Right now the interview is prepared at the beginning.

A larger version could dynamically choose later questions based on earlier answers.

For example:

Weak technical explanation
        ↓
Technical follow-up

Strong project example
        ↓
Deeper system-design question

Missing evidence
        ↓
Question asking for measurable impact
Enter fullscreen mode Exit fullscreen mode

Progress Tracking

Another direction would be comparing interview sessions over time.

The app could identify recurring patterns like:

  • vague answers
  • weak metrics
  • missing outcomes
  • overly long responses
  • weak STAR structure

and show whether those problems are improving.


What I Learned

The biggest lesson wasn't about prompting.

It was about turning an LLM into a product.

Generating text is easy.

Building a useful AI experience means thinking about:

  • what context the model actually needs
  • how outputs should be structured
  • latency
  • failure handling
  • privacy
  • interaction design
  • when not to call the model
  • and what action the user should take after receiving an AI response

For One More Try, the AI feedback itself is only half the product.

The important part is what happens next:

you get another attempt.

That's why I called it One More Try.

Top comments (0)