PRISM (Proactive Remediation & Intelligent Software Monitor)
Role: Solo, end-to-end. architecture, analysis pipeline, compression engine, CLI, reporting
Tech Stack: Python 3.10+, Playwright, AsyncIO, Pydantic, OpenAI/Anthropic/Gemini/Ollama, Pytest
Repository: Private. Demo available on request
Overview
PRISM is a modular, AI-powered web quality analysis platform. The name is literal: just as a glass prism refracts white light into a visible spectrum, PRISM takes the raw state of a web app and splits it through specialized Spectral Modules, each analyzing a different āwavelengthā of software quality.
Most web analysis tools do one thing. Lighthouse checks performance. axe-core checks accessibility. Visual regression tools compare screenshots. PRISM runs a unified pipeline where responsive design, accessibility, performance, security, SEO, and localization all go through the same capture-compress-analyze architecture, and each module produces copy-paste-ready artifacts (CSS fixes, HTML snippets, config files) rather than vague recommendations.
The system captures pages across multiple device viewports in parallel, runs a compression pipeline that cuts token costs by 70-90%, sends compressed data to specialist LLM agents for analysis, and then synthesizes findings across viewports into actionable output.
System Architecture
PRISM uses a capture-compress-analyze pipeline: Playwright captures raw page state, a compression engine strips it down to what matters, and parallel LLM agents analyze each viewport before a synthesis step resolves cross-viewport conflicts.
graph TD
subgraph "Capture Layer"
A[Target URL] --> B[Playwright Browser Manager]
B -->|Parallel Viewports| C[Mobile Capture]
B -->|Parallel Viewports| D[Tablet Capture]
B -->|Parallel Viewports| E[Desktop Capture]
end
subgraph "Compression Layer"
C --> F{Smart Compressor}
D --> F
E --> F
F -->|PII Scrubbing| G[Violet Hook]
F -->|DOM Skeleton| H[HTML Compression]
F -->|Style Summary| I[CSS Compression]
F -->|Screenshot Chunks| J[Image Optimization]
end
subgraph "Analysis Pipeline"
H --> K[ViewportAgent - Mobile]
H --> L[ViewportAgent - Tablet]
H --> M[ViewportAgent - Desktop]
K --> N[InterpreterAgent]
L --> N
M --> N
N --> O[Unified Report + CSS Artifacts]
end
K -.-> P[OpenAI GPT]
K -.-> Q[Anthropic Claude]
K -.-> R[Google Gemini]
K -.-> S[Local via Ollama]
Components
- Smart Compressor: the economic engine of the whole thing. Extracts DOM skeletons via BeautifulSoup, counts class usage, identifies layout patterns (grid/flex), summarizes form elements, compresses CSS via cssutils. Tall screenshots get split into overlapping viewport-height chunks for better LLM vision analysis. Reduces LLM token volume by 70-90%.
- ViewportAgent: takes compressed data for a single viewport, builds structured prompts, sends to the configured LLM with screenshot images, and validates responses against a Pydantic
ViewportReportschema. Runs in parallel viaasyncio.gather. - InterpreterAgent: synthesizes all viewport reports into unified recommendations, resolving conflicts (a hamburger menu is correct on mobile but a bug on desktop).
- LLM Provider Layer: abstract
LLMProviderbase class with concrete implementations for OpenAI, Anthropic, and local Ollama. Supports vision, streaming, retry logic, prompt caching, and model snapshot pinning for production reproducibility. Tiered pricing configs (best/balanced/cheapest). - Device Classification: loads from a curated
device_classes.jsonwith 2024-2025 market data. Maps viewport widths to device classes so responsive logic can be validated in context.
The Spectral Module System
Each analysis dimension maps to a color in the visible light spectrum. This isnāt branding, itās the architecture. Test directories, documentation, and the plugin system are all organized by color.
| Color | Module | Persona | Focus | Artifact |
|---|---|---|---|---|
| White | Core | Orchestrator | The prism itself: capture, compression, LLM gateway, pipeline coordination | (none) |
| Red | Regression | QA Engineer | Visual stability via pixel diffing (Pillow), stable test locator generation from DOM analysis | regression_diff.png |
| Orange | Discovery | Marketer | SEO and social: meta tags, Open Graph, JSON-LD, keyword density | head_tags_snippet.html |
| Yellow | Velocity | SRE | Performance: Core Web Vitals (LCP, CLS), asset optimization, bottleneck analysis | optimize_assets.sh, aspect-ratios.css |
| Green | Access | Advocate | WCAG 2.1 AA/AAA via axe-core, semantic HTML, keyboard nav, color contrast, screen reader simulation | a11y_remediation.md |
| Blue | Viewport | Designer | Responsive design: multi-viewport capture, DOM skeleton extraction, CSS analysis, cross-viewport synthesis | css_recommendations.css |
| Indigo | Global | Translator | Localization: i18n, RTL layout, pseudo-localization, hardcoded string detection | i18n_strings.json, logical_props.css |
| Violet | Fortress | SecOps | Security: PII scrubbing before data reaches any LLM, HTTP security header analysis | security_headers.conf, redacted_dom.html |
Every module follows a āPipelines, Not Enginesā philosophy: wrap proven tools (Pillow for pixel diffs, BeautifulSoup for DOM parsing, axe-core for accessibility, regex/presidio for PII detection) rather than rebuilding from scratch. The LLMās job is reasoning about why things broke and synthesizing findings, not detection.
Engineering Details
1. Smart Compression (The Economic Enabler)
Sending full HTML, CSS, and high-res screenshots to LLM APIs is prohibitively expensive. Without optimization the whole concept is a non-starter. So I built a dedicated compression pipeline that cuts token volume by 70-90% while preserving the signal LLMs actually need.
- HTML reduces to a structural DOM skeleton: tag hierarchy, class usage counts, ID extraction, form element summaries, layout pattern detection (grid/flex).
- CSS is compressed via cssutils, stripping redundancy while preserving responsive breakpoints.
- Screenshots get chunked intelligently into overlapping viewport-height segments. LLMs analyze images better at native resolution than as a massively scaled-down full-page capture.
- Token usage is calculated before sending requests so budgets donāt get blown.
This compression is what makes every other module economically viable. Without it, PRISM is an interesting prototype. With it, itās a tool you can actually run on every deploy.
2. Multi-Agent Viewport Analysis
A single LLM call analyzing all viewports at once produces vague, unfocused output. But separate analyses contradict each other. So I built a two-stage agent pipeline: parallel specialist analysis followed by cross-viewport synthesis.
ViewportAgentinstances run in parallel viaasyncio.gather, each analyzing a single viewport with device-specific context.- Each agentās response is validated against a Pydantic
ViewportReportschema, structured, parseable, no loose JSON drift. - The
InterpreterAgentreceives all viewport reports and resolves conflicts: is a missing sidebar a bug (desktop) or correct behavior (mobile)? - Final output includes unified CSS recommendations, an HTML report with collapsible viewport sections and screenshot thumbnails, and a markdown master plan.
3. Privacy-First PII Scrubbing
Web pages contain sensitive data, emails, phone numbers, API keys, SSNs. Sending raw page content to external LLMs is a real privacy risk. So the Violet moduleās PII scrubber runs deterministically before any data reaches an LLM.
- Regex-based detection for emails, SSNs, API keys, and phone numbers.
- Scrubbing happens in the compression layer, upstream of the analysis pipeline. There is no code path where raw PII reaches a provider API.
- Not optional, not configurable. Runs by default on every analysis.
4. Provider Abstraction with Production Pinning
Different LLM providers have different SDKs, payload formats, vision capabilities, and pricing. The system has to work with any provider without vendor lock-in. Abstract LLMProvider base class with concrete implementations that normalize inputs and outputs.
class LLMProvider(ABC):
@abstractmethod
async def chat(self, messages: list[dict], system: str = None) -> str:
pass
@abstractmethod
async def analyze_image(self, image_b64: str, prompt: str) -> dict:
pass
# Swap providers with a config change
class OpenAIProvider(LLMProvider): ...
class ClaudeProvider(LLMProvider): ...
class GeminiProvider(LLMProvider): ...
class OllamaProvider(LLMProvider): ...
- Tiered pricing configs (best/balanced/cheapest) let users choose their cost-quality tradeoff.
- Model snapshot pinning keeps production analyses reproducible across runs.
Current State
PRISM is an active, evolving project. The core pipeline and Blue (Viewport/Design) module are production-complete. Other modules are at various stages:
- Built: White (Core), Blue (Viewport), full capture-compress-analyze pipeline with multi-viewport synthesis and HTML reporting
- Partially Built: Red (Regression), pixel diffing via Pillow implemented; Violet (Fortress), PII scrubbing implemented in compression layer
- Planned: Green (Access), Orange (Discovery), Yellow (Velocity), Indigo (Global)
- Test Coverage: 303+ tests passing across core, blue, red, and violet modules
Tech Stack
- Core: Python 3.10+, AsyncIO
- Automation: Microsoft Playwright
- AI/LLM: OpenAI, Anthropic Claude, Google Gemini, Ollama (local inference), provider-agnostic with tiered pricing
- Compression: BeautifulSoup, cssutils, Pillow
- Validation: Pydantic (config and response schemas)
- Testing: Pytest, Pytest-Asyncio (303+ tests)
- DevOps: Docker, GitHub Actions