Spaces:
Sleeping
Sleeping
Paz Mundial
Browse files(primera vez!, ac谩)
Esta iteraci贸n me funcion贸 localmente, la subo a HF
app.py
ADDED
@@ -0,0 +1,230 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#Paz Munidal
|
2 |
+
#mi aporte
|
3 |
+
#
|
4 |
+
# Crea una consultor p煤blico, al servicio de las personas, sobre las normas formales Chilenas, las que est谩n publicadas oficialmente
|
5 |
+
# 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
|
6 |
+
# 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
|
7 |
+
# en arreglos ordenados matematicamente, los que luego matematicamente pueden ser comparados con la pregunta hecha al ingreso de la
|
8 |
+
# consulta y obtener un patron m谩t茅matico medible que en el mundo de las ideas, represente la semantica de la pregunta y responder
|
9 |
+
# con la norma que se consulta, en lo que m谩s sentido tenga.
|
10 |
+
#
|
11 |
+
# 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!!馃)!!!
|
12 |
+
# @fermaf
|
13 |
+
# Nostr: npub1fermafqdu9ghcmsflq9wdsfwhg3zf93e6n49204ch2ztf98utw6qmhavug
|
14 |
+
#
|
15 |
+
# (de ac谩 en adelante con mis garabatos/comentarios incluidos xd, sin ellos no hubiese hecho la primera iteraci贸n!! 馃 )
|
16 |
+
#
|
17 |
+
#(https://30days.streamlit.app/)
|
18 |
+
#pip install streamlit
|
19 |
+
i=0
|
20 |
+
import streamlit as st
|
21 |
+
import xml.etree.ElementTree as ET
|
22 |
+
|
23 |
+
st.header("Minvu Dijur")
|
24 |
+
st.subheader('Consulta en tu norma favorita 馃攷')
|
25 |
+
|
26 |
+
|
27 |
+
#option = st.selectbox(
|
28 |
+
# ' ',
|
29 |
+
# ('DS49 (V. y U.) de 2011', 'Ley 21.442 (Ley de copropiedad inmobiliaria)'))
|
30 |
+
|
31 |
+
|
32 |
+
########################################################
|
33 |
+
#######################################################
|
34 |
+
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)
|
35 |
+
########################################################
|
36 |
+
########################################################
|
37 |
+
norma = st.sidebar.selectbox(
|
38 |
+
"Selecciona una norma",
|
39 |
+
('DS49 (V. y U.) de 2011', 'Ley 21.442 (Ley de copropiedad inmobiliaria)'))
|
40 |
+
|
41 |
+
|
42 |
+
#st.write(type(option))
|
43 |
+
if norma=='DS49 (V. y U.) de 2011':
|
44 |
+
placeholder="驴qu茅 es una entidad patrocinante?"
|
45 |
+
url="https://www.leychile.cl/Consulta/obtxml?opt=7&idNorma=1039424"
|
46 |
+
else:
|
47 |
+
placeholder="驴qu茅 pasa si no se reunieren los qu贸rum para sesionar?"
|
48 |
+
url="https://www.leychile.cl/Consulta/obtxml?opt=7&idNorma=1174663"
|
49 |
+
|
50 |
+
question = st.text_input("haz una pregunta:",placeholder=placeholder)
|
51 |
+
|
52 |
+
#st.write("pregunta")
|
53 |
+
#st.write(question)
|
54 |
+
|
55 |
+
|
56 |
+
#=st.inp input("ingrese su API key?\n>")
|
57 |
+
openai_api_key = st.text_input("API key de OpenAI :",placeholder="sk-")
|
58 |
+
|
59 |
+
|
60 |
+
######### FIN WEB ###########
|
61 |
+
import os
|
62 |
+
os.environ['OPENAI_API_KEY'] = openai_api_key
|
63 |
+
#st.write( os.getenv('OPENAI_API_KEY'))
|
64 |
+
|
65 |
+
####BAJA NORMA
|
66 |
+
#Para bajar norma de BCN.CL otentiendo el XML
|
67 |
+
#DS49: https://www.leychile.cl/Consulta/obtxml?opt=7&idNorma=1039424
|
68 |
+
import requests
|
69 |
+
|
70 |
+
def obtener_contenido_url(url):
|
71 |
+
respuesta = requests.get(url)
|
72 |
+
contenido = respuesta.text
|
73 |
+
return contenido
|
74 |
+
|
75 |
+
#url = "https://www.leychile.cl/Consulta/obtxml?opt=7&idNorma=1039424" # Reemplazar con la URL deseada, para obtener el XML de la norma
|
76 |
+
#url="https://www.leychile.cl/Consulta/obtxml?opt=7&idNorma=1174663"
|
77 |
+
contenidoXML = obtener_contenido_url(url) #<--contiene el XML de la norma en texto
|
78 |
+
|
79 |
+
|
80 |
+
|
81 |
+
######################
|
82 |
+
|
83 |
+
|
84 |
+
#Normaliza eltexto XML para extraer texto
|
85 |
+
import re
|
86 |
+
|
87 |
+
def extraer_texto(contenidoXML):
|
88 |
+
# Espacio de nombres del XML
|
89 |
+
namespaces = {'emas': 'http://www.leychile.cl/esquemas'}
|
90 |
+
#print(contenidoXML)
|
91 |
+
|
92 |
+
# Parsear el archivo XML
|
93 |
+
#arbol = ET.parse(ruta_a_archivo) #tambien se puede pasar la ruta a un archivo /home/hola/ds49.xml
|
94 |
+
#raiz = arbol.getroot()
|
95 |
+
|
96 |
+
raiz = ET.fromstring(contenidoXML) #forma de "parsear" un XML directo desde string
|
97 |
+
|
98 |
+
|
99 |
+
# Crear una lista para almacenar todos los textos
|
100 |
+
textos = []
|
101 |
+
|
102 |
+
# Buscar todos los elementos 'texto' en el espacio de nombres correcto
|
103 |
+
for texto in raiz.iter('{http://www.leychile.cl/esquemas}Texto'):
|
104 |
+
texto.text = texto.text.replace("\t", " ")
|
105 |
+
texto.text = re.sub(" +", " ", texto.text)
|
106 |
+
|
107 |
+
texto.text = texto.text.replace(".\n", ".@")
|
108 |
+
texto.text = texto.text.replace(":\n", ":@")
|
109 |
+
texto.text = texto.text.replace("\n", " ")
|
110 |
+
texto.text = texto.text.replace(".@", ".\n")
|
111 |
+
texto.text = texto.text.replace(":@", ":\n")
|
112 |
+
|
113 |
+
texto.text = texto.text.strip()+"\n"
|
114 |
+
textos.append(texto.text)
|
115 |
+
|
116 |
+
return textos
|
117 |
+
|
118 |
+
|
119 |
+
###############
|
120 |
+
|
121 |
+
textos = extraer_texto(contenidoXML)
|
122 |
+
|
123 |
+
#TEXTO normalizado COMPLETO DE LA NORMA en ascii (sin metadata)
|
124 |
+
texto='\n'.join(textos)
|
125 |
+
#i=i+1
|
126 |
+
#st.write(i)
|
127 |
+
|
128 |
+
from langchain.schema import Document
|
129 |
+
|
130 |
+
documento = [Document(page_content=texto, metadata={"nombre": "norma"})] #<---- del tipo <class 'langchain.schema.document.Document'>
|
131 |
+
|
132 |
+
#st.write(texto[:200])
|
133 |
+
|
134 |
+
|
135 |
+
|
136 |
+
from langchain.indexes import VectorstoreIndexCreator
|
137 |
+
#st.write(i)
|
138 |
+
|
139 |
+
index = VectorstoreIndexCreator().from_documents(documento)
|
140 |
+
|
141 |
+
#st.write(texto[:100])
|
142 |
+
###############
|
143 |
+
|
144 |
+
####MUESRRA Respuesta 1
|
145 |
+
import time
|
146 |
+
|
147 |
+
if question:
|
148 |
+
respuesta=index.query(question)
|
149 |
+
|
150 |
+
st.write("馃懅 \n ",respuesta)
|
151 |
+
|
152 |
+
|
153 |
+
|
154 |
+
########################################
|
155 |
+
|
156 |
+
from langchain.text_splitter import RecursiveCharacterTextSplitter
|
157 |
+
text_splitter = RecursiveCharacterTextSplitter(chunk_size = 500, chunk_overlap = 100)
|
158 |
+
all_splits = text_splitter.split_documents(documento)
|
159 |
+
##
|
160 |
+
from langchain.vectorstores import Chroma
|
161 |
+
from langchain.embeddings import OpenAIEmbeddings
|
162 |
+
|
163 |
+
vectorstore = Chroma.from_documents(documents=all_splits,embedding=OpenAIEmbeddings())
|
164 |
+
##
|
165 |
+
if question:
|
166 |
+
docs = vectorstore.similarity_search(question)
|
167 |
+
##
|
168 |
+
#import logging
|
169 |
+
from langchain.chat_models import ChatOpenAI
|
170 |
+
from langchain.retrievers.multi_query import MultiQueryRetriever
|
171 |
+
#logging.basicConfig()
|
172 |
+
#logging.getLogger('langchain.retrievers.multi_query').setLevel(logging.INFO)
|
173 |
+
retriever_from_llm = MultiQueryRetriever.from_llm(retriever=vectorstore.as_retriever(),
|
174 |
+
llm=ChatOpenAI(temperature=0))
|
175 |
+
if question:
|
176 |
+
unique_docs = retriever_from_llm.get_relevant_documents(query=question)
|
177 |
+
|
178 |
+
|
179 |
+
####
|
180 |
+
from langchain.prompts import ChatPromptTemplate
|
181 |
+
|
182 |
+
chat = ChatOpenAI(openai_api_key=openai_api_key,temperature=0,max_tokens=600)
|
183 |
+
|
184 |
+
|
185 |
+
#customer_style = """alta contenido de modismos chilenos \
|
186 |
+
#y usando lenguaje con mucho slang
|
187 |
+
#"""
|
188 |
+
|
189 |
+
|
190 |
+
#customer_style = """Muy formal y anticuado\
|
191 |
+
#y usando lenguaje rimbombante.
|
192 |
+
#"""
|
193 |
+
|
194 |
+
|
195 |
+
template_string = """En una lista, en la que cada elemento tiene el siguiente formato: \
|
196 |
+
Document("page_content" y "metadata"), responde usando exclusivamente la informaci贸n contenida "page_content",\
|
197 |
+
a la siguiente pregunta: \
|
198 |
+
pregunta: ```{text}``` \n\n
|
199 |
+
|
200 |
+
Verifica que la respuesta cumpla con:
|
201 |
+
* Nunca mencionar tus fuentes de informacion, como decir "page_content" o elementos de la lista o documento.
|
202 |
+
* 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.
|
203 |
+
* Tu respuesta puede ser hasta de 600 tokens.
|
204 |
+
|
205 |
+
|
206 |
+
|
207 |
+
Finalmente verifica que la respuesta SIEMPRE responda esta pregunta primordial:\n
|
208 |
+
{pregunta}. \n
|
209 |
+
|
210 |
+
Si no responde, en no mas de 25 palabras, pide ingresar una nueva preguenta.
|
211 |
+
|
212 |
+
"""
|
213 |
+
|
214 |
+
prompt_template = ChatPromptTemplate.from_template(template_string)
|
215 |
+
|
216 |
+
|
217 |
+
|
218 |
+
|
219 |
+
####MUESRRA Respuesta 2
|
220 |
+
if question:
|
221 |
+
|
222 |
+
customer_messages = prompt_template.format_messages(
|
223 |
+
#style=customer_style,
|
224 |
+
pregunta=question,
|
225 |
+
text=unique_docs)
|
226 |
+
|
227 |
+
respuesta2 = chat(customer_messages)
|
228 |
+
st.divider()
|
229 |
+
st.write("馃懆\n",respuesta2.content)
|
230 |
+
|