| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>GraphRAG vs RAG vs LLM — Benchmark Dashboard</title> |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.min.js"></script> |
| <style> |
| @import url('https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&family=DM+Sans:wght@300;400;500;600&display=swap'); |
| |
| :root { |
| --bg: #0a0a0f; |
| --surface: #12121a; |
| --surface2: #1a1a26; |
| --border: #2a2a3a; |
| --accent: #6c63ff; |
| --accent2: #00d4aa; |
| --accent3: #ff6b6b; |
| --text: #e8e8f0; |
| --muted: #6b6b80; |
| --llm: #f59e0b; |
| --rag: #6c63ff; |
| --graphrag: #00d4aa; |
| } |
| |
| * { margin: 0; padding: 0; box-sizing: border-box; } |
| |
| body { |
| background: var(--bg); |
| color: var(--text); |
| font-family: 'DM Sans', sans-serif; |
| min-height: 100vh; |
| overflow-x: hidden; |
| } |
| |
| |
| body::before { |
| content: ''; |
| position: fixed; |
| inset: 0; |
| background-image: |
| linear-gradient(rgba(108,99,255,0.03) 1px, transparent 1px), |
| linear-gradient(90deg, rgba(108,99,255,0.03) 1px, transparent 1px); |
| background-size: 40px 40px; |
| pointer-events: none; |
| z-index: 0; |
| } |
| |
| .container { max-width: 1200px; margin: 0 auto; padding: 0 24px; position: relative; z-index: 1; } |
| |
| |
| header { |
| padding: 40px 0 32px; |
| border-bottom: 1px solid var(--border); |
| margin-bottom: 40px; |
| } |
| |
| .header-inner { display: flex; justify-content: space-between; align-items: flex-end; } |
| |
| .logo { |
| font-family: 'Space Mono', monospace; |
| font-size: 11px; |
| color: var(--accent); |
| letter-spacing: 3px; |
| text-transform: uppercase; |
| margin-bottom: 12px; |
| } |
| |
| h1 { |
| font-size: 36px; |
| font-weight: 600; |
| line-height: 1.1; |
| letter-spacing: -0.5px; |
| } |
| |
| h1 span { color: var(--accent2); } |
| |
| .badge { |
| background: rgba(0,212,170,0.1); |
| border: 1px solid rgba(0,212,170,0.3); |
| color: var(--accent2); |
| font-family: 'Space Mono', monospace; |
| font-size: 10px; |
| padding: 4px 10px; |
| border-radius: 2px; |
| letter-spacing: 2px; |
| } |
| |
| |
| .summary-grid { |
| display: grid; |
| grid-template-columns: repeat(4, 1fr); |
| gap: 16px; |
| margin-bottom: 40px; |
| } |
| |
| .card { |
| background: var(--surface); |
| border: 1px solid var(--border); |
| border-radius: 8px; |
| padding: 24px; |
| transition: border-color 0.2s; |
| } |
| |
| .card:hover { border-color: var(--accent); } |
| |
| .card-label { |
| font-family: 'Space Mono', monospace; |
| font-size: 10px; |
| color: var(--muted); |
| letter-spacing: 2px; |
| text-transform: uppercase; |
| margin-bottom: 12px; |
| } |
| |
| .card-value { |
| font-size: 40px; |
| font-weight: 600; |
| line-height: 1; |
| margin-bottom: 6px; |
| } |
| |
| .card-sub { font-size: 13px; color: var(--muted); } |
| |
| .green { color: var(--accent2); } |
| .purple { color: var(--accent); } |
| .amber { color: var(--llm); } |
| .red { color: var(--accent3); } |
| |
| |
| .charts-grid { |
| display: grid; |
| grid-template-columns: 1fr 1fr; |
| gap: 24px; |
| margin-bottom: 40px; |
| } |
| |
| .chart-card { |
| background: var(--surface); |
| border: 1px solid var(--border); |
| border-radius: 8px; |
| padding: 24px; |
| } |
| |
| .chart-title { |
| font-family: 'Space Mono', monospace; |
| font-size: 11px; |
| color: var(--muted); |
| letter-spacing: 2px; |
| text-transform: uppercase; |
| margin-bottom: 20px; |
| } |
| |
| .chart-wrap { position: relative; height: 220px; } |
| |
| |
| .legend { |
| display: flex; |
| gap: 20px; |
| margin-top: 16px; |
| flex-wrap: wrap; |
| } |
| |
| .legend-item { |
| display: flex; |
| align-items: center; |
| gap: 6px; |
| font-size: 12px; |
| color: var(--muted); |
| } |
| |
| .legend-dot { |
| width: 8px; height: 8px; |
| border-radius: 50%; |
| } |
| |
| |
| .table-card { |
| background: var(--surface); |
| border: 1px solid var(--border); |
| border-radius: 8px; |
| padding: 24px; |
| margin-bottom: 40px; |
| } |
| |
| .table-title { |
| font-family: 'Space Mono', monospace; |
| font-size: 11px; |
| color: var(--muted); |
| letter-spacing: 2px; |
| text-transform: uppercase; |
| margin-bottom: 20px; |
| } |
| |
| table { width: 100%; border-collapse: collapse; } |
| |
| th { |
| font-family: 'Space Mono', monospace; |
| font-size: 10px; |
| color: var(--muted); |
| letter-spacing: 1px; |
| text-align: left; |
| padding: 8px 12px; |
| border-bottom: 1px solid var(--border); |
| text-transform: uppercase; |
| } |
| |
| td { |
| padding: 14px 12px; |
| font-size: 13px; |
| border-bottom: 1px solid rgba(42,42,58,0.5); |
| vertical-align: top; |
| } |
| |
| tr:last-child td { border-bottom: none; } |
| tr:hover td { background: rgba(108,99,255,0.03); } |
| |
| .q-text { color: var(--muted); max-width: 260px; line-height: 1.4; } |
| .token-val { font-family: 'Space Mono', monospace; font-size: 12px; } |
| .reduction { font-family: 'Space Mono', monospace; font-size: 13px; font-weight: 700; } |
| .pos { color: var(--accent2); } |
| .neg { color: var(--accent3); } |
| |
| .pill { |
| display: inline-block; |
| padding: 2px 8px; |
| border-radius: 2px; |
| font-family: 'Space Mono', monospace; |
| font-size: 10px; |
| letter-spacing: 1px; |
| } |
| |
| .pill-pass { background: rgba(0,212,170,0.1); color: var(--accent2); border: 1px solid rgba(0,212,170,0.2); } |
| .pill-fail { background: rgba(255,107,107,0.1); color: var(--accent3); border: 1px solid rgba(255,107,107,0.2); } |
| |
| |
| .query-section { |
| background: var(--surface); |
| border: 1px solid var(--border); |
| border-radius: 8px; |
| padding: 24px; |
| margin-bottom: 40px; |
| } |
| |
| .query-section h3 { |
| font-family: 'Space Mono', monospace; |
| font-size: 11px; |
| color: var(--muted); |
| letter-spacing: 2px; |
| text-transform: uppercase; |
| margin-bottom: 16px; |
| } |
| |
| .input-row { display: flex; gap: 12px; margin-bottom: 16px; } |
| |
| input[type="text"] { |
| flex: 1; |
| background: var(--bg); |
| border: 1px solid var(--border); |
| border-radius: 4px; |
| padding: 12px 16px; |
| color: var(--text); |
| font-family: 'DM Sans', sans-serif; |
| font-size: 14px; |
| outline: none; |
| transition: border-color 0.2s; |
| } |
| |
| input[type="text"]:focus { border-color: var(--accent); } |
| |
| .btn-query { |
| background: var(--accent); |
| color: white; |
| border: none; |
| border-radius: 4px; |
| padding: 12px 24px; |
| font-family: 'Space Mono', monospace; |
| font-size: 11px; |
| letter-spacing: 2px; |
| cursor: pointer; |
| transition: opacity 0.2s; |
| white-space: nowrap; |
| } |
| |
| .btn-query:hover { opacity: 0.85; } |
| .btn-query:disabled { opacity: 0.4; cursor: not-allowed; } |
| |
| .api-url { |
| font-family: 'Space Mono', monospace; |
| font-size: 11px; |
| color: var(--muted); |
| margin-bottom: 16px; |
| } |
| |
| .api-url span { color: var(--accent2); } |
| |
| .results-grid { |
| display: grid; |
| grid-template-columns: repeat(3, 1fr); |
| gap: 16px; |
| } |
| |
| .result-box { |
| background: var(--bg); |
| border: 1px solid var(--border); |
| border-radius: 6px; |
| padding: 16px; |
| } |
| |
| .result-box-label { |
| font-family: 'Space Mono', monospace; |
| font-size: 10px; |
| letter-spacing: 2px; |
| text-transform: uppercase; |
| margin-bottom: 10px; |
| } |
| |
| .result-answer { |
| font-size: 13px; |
| line-height: 1.6; |
| color: var(--muted); |
| min-height: 80px; |
| } |
| |
| .result-meta { |
| display: flex; |
| gap: 12px; |
| margin-top: 12px; |
| padding-top: 12px; |
| border-top: 1px solid var(--border); |
| } |
| |
| .meta-item { font-family: 'Space Mono', monospace; font-size: 10px; color: var(--muted); } |
| .meta-item span { color: var(--text); } |
| |
| |
| .arch-card { |
| background: var(--surface); |
| border: 1px solid var(--border); |
| border-radius: 8px; |
| padding: 32px; |
| margin-bottom: 40px; |
| } |
| |
| .arch-title { |
| font-family: 'Space Mono', monospace; |
| font-size: 11px; |
| color: var(--muted); |
| letter-spacing: 2px; |
| text-transform: uppercase; |
| margin-bottom: 32px; |
| } |
| |
| .arch-grid { |
| display: grid; |
| grid-template-columns: repeat(3, 1fr); |
| gap: 24px; |
| } |
| |
| .pipeline { |
| border: 1px solid var(--border); |
| border-radius: 6px; |
| overflow: hidden; |
| } |
| |
| .pipeline-header { |
| padding: 12px 16px; |
| font-family: 'Space Mono', monospace; |
| font-size: 11px; |
| letter-spacing: 2px; |
| text-transform: uppercase; |
| } |
| |
| .pipeline-llm { background: rgba(245,158,11,0.1); color: var(--llm); border-bottom: 1px solid rgba(245,158,11,0.2); } |
| .pipeline-rag { background: rgba(108,99,255,0.1); color: var(--accent); border-bottom: 1px solid rgba(108,99,255,0.2); } |
| .pipeline-graph { background: rgba(0,212,170,0.1); color: var(--accent2); border-bottom: 1px solid rgba(0,212,170,0.2); } |
| |
| .pipeline-steps { padding: 16px; } |
| |
| .step { |
| display: flex; |
| align-items: flex-start; |
| gap: 10px; |
| margin-bottom: 12px; |
| font-size: 13px; |
| color: var(--muted); |
| } |
| |
| .step:last-child { margin-bottom: 0; } |
| |
| .step-num { |
| background: var(--border); |
| color: var(--text); |
| width: 20px; height: 20px; |
| border-radius: 50%; |
| display: flex; align-items: center; justify-content: center; |
| font-family: 'Space Mono', monospace; |
| font-size: 10px; |
| flex-shrink: 0; |
| margin-top: 1px; |
| } |
| |
| footer { |
| border-top: 1px solid var(--border); |
| padding: 24px 0; |
| text-align: center; |
| font-family: 'Space Mono', monospace; |
| font-size: 10px; |
| color: var(--muted); |
| letter-spacing: 2px; |
| } |
| |
| .loading { color: var(--muted); font-size: 13px; font-style: italic; } |
| |
| @keyframes pulse { 0%,100%{opacity:1} 50%{opacity:0.4} } |
| .pulsing { animation: pulse 1.5s ease-in-out infinite; } |
| </style> |
| </head> |
| <body> |
|
|
| <div class="container"> |
|
|
| |
| <header> |
| <div class="header-inner"> |
| <div> |
| <div class="logo">TigerGraph × GraphRAG</div> |
| <h1>Benchmark <span>Dashboard</span></h1> |
| </div> |
| <div style="text-align:right"> |
| <div class="badge">LIVE COMPARISON</div> |
| <div style="font-size:12px;color:var(--muted);margin-top:8px;font-family:'Space Mono',monospace">FinanceBench · SEC 10-K Filings</div> |
| </div> |
| </div> |
| </header> |
|
|
| |
| <div class="summary-grid"> |
| <div class="card"> |
| <div class="card-label">Avg Token Reduction</div> |
| <div class="card-value green">31.9%</div> |
| <div class="card-sub">GraphRAG vs Basic RAG</div> |
| </div> |
| <div class="card"> |
| <div class="card-label">LLM-as-Judge Pass</div> |
| <div class="card-value purple">70%</div> |
| <div class="card-sub">GraphRAG accuracy</div> |
| </div> |
| <div class="card"> |
| <div class="card-label">BERTScore F1</div> |
| <div class="card-value green">0.822</div> |
| <div class="card-sub">GraphRAG (RAG: 0.821)</div> |
| </div> |
| <div class="card"> |
| <div class="card-label">Dataset Size</div> |
| <div class="card-value amber">2.1M</div> |
| <div class="card-sub">tokens · 11,646 chunks</div> |
| </div> |
| </div> |
|
|
| |
| <div class="charts-grid"> |
| <div class="chart-card"> |
| <div class="chart-title">Token Usage Per Query</div> |
| <div class="chart-wrap"> |
| <canvas id="tokenChart"></canvas> |
| </div> |
| <div class="legend"> |
| <div class="legend-item"><div class="legend-dot" style="background:var(--llm)"></div>LLM Only</div> |
| <div class="legend-item"><div class="legend-dot" style="background:var(--rag)"></div>Basic RAG</div> |
| <div class="legend-item"><div class="legend-dot" style="background:var(--graphrag)"></div>GraphRAG</div> |
| </div> |
| </div> |
| <div class="chart-card"> |
| <div class="chart-title">Latency (seconds)</div> |
| <div class="chart-wrap"> |
| <canvas id="latencyChart"></canvas> |
| </div> |
| <div class="legend"> |
| <div class="legend-item"><div class="legend-dot" style="background:var(--llm)"></div>LLM Only</div> |
| <div class="legend-item"><div class="legend-dot" style="background:var(--rag)"></div>Basic RAG</div> |
| <div class="legend-item"><div class="legend-dot" style="background:var(--graphrag)"></div>GraphRAG</div> |
| </div> |
| </div> |
| <div class="chart-card"> |
| <div class="chart-title">Token Reduction % per Query</div> |
| <div class="chart-wrap"> |
| <canvas id="reductionChart"></canvas> |
| </div> |
| </div> |
| <div class="chart-card"> |
| <div class="chart-title">Accuracy Comparison</div> |
| <div class="chart-wrap"> |
| <canvas id="accuracyChart"></canvas> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="table-card"> |
| <div class="table-title">Per-Query Benchmark Results</div> |
| <table> |
| <thead> |
| <tr> |
| <th>Question</th> |
| <th>LLM Tokens</th> |
| <th>RAG Tokens</th> |
| <th>GraphRAG Tokens</th> |
| <th>Reduction</th> |
| <th>Judge</th> |
| </tr> |
| </thead> |
| <tbody id="resultsTable"> |
| <tr><td colspan="6" class="loading pulsing">Loading results...</td></tr> |
| </tbody> |
| </table> |
| </div> |
|
|
| |
| <div class="query-section"> |
| <h3>Live Query — Compare All 3 Pipelines</h3> |
| <div class="api-url">API: <span>POST /query/all</span> · Backend: <span>http://localhost:8000</span></div> |
| <div class="input-row"> |
| <input type="text" id="queryInput" placeholder="e.g. What was Apple's revenue in FY2022?" /> |
| <button class="btn-query" id="queryBtn" onclick="runQuery()">RUN QUERY</button> |
| </div> |
| <div class="results-grid"> |
| <div class="result-box"> |
| <div class="result-box-label" style="color:var(--llm)">LLM Only</div> |
| <div class="result-answer" id="llmAnswer">—</div> |
| <div class="result-meta"> |
| <div class="meta-item">Tokens: <span id="llmTokens">—</span></div> |
| <div class="meta-item">Latency: <span id="llmLat">—</span></div> |
| </div> |
| </div> |
| <div class="result-box"> |
| <div class="result-box-label" style="color:var(--rag)">Basic RAG</div> |
| <div class="result-answer" id="ragAnswer">—</div> |
| <div class="result-meta"> |
| <div class="meta-item">Tokens: <span id="ragTokens">—</span></div> |
| <div class="meta-item">Latency: <span id="ragLat">—</span></div> |
| </div> |
| </div> |
| <div class="result-box"> |
| <div class="result-box-label" style="color:var(--graphrag)">GraphRAG</div> |
| <div class="result-answer" id="gragAnswer">—</div> |
| <div class="result-meta"> |
| <div class="meta-item">Tokens: <span id="gragTokens">—</span></div> |
| <div class="meta-item">Reduction: <span id="gragReduction">—</span></div> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="arch-card"> |
| <div class="arch-title">System Architecture — 3 Pipeline Comparison</div> |
| <div class="arch-grid"> |
| <div class="pipeline"> |
| <div class="pipeline-header pipeline-llm">LLM Only</div> |
| <div class="pipeline-steps"> |
| <div class="step"><div class="step-num">1</div>User query input</div> |
| <div class="step"><div class="step-num">2</div>Direct to Groq llama3-70b</div> |
| <div class="step"><div class="step-num">3</div>No retrieval — pure parametric memory</div> |
| <div class="step"><div class="step-num">4</div>Answer + token count</div> |
| </div> |
| </div> |
| <div class="pipeline"> |
| <div class="pipeline-header pipeline-rag">Basic RAG</div> |
| <div class="pipeline-steps"> |
| <div class="step"><div class="step-num">1</div>Embed query via sentence-transformers</div> |
| <div class="step"><div class="step-num">2</div>ChromaDB top-5 similarity search</div> |
| <div class="step"><div class="step-num">3</div>Build context prompt (~2000 tokens)</div> |
| <div class="step"><div class="step-num">4</div>Groq → answer + token count</div> |
| </div> |
| </div> |
| <div class="pipeline"> |
| <div class="pipeline-header pipeline-graph">GraphRAG</div> |
| <div class="pipeline-steps"> |
| <div class="step"><div class="step-num">1</div>Extract entities from query</div> |
| <div class="step"><div class="step-num">2</div>Graph traversal — score chunks by entity match</div> |
| <div class="step"><div class="step-num">3</div>Retrieve top-1 chunk (~400 tokens)</div> |
| <div class="step"><div class="step-num">4</div>Groq → answer + token count</div> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| <footer>GRAPHRAG HACKATHON · TIGERGRAPH SAVANNA · FINANCEBENCH DATASET</footer> |
|
|
| </div> |
|
|
| <script> |
| |
| const benchmarkData = { |
| questions: [ |
| "FY2018 capital expenditure amount", |
| "Public equities analyst analysis", |
| "3M capital-intensive FY2022", |
| "Operating margin change FY2022", |
| "M&A segment growth" |
| ], |
| llm_tokens: [92, 246, 250, 272, 167], |
| rag_tokens: [1196,1859,1333,1892, 808], |
| grag_tokens: [1003,931, 648,1104, 409], |
| llm_latency: [0.57,0.42,2.77,2.63,2.50], |
| rag_latency: [0.93,0.80,15.21,18.96,7.19], |
| grag_latency: [0.87,2.85,6.12,7.21,4.12], |
| reductions: [16.1,49.9,51.4,41.6,44.6], |
| judges: ["FAIL","FAIL","PASS","PASS","PASS"] |
| }; |
| |
| const chartDefaults = { |
| plugins: { legend: { display: false } }, |
| scales: { |
| x: { grid: { color: 'rgba(42,42,58,0.5)' }, ticks: { color: '#6b6b80', font: { family: 'Space Mono', size: 9 } } }, |
| y: { grid: { color: 'rgba(42,42,58,0.5)' }, ticks: { color: '#6b6b80', font: { family: 'Space Mono', size: 9 } } } |
| } |
| }; |
| |
| |
| new Chart(document.getElementById('tokenChart'), { |
| type: 'bar', |
| data: { |
| labels: benchmarkData.questions, |
| datasets: [ |
| { label: 'LLM Only', data: benchmarkData.llm_tokens, backgroundColor: 'rgba(245,158,11,0.7)', borderRadius: 3 }, |
| { label: 'Basic RAG', data: benchmarkData.rag_tokens, backgroundColor: 'rgba(108,99,255,0.7)', borderRadius: 3 }, |
| { label: 'GraphRAG', data: benchmarkData.grag_tokens, backgroundColor: 'rgba(0,212,170,0.7)', borderRadius: 3 } |
| ] |
| }, |
| options: { ...chartDefaults, responsive: true, maintainAspectRatio: false } |
| }); |
| |
| |
| new Chart(document.getElementById('latencyChart'), { |
| type: 'bar', |
| data: { |
| labels: benchmarkData.questions, |
| datasets: [ |
| { label: 'LLM Only', data: benchmarkData.llm_latency, backgroundColor: 'rgba(245,158,11,0.7)', borderRadius: 3 }, |
| { label: 'Basic RAG', data: benchmarkData.rag_latency, backgroundColor: 'rgba(108,99,255,0.7)', borderRadius: 3 }, |
| { label: 'GraphRAG', data: benchmarkData.grag_latency, backgroundColor: 'rgba(0,212,170,0.7)', borderRadius: 3 } |
| ] |
| }, |
| options: { ...chartDefaults, responsive: true, maintainAspectRatio: false } |
| }); |
| |
| |
| new Chart(document.getElementById('reductionChart'), { |
| type: 'bar', |
| data: { |
| labels: benchmarkData.questions, |
| datasets: [{ |
| label: 'Token Reduction %', |
| data: benchmarkData.reductions, |
| backgroundColor: benchmarkData.reductions.map(v => v >= 0 ? 'rgba(0,212,170,0.7)' : 'rgba(255,107,107,0.7)'), |
| borderRadius: 3 |
| }] |
| }, |
| options: { ...chartDefaults, responsive: true, maintainAspectRatio: false } |
| }); |
| |
| |
| new Chart(document.getElementById('accuracyChart'), { |
| type: 'radar', |
| data: { |
| labels: ['BERTScore', 'Judge Pass%', 'Token Efficiency', 'Latency Score', 'Avg Reduction'], |
| datasets: [ |
| { |
| label: 'Basic RAG', |
| data: [82, 50, 30, 40, 0], |
| borderColor: 'rgba(108,99,255,0.8)', |
| backgroundColor: 'rgba(108,99,255,0.1)', |
| pointBackgroundColor: '#6c63ff' |
| }, |
| { |
| label: 'GraphRAG', |
| data: [82.2, 70, 75, 65, 31.9], |
| borderColor: 'rgba(0,212,170,0.8)', |
| backgroundColor: 'rgba(0,212,170,0.1)', |
| pointBackgroundColor: '#00d4aa' |
| } |
| ] |
| }, |
| options: { |
| responsive: true, |
| maintainAspectRatio: false, |
| plugins: { legend: { display: true, labels: { color: '#6b6b80', font: { family: 'Space Mono', size: 9 } } } }, |
| scales: { |
| r: { |
| grid: { color: 'rgba(42,42,58,0.8)' }, |
| ticks: { color: '#6b6b80', backdropColor: 'transparent', font: { size: 8 } }, |
| pointLabels: { color: '#6b6b80', font: { family: 'Space Mono', size: 9 } } |
| } |
| } |
| } |
| }); |
| |
| |
| const tbody = document.getElementById('resultsTable'); |
| tbody.innerHTML = ''; |
| benchmarkData.questions.forEach((q, i) => { |
| const r = benchmarkData.reductions[i]; |
| const j = benchmarkData.judges[i]; |
| tbody.innerHTML += ` |
| <tr> |
| <td class="q-text">${q}</td> |
| <td class="token-val" style="color:var(--llm)">${benchmarkData.llm_tokens[i]}</td> |
| <td class="token-val" style="color:var(--rag)">${benchmarkData.rag_tokens[i]}</td> |
| <td class="token-val" style="color:var(--graphrag)">${benchmarkData.grag_tokens[i]}</td> |
| <td class="reduction ${r >= 0 ? 'pos' : 'neg'}">${r >= 0 ? '+' : ''}${r}%</td> |
| <td><span class="pill ${j === 'PASS' ? 'pill-pass' : 'pill-fail'}">${j}</span></td> |
| </tr>`; |
| }); |
| |
| |
| async function runQuery() { |
| const q = document.getElementById('queryInput').value.trim(); |
| if (!q) return; |
| |
| const btn = document.getElementById('queryBtn'); |
| btn.disabled = true; |
| btn.textContent = 'RUNNING...'; |
| |
| ['llmAnswer','ragAnswer','gragAnswer'].forEach(id => { |
| document.getElementById(id).innerHTML = '<span class="pulsing">Querying...</span>'; |
| }); |
| |
| try { |
| const res = await fetch('http://localhost:8000/query/all', { |
| method: 'POST', |
| headers: { 'Content-Type': 'application/json' }, |
| body: JSON.stringify({ question: q }) |
| }); |
| const data = await res.json(); |
| |
| document.getElementById('llmAnswer').textContent = data.llm_only.answer; |
| document.getElementById('llmTokens').textContent = data.llm_only.total_tokens; |
| document.getElementById('llmLat').textContent = (data.llm_only.latency || '—') + 's'; |
| |
| document.getElementById('ragAnswer').textContent = data.rag.answer; |
| document.getElementById('ragTokens').textContent = data.rag.total_tokens; |
| document.getElementById('ragLat').textContent = (data.rag.latency || '—') + 's'; |
| |
| document.getElementById('gragAnswer').textContent = data.graphrag.answer; |
| document.getElementById('gragTokens').textContent = data.graphrag.total_tokens; |
| document.getElementById('gragReduction').textContent = data.token_reduction_vs_rag + '%'; |
| |
| } catch(e) { |
| ['llmAnswer','ragAnswer','gragAnswer'].forEach(id => { |
| document.getElementById(id).textContent = 'Start backend: uvicorn backend.main:app --reload'; |
| }); |
| } |
| |
| btn.disabled = false; |
| btn.textContent = 'RUN QUERY'; |
| } |
| |
| document.getElementById('queryInput').addEventListener('keydown', e => { |
| if (e.key === 'Enter') runQuery(); |
| }); |
| </script> |
| </body> |
| </html> |