Skip to content

Repository files navigation

πŸŽ™οΈ Aira - AI Technical Interview Coach

Empowering students in Tier-2/3 cities across India with voice-first, multilingual technical interview preparation

AWS Lambda Amazon Transcribe Amazon Polly Amazon EventBridge DynamoDB S3 Gemini WhatsApp Python

🌟 Overview

Aira is a serverless, voice-first interview coaching platform that helps students from rural and semi-urban India practice technical interviews in their comfort language. Built entirely on AWS with an event-driven architecture, it provides real-time feedback on both technical accuracy and communication skills, bridging the employability gap through accessible AI-powered coaching.

🎯 Key Features

🧠 AGI Intent Recognition

  • Intelligent Context Awareness: Gemini AI distinguishes between conversational commands (e.g., "skip question", "give me a hint") and actual technical answers
  • Dynamic UI Adaptation: Automatically adjusts response format based on user intent
  • Natural Conversation Flow: Handles code-switching and casual speech patterns seamlessly

⚑ Event-Driven Scaling

  • Decoupled Architecture: Audio processing pipeline using S3 β†’ Transcribe β†’ EventBridge β†’ Lambda
  • Zero Idle Costs: Lambda functions only run when needed, shutting down immediately after task completion
  • Asynchronous Processing: Transcribe jobs run independently, with EventBridge triggering response generation upon completion
  • Enterprise-Grade Reliability: Handles 1,000+ concurrent users without degradation

🌐 Multilingual ASR (Automatic Speech Recognition)

  • Hinglish Support: Seamlessly processes mixed Hindi-English speech using Amazon Transcribe
  • Multi-Language Detection: Supports en-IN (Indian English) and hi-IN (Hindi) with automatic language detection
  • Regional Accent Optimization: Fine-tuned for Indian accents and speech patterns

🎯 Smart Filtering

  • Filler Word Removal: LLM-powered prompting ignores "uh", "um", "matlab", "basically" while grading
  • Technical Accuracy Focus: Evaluates core logic and concepts, not linguistic perfection
  • Cleaned Answer Generation: Provides professional rephrasing of user responses

β™Ώ Accessibility

  • Dynamic Mode Selection: Users can choose "Text Only" or "Audio + Text" modes on-the-fly
  • Low-Bandwidth Optimization: Works on 2G/3G networks with compressed audio
  • WhatsApp-First: Zero app installation required - works directly in WhatsApp

πŸ“ˆ Adaptive Difficulty

  • Score-Based Progression: Automatically adjusts question difficulty based on previous performance
  • Personalized Learning Path: Tailors interview questions to user's resume and target role
  • Real-Time Feedback: Provides immediate scoring (1-10 scale) and improvement suggestions

πŸ—οΈ Architecture

System Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Student   β”‚
β”‚  (WhatsApp) β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
       β”‚ Voice/Text Message
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  API Gateway        β”‚
β”‚  (Webhook Endpoint) β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Lambda A: Ingestor (lambda_ingestor.py)                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ β€’ Receives WhatsApp messages                       β”‚  β”‚
β”‚  β”‚ β€’ Handles text/document/audio inputs               β”‚  β”‚
β”‚  β”‚ β€’ Processes text via Gemini AI                     β”‚  β”‚
β”‚  β”‚ β€’ Uploads audio to S3                              β”‚  β”‚
β”‚  β”‚ β€’ Triggers Amazon Transcribe job                   β”‚  β”‚
β”‚  β”‚ β€’ Shuts down immediately (cost optimization)       β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Amazon S3      β”‚
β”‚  (Audio Storage)β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Amazon Transcribe   β”‚
β”‚  (Async ASR Job)     β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚ Job Complete Event
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Amazon EventBridge  β”‚
β”‚  (State Change Rule) β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚ Triggers Lambda B
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Lambda B: Responder (lambda_responder.py)               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ β€’ Fetches transcription from Transcribe            β”‚  β”‚
β”‚  β”‚ β€’ Grades answer using Gemini AI                    β”‚  β”‚
β”‚  β”‚ β€’ Generates next question (adaptive difficulty)    β”‚  β”‚
β”‚  β”‚ β€’ Creates voice feedback via Amazon Polly          β”‚  β”‚
β”‚  β”‚ β€’ Sends response back to WhatsApp                  β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Amazon Polly   β”‚
β”‚  (TTS - Kajal)  β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Amazon S3      β”‚
β”‚  (Audio Output) β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  WhatsApp API   β”‚
β”‚  (Send Audio)   β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Student   β”‚
β”‚  (Receives  β”‚
β”‚   Feedback) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Shared Data Layer                                      β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚  Amazon DynamoDB (aira_sessions)                  β”‚ β”‚
β”‚  β”‚  β€’ User profiles                                  β”‚ β”‚
β”‚  β”‚  β€’ Interview history                              β”‚ β”‚
β”‚  β”‚  β€’ Current question state                         β”‚ β”‚
β”‚  β”‚  β€’ Preference settings (text/audio)               β”‚ β”‚
β”‚  β”‚  β€’ Last score tracking                            β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Architecture Diagram

