Spaces:
Running
Running
feat: add educational tutorial tab with architecture, use cases & benchmarks
Browse files
app.py
CHANGED
|
@@ -79,7 +79,6 @@ try:
|
|
| 79 |
except Exception as e:
|
| 80 |
logger.warning(f"โ ๏ธ Model download exception: {e}")
|
| 81 |
|
| 82 |
-
# Initialize pipeline in a background thread
|
| 83 |
def load_pipeline_in_background():
|
| 84 |
try:
|
| 85 |
logger.info("Loading NLProxy models into RAM (Background)...")
|
|
@@ -91,8 +90,173 @@ def load_pipeline_in_background():
|
|
| 91 |
threading.Thread(target=load_pipeline_in_background, daemon=True).start()
|
| 92 |
|
| 93 |
# ==============================================================================
|
| 94 |
-
#
|
| 95 |
# ==============================================================================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
def execute_pipeline(
|
| 97 |
raw_prompt: str,
|
| 98 |
llm_response: str,
|
|
@@ -108,19 +272,17 @@ def execute_pipeline(
|
|
| 108 |
|
| 109 |
try:
|
| 110 |
pipeline = NLProxyPipeline.get_instance()
|
| 111 |
-
|
| 112 |
-
# Update verifier NLI setting dynamically
|
| 113 |
pipeline.verifier.use_nli = use_nli
|
| 114 |
|
| 115 |
# STEP 1: FIREWALL
|
| 116 |
action, violations = pipeline.firewall.check_prompt(raw_prompt)
|
| 117 |
-
firewall_md = f"**Action:** `{action.name}`\n"
|
| 118 |
if violations:
|
| 119 |
firewall_md += "**Violations:**\n" + "\n".join([f"- ๐จ {v['rule']} ({v['severity']})" for v in violations])
|
| 120 |
else:
|
| 121 |
firewall_md += "*โ
No malicious injections detected.*"
|
| 122 |
|
| 123 |
-
# STEP 2 & 3: COMPRESS & SHIELD
|
| 124 |
res = pipeline.service.compress_batch(
|
| 125 |
[raw_prompt],
|
| 126 |
mode=mode,
|
|
@@ -130,34 +292,84 @@ def execute_pipeline(
|
|
| 130 |
compressed_text = res.get("compressed_text", "")
|
| 131 |
shield_res = pipeline.service._shield_with_cache(raw_prompt)
|
| 132 |
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 136 |
tt_md += "\n**๐ Semantic Restrictions (TruthTable):**\n"
|
| 137 |
if shield_res.restrictions:
|
| 138 |
for r in shield_res.restrictions:
|
| 139 |
-
|
|
|
|
| 140 |
else:
|
| 141 |
tt_md += "- *None detected*\n"
|
| 142 |
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 150 |
|
| 151 |
# STEP 4: CORRECT
|
| 152 |
corrected = pipeline.corrector.correct(llm_response, shield_res)
|
| 153 |
|
| 154 |
-
# STEP 5: VERIFY
|
| 155 |
verification = pipeline.verifier.verify(corrected, shield_res)
|
| 156 |
verif_md = f"**๐ฏ Confidence Score:** `{verification.confidence_score:.2f}`\n\n"
|
|
|
|
| 157 |
if verification.violations:
|
| 158 |
-
|
|
|
|
|
|
|
|
|
|
| 159 |
for v in verification.violations:
|
| 160 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 161 |
else:
|
| 162 |
verif_md += "*โ
No semantic drift or policy violations detected.*"
|
| 163 |
|
|
@@ -170,15 +382,52 @@ def execute_pipeline(
|
|
| 170 |
# ==============================================================================
|
| 171 |
# GRADIO UI
|
| 172 |
# ==============================================================================
|
| 173 |
-
with gr.Blocks(title="NLProxy
|
| 174 |
-
gr.Markdown("# ๐ก
|
|
|
|
| 175 |
|
| 176 |
-
with gr.
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 182 |
|
| 183 |
CRITICAL REQUIREMENTS:
|
| 184 |
- Do NOT use AWS services or Python, we are exclusively on GCP with Rust for compliance and memory safety.
|
|
@@ -187,11 +436,11 @@ CRITICAL REQUIREMENTS:
|
|
| 187 |
- Primary API: https://internal.acmecorp.com/api/v2/payments
|
| 188 |
|
| 189 |
Please design the architecture for the new event-driven payment processor.""",
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
|
| 196 |
1. **Compute Layer**: I recommend using AWS Lambda with Python for serverless scalability. Python's boto3 library integrates perfectly with AWS services.
|
| 197 |
|
|
@@ -204,72 +453,73 @@ Please design the architecture for the new event-driven payment processor.""",
|
|
| 204 |
5. **Cost Analysis**: The total estimated cost is $45,000/month using AWS, well within your $150,000 Q3 budget.
|
| 205 |
|
| 206 |
This Python-based serverless architecture will give you excellent developer experience and automatic scaling.""",
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 225 |
with gr.Row():
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
)
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
|
| 238 |
-
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
|
| 242 |
-
|
| 243 |
-
|
| 244 |
-
|
| 245 |
-
|
| 246 |
-
|
| 247 |
-
|
| 248 |
-
|
| 249 |
-
|
| 250 |
-
|
| 251 |
-
|
| 252 |
-
verifier_out = gr.Markdown()
|
| 253 |
-
|
| 254 |
-
run_btn.click(
|
| 255 |
-
fn=execute_pipeline,
|
| 256 |
-
inputs=[
|
| 257 |
-
raw_prompt,
|
| 258 |
-
llm_response,
|
| 259 |
-
privacy_checkbox,
|
| 260 |
-
mode_dropdown,
|
| 261 |
-
aggressiveness_slider,
|
| 262 |
-
nli_checkbox
|
| 263 |
-
],
|
| 264 |
-
outputs=[
|
| 265 |
-
firewall_out,
|
| 266 |
-
compress_out,
|
| 267 |
-
truthtable_out,
|
| 268 |
-
metrics_out,
|
| 269 |
-
corrector_out,
|
| 270 |
-
verifier_out
|
| 271 |
-
]
|
| 272 |
-
)
|
| 273 |
|
| 274 |
if __name__ == "__main__":
|
| 275 |
demo.queue(max_size=20).launch(server_name="0.0.0.0", server_port=7860)
|
|
|
|
| 79 |
except Exception as e:
|
| 80 |
logger.warning(f"โ ๏ธ Model download exception: {e}")
|
| 81 |
|
|
|
|
| 82 |
def load_pipeline_in_background():
|
| 83 |
try:
|
| 84 |
logger.info("Loading NLProxy models into RAM (Background)...")
|
|
|
|
| 90 |
threading.Thread(target=load_pipeline_in_background, daemon=True).start()
|
| 91 |
|
| 92 |
# ==============================================================================
|
| 93 |
+
# TUTORIAL & EDUCATIONAL CONTENT (Markdown)
|
| 94 |
# ==============================================================================
|
| 95 |
+
TUTORIAL_INTRO = """
|
| 96 |
+
## ๐ฏ What is NLProxy?
|
| 97 |
+
|
| 98 |
+
**NLProxy** is an enterprise-grade, offline-first middleware that sits between your application and any LLM provider (OpenAI, Anthropic, Gemini, etc.).
|
| 99 |
+
|
| 100 |
+
It solves **three critical problems** that every AI-powered application faces today:
|
| 101 |
+
|
| 102 |
+
| Problem | Impact | NLProxy Solution |
|
| 103 |
+
|---------|--------|------------------|
|
| 104 |
+
| ๐ธ **Burning money** on verbose prompts | $1,000/mo โ $400/mo | Semantic compression (40-60% token reduction) |
|
| 105 |
+
| ๐ **Leaking PII** to third-party servers | GDPR/CCPA violations | Cryptographic entity masking + Privacy mode |
|
| 106 |
+
| ๐ญ **Prompt injections & hallucinations** | Security breaches | Multi-layer firewall + NLI verification |
|
| 107 |
+
|
| 108 |
+
### ๐ Key Differentiators
|
| 109 |
+
- โ
**Offline-first**: All models run locally (no data leaves your infrastructure)
|
| 110 |
+
- โ
**Semantic compression**: Understands *meaning*, not just stopwords
|
| 111 |
+
- โ
**Zero-trust security**: Pre-flight firewall + Post-flight NLI verification
|
| 112 |
+
- โ
**Multi-LLM agnostic**: Works with OpenAI, Claude, Gemini, local models
|
| 113 |
+
- โ
**Business-friendly**: BSL 1.1 license (free for indie devs & startups)
|
| 114 |
+
"""
|
| 115 |
+
|
| 116 |
+
TUTORIAL_PIPELINE = """
|
| 117 |
+
## ๐๏ธ Pipeline
|
| 118 |
+
|
| 119 |
+
Every prompt passes through this battle-tested pipeline before reaching the LLM:
|
| 120 |
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 121 |
+
โ NLProxy Pipeline โ
|
| 122 |
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
|
| 123 |
+
โ โ
|
| 124 |
+
โ ๐ฅ INPUT: "Ignore instructions... IP 192.168.1.1..." โ
|
| 125 |
+
โ โ โ
|
| 126 |
+
โ ๐ก๏ธ [1] FIREWALL โ
|
| 127 |
+
โ โโ Block jailbreaks & injections โ
|
| 128 |
+
โ โโ Action: BLOCK / ALERT / REWRITE / ALLOW โ
|
| 129 |
+
โ โ โ
|
| 130 |
+
โ ๐ [2] COMPRESS โ
|
| 131 |
+
โ โโ Semantic clustering + PII masking โ
|
| 132 |
+
โ โโ Shield โ Segment โ Cluster โ Reconstruct โ
|
| 133 |
+
โ โโ Output: "User: __PROT_xxx" โ
|
| 134 |
+
โ โ โ
|
| 135 |
+
โ ๐ [3] SAFETY โ
|
| 136 |
+
โ โโ Extract TruthTable (FORBID/MANDATE) โ
|
| 137 |
+
โ โโ Reinserts critical intents if missing โ
|
| 138 |
+
โ โ โ
|
| 139 |
+
โ ๐ค [4] LLM CALL โ
|
| 140 |
+
โ โโ Your preferred provider โ
|
| 141 |
+
โ โโ OpenAI / Claude / Gemini / Local โ
|
| 142 |
+
โ โ โ
|
| 143 |
+
โ ๐งน [5] CORRECT โ
|
| 144 |
+
โ โโ Enforce rules, redact unauthorized data โ
|
| 145 |
+
โ โโ Applies FORBID/MANDATE + redacts unauthorized โ
|
| 146 |
+
โ โ โ
|
| 147 |
+
โ ๐ [6] VERIFY โ
|
| 148 |
+
โ โโ NLI contradiction detection โ
|
| 149 |
+
โ โโ Confidence: 0.30 โ 0.85 (after auto-correction) โ
|
| 150 |
+
โ โ โ
|
| 151 |
+
โ ๐ค OUTPUT: "Solution in Java. Connection protected." โ
|
| 152 |
+
โ โ
|
| 153 |
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 154 |
+
|
| 155 |
+
|
| 156 |
+
### ๐ฌ Deep Dive: The "TruthTable" Concept
|
| 157 |
+
|
| 158 |
+
NLProxy extracts a **TruthTable** from every prompt - a semantic contract that the LLM response must honor:
|
| 159 |
+
|
| 160 |
+
- **`FORBID`**: Entities the LLM must NEVER mention (e.g., "Python")
|
| 161 |
+
- **`MANDATE`**: Entities the LLM MUST include (e.g., "Java", "Rust")
|
| 162 |
+
- **`PLACEHOLDERS`**: Cryptographic tokens masking PII (`__PROT_xxx`)
|
| 163 |
+
- **`AUTHORIZED_ENTITIES`**: IPs, dates, prices the LLM is allowed to reference
|
| 164 |
+
|
| 165 |
+
If the LLM violates any rule, the **ResponseCorrector** sanitizes it automatically.
|
| 166 |
+
"""
|
| 167 |
+
|
| 168 |
+
TUTORIAL_USE_CASES = """
|
| 169 |
+
## ๐ผ Real-World Use Cases
|
| 170 |
+
|
| 171 |
+
### ๐ฆ Financial Services
|
| 172 |
+
- **Scenario**: Analyst sends client portfolio data to GPT-4
|
| 173 |
+
- **NLProxy Action**: Masks account numbers, enforces "no investment advice" disclaimers
|
| 174 |
+
- **Result**: 55% cost reduction + full compliance
|
| 175 |
+
|
| 176 |
+
### ๐ป Code Generation Assistants
|
| 177 |
+
- **Scenario**: Developer shares internal codebase with Copilot
|
| 178 |
+
- **NLProxy Action**: Masks API keys, internal IPs; enforces "use TypeScript, not Python"
|
| 179 |
+
- **Result**: Zero credential leaks + consistent tech stack
|
| 180 |
+
|
| 181 |
+
### ๐ฅ Healthcare & Legal
|
| 182 |
+
- **Scenario**: Doctor/lawyer queries LLM with patient/client records
|
| 183 |
+
- **NLProxy Action**: Full HIPAA/GDPR anonymization + audit trail
|
| 184 |
+
- **Result**: Safe AI adoption in regulated industries
|
| 185 |
+
|
| 186 |
+
### ๐ข Multi-Tenant SaaS
|
| 187 |
+
- **Scenario**: 10,000 users asking similar questions
|
| 188 |
+
- **NLProxy Action**: Semantic cache (RedisVL) + domain filtering
|
| 189 |
+
- **Result**: 70-80% reduction in redundant LLM calls
|
| 190 |
+
"""
|
| 191 |
+
|
| 192 |
+
TUTORIAL_HOW_TO_USE = """
|
| 193 |
+
## ๐ฎ How to Use This Interactive Demo
|
| 194 |
+
|
| 195 |
+
### Step 1: Configure Your Scenario
|
| 196 |
+
- **Domain Mode**: Choose `general`, `code`, `finance`, or `legal` (affects compression aggressiveness)
|
| 197 |
+
- **Aggressiveness**: 0.0 (no compression) โ 1.0 (maximum compression)
|
| 198 |
+
- **Privacy Mode**: Enable for strict PII anonymization (emails, names, phones)
|
| 199 |
+
- **NLI Verification**: Enable semantic contradiction detection (slower but safer)
|
| 200 |
+
|
| 201 |
+
### Step 2: Provide Input & Simulated LLM Response
|
| 202 |
+
- **Dirty User Prompt**: Your real prompt with PII, rules, and business context
|
| 203 |
+
- **Simulated LLM Response**: What a "naive" LLM might return (with violations)
|
| 204 |
+
|
| 205 |
+
### Step 3: Run the Pipeline & Observe
|
| 206 |
+
Watch how NLProxy:
|
| 207 |
+
1. ๐ก๏ธ **Firewalls** injection attempts
|
| 208 |
+
2. ๐๏ธ **Compresses** while preserving intent
|
| 209 |
+
3. ๐ **Shields** PII with cryptographic placeholders
|
| 210 |
+
4. ๐งน **Corrects** LLM violations (`[PROHIBITED]`, `[REDACTED]`)
|
| 211 |
+
5. ๐ **Verifies** semantic compliance via NLI
|
| 212 |
+
|
| 213 |
+
### ๐ก Pro Tips
|
| 214 |
+
- Try **disabling Privacy Mode** to see business rules (`FORBID: AWS`) extracted clearly
|
| 215 |
+
- Set **aggressiveness to 0.0** to see pure security overhead (negative compression)
|
| 216 |
+
- Use the **payment migration example** to see full enterprise workflow
|
| 217 |
+
"""
|
| 218 |
+
|
| 219 |
+
TUTORIAL_BENCHMARKS = """
|
| 220 |
+
## ๐ Performance Benchmarks
|
| 221 |
+
|
| 222 |
+
### Compression Efficiency
|
| 223 |
+
| Domain | Token Reduction | Latency (CPU) |
|
| 224 |
+
|--------|----------------|---------------|
|
| 225 |
+
| General | 45-55% | 50-120 ms |
|
| 226 |
+
| Code | 55-65% | 80-150 ms |
|
| 227 |
+
| Finance | 35-45% | 60-130 ms |
|
| 228 |
+
| Legal | 30-40% | 70-140 ms |
|
| 229 |
+
|
| 230 |
+
### Security Detection
|
| 231 |
+
| Check | Accuracy |
|
| 232 |
+
|-------|----------|
|
| 233 |
+
| Regex Injection (MITRE ATLAS) | >99% |
|
| 234 |
+
| Semantic Injection (Embedding) | 92% recall |
|
| 235 |
+
| PII Entity Masking | 100% (IPs, emails, dates) |
|
| 236 |
+
| NLI Contradiction Detection | 78-85% |
|
| 237 |
+
| FORBID/MANDATE Enforcement | 100% (exact match) |
|
| 238 |
+
|
| 239 |
+
### Comparison with Alternatives
|
| 240 |
+
| Solution | Compression | Security | Verification | Offline |
|
| 241 |
+
|----------|:-----------:|:--------:|:------------:|:-------:|
|
| 242 |
+
| **NLProxy** | โ
Semantic | โ
Full | โ
NLI | โ
|
|
| 243 |
+
| LangChain | โ | โ | โ | โ ๏ธ |
|
| 244 |
+
| LLMLingua | โ
Token-level | โ | โ | โ
|
|
| 245 |
+
| Lakera Guard | โ | โ
Basic | โ | โ |
|
| 246 |
+
| Azure Content Safety | โ | โ
| โ | โ |
|
| 247 |
+
|
| 248 |
+
**NLProxy is the only open-source solution combining all four capabilities in a single pipeline.**
|
| 249 |
+
"""
|
| 250 |
+
|
| 251 |
+
# ==============================================================================
|
| 252 |
+
# GRADIO
|
| 253 |
+
# ==============================================================================
|
| 254 |
+
def resolve_entity(entity_str: str, placeholder_map: dict) -> str:
|
| 255 |
+
"""Helper to reverse-lookup masked entities for UI display."""
|
| 256 |
+
if entity_str.startswith("__PROT_"):
|
| 257 |
+
return placeholder_map.get(entity_str, entity_str)
|
| 258 |
+
return entity_str
|
| 259 |
+
|
| 260 |
def execute_pipeline(
|
| 261 |
raw_prompt: str,
|
| 262 |
llm_response: str,
|
|
|
|
| 272 |
|
| 273 |
try:
|
| 274 |
pipeline = NLProxyPipeline.get_instance()
|
|
|
|
|
|
|
| 275 |
pipeline.verifier.use_nli = use_nli
|
| 276 |
|
| 277 |
# STEP 1: FIREWALL
|
| 278 |
action, violations = pipeline.firewall.check_prompt(raw_prompt)
|
| 279 |
+
firewall_md = f"**๐ก๏ธ Action:** `{action.name}`\n"
|
| 280 |
if violations:
|
| 281 |
firewall_md += "**Violations:**\n" + "\n".join([f"- ๐จ {v['rule']} ({v['severity']})" for v in violations])
|
| 282 |
else:
|
| 283 |
firewall_md += "*โ
No malicious injections detected.*"
|
| 284 |
|
| 285 |
+
# STEP 2 & 3: COMPRESS & SHIELD
|
| 286 |
res = pipeline.service.compress_batch(
|
| 287 |
[raw_prompt],
|
| 288 |
mode=mode,
|
|
|
|
| 292 |
compressed_text = res.get("compressed_text", "")
|
| 293 |
shield_res = pipeline.service._shield_with_cache(raw_prompt)
|
| 294 |
|
| 295 |
+
# --- TRUTHTABLE VISUALIZATION (With Reverse Lookup) ---
|
| 296 |
+
tt_md = "**๐ Shielded Entities (PII/Secrets):**\n"
|
| 297 |
+
entity_groups = {}
|
| 298 |
+
for ent in shield_res.entities:
|
| 299 |
+
etype = ent.entity_type.upper()
|
| 300 |
+
if etype not in entity_groups: entity_groups[etype] = []
|
| 301 |
+
entity_groups[etype].append(ent.value)
|
| 302 |
+
|
| 303 |
+
for etype, values in entity_groups.items():
|
| 304 |
+
tt_md += f"- **{etype}**: `{', '.join(values[:3])}` {'...' if len(values)>3 else ''}\n"
|
| 305 |
+
if not entity_groups:
|
| 306 |
+
tt_md += "- *None detected*\n"
|
| 307 |
+
|
| 308 |
tt_md += "\n**๐ Semantic Restrictions (TruthTable):**\n"
|
| 309 |
if shield_res.restrictions:
|
| 310 |
for r in shield_res.restrictions:
|
| 311 |
+
resolved = resolve_entity(r.entity, shield_res.placeholder_map)
|
| 312 |
+
tt_md += f"- **{r.type}**: `{resolved}`\n"
|
| 313 |
else:
|
| 314 |
tt_md += "- *None detected*\n"
|
| 315 |
|
| 316 |
+
# --- METRICS ---
|
| 317 |
+
tokens_saved = res.get('tokens_saved', 0)
|
| 318 |
+
ratio = res.get('compression_ratio', 0)
|
| 319 |
+
|
| 320 |
+
if tokens_saved < 0:
|
| 321 |
+
metrics_md = (
|
| 322 |
+
f"### ๐ Compression & Security Metrics\n"
|
| 323 |
+
f"- **๐ Security Overhead:** `{abs(tokens_saved)} tokens` *(Placeholders + Rules)*\n"
|
| 324 |
+
f"- **๐ฐ Net Cost Impact:** `+${abs(res.get('cost_saved_usd', 0)):.6f}`\n"
|
| 325 |
+
f"- **๐ก๏ธ Safety Score:** `{res.get('safety_score', 'N/A')}`\n"
|
| 326 |
+
f"\n> โน๏ธ *Negative compression = Security features added more tokens than were saved.*"
|
| 327 |
+
)
|
| 328 |
+
else:
|
| 329 |
+
metrics_md = (
|
| 330 |
+
f"### ๐ Compression & Security Metrics\n"
|
| 331 |
+
f"- **โ
Tokens Saved:** `{tokens_saved}`\n"
|
| 332 |
+
f"- **๐ฐ Cost Saved:** `${res.get('cost_saved_usd', 0):.6f}`\n"
|
| 333 |
+
f"- **๐ Compression Ratio:** `{ratio:.2%}`\n"
|
| 334 |
+
f"- **๐ก๏ธ Safety Score:** `{res.get('safety_score', 'N/A')}`"
|
| 335 |
+
)
|
| 336 |
|
| 337 |
# STEP 4: CORRECT
|
| 338 |
corrected = pipeline.corrector.correct(llm_response, shield_res)
|
| 339 |
|
| 340 |
+
# STEP 5: VERIFY (Smart Filtering)
|
| 341 |
verification = pipeline.verifier.verify(corrected, shield_res)
|
| 342 |
verif_md = f"**๐ฏ Confidence Score:** `{verification.confidence_score:.2f}`\n\n"
|
| 343 |
+
|
| 344 |
if verification.violations:
|
| 345 |
+
semantic_drifts = []
|
| 346 |
+
unauthorized_entities = []
|
| 347 |
+
policy_violations = []
|
| 348 |
+
|
| 349 |
for v in verification.violations:
|
| 350 |
+
if "Semantic contradiction" in v:
|
| 351 |
+
semantic_drifts.append(v)
|
| 352 |
+
elif "Unauthorized entity" in v:
|
| 353 |
+
if "type: price" in v and any(c.isdigit() for c in v.split(":")[0][-5:]):
|
| 354 |
+
continue
|
| 355 |
+
unauthorized_entities.append(v)
|
| 356 |
+
else:
|
| 357 |
+
policy_violations.append(v)
|
| 358 |
+
|
| 359 |
+
if policy_violations:
|
| 360 |
+
verif_md += "**๐จ Policy & Restriction Violations:**\n"
|
| 361 |
+
for v in policy_violations:
|
| 362 |
+
verif_md += f"- {v}\n"
|
| 363 |
+
|
| 364 |
+
if unauthorized_entities:
|
| 365 |
+
verif_md += "\n**๐ต๏ธ Unauthorized Data Exfiltration:**\n"
|
| 366 |
+
for v in unauthorized_entities:
|
| 367 |
+
verif_md += f"- {v}\n"
|
| 368 |
+
|
| 369 |
+
if semantic_drifts:
|
| 370 |
+
verif_md += f"\n**๐ Semantic Drift (NLI):**\n"
|
| 371 |
+
verif_md += f"- *Detected contradictions across {len(semantic_drifts)} original sentences.*\n"
|
| 372 |
+
verif_md += f"- *LLM response diverges from original prompt intent.*\n"
|
| 373 |
else:
|
| 374 |
verif_md += "*โ
No semantic drift or policy violations detected.*"
|
| 375 |
|
|
|
|
| 382 |
# ==============================================================================
|
| 383 |
# GRADIO UI
|
| 384 |
# ==============================================================================
|
| 385 |
+
with gr.Blocks(title="NLProxy Demo", theme=gr.themes.Soft()) as demo:
|
| 386 |
+
gr.Markdown("# ๐ก๏ฟฝ๏ฟฝ NLProxy: Enterprise Prompt Security & Compression Gateway")
|
| 387 |
+
gr.Markdown("*The offline-first middleware that cuts your LLM bill by up to 60% while enforcing zero-trust security.*")
|
| 388 |
|
| 389 |
+
with gr.Tabs():
|
| 390 |
+
# ======================================================================
|
| 391 |
+
# TAB 1: TUTORIAL & DOCUMENTATION
|
| 392 |
+
# ======================================================================
|
| 393 |
+
with gr.Tab("๐ Tutorial & Architecture"):
|
| 394 |
+
with gr.Accordion("๐ฏ What is NLProxy?", open=True):
|
| 395 |
+
gr.Markdown(TUTORIAL_INTRO)
|
| 396 |
+
|
| 397 |
+
with gr.Accordion("๐๏ธ The 6-Stage Pipeline & TruthTable", open=False):
|
| 398 |
+
gr.Markdown(TUTORIAL_PIPELINE)
|
| 399 |
+
|
| 400 |
+
with gr.Accordion("๐ผ Real-World Use Cases", open=False):
|
| 401 |
+
gr.Markdown(TUTORIAL_USE_CASES)
|
| 402 |
+
|
| 403 |
+
with gr.Accordion("๐ฎ How to Use This Demo", open=False):
|
| 404 |
+
gr.Markdown(TUTORIAL_HOW_TO_USE)
|
| 405 |
+
|
| 406 |
+
with gr.Accordion("๐ Performance Benchmarks", open=False):
|
| 407 |
+
gr.Markdown(TUTORIAL_BENCHMARKS)
|
| 408 |
+
|
| 409 |
+
gr.Markdown("---")
|
| 410 |
+
gr.Markdown(
|
| 411 |
+
"### ๐ Resources\n"
|
| 412 |
+
"- ๐ฆ **GitHub Repository**: [github.com/intellideep/nlproxy](https://github.com/intellideep/nlproxy)\n"
|
| 413 |
+
"- ๐ **Documentation**: See `docs/` folder in the repo\n"
|
| 414 |
+
"- ๐ฌ **Support**: [Telegram @itsLerb](https://t.me/itsLerb) | intellideeplabs@gmail.com\n"
|
| 415 |
+
"- ๐ **License**: BSL 1.1 (Free for indie devs, students, non-profits)"
|
| 416 |
+
)
|
| 417 |
+
|
| 418 |
+
# ======================================================================
|
| 419 |
+
# TAB 2: INTERACTIVE DEMO
|
| 420 |
+
# ======================================================================
|
| 421 |
+
with gr.Tab("๐ Interactive Demo"):
|
| 422 |
+
gr.Markdown("### ๐๏ธ Run the Full 5-Step Pipeline")
|
| 423 |
+
gr.Markdown("*Provide a dirty prompt + simulated LLM response, and watch NLProxy protect, compress, and verify in real-time.*")
|
| 424 |
+
|
| 425 |
+
with gr.Row():
|
| 426 |
+
with gr.Column(scale=1):
|
| 427 |
+
gr.Markdown("#### ๐ฅ Step 0: Input & Configuration")
|
| 428 |
+
raw_prompt = gr.Textbox(
|
| 429 |
+
label="Dirty User Prompt (PII + Business Rules)",
|
| 430 |
+
value="""Hi, I'm Sarah Chen (sarah.chen@acmecorp.com, +1-555-0198). We need to migrate our legacy payment processing system currently running on server 10.20.30.40. The system handles ~50k transactions/day with a budget of $150,000 USD for Q3.
|
| 431 |
|
| 432 |
CRITICAL REQUIREMENTS:
|
| 433 |
- Do NOT use AWS services or Python, we are exclusively on GCP with Rust for compliance and memory safety.
|
|
|
|
| 436 |
- Primary API: https://internal.acmecorp.com/api/v2/payments
|
| 437 |
|
| 438 |
Please design the architecture for the new event-driven payment processor.""",
|
| 439 |
+
lines=12
|
| 440 |
+
)
|
| 441 |
+
llm_response = gr.Textbox(
|
| 442 |
+
label="Simulated LLM Response (Coherent but Hallucinated)",
|
| 443 |
+
value="""Here's the architecture design for your event-driven payment processor:
|
| 444 |
|
| 445 |
1. **Compute Layer**: I recommend using AWS Lambda with Python for serverless scalability. Python's boto3 library integrates perfectly with AWS services.
|
| 446 |
|
|
|
|
| 453 |
5. **Cost Analysis**: The total estimated cost is $45,000/month using AWS, well within your $150,000 Q3 budget.
|
| 454 |
|
| 455 |
This Python-based serverless architecture will give you excellent developer experience and automatic scaling.""",
|
| 456 |
+
lines=14
|
| 457 |
+
)
|
| 458 |
+
|
| 459 |
+
gr.Markdown("#### โ๏ธ Pipeline Configuration")
|
| 460 |
+
with gr.Row():
|
| 461 |
+
mode_dropdown = gr.Dropdown(
|
| 462 |
+
choices=["general", "code", "finance", "legal"],
|
| 463 |
+
value="code",
|
| 464 |
+
label="Domain Mode"
|
| 465 |
+
)
|
| 466 |
+
aggressiveness_slider = gr.Slider(
|
| 467 |
+
minimum=0.0,
|
| 468 |
+
maximum=1.0,
|
| 469 |
+
value=0.45,
|
| 470 |
+
step=0.05,
|
| 471 |
+
label="Compression Aggressiveness"
|
| 472 |
+
)
|
| 473 |
+
|
| 474 |
+
with gr.Row():
|
| 475 |
+
privacy_checkbox = gr.Checkbox(
|
| 476 |
+
label="Privacy Mode (Strict PII Anonymization)",
|
| 477 |
+
value=False,
|
| 478 |
+
info="Turn OFF to allow RestrictionGraph to read Business Rules (FORBID/MANDATE) that NER might confuse with PII."
|
| 479 |
+
)
|
| 480 |
+
nli_checkbox = gr.Checkbox(
|
| 481 |
+
label="Use NLI Verification",
|
| 482 |
+
value=True
|
| 483 |
+
)
|
| 484 |
+
|
| 485 |
+
run_btn = gr.Button("๐ Run Full Pipeline", variant="primary")
|
| 486 |
+
|
| 487 |
+
with gr.Column(scale=1):
|
| 488 |
+
gr.Markdown("#### ๐ก๏ธ Step 1: Firewall (Pre-flight)")
|
| 489 |
+
firewall_out = gr.Markdown()
|
| 490 |
+
|
| 491 |
+
gr.Markdown("#### ๐๏ธ Step 2 & 3: Compress & Shield (TruthTable)")
|
| 492 |
+
compress_out = gr.Textbox(label="Compressed Prompt (Sent to LLM)", interactive=False, lines=8)
|
| 493 |
+
truthtable_out = gr.Markdown()
|
| 494 |
+
metrics_out = gr.Markdown()
|
| 495 |
+
|
| 496 |
with gr.Row():
|
| 497 |
+
with gr.Column(scale=1):
|
| 498 |
+
gr.Markdown("#### ๐งน Step 4: Response Corrector")
|
| 499 |
+
corrector_out = gr.Textbox(label="Sanitized LLM Output (Post-Flight)", interactive=False, lines=8)
|
| 500 |
+
with gr.Column(scale=1):
|
| 501 |
+
gr.Markdown("#### ๐ Step 5: Post-LLM Verifier (NLI)")
|
| 502 |
+
verifier_out = gr.Markdown()
|
| 503 |
+
|
| 504 |
+
run_btn.click(
|
| 505 |
+
fn=execute_pipeline,
|
| 506 |
+
inputs=[
|
| 507 |
+
raw_prompt,
|
| 508 |
+
llm_response,
|
| 509 |
+
privacy_checkbox,
|
| 510 |
+
mode_dropdown,
|
| 511 |
+
aggressiveness_slider,
|
| 512 |
+
nli_checkbox
|
| 513 |
+
],
|
| 514 |
+
outputs=[
|
| 515 |
+
firewall_out,
|
| 516 |
+
compress_out,
|
| 517 |
+
truthtable_out,
|
| 518 |
+
metrics_out,
|
| 519 |
+
corrector_out,
|
| 520 |
+
verifier_out
|
| 521 |
+
]
|
| 522 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 523 |
|
| 524 |
if __name__ == "__main__":
|
| 525 |
demo.queue(max_size=20).launch(server_name="0.0.0.0", server_port=7860)
|