DEMO_NLP_FISCAL / app.py
Benjov's picture
12/08/2023
29d2476
import os
import pandas as pd
import openai
import re
import json
from langchain.chat_models import ChatOpenAI
import regex
import gradio as gr
from langchain.schema import Document
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings.openai import OpenAIEmbeddings
from openai.embeddings_utils import get_embedding
from openai.embeddings_utils import cosine_similarity
import gspread # See: https://docs.gspread.org/en/v5.10.0/user-guide.html
from oauth2client.service_account import ServiceAccountCredentials
from datetime import datetime
# API de OpenAI
openai.api_key = os.getenv("OPENAI_API_KEY")
# Establece las credenciales y la API
credentials = os.getenv( "credentials" )
credentials = json.loads( credentials )
gc = gspread.service_account_from_dict( credentials )
Google_URL = os.getenv( "Google_URL" )
# Cargar el archivo
df_Normas_Embeddings = pd.read_csv( os.getenv( "Data" ) )
# Main OpenAI Function
#
def get_completion_from_messages( messages, model = "gpt-3.5-turbo-16k",
temperature = 0, max_tokens = 4500 ): ##Check max_tokens
response = openai.ChatCompletion.create(
model = model,
messages = messages,
temperature = temperature,
max_tokens = max_tokens,
)
return response.choices[0].message["content"]
# Get LEY
#
def get_topic( user_message ):
#
delimiter = "####"
system_message = f"""
Eres un especialista en temas fiscales en México. \
Se le proporcionarán consultas o preguntas respecto de temas fiscales. \
Las consultas o preguntas se delimitarán con los caracteres {delimiter}.
Las consultas serán sobre diferentes Leyes, Códigos Federales y normativas como:
1. La LEY DEL IMPUESTO ESPECIAL SOBRE PRODUCCIÓN Y SERVICIOS y el REGLAMENTO DE LA LEY DEL \
IMPUESTO ESPECIAL SOBRE PRODUCCIÓN Y SERVICIOS
2. La LEY DEL IMPUESTO SOBRE LA RENTA y el REGLAMENTO DE LA LEY DEL IMPUESTO SOBRE LA RENTA
3. La LEY DEL IMPUESTO AL VALOR AGREGADO y el REGLAMENTO DE LA LEY DEL IMPUESTO AL VALOR AGREGADO
Proporciona una lista de objetos de python, donde cada objeto sea alguno de: \
'IMPUESTO AL VALOR AGREGADO', 'IMPUESTO SOBRE LA RENTA', o 'IMPUESTO ESPECIAL SOBRE PRODUCCIÓN Y SERVICIOS'.
Donde el tema se debe encontrar en la consulta o pregunta relacionada con temas fiscales.
Solo proporciona la lista de objetos, nada más.
"""
#
messages = [
{'role':'system',
'content': system_message},
{'role':'user',
'content': f"{delimiter}{user_message}{delimiter}"},
]
return get_completion_from_messages( messages )
# Function: Get embeddings
def get_embedding( text , model ):
text = text.replace("\n", " ")
return openai.Embedding.create( input = [text], model = model )['data'][0]['embedding']
# Función de búsqueda
def buscar( busqueda, datos, n_resultados):
#
busqueda_embed = get_embedding( busqueda, model = "text-embedding-ada-002" )
datos['Similitud'] = datos['Embedding'].apply( lambda x: cosine_similarity( eval( x ) , busqueda_embed ) )
datos = datos.sort_values('Similitud', ascending = False )
#
return datos.iloc[:n_resultados][['Tema', 'Norma', 'Textos', 'NumPalabras', 'Embedding', 'Similitud']]
#
def get_respuesta( user_message, informacion ):
#
delimiter = "####"
system_message = f"""
Eres un especialista en temas fiscales en México. \
Se le proporcionarán consultas o preguntas respecto de temas fiscales. \
Las consultas o preguntas e información para responder se delimitarán \
con los caracteres {delimiter}.
La información que se te proporcionará para responder las consultas o preguntas \
estará en una lista de Python.
La información corresponde a extractos de Leyes, Códigos Federales y normativas como:
1. La LEY DEL IMPUESTO ESPECIAL SOBRE PRODUCCIÓN Y SERVICIOS y el REGLAMENTO DE LA LEY DEL \
IMPUESTO ESPECIAL SOBRE PRODUCCIÓN Y SERVICIOS.
2. La LEY DEL IMPUESTO SOBRE LA RENTA y el REGLAMENTO DE LA LEY DEL IMPUESTO SOBRE LA RENTA.
3. La LEY DEL IMPUESTO AL VALOR AGREGADO y el REGLAMENTO DE LA LEY DEL IMPUESTO AL VALOR AGREGADO.
4. El CÓDIGO FISCAL DE LA FEDERACIÓN y el REGLAMENTO DEL CÓDIGO FISCAL DE LA FEDERACIÓN.
La información se te proporcionará con la siguiente estructura: Nombre de la Ley, Código o \
Reglamento, seguido del Artículo y el texto del Artículo.
Asegúrate de realizar preguntas de seguimiento.
"""
#
messages = [
{'role':'system',
'content': system_message},
{'role':'user',
'content': f"""
{delimiter}
Usa exclusivamente la información contenida en la siguiente lista:
{informacion}
para responder sin límite de palabras lo siguiente: {user_message}
En tu respuesta menciona el Nombre de la Ley, Código o Reglamento de donde proviene la información \
incluida en tu respuesta.
Responde de forma detallada.
{delimiter}
"""},
]
#
return get_completion_from_messages(messages)
#
#
#
def update_records( user_message ):
#
sht = gc.open_by_url(Google_URL)
#
sht.sheet1.get_all_records()
#
sht.sheet1.update_cell( len( sht.sheet1.get_all_records()[:] ) + 2 ,
1 , datetime.now().strftime("%m/%d/%Y, %H:%M:%S") )
#
sht.sheet1.update_cell( len( sht.sheet1.get_all_records()[:] ) + 1 ,
2 , user_message )
#
def Chat( user_message_1 ):
#
norma_y_tema_response_1 = get_topic( user_message_1 )
norma_y_tema_response_1 = eval(norma_y_tema_response_1)
norma_y_tema_response_1.append( 'Todos' )
#
df_datos = df_Normas_Embeddings[ df_Normas_Embeddings['Tema'].isin(norma_y_tema_response_1) ]
#
df_final = buscar( user_message_1, df_datos, 10).reset_index( drop = True)
#
df_final['Cum_NumPalabras'] = df_final['NumPalabras'].cumsum()
#
df_final = df_final[ df_final['Cum_NumPalabras'] <= 1400 ]
#
df_final[ 'Final_Text' ] = df_final[ 'Norma' ] + ', ' + df_final[ 'Textos' ]
#
Textos = df_final[ 'Final_Text' ].tolist()
#
# Save Question and date time
update_records( user_message_1 )
#
return get_respuesta( user_message_1, Textos ), '\n'.join(Textos)
#
#
with gr.Blocks() as demo:
#
gr.Markdown("App basada en servicios (Embeddings) de OpenAI (Chat GPT-3.5)")
gr.Markdown("Este es un producto de prueba desarrollado por Analítica Boutique, S.C.")
gr.Markdown("Contacto: vicente@analiticaboutique.com.mx")
gr.Markdown("La base de información de este ChatBot es:\
1. La LEY DEL IMPUESTO ESPECIAL SOBRE PRODUCCIÓN Y SERVICIOS y el \
REGLAMENTO DE LA LEY DEL IMPUESTO ESPECIAL SOBRE PRODUCCIÓN Y SERVICIOS. \n\
2. La LEY DEL IMPUESTO SOBRE LA RENTA y el REGLAMENTO DE LA LEY DEL IMPUESTO \
SOBRE LA RENTA. \n\
3. La LEY DEL IMPUESTO AL VALOR AGREGADO y el REGLAMENTO DE LA LEY DEL IMPUESTO \
AL VALOR AGREGADO. \n\
4. El CÓDIGO FISCAL DE LA FEDERACIÓN y el REGLAMENTO DEL CÓDIGO FISCAL DE LA \
FEDERACIÓN.")
busqueda = gr.Textbox(label = "Escribe la pregunta o tarea para iniciar la conversación.")
greet_btn = gr.Button("Preguntar")
# Crear dos widgets de salida en lugar de uno
output1 = gr.Textbox(label = "Mi propuesta de respuesta:")
output2 = gr.Textbox(label = "Los extractos de las Leyes, Reglamentos y Código que usé:")
# Modificar la función click para asignar cada parte de la tupla a un widget diferente
greet_btn.click(fn=Chat, inputs=[busqueda], outputs=[output1, output2])
#
#demo.launch( share = True )
demo.launch( )
#
#