The difference between a form and an interview is the follow-up. A form asks its five questions no matter what you say. A good interviewer hears a vague answer and digs — "you said you'd use a queue there; why not a stack?" — and moves on when you've clearly got it.
Most "AI interview" tools are forms with a chat skin: a fixed list, one model call per question, no memory of how the conversation is going. The core of AI Interview SDK (@interview-sdk/core) is a genuine follow-up engine, and it's the piece I spent the most time getting right.
What "dynamic" actually means here
Three properties, each of which is a real constraint the engine enforces:
- Depth-limited. Follow-ups can go deeper on a concept, but only to a bounded depth — so a candidate never falls into an infinite "explain that, now explain that" hole on one question.
- Repeat-preventing. The engine tracks what's already been asked and answered, and won't re-ask the same thing in different words. Small models love to loop; this stops it.
- Difficulty-scaled. It reads how the candidate is doing and adjusts. Strong answers earn harder probes; a struggling candidate isn't buried deeper.
None of that works if the model is just freewheeling. It works because the flow is a state machine with the model as one bounded step inside it, not the whole thing.
Evaluation before follow-up
A follow-up is only as good as the read of the previous answer. The core does semantic evaluation against the concepts you declared for each question, then rubric scoring with the weights you set:
questions={[
{ id: 'q1', prompt: 'Explain how hash maps handle collisions.',
concepts: ['hashing', 'collisions', 'load factor'] }
]}
rubric={[{ id: 'technical', label: 'Technical depth', weight: 1 }]}
The engine decides whether a concept was actually covered — not whether the right keyword appeared. That's what lets it tell "I'd use chaining, because a good hash still collides at high load factor" apart from "I'd use a hash thing." One earns a move-on; the other earns a probe.
The lesson that keeps repeating
I've written before about building CommitAI on a local LLM — and the same rule showed up here, louder. Structure beats instruction. Every time I tried to make the model "be a better interviewer" with more adjectives in the prompt, follow-ups got worse. The wins came from giving the model a smaller, bounded job — evaluate this one answer against these concepts; propose one follow-up under these limits — and letting the surrounding state machine own the intelligence.
An interview that reacts is worth far more than a longer list of questions. Next up: how you test that engine for bias before a real candidate ever meets it.