Download src/cpptai/responsible_ai.py from Fra150/Cpptai: direct link, hf CLI and curl.
- Browser
- Download file 3.11 kB
-
https://huggingface.co/spaces/Fra150/Cpptai/resolve/main/src/cpptai/responsible_ai.py
- Command line
-
hf download hf://spaces/Fra150/Cpptai/src/cpptai/responsible_ai.py
-
curl -L -o responsible_ai.py https://huggingface.co/spaces/Fra150/Cpptai/resolve/main/src/cpptai/responsible_ai.py
3.11 kB
| """Responsible AI auditor — bias detection and fairness checks. | |
| Extracted from core.py into its own module for clarity and testability. | |
| """ | |
| from __future__ import annotations | |
| import re | |
| from typing import Any, Dict, List | |
| class ResponsibleAIAuditor: | |
| """Audits generated outputs for protected-attribute bias and negative framing. | |
| Maintains a vocabulary of protected terms (demographic attributes) and | |
| negative-context keywords. Scans text for co-occurrence patterns and | |
| returns a structured risk assessment. | |
| """ | |
| def __init__(self): | |
| self.protected_terms = [ | |
| "woman", "women", "man", "men", "male", "female", | |
| "girl", "boy", "black", "white", "asian", "latino", | |
| "hispanic", "arab", "jewish", "muslim", "christian", | |
| "gay", "lesbian", "bisexual", "trans", "transgender", | |
| "disabled", "autistic", "elderly", "old", "young", | |
| "immigrant", | |
| ] | |
| self.negative_terms = { | |
| "inferior", "superior", "lazy", "stupid", "criminal", | |
| "dangerous", "dirty", "illegal", "terrorist", "untrustworthy", | |
| } | |
| def audit_bias_detection(self, text: str) -> Dict[str, Any]: | |
| """Analyse *text* for protected-attribute mentions near negative terms. | |
| Returns a verdict dict with keys: | |
| verdict — "pass" | "review" | |
| risk_score — float in [0, 1] | |
| protected_attribute_mentions — sorted list of matched terms | |
| negative_context_hits — list of {term, negative_terms, context} | |
| flags — human-readable notes | |
| """ | |
| lowered = text.lower() | |
| mentions: List[str] = [] | |
| negative_hits: List[Dict[str, Any]] = [] | |
| words = re.findall(r"[a-zA-Z']+", lowered) | |
| for idx, w in enumerate(words): | |
| if w not in self.protected_terms: | |
| continue | |
| mentions.append(w) | |
| start = max(0, idx - 6) | |
| end = min(len(words), idx + 7) | |
| window = words[start:end] | |
| hit_terms = sorted(set(t for t in window if t in self.negative_terms)) | |
| if hit_terms: | |
| negative_hits.append({ | |
| "term": w, | |
| "negative_terms": hit_terms, | |
| "context": " ".join(window), | |
| }) | |
| unique_mentions = sorted(set(mentions)) | |
| unique_negative = len(negative_hits) | |
| risk = 0.0 | |
| if unique_mentions: | |
| risk = 0.3 | |
| if unique_negative: | |
| risk = min(1.0, risk + 0.2 * unique_negative) | |
| verdict = "pass" | |
| flags: List[str] = [] | |
| if unique_negative: | |
| verdict = "review" | |
| flags.append("negative_context_near_protected_attribute") | |
| if not unique_mentions: | |
| flags.append("no_protected_attribute_mentions_detected") | |
| return { | |
| "verdict": verdict, | |
| "risk_score": round(risk, 3), | |
| "protected_attribute_mentions": unique_mentions, | |
| "negative_context_hits": negative_hits, | |
| "flags": flags, | |
| } | |