Spaces:
Runtime error
Runtime error
| import streamlit as st | |
| from rag_pipeline import chunk_text, build_index, retrieve, generate_answer | |
| from evaluator import evaluate | |
| st.set_page_config( | |
| page_title="RAG Evaluator", | |
| page_icon="π", | |
| layout="wide", | |
| ) | |
| st.markdown(""" | |
| <style> | |
| .metric-card { | |
| background: #f8fafc; | |
| border: 1px solid #e2e8f0; | |
| border-radius: 10px; | |
| padding: 1rem 1.25rem; | |
| text-align: center; | |
| } | |
| .metric-label { | |
| font-size: 12px; | |
| color: #64748b; | |
| text-transform: uppercase; | |
| letter-spacing: 0.05em; | |
| margin-bottom: 0.25rem; | |
| } | |
| .metric-value { | |
| font-size: 28px; | |
| font-weight: 600; | |
| } | |
| .score-high { color: #16a34a; } | |
| .score-mid { color: #d97706; } | |
| .score-low { color: #dc2626; } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| st.title("π RAG Evaluator") | |
| st.markdown( | |
| "Paste any document and ask a question. " | |
| "Get an AI-generated answer with **live quality scores** β " | |
| "faithfulness, relevance, groundedness, and completeness." | |
| ) | |
| st.markdown("---") | |
| with st.sidebar: | |
| st.header("βοΈ Configuration") | |
| api_key = st.text_input( | |
| "OpenAI API Key", | |
| type="password", | |
| help="Your key is never stored. Used only for this session.", | |
| ) | |
| st.markdown("---") | |
| st.markdown("**About this tool**") | |
| st.markdown( | |
| "Built by [Faraz Mubeen Haider](https://linkedin.com/in/farazmubeen) " | |
| "to demonstrate production RAG evaluation techniques." | |
| ) | |
| st.markdown("[GitHub](https://github.com/Faraz6180) | " | |
| "[LinkedIn](https://linkedin.com/in/farazmubeen)") | |
| col1, col2 = st.columns([1, 1], gap="large") | |
| with col1: | |
| st.subheader("π Document") | |
| document = st.text_area( | |
| "Paste your document here", | |
| height=300, | |
| placeholder="Paste any text document β a report, article, policy, or knowledge base excerpt...", | |
| ) | |
| st.subheader("β Question") | |
| query = st.text_input( | |
| "Ask a question about the document", | |
| placeholder="e.g. What are the main findings of this report?", | |
| ) | |
| run = st.button("βΆ Evaluate", use_container_width=True, type="primary") | |
| with col2: | |
| st.subheader("π Results") | |
| if run: | |
| if not api_key: | |
| st.error("Please enter your OpenAI API key in the sidebar.") | |
| elif not document.strip(): | |
| st.error("Please paste a document.") | |
| elif not query.strip(): | |
| st.error("Please enter a question.") | |
| else: | |
| with st.spinner("Running RAG pipeline..."): | |
| chunks = chunk_text(document) | |
| index, _ = build_index(chunks) | |
| context_chunks = retrieve(query, chunks, index) | |
| answer, context = generate_answer(query, context_chunks, api_key) | |
| with st.spinner("Evaluating answer quality..."): | |
| scores = evaluate(query, answer, context, api_key) | |
| st.markdown("**Answer**") | |
| st.info(answer) | |
| st.markdown("**Quality Scores**") | |
| def color_class(val): | |
| if val >= 0.75: | |
| return "score-high" | |
| elif val >= 0.5: | |
| return "score-mid" | |
| return "score-low" | |
| metrics = [ | |
| ("Faithfulness", scores["faithfulness"], | |
| "Is every claim supported by the document?"), | |
| ("Relevance", scores["relevance"], | |
| "Does the answer address the question?"), | |
| ("Groundedness", scores["groundedness"], | |
| "Does it avoid speculation?"), | |
| ("Completeness", scores["completeness"], | |
| "Does it cover all aspects of the question?"), | |
| ] | |
| c1, c2 = st.columns(2) | |
| for i, (label, val, tip) in enumerate(metrics): | |
| col = c1 if i % 2 == 0 else c2 | |
| with col: | |
| css_class = color_class(val) | |
| st.markdown( | |
| f"""<div class="metric-card" title="{tip}"> | |
| <div class="metric-label">{label}</div> | |
| <div class="metric-value {css_class}">{val:.2f}</div> | |
| </div>""", | |
| unsafe_allow_html=True, | |
| ) | |
| st.progress(val) | |
| st.caption(tip) | |
| avg = sum(scores.values()) / len(scores) | |
| st.markdown("---") | |
| overall_class = color_class(avg) | |
| st.markdown( | |
| f"""<div class="metric-card"> | |
| <div class="metric-label">Overall Quality Score</div> | |
| <div class="metric-value {overall_class}">{avg:.2f}</div> | |
| </div>""", | |
| unsafe_allow_html=True, | |
| ) | |
| with st.expander("π Retrieved context chunks"): | |
| for i, chunk in enumerate(context_chunks): | |
| st.markdown(f"**Chunk {i+1}:**") | |
| st.text(chunk) | |
| else: | |
| st.markdown( | |
| """<div style='padding:2rem;text-align:center;color:#94a3b8;border:1px dashed #e2e8f0;border-radius:10px;'> | |
| Paste a document and question,<br>then click <b>Evaluate</b> to see results. | |
| </div>""", | |
| unsafe_allow_html=True, | |
| ) |