fermaf commited on
Commit
db19a5e
1 Parent(s): 0e5f3a9

Paz Mundial

Browse files

(primera vez!, acá)
Esta iteración me funcionó localmente, la subo a HF

Files changed (1) hide show
  1. app.py +230 -0
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
+