Archivo python para crear el modelo de lenguaje, archivo llamado app.py
import gradio as gr
import pandas as pd
import io
from google.oauth2 import service_account
from googleapiclient.discovery import build
from googleapiclient.http import MediaIoBaseDownload
from huggingface_hub import InferenceClient
import os
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain.schema import Document
# Configuración del modelo de embeddings
embedding_model = "sentence-transformers/all-MiniLM-L6-v2"
embeddings = HuggingFaceEmbeddings(model_name=embedding_model)
# Configuración del cliente de inferencia en Hugging Face
hf_token = os.getenv("HF_API_TOKEN")
client = InferenceClient("microsoft/Phi-3-mini-4k-instruct", token=hf_token)
# Ruta al archivo JSON de credenciales de la cuenta de servicio de Google.
SERVICE_ACCOUNT_FILE = 'prueba-93847hj4h5-93487543kj5h.json'
file_id = '9837459kj34h5kjh3487435k3jh5k34jh5k4'
# Autenticación y configuración de Google Drive API
credentials = service_account.Credentials.from_service_account_file(
SERVICE_ACCOUNT_FILE,
scopes=["https://www.googleapis.com/auth/drive"]
)
drive_service = build('drive', 'v3', credentials=credentials)
def cargar_excel():
"""Descarga y carga el archivo de Google Sheets en formato Excel y lo procesa para construir una base de datos vectorial."""
try:
# Descargar el archivo de Google Sheets en formato .xlsx
request = drive_service.files().export_media(fileId=file_id, mimeType='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
fh = io.BytesIO()
downloader = MediaIoBaseDownload(fh, request)
done = False
while not done:
status, done = downloader.next_chunk()
print(f"Descarga {int(status.progress() * 100)}% completada.")
fh.seek(0)
# Cargar el archivo Excel en un DataFrame
df = pd.read_excel(fh)
# Combina todas las celdas en un solo texto y crea objetos Document
data = [Document(page_content=" ".join(df.astype(str).values.flatten()))]
# Divide el contenido en fragmentos
text_splitter = RecursiveCharacterTextSplitter(chunk_size=7500, chunk_overlap=100)
chunks = text_splitter.split_documents(data)
# Crear la base de datos de vectores con embeddings
vector_db = Chroma.from_documents(
documents=chunks,
embedding=embeddings,
collection_name="excel-rag"
)
return vector_db, "Archivo de Excel descargado y procesado exitosamente."
except Exception as e:
return None, f"Error al descargar o procesar el archivo: {str(e)}"
def responder(pregunta):
"""Genera una respuesta basada en la pregunta del usuario, reconstruyendo la base de datos de vectores para obtener los datos actualizados."""
# Recargar la base de datos vectorial en cada consulta
vector_db, status_message = cargar_excel()
if not vector_db:
return status_message
try:
# Recuperar el contexto relevante desde la base de datos de vectores
retriever = vector_db.as_retriever()
retrieved_docs = retriever.get_relevant_documents(pregunta)
# Construir el contexto a partir de los documentos recuperados
context = "\n".join([doc.page_content for doc in retrieved_docs])
# Construir el prompt para el LLM, destacando la pregunta del usuario
prompt_text = f"Contexto relevante:\n{context}\n\nPregunta del usuario: {pregunta}\n\nPor favor responde considerando el contexto y la pregunta."
messages = [{"role": "user", "content": prompt_text}]
# Realizar la inferencia usando el cliente de Hugging Face
response = client.chat_completion(messages=messages, max_tokens=500)
# Extraer el texto generado
if hasattr(response, 'choices') and response.choices:
generated_text = response.choices[0].message.content
else:
generated_text = str(response)
return generated_text
except Exception as e:
return f"Error al procesar la pregunta: {str(e)}"
# Configuración de la interfaz de Gradio
with gr.Blocks() as demo:
gr.Markdown("# Asistente de IA con Datos de Google Sheets (Acceso Privado y Actualización en Cada Consulta)")
# Mensaje de estado inicial
output_text = gr.Textbox(label="Estado", value="Esperando consulta...", interactive=False)
with gr.Tab("Chat"):
question = gr.Textbox(label="Haz una pregunta")
chat_output = gr.Textbox(label="Respuesta")
question.submit(responder, inputs=question, outputs=chat_output)
demo.launch()
Archivo requirements.txt
pandas
openpyxl
requests
gradio
langchain
langchain_community
langchain_text_splitters
chromadb
sentence-transformers
google-api-python-client
google-auth
google-auth-oauthlib
google-auth-httplib2