An AI-powered technical interview preparation platform that generates role-specific questions, conducts voice-based interviews, and provides detailed feedback with scoring.
Getting Started β’ Features β’ Architecture β’ Azure Setup β’ Contributing
- Overview
- Key Features
- How It Works
- Technology Stack
- Architecture
- Getting Started
- Azure Services Setup
- Project Structure
- Seniority-Based Question Generation
- Evaluation Metrics
- API Reference
- Cost Estimation
- Documentation
- Roadmap
- Contributing
- License
AI Tech Interview is a fullstack application designed to help software developers prepare for technical interviews through realistic, voice-based practice sessions. The platform leverages Azure AI services to:
- Generate tailored interview questions based on your target role and job description
- Read questions aloud using natural-sounding neural voices
- Record and transcribe your responses in real-time
- Evaluate answers and provide detailed feedback with actionable improvements
Traditional interview preparation often lacks the pressure and spontaneity of real interviews. This platform bridges that gap by:
- π€ Voice-first interaction - Practice speaking your answers, not just writing them
- π― Role-specific questions - Questions tailored to your exact target position and seniority level
- π Objective feedback - AI-powered evaluation with consistent scoring criteria
- β‘ Instant results - No waiting for feedback; get insights immediately after each session
| Feature | Description |
|---|---|
| π― Seniority-Aligned Questions | Questions are generated matching your target seniority level (Junior, Semi-Senior, Senior) |
| π€ Voice Interaction | Text-to-Speech reads questions; Speech-to-Text captures your responses |
| β±οΈ Timed Responses | Each question has a time limit (1-10 min) based on category with visible countdown |
| π€ AI-Powered Evaluation | GPT-4o-mini analyzes responses against expected competencies |
| π Detailed Scoring | Multi-dimensional scoring across 6 evaluation criteria |
| πΌ Role Customization | Supports any technical role with custom job descriptions |
| π Structured Feedback | Strengths, improvements, and actionable suggestions |
| π Session History | Track progress across multiple practice sessions |
(The voice-driven interview loop)
πΈ See more visuals: Check docs/README.md for architecture diagrams, screenshots, and detailed component descriptions.
stateDiagram-v2
[*] --> QuestionDisplayed
QuestionDisplayed --> Recording : User Clicks "Start"
state Recording {
[*] --> CountingDown
CountingDown --> Timeout : Timer reaches 0
CountingDown --> ManualStop : User clicks "Stop"
}
Timeout --> Processing : Auto-save
ManualStop --> Processing : Save
Processing --> [*] : Transcript Ready
(State diagram of the recording process)
Key Points:
- β User must press a button to start recording (gives time to think)
- β Visible countdown timer shows remaining time (1-10 min based on category)
- β Recording auto-stops when time runs out
- β User can manually stop earlier if finished
- β Whatever was spoken is saved and transcribed
| Layer | Technology | Version | Purpose |
|---|---|---|---|
| Frontend | Next.js (App Router) | 16.x | React framework with Server Components |
| Runtime | React | 19.x | UI library with concurrent features |
| Language | TypeScript | 5.x | Type-safe development |
| Styling | Tailwind CSS | 4.x | Utility-first CSS with @theme inline |
| AI/LLM | Azure OpenAI | GPT-4o-mini | Question generation & evaluation |
| Text-to-Speech | Azure Speech Service | Neural voices | Reading questions aloud |
| Speech-to-Text | Azure Speech Service | Real-time STT | Transcribing user responses |
| Database | PostgreSQL | - | Session and response storage |
- Turbopack by default - No need for
--turbopackflag - Server Actions - Seamless server-side operations without explicit API routes
- React 19 - Latest concurrent features and improved performance
- App Router - Modern file-based routing with layouts and nested routes
- Streaming - Real-time response streaming support
- TypeScript First - Excellent type safety and developer experience
(The hybrid architecture: A local Next.js app connecting to Azure AI services)
- Node.js 20.x or higher
- pnpm
- Azure subscription with:
- Azure OpenAI Service access
- Azure Speech Service resource
- Modern browser with microphone access (Chrome, Firefox, Edge recommended)
- Clone the repository
git clone https://github.com/cristofima/AI-Tech-Interview.git
cd AI-Tech-Interview- Install dependencies
pnpm install- Configure environment variables
Copy the example file and update with your Azure credentials:
cp .env.local.example .env.localThen edit .env.local with your values:
# Azure OpenAI Configuration
AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com/
AZURE_OPENAI_API_KEY=your-api-key
AZURE_OPENAI_DEPLOYMENT=gpt-4o-mini
AZURE_OPENAI_API_VERSION=2024-10-21
# Azure Speech Service Configuration
AZURE_SPEECH_KEY=your-speech-key
AZURE_SPEECH_REGION=eastusπ‘ Terraform Users: Run
terraform output -raw env_file_content > .env.localin theinfra/folder to auto-generate this file after provisioning.
- Run the development server
pnpm devNote: Next.js 16 uses Turbopack by default - no
--turbopackflag needed!
- Open your browser
Navigate to http://localhost:3000
- Go to Azure Portal
- Search for "Azure OpenAI" and click Create
- Select your subscription and resource group
- Choose a region (e.g., East US)
- Provide a unique name for your resource
- Select pricing tier (Standard S0)
- Review and create
- Navigate to your Azure OpenAI resource
- Go to Model deployments β Manage Deployments
- Click Create new deployment
- Select model:
gpt-4o-mini - Provide a deployment name (e.g.,
gpt-4o-mini) - Set tokens-per-minute rate limit as needed
- Go to Keys and Endpoint in your resource
- Copy KEY 1 or KEY 2 β
AZURE_OPENAI_API_KEY - Copy Endpoint β
AZURE_OPENAI_ENDPOINT
- Go to Azure Portal
- Search for "Speech" and select Speech Services
- Click Create
- Select your subscription and resource group
- Choose a region (e.g., East US)
- Provide a unique name
- Select pricing tier (Free F0 for development, Standard S0 for production)
- Review and create
- Go to Keys and Endpoint in your Speech resource
- Copy KEY 1 β
AZURE_SPEECH_KEY - Note the Location/Region β
AZURE_SPEECH_REGION
| Model | Version | Features |
|---|---|---|
gpt-4o-mini |
2024-07-18 | β JSON Mode, β Structured Outputs, Fast, Cost-effective |
gpt-4o |
2024-08-06+ | β JSON Mode, β Structured Outputs, Higher capability |
gpt-4.1-mini |
2025-04-14 | β JSON Mode, β Structured Outputs, Latest features |
AI-Tech-Interview/
βββ infra/ # Terraform Infrastructure-as-Code
β βββ main.tf # Azure resources (OpenAI, Speech)
β βββ variables.tf # Input variables
β βββ outputs.tf # Output values
β βββ versions.tf # Terraform & provider versions
β βββ README.md # Infrastructure documentation
βββ src/ # Next.js source code
β βββ app/ # App Router (pages, layouts, API)
β β βββ api/ # API Routes (sessions, responses, evaluate, speech)
β β βββ history/ # Session history page
β β βββ interview/ # Interview room page
β β βββ results/ # Results dashboard page
β β βββ globals.css # Global styles + Tailwind theme
β β βββ layout.tsx # Root layout
β β βββ page.tsx # Home page
β βββ components/ # React Components
β β βββ InterviewRoom.tsx # Main interview logic
β β βββ OfflineStatusIndicator.tsx # Network status UI
β β βββ PermissionsCheck.tsx # Mic/Speech permissions
β β βββ ScoreCard.tsx # Result visualization
β β βββ SessionForm.tsx # Setup form
β βββ generated/ # Generated code (Prisma)
β βββ hooks/ # Custom Hooks
β β βββ useAudioRecorder.ts # Audio recording logic
β β βββ useOfflineSupport.ts # Offline sync logic
β β βββ useSpeechRecognition.ts # Azure STT
β β βββ useSpeechSynthesis.ts # Azure TTS
β βββ lib/ # Libraries & Utilities
β β βββ azure-openai.ts # OpenAI client
β β βββ azure-speech.ts # Speech SDK
β β βββ offline-storage.ts # IndexedDB manager
β β βββ prisma.ts # DB client
β β βββ prompts.ts # System prompts
β β βββ utils.ts # Helpers
β βββ types/ # TypeScript Definitions
βββ public/ # Static assets
βββ scripts/ # Utility scripts (diagrams, etc.)
βββ docs/ # Documentation & Images
βββ diagrams/ # Architecture diagrams
βββ screenshots/ # Application screenshots
| Folder | Purpose |
|---|---|
infra/ |
Terraform IaC for Azure resources (kept at root for clear separation) |
src/ |
All Next.js application code (cleaner root directory) |
public/ |
Static assets (must remain at root for Next.js) |
const config = {
plugins: {
"@tailwindcss/postcss": {},
},
};
export default config;@import "tailwindcss";
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
}{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src/**/*.ts", "src/**/*.tsx"],
"exclude": ["node_modules", "infra"]
}import { dirname } from "path";
import { fileURLToPath } from "url";
import { FlatCompat } from "@eslint/eslintrc";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
});
const eslintConfig = [
...compat.extends("next/core-web-vitals", "next/typescript"),
];
export default eslintConfig;When creating an interview session, users provide the following fields:
| Field | Description | Example | Validation |
|---|---|---|---|
| Role Title | The target position with seniority level | "Senior FullStack .NET/Angular Developer" | β Required, min 10 characters |
| Company Name | The company you're interviewing for | "Google", "Microsoft", "Amazon" | βͺ Optional |
| Job Description | Full job posting or key responsibilities | "Design and implement scalable APIs..." | β Required, min 50 characters |
Note: Role Title and Job Description are mandatory. The Company Name is optional but can help tailor questions to the company's culture and tech stack.
Important: Both fields are mandatory. The system will not generate questions without a complete role title and job description. The seniority level (Junior, Mid, Senior) is extracted from the role title to ensure questions match the expected competency level.
Questions are generated to match the specified seniority level:
| Target Seniority | Senior Questions | Semi-Senior Questions | Junior Questions |
|---|---|---|---|
| Junior | 0% | 20% | 80% |
| Semi-Senior/Mid | 20% | 60% | 20% |
| Senior | 70-80% | 20-30% | 0% |
For a Senior FullStack .NET/Angular Developer role, the question distribution would be:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 10 INTERVIEW QUESTIONS β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β ββββββββββββββββββββββββββββββββββββββββ 70-80% Senior β
β ββββββββββββ 20-30% Semi-Seniorβ
β 0% Junior β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Each question category has a recommended response time based on real interview scenarios:
| Category | Description | Examples | Time Limit | Rationale |
|---|---|---|---|---|
| Technical | Deep-dive into specific technologies | ".NET Core DI, Angular signals, RxJS" | β±οΈ 1-4 min | Direct answers with depth |
| System Design | Architecture and scalability | "Design a real-time notification system" | β±οΈ 5-10 min | Condensed version of real 30-45 min interviews |
| Behavioral | Leadership, communication, problem-solving | "Describe a technical decision you influenced" | β±οΈ 2-5 min | Full STAR method response |
| Problem Solving | Algorithmic thinking and debugging | "How would you optimize this query?" | β±οΈ 2-6 min | Explain approach + solution |
| Constraint | Value | Description |
|---|---|---|
| Minimum | 60 seconds (1 min) | Ensures meaningful, complete responses |
| Maximum | 600 seconds (10 min) | Allows thorough System Design answers |
| Default | 240 seconds (4 min) | Standard for most technical questions |
Why 10 minutes max? In real interviews, System Design questions take 30-45 minutes. Since this is a practice tool where users prepare answers beforehand, 10 minutes allows for a condensed but realistic response covering: requirements clarification, high-level design, key components, and trade-offs.
How it works: When the user presses the "Start Recording" button, a visible countdown timer begins on screen. The recording automatically stops when the time limit is reached, or the user can manually stop it earlier. The system saves whatever the user managed to say within the time limit.
The AI uses this structured prompt to generate seniority-aligned questions:
const systemPrompt = `You are a technical interview expert specializing in software engineering roles.
CRITICAL RULES:
1. Questions MUST align with the seniority level specified in the role title
2. For Senior roles: 70-80% Senior-level questions, 20-30% Semi-Senior, 0% Junior
3. For Mid-level roles: 20% Senior, 60% Mid-level, 20% Junior
4. For Junior roles: 0% Senior, 20% Mid-level, 80% Junior
5. Senior questions should test: architecture decisions, system design, leadership, mentoring
6. Never include junior-level questions for senior positions
Generate 10 interview questions based on the role and job description provided.
Output JSON format:
{
"questions": [
{
"id": 1,
"question": "...",
"difficulty": "senior|mid|junior",
"category": "technical|behavioral|system-design|problem-solving",
"expectedTopics": ["topic1", "topic2"],
"timeLimit": 240 // seconds (min: 60, max: 600)
}
]
}
Time limit guidelines by category:
- technical: 60-240 seconds (1-4 min)
- system-design: 300-600 seconds (5-10 min)
- behavioral: 120-300 seconds (2-5 min)
- problem-solving: 120-360 seconds (2-6 min)`;| Metric | Weight | Description |
|---|---|---|
| Relevance | 25% | How well the answer addresses the specific question asked |
| Technical Accuracy | 25% | Correctness of technical concepts, terminology, and best practices |
| Clarity | 20% | Clear, concise communication without rambling or tangents |
| Depth | 15% | Level of detail, thoroughness, and real-world examples |
| Structure | 10% | Logical organization (problem β approach β solution) |
| Confidence | 5% | Speech fluency, minimal filler words ("um", "uh", "like") |
| Score Range | Rating | Description | Hiring Signal |
|---|---|---|---|
| 90-100 | π Excellent | Exceptional responses demonstrating mastery | Strong hire |
| 75-89 | β Good | Solid answers with minor gaps | Hire with minor concerns |
| 60-74 | Adequate but needs improvement | Consider with reservations | |
| 40-59 | π Needs Work | Significant gaps in knowledge or communication | Not ready |
| 0-39 | β Poor | Major deficiencies requiring substantial preparation | Major concerns |
const evaluationPrompt = `You are an expert technical interviewer evaluating a candidate response.
CONTEXT:
- Role: {role}
- Seniority Expected: {seniority}
- Question: {question}
- Expected Topics: {expectedTopics}
- Candidate Response: {transcribedResponse}
EVALUATION CRITERIA:
Score each criterion from 0-100:
1. Relevance (25%): Does the answer directly address what was asked?
2. Technical Accuracy (25%): Are concepts, terminology, and best practices correct?
3. Clarity (20%): Is the answer clear, concise, and well-articulated?
4. Depth (15%): Does it show real-world experience and thorough understanding?
5. Structure (10%): Is there a logical flow (context β approach β outcome)?
6. Confidence (5%): Is speech fluent with minimal filler words?
SENIORITY EXPECTATIONS:
- For Senior roles: Expect architectural thinking, leadership examples, mentoring mentions
- For Mid-level roles: Expect solid technical execution and problem-solving
- For Junior roles: Expect foundational knowledge and learning attitude
Output JSON:
{
"scores": {
"relevance": 85,
"technicalAccuracy": 90,
"clarity": 75,
"depth": 80,
"structure": 70,
"confidence": 85
},
"overallScore": 82,
"performanceBand": "good",
"feedback": {
"strengths": ["Clear explanation of...", "Good use of..."],
"improvements": ["Could elaborate more on...", "Consider mentioning..."],
"suggestion": "To strengthen this answer, try using the STAR method..."
}
}`;POST /api/sessions
Content-Type: application/json
{
"roleTitle": "Senior FullStack .NET/Angular Developer",
"companyName": "Google", // Optional
"jobDescription": "We are looking for a Senior FullStack Developer..."
}Response:
{
"id": "sess_abc123",
"roleTitle": "Senior FullStack .NET/Angular Developer",
"companyName": "Google",
"seniorityLevel": "senior",
"createdAt": "2024-12-14T10:00:00Z",
"status": "in-progress"
}GET /api/sessions/{id}Response:
{
"success": true,
"data": {
"session": {
"id": "sess_abc123",
"roleTitle": "Senior FullStack .NET/Angular Developer",
"status": "in-progress"
},
"questions": [
{
"id": 1,
"question": "Describe how you would architect...",
"difficulty": "senior",
"category": "system-design",
"timeLimit": 600
}
]
}
}Note:
timeLimitis in seconds. System Design questions get up to 600s (10 min) to allow for comprehensive architectural explanations, while Technical questions typically get 60-240s (1-4 min).
GET /api/speech/tokenResponse:
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJS...",
"region": "eastus",
"expiresAt": "2024-12-14T10:10:00Z"
}POST /api/evaluate
Content-Type: application/json{
"sessionId": "sess_abc123",
"responses": [
{
"questionId": 1,
"transcription": "For a high-traffic e-commerce platform, I would design..."
}
]
}Response:
{
"sessionId": "sess_abc123",
"overallScore": 78,
"performanceBand": "good",
"evaluations": [
{
"questionId": 1,
"scores": {
"relevance": 85,
"technicalAccuracy": 82,
"clarity": 75,
"depth": 78,
"structure": 70,
"confidence": 80
},
"overallScore": 79,
"feedback": {
"strengths": ["Good understanding of microservices patterns"],
"improvements": ["Could mention specific .NET libraries"],
"suggestion": "Consider discussing containerization with Docker/K8s"
}
}
]
}Model: gpt-4o-mini (version 2024-07-18)
Default Quota: 450K tokens per minute (TPM)
| Usage Type | Price (Standard Deployment) | Notes |
|---|---|---|
| Input tokens | $0.165 / 1M tokens | ~$0.02-0.08 per session |
| Cached input tokens* | $0.0825 / 1M tokens | 50% discount with prompt caching |
| Output tokens | $0.66 / 1M tokens | ~$0.05-0.20 per session |
*Prompt caching available for gpt-4o-mini-2024-07-18 (API version 2024-10-01-preview+)
Capacity Configuration:
- This project uses: 30K TPM (30 capacity units in Terraform)
- Sufficient for ~3,000 requests/minute
Default SKU: S0 (Standard) - Pay-as-you-go
| Feature | Free Tier (F0) | Standard Tier (S0) Price |
|---|---|---|
| Text-to-Speech (Neural) | 500K characters/month | $16 / 1M characters |
| Text-to-Speech (Neural HD) | N/A | $28 / 1M characters |
| Speech-to-Text (Standard) | 5 hours/month | $1 / hour (real-time) |
| Speech-to-Text (Custom) | N/A | $1.40 / hour (real-time) |
Example Usage:
- 100 questions β 50K TTS characters β $0.80 (or free with F0)
- 100 responses β 2 hours STT β $2.00 (or free with F0)
| Scenario | Monthly Usage | OpenAI Cost | Speech Cost | Total |
|---|---|---|---|---|
| Development | 10 sessions | $0.30-1.00 | $0 (Free F0) | $0.30-1.00 |
| Moderate | 50 sessions | $3-8 | $10-15 | $13-23 |
| Heavy | 200 sessions | $15-30 | $40-60 | $55-90 |
- Use F0 (Free) tier for Speech Service during development (500K TTS chars + 5 hours STT/month)
- Enable prompt caching for repeated system prompts (50% savings on input tokens)
- Requires API version
2024-10-01-previewor later
- Requires API version
- Use dynamic quota for batch deployments to optimize capacity usage
- Implement token counting and set usage limits per user/session
- Cache topic extraction results for similar job descriptions
- Monitor usage through Azure Portal > Cost Management + Billing
Comprehensive documentation is available in the docs/ directory:
- π Architecture Diagrams - System architecture and interview flow visualizations
- πΈ Screenshots - UI walkthrough showing setup, interview, and results pages
- π Lessons Learned - Technical challenges and solutions from building the platform
- ποΈ Infrastructure Guide - Terraform deployment guide for Azure resources
Quick Links:
- View All Diagrams & Screenshots
- Lessons Learned - Real Technical Challenges
- Infrastructure Setup Guide
- Project architecture design
- Next.js 16 project setup with TypeScript
- Session creation with role & job description (mandatory fields)
- Azure OpenAI integration for question generation
- Seniority-aligned question logic
- Countdown timer per question (1-10 min based on category)
- Azure TTS for reading questions
- Azure STT for recording responses with auto-stop
- Basic evaluation with scoring
- Results display
- Audio waveform visualization
- Response playback feature
- Detailed feedback with charts
- Export results as PDF
- Dark/light theme support
- Pause/resume recording
- Multiple interview modes (behavioral, coding, system design)
- Practice history and progress tracking
- Custom question banks
- Real-time coaching during responses
- Multi-language support
- Team/enterprise features
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow TypeScript best practices
- Use Server Components where possible
- Write meaningful commit messages
- Add tests for new features
- Update documentation as needed
This project is licensed under the MIT License - see the LICENSE file for details.
- Microsoft Azure AI Services for powerful AI capabilities
- Next.js for the amazing React framework
- Vercel for the Geist font family
- shadcn/ui for beautiful UI components
- Tailwind CSS v4 for utility-first styling
Built with β€οΈ using Azure AI Services and Next.js 16






