#Paz Munidal #mi aporte # # Crea una consultor público, al servicio de las personas, sobre las normas formales Chilenas, las que están publicadas oficialmente # en la Biblioteca del Congreso Nacional (www.bcn.cl), quienes a través de sus deberes a la ciudadanía facilitan el accesso a la # información a través de datos en XML, los que luego son alimentados a un modelo LLM (a una A.I.) para que diga cómo lo clasifica en # en arreglos ordenados matematicamente, los que luego matematicamente pueden ser comparados con la pregunta hecha al ingreso de la # consulta y obtener un patron mátématico medible que en el mundo de las ideas, represente la semantica de la pregunta y responder # con la norma que se consulta, en lo que más sentido tenga. # # Esto tiene liciencia GNU GPLv3 <--- software libre y las was que hagai con él también lo deben ser 🤟 (for ever, sin trampas, maldidta rata!!🤗)!!! # @fermaf # Nostr: npub1fermafqdu9ghcmsflq9wdsfwhg3zf93e6n49204ch2ztf98utw6qmhavug # # (de acá en adelante con mis garabatos/comentarios incluidos xd, sin ellos no hubiese hecho la primera iteración!! 🤓 ) # #(https://30days.streamlit.app/) #pip install streamlit import os import streamlit as st import xml.etree.ElementTree as ET import requests import re import time openai_api_key = os.getenv("OPENAI_API_KEY") #st.write(openai_api_key) #st.write("HOLASAS") def extraer_texto(contenidoXML): # Espacio de nombres del XML namespaces = {'emas': 'http://www.leychile.cl/esquemas'} #print(contenidoXML) # Parsear el archivo XML #arbol = ET.parse(ruta_a_archivo) #tambien se puede pasar la ruta a un archivo /home/hola/ds49.xml #raiz = arbol.getroot() raiz = ET.fromstring(contenidoXML) #forma de "parsear" un XML directo desde string # Crear una lista para almacenar todos los textos textos = [] # Buscar todos los elementos 'texto' en el espacio de nombres correcto for texto in raiz.iter('{http://www.leychile.cl/esquemas}Texto'): texto.text = texto.text.replace("\t", " ") texto.text = re.sub(" +", " ", texto.text) texto.text = texto.text.replace(".\n", ".@") texto.text = texto.text.replace(":\n", ":@") texto.text = texto.text.replace("\n", " ") texto.text = texto.text.replace(".@", ".\n") texto.text = texto.text.replace(":@", ":\n") texto.text = texto.text.strip()+"\n" textos.append(texto.text) return textos def obtener_contenido_url(url): respuesta = requests.get(url) contenido = respuesta.text return contenido st.header("Minvu Dijur") st.subheader('Consulta en tu norma favorita 🔎') ######################################################## ####################################################### st.sidebar.image('./image/logos/minvu.png') # <--- Este es un caso de uso, para un Consultor con toda la normativa de un organo/servicio del Estado, como el MINVU (en este caso) ######################################################## ######################################################## norma = st.sidebar.selectbox( "Selecciona una norma", ('DS49 (V. y U.) de 2011', 'Ley 21.442 (Ley de copropiedad inmobiliaria)')) #st.write(type(option)) if norma=='DS49 (V. y U.) de 2011': placeholder="¿qué es una entidad patrocinante?" url="https://www.leychile.cl/Consulta/obtxml?opt=7&idNorma=1039424" else: placeholder="¿qué pasa si no se reunieren los quórum para sesionar?" url="https://www.leychile.cl/Consulta/obtxml?opt=7&idNorma=1174663" question = st.text_input("haz una pregunta:",placeholder=placeholder) ######### FIN WEB ########### #os.environ['OPENAI_API_KEY'] = openai_api_key contenidoXML = obtener_contenido_url(url) #<--contiene el XML de la norma en texto #st.write(url) ###################### #Normaliza eltexto XML para extraer texto ############### textos = extraer_texto(contenidoXML) #TEXTO normalizado COMPLETO DE LA NORMA en ascii (sin metadata) texto='\n'.join(textos) #i=i+1 #st.write("HOLA1") from langchain.schema import Document documento = [Document(page_content=texto, metadata={"nombre": "norma"})] #<---- del tipo #st.write(texto[:50]) #st.write("HOLA2") from langchain.indexes import VectorstoreIndexCreator #st.write(i) index = VectorstoreIndexCreator().from_documents(documento) #st.write("HOLA3") #st.write(texto[:100]) ############### ####MUESRRA Respuesta 1 if question: respuesta=index.query(question) st.write("👧 \n ",respuesta) ######################################## from langchain.text_splitter import RecursiveCharacterTextSplitter text_splitter = RecursiveCharacterTextSplitter(chunk_size = 500, chunk_overlap = 100) all_splits = text_splitter.split_documents(documento) ## from langchain.vectorstores import Chroma from langchain.embeddings import OpenAIEmbeddings vectorstore = Chroma.from_documents(documents=all_splits,embedding=OpenAIEmbeddings(openai_api_key=openai_api_key)) ## if question: docs = vectorstore.similarity_search(question) ## #import logging from langchain.chat_models import ChatOpenAI from langchain.retrievers.multi_query import MultiQueryRetriever #logging.basicConfig() #logging.getLogger('langchain.retrievers.multi_query').setLevel(logging.INFO) retriever_from_llm = MultiQueryRetriever.from_llm(retriever=vectorstore.as_retriever(), llm=ChatOpenAI(temperature=0)) if question: unique_docs = retriever_from_llm.get_relevant_documents(query=question) #### from langchain.prompts import ChatPromptTemplate chat = ChatOpenAI(openai_api_key=openai_api_key,temperature=0,max_tokens=600) #customer_style = """alta contenido de modismos chilenos \ #y usando lenguaje con mucho slang #""" #customer_style = """Muy formal y anticuado\ #y usando lenguaje rimbombante. #""" template_string = """En una lista, en la que cada elemento tiene el siguiente formato: \ Document("page_content" y "metadata"), responde usando exclusivamente la información contenida "page_content",\ a la siguiente pregunta: \ pregunta: ```{text}``` \n\n Verifica que la respuesta cumpla con: * Nunca mencionar tus fuentes de informacion, como decir "page_content" o elementos de la lista o documento. * No citar normas ni articulos, pero si es necesesario solo usa la información de "paga_content", señalandor Tipo de norma, año y de quien es y/o el número de articulo. * Tu respuesta puede ser hasta de 600 tokens. Finalmente verifica que la respuesta SIEMPRE responda esta pregunta primordial:\n {pregunta}. \n Si no responde, en no mas de 25 palabras, pide ingresar una nueva preguenta. """ prompt_template = ChatPromptTemplate.from_template(template_string) ####MUESRRA Respuesta 2 if question: customer_messages = prompt_template.format_messages( #style=customer_style, pregunta=question, text=unique_docs) respuesta2 = chat(customer_messages) st.divider() st.write("👨\n",respuesta2.content)