NightmareFox12 commited on
Commit
2b1c0f5
verified
1 Parent(s): e40af0b

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +95 -0
app.py ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from fastapi import FastAPI
3
+ from pydantic import BaseModel
4
+ from langchain_community.vectorstores import FAISS
5
+ from langchain_community.embeddings import HuggingFaceEmbeddings
6
+ from langchain.chains import RetrievalQA
7
+ from langchain.prompts import PromptTemplate
8
+ from langchain_groq import ChatGroq
9
+
10
+ # --------------------------------------------------------
11
+ # 1. CONFIGURACI脫N
12
+ # --------------------------------------------------------
13
+ # La clave se lee del secreto de Hugging Face. NO PEGAR CLAVE AQU脥.
14
+ os.environ['GROQ_API_KEY'] = os.environ.get('GROQ_API_KEY')
15
+ DB_FAISS_PATH = 'vectorstore/db_faiss'
16
+
17
+ # --------------------------------------------------------
18
+ # 2. CLASES Y CARGA DEL RAG CORE
19
+ # --------------------------------------------------------
20
+
21
+ class QueryRequest(BaseModel):
22
+ """Define el formato de la pregunta que recibir谩 el endpoint /query."""
23
+ query: str
24
+
25
+ def load_and_configure_rag():
26
+ """
27
+ Carga la base de datos FAISS pre-entrenada y configura el RAG Chain.
28
+ Esta funci贸n se ejecuta SOLO UNA VEZ al iniciar el servidor.
29
+ """
30
+ try:
31
+ # 1. Cargar Embeddings (necesario para saber c贸mo buscar)
32
+ embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
33
+
34
+ # 2. Cargar Vector Store (busca la carpeta que subiste a Hugging Face)
35
+ # Esto fallar谩 si la carpeta 'vectorstore/db_faiss' no se sube.
36
+ vectorstore = FAISS.load_local(DB_FAISS_PATH, embeddings, allow_dangerous_deserialization=True)
37
+
38
+ # 3. Configurar LLM y Prompt
39
+ llm_groq = ChatGroq(temperature=0.0, model_name="llama-3.1-8b-instant")
40
+
41
+ custom_prompt = """
42
+ Eres un asistente de preguntas y respuestas experto en la documentaci贸n de NutriActive.
43
+ Tu tarea es responder a la pregunta del usuario bas谩ndote EXCLUSIVAMENTE en el contexto proporcionado.
44
+ Si la respuesta no se encuentra en el contexto, indica amablemente: "Lo siento, la informaci贸n que buscas no se encuentra en la documentaci贸n de NutriActive."
45
+
46
+ Contexto: {context}
47
+ Pregunta: {question}
48
+
49
+ Respuesta concisa:
50
+ """
51
+ RAG_PROMPT = PromptTemplate(template=custom_prompt, input_variables=["context", "question"])
52
+
53
+ # 4. Crear la cadena de RAG
54
+ qa_chain = RetrievalQA.from_chain_type(
55
+ llm=llm_groq,
56
+ chain_type="stuff",
57
+ retriever=vectorstore.as_retriever(search_kwargs={"k": 3}),
58
+ return_source_documents=True,
59
+ chain_type_kwargs={"prompt": RAG_PROMPT}
60
+ )
61
+ return qa_chain
62
+
63
+ except Exception as e:
64
+ print(f"Error cr铆tico al cargar la configuraci贸n RAG: {e}")
65
+ return None
66
+
67
+ # --------------------------------------------------------
68
+ # 3. CONFIGURACI脫N DE FASTAPI Y ENDPOINTS
69
+ # --------------------------------------------------------
70
+
71
+ app = FastAPI(title="NutriActive RAG API")
72
+ qa_chain = load_and_configure_rag() # Carga la cadena al iniciar
73
+
74
+ @app.get("/")
75
+ def home():
76
+ """Verifica que el servidor est谩 corriendo."""
77
+ return {"message": "API de NutriActive RAG operativa. Usa el endpoint /query."}
78
+
79
+ @app.post("/query")
80
+ async def process_query(request: QueryRequest):
81
+ """Endpoint principal para recibir la pregunta y devolver la respuesta."""
82
+ if qa_chain is None:
83
+ return {"error": "El sistema RAG no se pudo cargar. Verifique que la carpeta 'vectorstore' existe."}
84
+
85
+ try:
86
+ result = qa_chain.invoke({"query": request.query})
87
+ sources = [doc.metadata.get('source', 'N/A') for doc in result['source_documents']]
88
+
89
+ return {
90
+ "query": request.query,
91
+ "response": result['result'],
92
+ "sources": sources
93
+ }
94
+ except Exception as e:
95
+ return {"error": f"Error al procesar la consulta: {e}"}