Crackershoot's picture
Update app.py
f6fc25b verified
import os
import logging
import sys
import gradio as gr
from pinecone import Pinecone
from llama_index.core import VectorStoreIndex, Settings, StorageContext
from llama_index.vector_stores.pinecone import PineconeVectorStore
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.core.prompts import PromptTemplate
# --- Logging ---
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
# --- Secrets ---
PINECONE_API_KEY = os.environ.get("PINECONE_API_KEY")
OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
if not PINECONE_API_KEY:
raise ValueError("Missing PINECONE_API_KEY")
if not OPENAI_API_KEY:
raise ValueError("Missing OPENAI_API_KEY")
# --- LLM Settings ---
Settings.llm = OpenAI(
model="gpt-4.1-mini",
temperature=0.2,
api_key=OPENAI_API_KEY
)
Settings.embed_model = OpenAIEmbedding(
model="text-embedding-ada-002",
api_key=OPENAI_API_KEY
)
# Better chunking (IMPORTANT)
Settings.chunk_size = 500
Settings.chunk_overlap = 100
# --- ✅ REAL FIX: Custom QA Prompt ---
qa_prompt = PromptTemplate(
"""
You are Helen, the Decoding Data Science (DDS) HR Enterprise chatbot.
You must ONLY answer HR-related questions using the provided context.
---------------------
Context:
{context_str}
---------------------
Question:
{query_str}
Instructions:
- First determine if the question is DDS HR-related
- If NOT HR-related, respond:
"I’m here to answer only HR-related questions. Please ask a question related to HR policies or employee matters."
- If HR-related but answer is NOT in the context, respond:
"I’m sorry, I don’t have enough information to answer that. Please contact connect@decodingdatascience.com for further assistance."
- If answer EXISTS in the context:
- Answer strictly using the context
- Do NOT add external knowledge
- Keep answer between 2–4 sentences
- Maintain a professional and polite tone
- ALWAYS end with a citation from the context that links to the answer
- Do NOT include reasoning steps
- Do NOT hallucinate
Answer:
"""
)
# --- Pinecone اتصال ---
index_name = "quickstart"
pc = Pinecone(api_key=PINECONE_API_KEY)
pinecone_index = pc.Index(index_name)
# --- Vector Store ---
vector_store = PineconeVectorStore(pinecone_index=pinecone_index)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_vector_store(
vector_store=vector_store,
storage_context=storage_context
)
# --- ✅ Fixed Query Engine ---
query_engine = index.as_query_engine(
text_qa_template=qa_prompt,
similarity_top_k=3
)
# --- Gradio ---
def query_doc(prompt):
try:
if not prompt or not prompt.strip():
return "Please enter your HR-related question."
response = query_engine.query(prompt)
return str(response)
except Exception as e:
return f"Error: {str(e)}"
demo = gr.Interface(
fn=query_doc,
inputs=
gr.Textbox(label="Ask Helen your HR-related question: ", lines = 5),
outputs=gr.Textbox(label="Answer", lines = 5),
title="Helen the DDS Enterprise Professional Chatbot",
description="Ask HR questions based on the indexed HR documents. Powered by OpenAI, LlamaIndex & Pinecone.",
examples=[
"Can I take leave next month?",
"How many annual leave days do I get?",
"Can I travel and work at the same time?",
"What happens if I miss too many meetings?"
],
theme = "ocean"
)
if __name__ == "__main__":
demo.launch()