See your website through 200 AI personas backed by real eye-tracking ML and 1 million Big Five personality assessments.
Perception Lab is an AI-powered UX research platform that simulates how diverse, data-grounded user personas experience your website — then automatically generates an improved redesign. It replaces weeks of expensive user testing with a 60-second analysis.
- What It Does
- Why It's Different
- System Architecture
- Key Features
- Tech Stack
- ML Models & Datasets
- Getting Started
- API Reference
- Project Structure
- Research Foundation
- Security
- Contributing
- License
Paste any website URL. In 60 seconds, Perception Lab:
- Captures the page with Playwright (full-page screenshot + DOM + performance + accessibility)
- Analyzes visual design with real ML models (TranSalNet eye-tracking, LAION aesthetics, OpenCV design metrics)
- Simulates 200 AI personas drawn from 1,010,690 real Big Five personality assessments evaluating the site
- Gives 10 "featured" personas full multimodal LLM treatment — they actually see the screenshot and produce emotional journeys, verbatim quotes, and cursor replay paths
- Scores 8 UX dimensions plus a Conversion Potential Score tied to Baymard Institute benchmarks
- Generates an AI-powered redesign — complete HTML/CSS for an improved version of the site you can preview and download
https://your-site.com
↓
┌──────────────┐ ┌──────────────┐ ┌────────────────┐
│ Screenshot │───▶│ ML Stack │───▶│ 200 Personas │
│ (Playwright)│ │ (TranSalNet │ │ (Big Five GMM)│
│ │ │ + LAION) │ │ │
└──────────────┘ └──────────────┘ └────────────────┘
↓
┌──────────────┐ ┌──────────────┐ ┌────────────────┐
│ AI Redesign │◀───│ 10 Featured │◀───│ Scores + Fixes │
│ (Gemini HTML)│ │ Vision LLM │ │ (8 dimensions)│
└──────────────┘ └──────────────┘ └────────────────┘
Perception Lab is not another LLM wrapper. Every layer is backed by real ML models trained on real human data:
| Layer | Approach | Data Source |
|---|---|---|
| Eye-tracking | TranSalNet CNN + Transformer | SALICON: 10,000 images with real mouse-tracked gaze |
| Aesthetics | CLIP ViT-L/14 + MLP regression head | AVA: 255,530 images with human ratings 1-10 |
| Web design | Research-informed feature ensemble | Calista: 317 sites × 441,479 human evaluations |
| Personas | GMM clustering + demographic conditioning | IPIP-FFM: 1,010,690 real Big Five assessments |
| Vision LLM | Gemini 2.5 Flash multimodal | Grounded by all of the above |
| Population scorer | 35 research-weighted UX heuristics | Nielsen Norman Group, Baymard Institute, NN/g |
Most competitors use a single LLM prompt. We use seven specialized models plus a deterministic population engine that evaluates 200 personas in 7 milliseconds.
flowchart TB
User([User]) -->|URL| Frontend[Next.js Frontend<br/>:3000]
Frontend -->|POST /api/analyze| API[FastAPI Gateway<br/>:8000]
API -->|capture| Screenshot[Screenshot Service<br/>Playwright + axe-core<br/>:8082]
API -->|analyze image| ML[ML Service<br/>TranSalNet + LAION + OpenCV<br/>:8081]
API -->|persona vision| Gemini[(Gemini 2.5 Flash<br/>Multimodal)]
API -->|fallback| Groq[(Groq Llama 4 Scout)]
API -->|fallback| OpenRouter[(OpenRouter)]
API -->|persist| Supabase[(Supabase Postgres)]
Screenshot -->|PNG + DOM + a11y + perf| API
ML -->|saliency + aesthetics + metrics| API
Gemini -->|persona walkthrough| API
API -->|results JSON| Frontend
sequenceDiagram
participant U as User
participant F as Frontend
participant A as API
participant S as Screenshot
participant M as ML Service
participant P as Population Scorer
participant L as LLM (Gemini)
participant D as Supabase
U->>F: Paste URL
F->>A: POST /api/analyze
Note over A: Validate URL (SSRF guard)
A->>S: Capture screenshot + DOM
S-->>A: PNG + HTML + perf + a11y
A->>M: Analyze image
Note over M: TranSalNet saliency<br/>LAION aesthetics<br/>OpenCV metrics
M-->>A: Heatmap + scores
A->>P: Score 200 personas
Note over P: 35 UX heuristics ×<br/>OCEAN weights × O(n)
P-->>A: Individual + aggregate scores
A->>L: 10 featured personas (parallel)
Note over L: Vision prompt +<br/>emotional journey +<br/>critic validation
L-->>A: Walkthroughs + quotes
A->>D: Persist analysis
A-->>F: Full results JSON
F->>U: Render dashboard
graph LR
subgraph Tier3["Tier 3: Statistical Extrapolation"]
EXT[1M+ Big Five<br/>population estimate]
end
subgraph Tier2["Tier 2: Deterministic (0.007s)"]
POP[200 personas<br/>35 UX heuristics<br/>OCEAN weights<br/>No LLM calls]
end
subgraph Tier1["Tier 1: Multimodal LLM (30-60s)"]
FEAT[10 featured personas<br/>Vision-based<br/>Emotional journeys<br/>Verbatim quotes]
end
POP -->|select extremes +<br/>demographic coverage| FEAT
POP -->|extrapolate| EXT
POP -.->|aggregate stats| Dashboard[Population Dashboard]
FEAT -.->|deep dives| Dashboard
EXT -.->|confidence intervals| Dashboard
flowchart LR
Screenshot[Screenshot] --> TS[TranSalNet]
Screenshot --> LAION[LAION V2]
Screenshot --> OCV[OpenCV Metrics]
TS -->|attention heatmap| Saliency[Saliency<br/>attention %]
LAION -->|CLIP + MLP| Aesthetic[Aesthetic score<br/>1-10]
OCV --> Colorfulness
OCV --> Complexity
OCV --> Whitespace
OCV --> Symmetry
OCV --> Harmony[Color Harmony]
Saliency --> Scorer
Aesthetic --> Scorer
Colorfulness --> Scorer
Complexity --> Scorer
Whitespace --> Scorer
Symmetry --> Scorer
Harmony --> Scorer
Scorer[Scoring Engine<br/>8 dimensions + benchmarks] --> Output[Output]
TranSalNet (Lou et al. 2022) trained on SALICON — 10,000 images with actual human gaze data. Not heuristics. Not boxes drawn around headings. Real attention prediction.
Drawn from 1,010,690 real Big Five personality assessments via GMM clustering. Each persona has statistically valid OCEAN traits, demographic grounding (Pew Research 2024-2025), and behavioral modifiers derived from HCI research.
10 featured personas receive the actual screenshot as input to Gemini 2.5 Flash (multimodal). They describe what they see, not what a text summary implies. Includes chain-of-feeling emotional journey tracking via Plutchik's wheel.
The killer feature. After analysis, click one button and Gemini generates a complete improved HTML/CSS version of the site addressing the identified issues. Renders side-by-side with the original in a sandboxed iframe.
Visual Hierarchy, Typography, Color Palette, Layout & Spacing, Content Quality, Trustworthiness, Accessibility, Performance — each scored independently with research-backed weights and industry benchmarks (SaaS, E-Commerce, News, Portfolio, Healthcare, Government).
A 0-100 score mapped to estimated conversion rate ranges (Baymard Institute benchmarks). Breakdown by CTA strength, trust signals, speed, value prop clarity, information scent, and readability.
Given a homepage URL, the crawler discovers 3-6 key internal pages (pricing, signup, about, etc.) and analyzes each, identifying the weakest page in your conversion funnel.
Streaming real-time persona reactions — Twitter-like feed where each persona's quote types out character-by-character with emotional indicators. Demo-friendly theatrical moment.
Dedicated /science page showing every model, dataset size, training data, accuracy metrics, and peer-reviewed paper links. Full transparency for judges and technical users.
- SSRF protection blocks private IPs, cloud metadata endpoints, link-local addresses
- Iframe sandboxing with maximum restriction for AI-generated HTML
- Rate limiting per IP (30 req/min default)
- Security headers (X-Frame-Options, CSP, Referrer-Policy)
- No secrets in code, all config via env vars
| Technology | Purpose |
|---|---|
| Next.js 16 | React framework with App Router, Turbopack |
| TypeScript | Type safety |
| Tailwind CSS 4 | Utility-first styling |
| Framer Motion | Animations |
| Recharts | Data visualization (radar, histograms, bars) |
| Lucide React | Icons |
| Lenis | Smooth scroll |
| Technology | Purpose |
|---|---|
| FastAPI | Async API gateway (Python 3.13) |
| PyTorch 2.11 | ML model runtime |
| open-clip-torch | CLIP vision encoder |
| OpenCV | Image processing / design metrics |
| scikit-learn | GMM clustering |
| sentence-transformers | Information scent (all-MiniLM-L6-v2) |
| Playwright | Browser automation for screenshots |
| axe-core | WCAG accessibility auditing |
| textstat | Readability metrics (Flesch-Kincaid) |
| httpx | Async HTTP client |
| google-genai | Gemini 2.5 Flash client |
| supabase-py | Database client |
| Pillow | Image compression |
| Technology | Purpose |
|---|---|
| Supabase | PostgreSQL + Storage |
| Gemini 2.5 Flash | Primary vision LLM |
| Groq Llama 4 Scout | Vision LLM fallback |
| OpenRouter | Second fallback (free models) |
| Docker Compose | Multi-service orchestration |
| Model | Type | Training Data | Accuracy |
|---|---|---|---|
| TranSalNet | Saliency prediction (CNN + Transformer) | SALICON (10K eye-tracking images) | CC 0.907, NSS 2.47 on MIT1003 |
| LAION Aesthetic V2 | CLIP ViT-L/14 + MLP regression | AVA (250K) + SAC (176K) + LAION-Logos | Pearson r ~0.71 with humans |
| Web Aesthetics Scorer | OpenCV feature ensemble | Calista + Reinecke research | ~50% variance explained (Reinecke) |
| Sentence-Transformers | all-MiniLM-L6-v2 embeddings | Paraphrase corpus + more | 81% on SNIF-ACT (info scent) |
| Population Scorer | Rule-based + OCEAN weights | Nielsen Norman Group research | Deterministic |
| Gemini 2.5 Flash | Multimodal foundation LLM | Google training data | Grounded by above |
| Dataset | Size | Use |
|---|---|---|
| IPIP-FFM Big Five | 1,010,690 responses | Persona GMM clustering |
| SALICON | 10,000 images | TranSalNet training |
| AVA | 255,530 images | LAION aesthetic training |
| Calista Web Aesthetics | 317 sites × 441K evaluations | Web-specific features |
| Pew Research | Nationally representative | Tech usage by demographic |
| CDC DHDS 2023 | US population | Accessibility prevalence |
| Reinecke (CHI 2013) | 548 users × 450 sites | Visual complexity model |
- Python 3.13 (ML service requires this specific version due to PyTorch 2.11)
- Python 3.14 works for the API service
- Node.js 20+ for the frontend
- macOS, Linux, or WSL2 (Playwright doesn't support native Windows well)
- At least 4 GB free disk for ML model weights and Python dependencies
- At least 8 GB RAM (ML inference is CPU-based)
- Gemini API key — https://aistudio.google.com/apikey (recommended)
- Groq API key — https://console.groq.com/keys (fallback)
- OpenRouter API key — https://openrouter.ai/keys (second fallback)
- Supabase (optional, for history persistence) — https://supabase.com
# 1. Clone the repo
git clone https://github.com/YOUR_USERNAME/perception-lab.git
cd perception-lab
# 2. Configure environment
cp .env.example .env
# Edit .env and add your API keys
# 3. Set up the API service (Python 3.14)
cd services/api
python3.14 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pip install supabase Pillow # additional deps
cd ../..
# 4. Set up the ML service (Python 3.13)
cd services/ml
python3.13 -m venv venv
source venv/bin/activate
pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
pip install -r requirements.txt
pip install pandas scikit-image open-clip-torch timm
cd ../..
# 5. Set up the screenshot service
cd services/screenshot
npm install
npx playwright install chromium
cd ../..
# 6. Set up the frontend
cd apps/web
npm install
cd ../..
# 7. Download ML model weights (TranSalNet + LAION)
# These are too large for git — see docs/model-setup.md
# Approximate download: ~400 MBOpen four terminals (one per service):
# Terminal 1 — API
cd services/api && source venv/bin/activate
uvicorn app.main:app --reload --host 127.0.0.1 --port 8000
# Terminal 2 — ML Service (may take 30s to load models)
cd services/ml && source venv/bin/activate
uvicorn app.main:app --host 127.0.0.1 --port 8081
# Terminal 3 — Screenshot Service
cd services/screenshot
node src/server.js
# Terminal 4 — Frontend
cd apps/web
NEXT_PUBLIC_API_URL=http://127.0.0.1:8000 npm run devThen open http://localhost:3000.
curl http://127.0.0.1:8000/health
# {"status":"ok","service":"api"}
curl http://127.0.0.1:8081/health
# {"status":"ok","service":"ml","models":{"saliency":"transalnet","aesthetics":"loaded","ocr":"not loaded"}}
curl http://127.0.0.1:8082/health
# {"status":"ok","service":"screenshot"}Run the end-to-end test suite:
source services/api/venv/bin/activate
python scripts/test_backend.py
# Expected: 46-50 tests passBase URL: http://127.0.0.1:8000
Full website analysis with ML + population personas + vision LLM.
Request:
{
"url": "https://example.com",
"population_size": 200,
"panel_preset": "diverse-panel",
"viewport": "desktop"
}Response: ~200KB JSON with scores, saliency heatmap, aesthetics, design metrics, accessibility, performance, population results, featured personas, qualitative analysis, AOI scores, conversion potential, and fix suggestions.
Generate an AI-powered redesign as complete HTML/CSS.
Request:
{ "url": "https://example.com" }Response:
{
"html": "<!DOCTYPE html>...",
"metadata": { "model": "gemini-2.5-flash", "length_chars": 6157 },
"issues_fixed": [...]
}Multi-page site flow analysis.
Request:
{ "url": "https://example.com", "max_pages": 5 }Response: List of analyzed pages with scores, weakest page in funnel, funnel insights.
A/B comparison with counterbalanced persona voting (SimAB protocol).
Request:
{ "url_a": "https://v1.example.com", "url_b": "https://v2.example.com" }Generate a custom persona panel.
Request:
{
"count": 10,
"age_min": 50,
"age_max": 70,
"gender": "female",
"tech_literacy": "low"
}List recent analyses from Supabase.
Retrieve a specific analysis.
Create a GitHub PR with CSS fixes.
Request:
{
"token": "ghp_...",
"repo": "owner/repo",
"css_content": "...",
"file_path": "styles/fixes.css"
}Service health check.
perception-lab/
├── apps/
│ └── web/ # Next.js 16 frontend
│ ├── src/
│ │ ├── app/ # App Router pages
│ │ │ ├── playground/ # Main analysis tool
│ │ │ ├── science/ # Research & model backing
│ │ │ ├── personas/ # Persona library
│ │ │ ├── history/ # Past analyses
│ │ │ └── ...
│ │ └── components/
│ │ ├── landing/ # Landing page sections
│ │ └── playground/ # Analysis UI components
│ │ ├── ai-redesign.tsx
│ │ ├── live-panel-feed.tsx
│ │ ├── hero-score.tsx
│ │ ├── visual-analysis.tsx
│ │ ├── persona-society.tsx
│ │ ├── qualitative-analysis.tsx
│ │ ├── conversion-score.tsx
│ │ └── ...
│ └── package.json
├── services/
│ ├── api/ # FastAPI gateway (Python 3.14)
│ │ ├── app/
│ │ │ ├── main.py # Endpoints + middleware
│ │ │ ├── core/config.py # Settings
│ │ │ └── services/
│ │ │ ├── persona_factory.py # Big Five persona generation
│ │ │ ├── population_scorer.py # 200-persona rule engine
│ │ │ ├── enhanced_persona.py # Vision LLM persona simulation
│ │ │ ├── scoring.py # 8-dimension UX scoring
│ │ │ ├── scanpath_generator.py # Cursor path simulation
│ │ │ ├── redesigner.py # AI redesign generator
│ │ │ ├── llm_provider.py # Multi-provider fallback
│ │ │ ├── url_validator.py # SSRF protection
│ │ │ └── persona_engine.py # Fixed 8 archetypes
│ │ ├── requirements.txt
│ │ └── Dockerfile
│ ├── ml/ # ML inference service (Python 3.13)
│ │ ├── app/
│ │ │ ├── main.py
│ │ │ ├── analyzers/
│ │ │ │ ├── aesthetics.py # LAION V2
│ │ │ │ └── design_metrics.py # OpenCV features
│ │ │ └── models/
│ │ │ └── transalnet_loader.py
│ │ ├── requirements.txt
│ │ └── Dockerfile
│ └── screenshot/ # Playwright + axe-core (Node.js)
│ ├── src/server.js
│ └── package.json
├── data/
│ ├── personas/
│ │ └── gmm_clusters.json # 8 clusters from 1M+ Big Five
│ ├── models/ # ML weights (gitignored)
│ │ ├── transalnet/
│ │ └── aesthetic_predictor_v2_linear.pth
│ └── web_aesthetics/ # Calista dataset (gitignored)
├── scripts/
│ ├── test_backend.py # Integration test suite
│ └── supabase_schema.sql
├── .env.example
├── .gitignore
├── docker-compose.yml
└── README.md
Perception Lab builds on decades of peer-reviewed UX and ML research:
| Paper | Authors | Contribution |
|---|---|---|
| "Out of One, Many" | Argyle et al. (2023) | Algorithmic fidelity in LLM persona simulation |
| "TranSalNet" | Lou et al. (2022) | State-of-the-art saliency prediction |
| "Predicting users' first impressions of website aesthetics" | Reinecke et al. (CHI 2013) | Colorfulness + complexity model |
| "A deep learning-based system for understanding and evaluating website aesthetics" | Delitzas et al. (2023) | Calista dataset & methodology |
| "Attention web designers: You have 50 ms" | Lindgaard et al. (2006) | 50ms first impressions |
| "PersonaLLM" | Jiang et al. (2024) | Big Five personality expression in LLMs |
| "Artificial Intelligence Chatbots Mimic Human Collective Behaviour" | He et al. (2024) | Multi-agent simulation validity |
See the Science page for the full list with links.
Perception Lab takes security seriously for a hackathon-grade project.
| Threat | Mitigation |
|---|---|
| SSRF via user-supplied URLs | url_validator.py blocks private networks (10/8, 172.16/12, 192.168/16, 127/8), link-local (169.254/16 — AWS/GCP metadata), loopback, and non-HTTP(S) schemes. Validates both IPs and DNS resolution. |
| XSS in AI-generated HTML | Rendered in iframe with sandbox="" (maximum restriction — no scripts, no forms, no same-origin access, no popups). |
| Secret leakage | All API keys in .env (gitignored). No hardcoded secrets in source. .env.example is a template only. |
| CORS abuse | Explicit origin allowlist in production (CORS_ORIGINS env var). Wildcard only in dev. allow_credentials=False prevents credential-based CSRF. |
| Rate limit abuse / DoS | In-memory per-IP rate limiting (30 req/min default, configurable). Applies to POST endpoints. |
| Clickjacking | X-Frame-Options: DENY header on all API responses. |
| MIME sniffing | X-Content-Type-Options: nosniff header. |
| Referrer leakage | Referrer-Policy: strict-origin-when-cross-origin. |
| Prompt injection via screenshots | LLM outputs validated/cleaned, max token limits, fallback providers if one fails. |
| GitHub token abuse | User-provided PATs used once per request, never stored. Only repo scope documented. |
| Large input DoS | URL length capped at 2048, population size capped at 500, screenshot size limited. |
| Dependency vulnerabilities | Pinned versions in requirements.txt and package.json. |
Set these in .env for production:
ENVIRONMENT=production
ALLOW_LOCAL_URLS=false
CORS_ORIGINS=https://yourdomain.com
RATE_LIMIT_PER_MINUTE=20Found a security issue? Email neojingyi7@gmail.com rather than opening a public issue.
This is a hackathon project (Quantum Sprint 2026). Contributions welcome after the submission period.
Steps:
- Fork the repo
- Create a feature branch
- Run
python scripts/test_backend.pyto verify - Submit a PR
MIT License. Free to use for research, education, and commercial purposes.
- Open Psychometrics for the public-domain IPIP-FFM dataset
- LAION for aesthetic training data and the open-clip project
- LJOVO/TranSalNet for the pre-trained saliency model
- Calista (Delitzas et al.) for web-specific aesthetic research
- Nielsen Norman Group and Baymard Institute for decades of UX research
- Google, Groq, OpenRouter for free LLM access
Built for Quantum Sprint 2026 — For Social Good
Today websites are designed for one generic user. Tomorrow every designer has a focus group of 10,000 in their pocket.