Aira Architecture Event-driven, fully decoupled serverless architecture on AWS

Key Architectural Decisions

  1. Decoupled Audio Processing: Lambda A uploads audio to S3 and triggers Transcribe, then immediately shuts down. EventBridge wakes up Lambda B when transcription completes, minimizing compute costs.

  2. Asynchronous Workflow: No blocking operations - users get immediate acknowledgment while processing happens in the background.

  3. Stateless Lambda Functions: All session state stored in DynamoDB, enabling horizontal scaling.

  4. Cost Optimization: Lambda functions run only when needed, with automatic shutdown after task completion.

πŸš€ Setup & Deployment

Prerequisites

  • AWS Account with the following services enabled:
    • AWS Lambda
    • Amazon S3
    • Amazon Transcribe
    • Amazon Polly
    • Amazon DynamoDB
    • Amazon EventBridge
    • Amazon API Gateway
  • WhatsApp Business API credentials (Meta/Twilio)
  • Google Gemini API key
  • Python 3.11+
  • AWS CLI configured

Step 1: Clone the Repository

git clone https://github.com/yourusername/aira.git
cd aira

Step 2: Configure Environment Variables

Copy the .env.example file to .env and fill in your actual credentials:

cp .env.example .env

Then edit .env with your actual values:

# AWS Configuration
AWS_REGION=ap-south-1

# S3 Buckets
BUCKET_IN=your-audio-input-bucket-name
BUCKET_OUT=your-audio-output-bucket-name

# API Keys
GEMINI_API_KEY=your-gemini-api-key-here
META_ACCESS_TOKEN=your-meta-permanent-access-token
META_PHONE_ID=your-meta-phone-id
META_VERIFY_TOKEN=your-custom-verify-token

# DynamoDB
DYNAMODB_TABLE=aira_sessions

Important: Never commit your .env file to GitHub. It's already included in .gitignore.

Step 3: Create AWS Resources

3.1 Create S3 Buckets

aws s3 mb s3://your-audio-input-bucket-name --region ap-south-1
aws s3 mb s3://your-audio-output-bucket-name --region ap-south-1

3.2 Create DynamoDB Table

aws dynamodb create-table \
    --table-name aira_sessions \
    --attribute-definitions AttributeName=phone_number,AttributeType=S \
    --key-schema AttributeName=phone_number,KeyType=HASH \
    --billing-mode PAY_PER_REQUEST \
    --region ap-south-1

3.3 Deploy Lambda Functions

Lambda A (Ingestor):

cd lambda_ingestor
zip -r lambda_ingestor.zip lambda_ingestor.py
aws lambda create-function \
    --function-name aira-ingestor \
    --runtime python3.11 \
    --role arn:aws:iam::YOUR_ACCOUNT_ID:role/lambda-execution-role \
    --handler lambda_ingestor.lambda_handler \
    --zip-file fileb://lambda_ingestor.zip \
    --timeout 300 \
    --memory-size 512 \
    --region ap-south-1

Lambda B (Responder):

cd lambda_responder
zip -r lambda_responder.zip lambda_responder.py
aws lambda create-function \
    --function-name aira-responder \
    --runtime python3.11 \
    --role arn:aws:iam::YOUR_ACCOUNT_ID:role/lambda-execution-role \
    --handler lambda_responder.lambda_handler \
    --zip-file fileb://lambda_responder.zip \
    --timeout 300 \
    --memory-size 512 \
    --region ap-south-1

Step 4: Configure EventBridge Rule

CRITICAL: This rule triggers Lambda B when Transcribe jobs complete.

aws events put-rule \
    --name aira-transcribe-complete \
    --event-pattern '{
      "source": ["aws.transcribe"],
      "detail-type": ["Transcribe Job State Change"],
      "detail": {
        "TranscriptionJobStatus": ["COMPLETED", "FAILED"]
      }
    }' \
    --region ap-south-1

aws events put-targets \
    --rule aira-transcribe-complete \
    --targets "Id"="1","Arn"="arn:aws:lambda:ap-south-1:YOUR_ACCOUNT_ID:function:aira-responder"

