Spaces:
Running
Running
Download myapp/step3_rag.py from sungho7373/dark-pattern-auditor: direct link, hf CLI and curl.
- Browser
- Download file 5.17 kB
-
https://huggingface.co/spaces/sungho7373/dark-pattern-auditor/resolve/main/myapp/step3_rag.py
- Command line
-
hf download hf://spaces/sungho7373/dark-pattern-auditor/myapp/step3_rag.py
-
curl -L -o step3_rag.py https://huggingface.co/spaces/sungho7373/dark-pattern-auditor/resolve/main/myapp/step3_rag.py
5.17 kB
| import os | |
| import re | |
| import torch | |
| import numpy as np | |
| from openai import OpenAI | |
| from sentence_transformers import SentenceTransformer, util | |
| from dotenv import load_dotenv | |
| # Load environment variables | |
| load_dotenv() | |
| class FactCheckerRAG: | |
| def __init__(self): | |
| print("📚 [Step 3] Loading the Global Compliance RAG (FTC Guidelines)...") | |
| # Use a universal English model for better retrieval accuracy | |
| self.device = "mps" if torch.backends.mps.is_available() else ("cuda" if torch.cuda.is_available() else "cpu") | |
| self.retriever = SentenceTransformer('all-MiniLM-L6-v2', device=self.device) | |
| api_key = os.getenv("OPENAI_API_KEY") | |
| if not api_key: | |
| print("⚠️ Warning: OPENAI_API_KEY is not set.") | |
| self.client = OpenAI(api_key=api_key) | |
| # ⚖️ FTC Regulatory Knowledge Base (Negative Option & Dark Patterns) | |
| self.fact_db = [ | |
| # 1. Disclosure Requirements | |
| "Material terms of the negative option offer (billing frequency, amount, cancellation) must be disclosed clearly and conspicuously before obtaining billing information.", | |
| "The disclosure must be placed in close proximity to the request for consent and must not be hidden in fine print or separate terms and conditions pages.", | |
| # 2. Express Informed Consent | |
| "Marketers must obtain the consumer's express informed consent before charging them for a subscription or recurring service.", | |
| "Deceptive checkboxes or 'pre-checked' boxes for additional paid services are considered unfair and deceptive acts.", | |
| # 3. Simple Cancellation (The 'Click-to-Cancel' Rule) | |
| "The cancellation mechanism must be at least as simple as the mechanism used to initiate the subscription (e.g., if you join online, you must be able to cancel online).", | |
| "Failing to provide a simple method to stop recurring charges is a direct violation of the ROSCA (Restore Online Shoppers' Confidence Act).", | |
| # 4. Misleading Pricing (Bait & Switch) | |
| "Promising a 'Free' or '$0' trial without disclosing that a full-price subscription begins automatically after a short period is a deceptive practice.", | |
| "Requiring credit card information for a 'free' service must be accompanied by a clear explanation of when and why the card will be charged." | |
| ] | |
| # Pre-calculate DB embeddings | |
| self.db_embeddings = self.retriever.encode(self.fact_db, convert_to_tensor=True) | |
| def calculate_x3_score(self, text): | |
| """Calculate a regulatory non-compliance score based on FTC guidelines via RAG.""" | |
| if not text or len(text.strip()) < 10: | |
| return 0.0, "Insufficient text provided for compliance audit." | |
| try: | |
| # 1. Retrieval: Find the most relevant FTC guideline | |
| query_embedding = self.retriever.encode(text, convert_to_tensor=True) | |
| cosine_scores = util.cos_sim(query_embedding, self.db_embeddings)[0] | |
| best_idx = torch.argmax(cosine_scores).item() | |
| retrieved_fact = self.fact_db[best_idx] | |
| # 2. Generation: GPT Audit | |
| prompt = f""" | |
| You are a senior auditor for the FTC (Federal Trade Commission) specialized in deceptive subscription practices. | |
| Audit the [Ad/Service Copy] based on the [Relevant Regulation]. | |
| [Relevant Regulation]: {retrieved_fact} | |
| [Ad/Service Copy]: {text} | |
| Response Format (Strictly follow this): | |
| Compliance Risk: [Score from 0 to 100, where 100 is a definite violation] | |
| Specific Violation: [1-2 sentences explaining why it violates or follows the rule] | |
| Verdict: [CRITICAL / SUSPICIOUS / COMPLIANT] | |
| """ | |
| print(" -> 🤖 GPT Auditor is cross-checking with federal regulations...") | |
| response = self.client.chat.completions.create( | |
| model="gpt-4o", # Using 4o for better reasoning in English | |
| messages=[{"role": "user", "content": prompt}], | |
| temperature=0.0 | |
| ) | |
| result_text = response.choices[0].message.content | |
| print(f" [Audit Report]\n{result_text}") | |
| # Extract score | |
| score_match = re.search(r"Compliance Risk:\s*(\d+)", result_text) | |
| x3_score = float(score_match.group(1)) if score_match else 0.0 | |
| return x3_score, retrieved_fact | |
| except Exception as e: | |
| print(f"⚠️ Audit Error: {e}") | |
| return 0.0, "An error occurred during regulatory analysis." | |
| if __name__ == "__main__": | |
| checker = FactCheckerRAG() | |
| # Test case: Typical subscription trap language | |
| test_copy = "Get your FREE trial now! $0.00 today. Just enter your credit card to verify your identity." | |
| score, fact = checker.calculate_x3_score(test_copy) | |
| print("-" * 50) | |
| print(f"Final Non-Compliance Score: {score}") | |
| print(f"Reference FTC Guideline: {fact}") |