interview_agents_api / src /services /integrity_service.py
quentinL52
Initial commit
4e9b744
import logging
from src.services.nlp_service import NLPService
from typing import Dict, Any
logger = logging.getLogger(__name__)
class IntegrityService:
def __init__(self):
self.nlp = NLPService()
def analyze_integrity(self, cv_text: str, interview_text: str, existing_metrics: Dict[str, Any] = None) -> Dict[str, Any]:
"""
Combines stylometric analysis and AI detection to produce an integrity report.
"""
logger.info("Starting Integrity Analysis...")
# 1. AI Detection on Interview Transcript
interview_metrics = self.nlp.compute_all_metrics(interview_text)
# 2. Stylometric Consistency (CV vs Interview)
# We only care about consistency if we have enough text
stylometric_flag = False
gap_details = ""
if cv_text and len(cv_text) > 100:
cv_metrics = self.nlp.compute_all_metrics(cv_text)
# Compare Readability (Flesch)
readability_gap = abs(interview_metrics["readability"] - cv_metrics["readability"])
if readability_gap > 30: # Huge gap in complexity
stylometric_flag = True
gap_details += f"Readability Gap ({readability_gap}); "
# Compare Vocabulary Richness
ttr_gap = abs(interview_metrics["lexical_diversity"] - cv_metrics["lexical_diversity"])
if ttr_gap > 0.2:
stylometric_flag = True
gap_details += f"Vocab Gap ({ttr_gap}); "
# 3. Rules for Red Flags
ai_suspicion_score = 0
reasons = []
# Low Perplexity = AI
if interview_metrics["perplexity"] < 25:
ai_suspicion_score += 40
reasons.append("Perplexity very low (Robotic)")
# Low Burstiness = AI
if interview_metrics["burstiness"] < 0.2:
ai_suspicion_score += 30
reasons.append("Low Burstiness (Monotone)")
# Stylometric Mismatch
if stylometric_flag:
ai_suspicion_score += 20
reasons.append(f"Style Mismatch with CV: {gap_details}")
final_score = min(100, ai_suspicion_score)
return {
"ai_score": final_score,
"stylometry_mismatch": stylometric_flag,
"metrics": interview_metrics,
"reasons": reasons,
"raw_gap": gap_details
}