File size: 2,462 Bytes
4e9b744
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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
        }