Hi, this is John with this week’s Coding Challenge.
🙏 Thank you for being a subscriber, I’m honoured to have you as a reader. 🎉
If there is a Coding Challenge you’d like to see, please let me know by replying to this email📧
This challenge is to build your own mock interview coach, a tool that lets you practise behavioural interviews face-to-face speaking to a photorealistic AI interviewer.
Behavioural interviews are the part of the hiring process that engineers practise least. Reading sample STAR answers is nothing like composing one out loud, under time pressure, while someone watches you. In this challenge you’ll build a coach that puts a live, talking interviewer on your screen using Anam’s real-time persona platform and their latest cara-4 model. It will ask you behavioural questions, probe your weak answers with follow-ups, and then score your performance and tell you how to improve. Along the way you’ll work with real-time avatar streaming, persona and prompt design, session-based authentication, and post-session transcript analysis.
This project is kindly sponsored by Anam.
You’re going to build a web application with two halves. The backend, in any language you like, will manage interview setup, issue Anam session tokens, and analyse transcripts to produce feedback reports. The frontend is a thin web page that streams the interviewer’s face and voice into a video element and lets you talk to them over your microphone.
The interesting parts are the persona design (writing a system prompt that makes an AI interview you rather than help you), the security model (keeping your API key server-side while the browser streams in real time), and the feedback loop (turning a raw conversation transcript into a structured STAR assessment).
This is an intermediate to advanced challenge. The backend can be written in any language that can serve HTTP and call a REST API, so pick whatever you’re most comfortable with. The frontend needs only a small amount of JavaScript, so don’t be put off if you’re not a frontend developer.
What you’ll build will look something like this:
In this introductory step you’re going to set your environment up ready to begin developing and testing your solution.
First, sign up for a free Anam account. The free tier gives you API access, 30 minutes of conversation per month, and a 3 minute limit per conversation. That’s enough to complete this challenge, but it does mean each test session is short, so plan to test with brief exchanges rather than full-length interviews.
From your Anam account, create an API key and make a note of it. We’ll be keeping it server-side, so think about how you’ll provide it to your backend, an environment variable named ANAM_API_KEY is the convention we’ll use in this challenge.
Next, pick your backend language and an HTTP server library you’re comfortable with. Then spend a little time with the Anam documentation, particularly the JavaScript SDK quickstart, to understand the moving parts: personas, session tokens, and the streaming client.
Finally, make sure you have a browser with a working microphone and camera permissions you can grant to localhost.
In this step your goal is to design your interviewer persona.
A persona on the Anam platform combines a face, a voice, an LLM, and a system prompt. The system prompt is where your coaching product lives, it’s what turns a general-purpose talking avatar into a behavioural interviewer.
Define a persona configuration (name, avatar, voice, LLM, and system prompt) for an interviewer that:
Asks one behavioural question at a time and waits for the answer.
Probes with a follow-up when an answer lacks specifics, for example asking “what was the outcome?” when the candidate doesn’t say.
Never suggests answers or completes the candidate’s stories for them.
Stays in role, politely steering the conversation back to the interview if the candidate drifts off topic.
Getting this behaviour reliable is a prompt engineering exercise, expect to iterate. If you want some great ideas for what to include in the system prompt, check out my interview with Austen McDonald about mastering behavioural interviews. Also check out Austen’s newsletter: Mastering Behavioral Interviews. He also has a guide to doing mock interviews.
Testing: Use the Anam Lab to create the persona and talk to it. Try three conversations: give a vague answer (”we fixed it and it was fine”) and check you get a probing follow-up; ask the interviewer “what would you say in my situation?” and check it declines to answer for you; try changing the subject to the weather and check it brings you back to the interview. The lab is a great no-code option for refining the avatar before you build the full system.
Here’s what it looks like:
Use the prompt tab to enter your prompt, the avatar tab to upload / take a photo of you, the voice tab to clone your voice if you want to. Otherwise pick suitable ones from the existing options.
In this step your goal is to build the session token service, the backend half of the security model.
Anam’s streaming sessions are authorised with short-lived session tokens, created by calling POST <https://api.anam.ai/v1/auth/session-token> with your API key and a persona configuration. The API key must never reach the browser, so your backend will act as the exchange point.
Build a backend with an endpoint that, when called by your frontend, requests a session token from the Anam API using the persona configuration from Step 1, and returns that token to the caller. Read the API key from the ANAM_API_KEY environment variable.
Your endpoint should also apply a time limit to each interview session. Make the limit configurable, and default it to fit inside the free tier’s 3 minute conversation limit.
Testing: Start your backend and request a token from the command line:
curl -X POST <http://localhost:8080/api/session-token>You should get back a JSON response containing a session token. Check your frontend code and browser network tab later in the challenge to confirm the Anam API key itself never appears anywhere client-side. Try setting the time limit configuration to a different value and confirm the session created with the token respects it.
In this step your goal is to get your interviewer on screen, streaming in real time.
Build a minimal web page, served by your backend, that:
Fetches a session token from the endpoint you built in Step 2.
Creates a streaming client using Anam’s
@anam-ai/js-sdkpackage and attaches it to a video element withstreamToVideoElement.Has controls to start the interview and to end the session at any time.
Once connected, the candidate speaks their answers over their microphone and the interviewer responds with voice and video. Have the interviewer open the session by greeting the candidate and explaining the format: how many questions to expect and how the interview will run. That behaviour belongs in your persona’s system prompt or greeting configuration, not in your JavaScript.
Testing: Open the page in your browser, click start, and grant microphone access. You should see your interviewer appear in the video element, greet you, explain the format, and ask the first question within a few seconds. Answer out loud and confirm the interviewer hears you and responds. Click your end control mid-conversation and confirm the stream stops cleanly.
In this step your goal is to make each interview a real, configurable interview rather than a single hard-coded conversation.
First, build a question bank of at least 20 behavioural questions, each tagged with a competency such as leadership, conflict, failure, teamwork, or delivery. Store it however you like, this is data your backend owns.
Then add an interview setup screen where, before the session starts, the candidate chooses:
The target role they’re practising for.
The seniority level.
Which competencies they want to be assessed on.
Your backend should generate each interview from those choices, drawing suitable questions from the bank, so that repeated sessions produce different interviews rather than the same script every time.
Testing: Set up an interview targeting a senior role with the “conflict” and “failure” competencies. Confirm the questions asked relate to those competencies. Run a second interview with the same setup and confirm you get different questions from the bank. Change the competencies and confirm the questions change to match.
In this step your goal is to capture and store the interview transcript.
The feedback report in the next step needs the full conversation, both the interviewer’s questions and the candidate’s answers. Anam gives you two routes to it: the SDK emits message history events while the session runs, and there is a session transcript API you can call after the session ends. Pick whichever suits your design.
Once you have the transcript, persist each completed interview with its date, the setup choices from Step 4, and the full transcript, so past sessions can be reviewed later.
Testing: Complete a short interview, answering at least two questions. Then inspect your stored data and confirm it contains the date, the role, seniority and competencies you chose, and the complete conversation with both the interviewer’s and your own words. Complete a second interview and confirm both sessions are stored separately.
In this step your goal is to turn the transcript into a feedback report, this is where your tool becomes a coach.
The standard framework for behavioural answers is the STAR method: Situation, Task, Action, Result. Strong answers cover all four; weak answers typically describe a situation and then trail off without actions or results.
Analyse each answer in the stored transcript and produce a written feedback report that includes:
Which STAR elements were present and which were missing from each answer.
A score from 1 to 5 for each answer.
The candidate’s overall strengths.
One specific improvement suggestion per question.
You’ll want an LLM to do the analysis, any provider works, this part is independent of the live Anam session.
Finally, track scores across sessions so the candidate can see whether they’re improving over time.
Testing: Run an interview and deliberately give one incomplete answer, describe a situation but never say what the result was. The report should flag the missing Result for that answer and score it lower. Give one full STAR answer in the same interview and confirm it scores higher. Complete a few sessions and confirm you can see your scores across them.
In this step your goal is to add interviewer styles and give the candidate control over the flow of the interview.
Different interviewers put different pressure on candidates, and practising with only one style leaves you unprepared for the others. Offer at least two selectable interviewer personas with distinct voices and personalities, for example a supportive coach who encourages you along, and a formal bar-raiser who is polite but gives you nothing back.
Then add flow control: the candidate should be able to skip a question they don’t want to answer, and end the interview early. When they do, the feedback report should cover only the questions actually answered, with no scores or feedback invented for questions that were skipped.
Testing: Run an interview with each persona and confirm the voice and manner are noticeably different while the interview structure stays the same. In another session, skip the second question and end the interview after the third. Check the report covers exactly the questions you answered, with the skipped question absent.
Once you have the core coach working, here are some ideas to take it further:
Add a per-answer timer so candidates can practise keeping answers to two or three minutes.
Generate a printable or PDF version of the feedback report to share with a mentor.
Add technical and system design interview modes with their own question banks and scoring rubrics.
Bring your own LLM to the live conversation, so the same brain that scores the answers also drives the interviewer’s follow-up questions.
If you think your solution is an example other developers can learn from please share it, put it on GitHub, GitLab or elsewhere. Then let me know via Bluesky or LinkedIn or just post about it there and tag me. Alternately please add a link to it in the Coding Challenges Shared Solutions Github repo
I’m writing these challenges to help you develop your skills as a software engineer based on how I’ve approached my own personal learning and development. What works for me, might not be the best way for you - so if you have suggestions for how I can make these challenges more useful to you and others, please get in touch and let me know. All feedback is greatly appreciated.
You can reach me on Bluesky, LinkedIn or through SubStack
Thanks and happy coding!
John

Comments
Nothing yet. Say the first thing.
Sign in to join the conversation.