Step 5: Configure API Gateway

  1. Create a new REST API in API Gateway
  2. Create a POST method pointing to aira-ingestor Lambda
  3. Create a GET method for WhatsApp webhook verification
  4. Deploy the API and note the endpoint URL
  5. Configure the endpoint as your WhatsApp webhook URL

Step 6: Configure WhatsApp Webhook

  1. Go to Meta for Developers β†’ Your App β†’ WhatsApp β†’ Configuration
  2. Set Webhook URL to your API Gateway endpoint
  3. Set Verify Token to match META_VERIFY_TOKEN in your environment variables
  4. Subscribe to messages webhook field

πŸ“‹ Environment Variables Reference

Variable Description Example
AWS_REGION AWS region for all services ap-south-1
BUCKET_IN S3 bucket for incoming audio files aira-audio-input
BUCKET_OUT S3 bucket for generated audio responses aira-audio-output
GEMINI_API_KEY Google Gemini API key AIza...
META_ACCESS_TOKEN WhatsApp Business API permanent token EAAG...
META_PHONE_ID WhatsApp Business phone number ID 123456789
META_VERIFY_TOKEN Custom token for webhook verification your-secret-token
DYNAMODB_TABLE DynamoDB table name aira_sessions

πŸŽ“ Usage

Starting an Interview

  1. Send "Hi" or upload your resume (PDF) to the WhatsApp number
  2. Aira will analyze your resume and ask the first question
  3. Answer via voice note or text message

During the Interview

  • Answer Questions: Send voice notes or text messages
  • Get Hints: Tap the "πŸ’‘ Hint" button
  • Change Mode: Tap "πŸ“ Text Only" to disable audio responses
  • End Interview: Tap "πŸ›‘ End Interview" or say "end interview"

After the Interview

  • Receive a detailed report card with:
    • Overall performance summary
    • 3 key strengths
    • 3 areas for improvement
    • Recommended next steps

πŸ“Š Cost Breakdown

Per user per month (assuming 10 interview sessions, 5 minutes each):

Service Usage Cost
Lambda (Ingestor) 10 invocations Γ— 2s $0.00
Lambda (Responder) 10 invocations Γ— 3s $0.00
Amazon Transcribe 50 minutes audio $1.00
Amazon Polly 5,000 characters $0.10
Gemini API 100K tokens $0.15
DynamoDB 100 read/write units $0.05
S3 Storage 500MB $0.01
Total ~$1.31/user/month

Lambda costs are negligible due to AWS Free Tier (1M requests/month)

πŸ› οΈ Technology Stack

Component Technology Purpose
Frontend WhatsApp Business API User interface
Backend AWS Lambda (Python 3.11) Serverless compute
Speech-to-Text Amazon Transcribe Audio transcription
LLM Google Gemini 2.5 Flash Answer evaluation & question generation
Text-to-Speech Amazon Polly (Kajal voice) Audio feedback generation
Database Amazon DynamoDB User state & session management
Storage Amazon S3 Audio file storage
Event Bus Amazon EventBridge Async workflow orchestration
API Gateway Amazon API Gateway Webhook endpoint

πŸ“– Documentation

🎯 Use Cases

  1. Technical Interview Prep: Practice DSA, system design, and domain-specific questions
  2. Communication Training: Learn to articulate technical concepts in professional English
  3. Resume-Based Coaching: Get personalized questions based on your skills
  4. Progress Tracking: Monitor improvement over multiple sessions
  5. Multilingual Support: Practice in Hindi, Hinglish, or English

πŸ’‘ Why Aira?

  • Accessibility: Works on low-bandwidth networks (2G/3G)
  • Inclusivity: Supports vernacular languages and code-switching
  • Scalability: Handles 1,000+ concurrent users with event-driven architecture
  • Privacy: No PII stored, encrypted data, 30-day retention
  • Impact: Targets 100M+ students in underserved regions
  • Cost-Effective: ~$1.31/user/month with serverless architecture

🀝 Contributing

We welcome contributions! Please see CONTRIBUTING.md for guidelines.

πŸ“„ License

This project is licensed under the MIT License - see LICENSE file for details.

πŸ™ Acknowledgments

  • Built for AWS AI for Bharat Hackathon
  • Inspired by the need to democratize interview preparation in India
  • Special thanks to students from Tier-2/3 cities who provided feedback

πŸ“§ Contact

For questions or feedback, reach out at [pandyashashank1@gmail.com]


Made with ❀️ for students across India

About

Voice-first multilingual technical interview coach for Tier-2/3 cities in India using AWS Generative AI services

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages