Jorge Henao commited on
Commit
44c25e2
1 Parent(s): ae5fd49

pages refactor

Browse files
.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ venv/
2
+ __pycache__/
README.md CHANGED
@@ -5,7 +5,7 @@ colorFrom: yellow
5
  colorTo: blue
6
  sdk: streamlit
7
  sdk_version: 1.10.0
8
- app_file: app_pinecode.py
9
  pinned: True
10
  license: apache-2.0
11
  ---
 
5
  colorTo: blue
6
  sdk: streamlit
7
  sdk_version: 1.10.0
8
+ app_file: main_page.py
9
  pinned: True
10
  license: apache-2.0
11
  ---
__pycache__/config.cpython-38.pyc DELETED
Binary file (569 Bytes)
 
__pycache__/document_quieries.cpython-38.pyc DELETED
Binary file (3.26 kB)
 
__pycache__/pinecode_quieries.cpython-38.pyc DELETED
Binary file (5.23 kB)
 
about.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+
3
+ def about_ask2democracy():
4
+ st.markdown("""
5
+ <h1 style='
6
+ text-align: center;
7
+ color: #39AA35'>
8
+ Ask2Democracy 🇨🇴
9
+ </h1>
10
+ <p>Muchas de las discusiones que ocurren en Colombia generalmente están sustentadas en artículos o pdfs que salvo excpciones, casi nadie lee.
11
+ Este sistema ha indexado algunos textos relevantes para la discución pública que suelen estar dispersos y poco accesibles, además, apoyandose en modelos de lenguaje (abajo más detalles) puede entender preguntas elaboradas.
12
+ Algunos de los textos indexados: las propuestas presidenciales del 22, los hallazgos de la comisión de la verdad, los textos de las reformas, entre otros.
13
+ <div align="right">
14
+ Creado por Jorge Henao 🇨🇴 <a href="https://twitter.com/jhenaotw" target='_blank'>Twitter</a> <a href="https://www.linkedin.com/in/henaojorge" target='_blank'/>LinkedIn</a>
15
+ </div>
16
+ """, unsafe_allow_html=True)
17
+ description = """
18
+ <p>
19
+ <h2>Sobre esta iniciativa</h2>
20
+ Pretende ayudar a construir democracia participativa apaloncándose en el estado del arte de la inteligencia artificial.
21
+ Siendo una herramienta que aporta a la discución pública, empoderando al ciudadano del común para ser partícipe del debate público mientras hace preguntas en su propio lenguaje, y llegando a sus propias conclusiones.
22
+ <h2>Inteligencia artificial abierta en la democracia</h2>
23
+ Uno de los objetivos es contribuir a la inteligencia artificial abierta y en español, con la construcción de un dataset y el entrenamiento de un modelo de lenguaje adaptado para las discuciones ciudadanas.
24
+ Algo útil para elevar la calidad del debate en todos los países de habla hispana.
25
+ <h2>¿Cómo utilizar este espacio?</h2>
26
+ Selecciona el texto sobre el que quieres buscar en el panel de la izquierda. Luego puedes escribir preguntas concretas como “¿cantidad de víctimas en la masacre de bojayá?”. No se trata de un sistema de búsquedas basado en palabras clave, por el contrario, puedes redactar preguntas más extensas y elaboradas. Cuanto más contexto le des a la pregunta, mejor funciona.
27
+ <h2>Ask2Democracy v 1.2</h2>
28
+ Esta version usa sentence transformers, Cosine similarity, y una base de dactos vectorial Pinecone para mejorar la precision en las respuestas.
29
+ Los modelos transformers de lenguaje utilizados son:
30
+ <code aligh="left">
31
+ sentence-transformers/multi-qa-MiniLM-L6-cos-v1
32
+ deepset/xlm-roberta-base-squad2-distilled
33
+ </code>
34
+ <h2>Beta disclaimer</h2>
35
+ Las respuestas que arroja el sistema no han sido pregrabadas ni basadas en opiniones. Todas son respuestas extraídas de fuentes oficiales, como el Informe final de la CEV.
36
+ Este explorador usa modelos de lenguaje (sentence transformers, bert, otros ) para entender el lenguaje español, sin embargo, necesita de un mayor entrenamiento por lo que, en ocasiones, puede ser confuso y no tan preciso.
37
+ Si quieres apoyar escríbeme a <a href="mailto:jorge.henao@diezonce.co">jorge.henao@diezonce.co</a>
38
+ </p>
39
+ """
40
+ st.markdown(description, unsafe_allow_html=True)
app_es.py DELETED
@@ -1,101 +0,0 @@
1
- import streamlit as st
2
- import json
3
- import time
4
- from config import Config
5
- from document_quieries import ExtractiveProposalQueries
6
-
7
- extractive_query = ExtractiveProposalQueries(es_host = Config.es_host, es_index = Config.proposals_index,
8
- es_user = Config.es_user, es_password = Config.es_password,
9
- reader_name_or_path = Config.reader_model_name_or_path,
10
- use_gpu = Config.use_gpu)
11
-
12
- def fake_search(question, retriever_top_k, reader_top_k):
13
- #p1_result = query.search_by_query(query = question, retriever_top_k = retriever_top_k, reader_top_k = reader_top_k, es_index = "informecomisionverdad")
14
- result = []
15
- p = """
16
- La masacre de Bojayá fue perpetrada por el Frente José María Córdoba, de las FARC-EP, al lanzar un cilindro bomba que cayó en una iglesia en la que los pobladores se refugiaban del enfrentamiento de este grupo con el Bloque Élmer Cárdenas de las AUC. Las víctimas fueron 81 personas, 47 de ellas eran niñas, niños y adolescentes
17
- """
18
- for i in range(0, reader_top_k):
19
- result.append([[i+1],"81 personas", p[:250],"Las masacres","Comisión de la verdad - Informe de hallazgos y recomendaciones Junio 2022","5"])
20
-
21
- return result
22
-
23
- def search(question, retriever_top_k, reader_top_k):
24
- query_result = extractive_query.search_by_query(query = question, retriever_top_k = retriever_top_k, reader_top_k = reader_top_k)
25
- result = []
26
- for i in range(0, len(query_result)):
27
- item = query_result[i]
28
- result.append([[i+1], item.answer, item.context[:200], item.meta['title'], item.meta['source'], int(item.meta['page'])])
29
-
30
- return result
31
-
32
- if __name__ == "__main__":
33
- # streamlit part starts here with title
34
- title = """
35
- <h1 style='
36
- text-align: center;
37
- color: #39AA35'>
38
- Ask2Democracy 🇨🇴 - Informe de la comisión de la verdad Junio 2022
39
- </h1>
40
- <p>
41
- El 28 de junio del 2022, la Comisión de la Verdad en Colombia liberó su informe final. Fue el resultado de más de 3 años de investigación sobre el conflicto armado interno durante los últimos 60 años. Apoyándose en un modelo de inteligencia artificial. Este espacio pretende ayudar a explorar las más de 6000 páginas que conforman más de 10 libros del Informe, comenzando por el de Hallazgos y recomendaciones.
42
- """
43
- st.markdown(title, unsafe_allow_html=True)
44
- # input form
45
- with st.form("my_form"):
46
- # here we have input space
47
- query = st.text_input("Ingresa la pregunta, frase abierta o tema que quieres explorar",
48
- placeholder="Escribe tu consulta aquí...")
49
- # Every form must have a submit button.
50
- submitted = st.form_submit_button("Buscar")
51
-
52
- # on submit we execute search
53
- if(submitted):
54
- # set start time
55
- stt = time.time()
56
- # retrieve top 5 documents
57
- results = search(query, retriever_top_k=5, reader_top_k=3)
58
- # set endtime
59
- ent = time.time()
60
- # measure resulting time
61
- elapsed_time = round(ent - stt, 2)
62
-
63
- # show which query was entered, and what was searching time
64
- st.write(f"**Resultados relacionados con:** \"{query}\" ({elapsed_time} sec.)")
65
- # then we use loop to show results
66
- for i, answer in enumerate(results):
67
- # answer starts with header
68
- st.subheader(f"{answer[1]}")
69
- # cropped answer
70
- doc = answer[2][:250] + "..."
71
- # and url to the full answer
72
- url = f"https://www.comisiondelaverdad.co/sites/default/files/descargables/2022-06/Informe%20Final%20capi%CC%81tulo%20Hallazgos%20y%20recomendaciones.pdf#page={answer[5]+1}"
73
- # then we display it
74
- #st.markdown(f'{doc}\n<br>Fuente: {answer[4]}\n<br>Capítulo: {answer[3]}\n<br>Página: {answer[5]}\n[**Lee más aquí**]({url})\n', unsafe_allow_html=True)
75
- st.markdown(f"{doc}[**Lee más aquí**]({url})")
76
- st.caption(f"Fuente: {answer[4]} - Capítulo: {answer[3]} - Página: {answer[5]}")
77
-
78
- st.markdown("---")
79
- else:
80
- st.markdown("""Cuanto más contexto le des a la pregunta, mejor funciona. puedes escribir consultas como: _**\"¿periodo con más detenciones arbitrarias registradas?\"**_,\_**\"¿cantidad de víctimas en la masacre de bojayá?\"**_,\
81
- _**\"¿cuantas víctimas de desplazamiento en antioquia?\"**_""")
82
- st.markdown("""
83
- <div align="right">
84
- Creado por Jorge Henao 🇨🇴 <a href="https://twitter.com/jhenaotw" target='_blank'>Twitter</a> <a href="https://www.linkedin.com/in/henaojorge" target='_blank'/>LinkedIn</a>
85
- <br>Con el apoyo de Manuela Gonima en comunicaciones 🇨🇴 <a href="https://www.instagram.com/mgcomunicacionesco/" target='_blank'/>Instagram</a> <a href="https://www.linkedin.com/in/manuela-gonima-carvajal" target='_blank'/>LinkedIn</a>
86
- </div>
87
- """, unsafe_allow_html=True)
88
-
89
- description = """
90
- <p>
91
- <h2>Sobre esta iniciativa</h2>
92
- Se enmarca en la construcción de ciudadanía, la creación de valor público y el fortalecimiento de la democracia participativa desde la invitación a la población a informarse, conocer, compartir y dialogar en torno a la memoria histórica y a la verdad del conflicto armado colombiano, partiendo del Informe de la Comisión de la Verdad, se espera incluir varias fuentes adicionales. Hace parte de un proyecto open-source que utiliza Inteligencia Artificial para contribuir al entendimiento de temas relevantes para el país.<a href= "https://github.com/jorge-henao/ask_to_democracy"> repo en github con FastAPI</a>
93
- </br></br>Por: Jorge Henao 🇨🇴 <a href="https://twitter.com/jhenaotw" target='_blank'>Twitter</a> <a href="https://www.linkedin.com/in/henaojorge" target='_blank'/>LinkedIn</a>, con el apoyo de Manuela Gónima 🇨🇴 <a href="https://www.instagram.com/mgcomunicacionesco/" target='_blank'/>Instagram</a> <a href="https://www.linkedin.com/in/manuela-gonima-carvajal" target='_blank'/>LinkedIn</a>
94
- <h2>¿Cómo utilizar este espacio?</h2>
95
- Puedes escribir oraciones abiertas como “Masacres en Antioquia”, o una pregunta concreta como “¿cantidad de víctimas en la masacre de bojayá?”. No se trata de un sistema de búsquedas basado en palabras clave, por el contrario, puedes redactar preguntas más extensas y elaboradas. Cuanto más contexto le des a la pregunta, mejor funciona.
96
- <h2>Beta disclaimer</h2>
97
- Las respuestas que arroja el sistema no han sido pregrabadas ni basadas en opiniones. Todas son respuestas extraídas del Informe final de la CEV, por un sistema en beta. Este explorador se basa en un modelo de inteligencia artificial entrenado para entender el lenguaje español, sin embargo, necesita de un mayor entrenamiento por lo que, en ocasiones, puede ser confuso y no tan preciso.
98
- Si quieres apoyar escríbeme a <a href="mailto:jorge.henao@diezonce.co">jorge.henao@diezonce.co</a>
99
- </p>
100
- """
101
- st.markdown(description, unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app_pinecode.py DELETED
@@ -1,165 +0,0 @@
1
- import streamlit as st
2
- import json
3
- import time
4
- from config import Config
5
- from pinecode_quieries import PinecodeProposalQueries
6
-
7
- import logging
8
-
9
-
10
- logging.basicConfig(format="%(levelname)s - %(name)s - %(message)s", level=logging.WARNING)
11
- logging.getLogger("haystack").setLevel(logging.INFO)
12
-
13
- logging.info("This is a test log ..")
14
-
15
- samples_salud = """
16
- ¿Cuándo se implementará el Sistema de Salud?
17
- ¿Cómo se implementará el Sistema de Salud?
18
- ¿Qué es principio de interpretación y fundamento de la transición en relación al Sistema de Salud?
19
- ¿Qué se garantiza en todo momento con el nuevo Sistema de Salud?
20
- ¿Qué son los Centros de Atención Primaria Integrales y Resolutivos en Salud - CAPIRS?
21
- ¿Qué se garantiza durante el periodo de transición del nuevo Sistema de Salud?
22
- ¿Puede haber personas sin protección de su salud durante el periodo de transición?
23
- ¿Cuál es el derecho fundamental que se garantiza en todo momento durante la transición del nuevo Sistema de Salud?
24
- ¿En qué país se está implementando este Sistema de Salud?
25
- ¿Qué se debe realizar para garantizar la gestión de los recursos en el nivel nacional y desconcentrado?
26
- ¿Cómo se regirá el régimen de contratación de los contratos mencionados en el texto?
27
- ¿Qué son las cláusulas exorbitantes previstas en el estatuto General de Contratación de la administración pública?
28
- ¿Qué principios deben atender los contratos mencionados en el texto?
29
- ¿Cuál es el ámbito de aplicación de los contratos mencionados en el texto?
30
- ¿Quién tiene la responsabilidad de realizar la auditoría de las cuentas en relación a estos contratos?
31
- ¿Cuáles son las características que deben cumplir los contratos mencionados en el texto?
32
- ¿Qué se entiende por "coordinación" en el contexto de los contratos mencionados en el texto?
33
- ¿Qué objetivo se busca con los contratos mencionados en el texto?
34
- ¿Quién será el encargado de contratar los servicios de salud y otros requerimientos para el cumplimiento de su labor en el nivel regional?
35
- ¿Qué tipo de instituciones hospitalarias y ambulatorias se integran a la red de servicios del territorio?
36
- ¿Qué tarifas deben seguir las instituciones hospitalarias y ambulatorias para la prestación de servicios de salud?
37
- ¿Qué busca modular el régimen de tarifas y formas de pago para la prestación de servicios de salud?
38
- ¿Qué tipo de registro llevará el Fondo Regional de Salud?
39
- ¿Cuáles son algunas de las variables que se incluirán en el registro de cada servicio prestado y pagado?
40
- """
41
-
42
- samples_hallazgos = """
43
- ¿Cuándo se implementará el Sistema de Salud?
44
- ¿Cómo se implementará el Sistema de Salud?
45
- ¿Qué es principio de interpretación y fundamento de la transición en relación al Sistema de Salud?
46
- ¿Qué se garantiza en todo momento con el nuevo Sistema de Salud?
47
- ¿Qué son los Centros de Atención Primaria Integrales y Resolutivos en Salud - CAPIRS?
48
- ¿Qué se garantiza durante el periodo de transición del nuevo Sistema de Salud?
49
- ¿Puede haber personas sin protección de su salud durante el periodo de transición?
50
- ¿Cuál es el derecho fundamental que se garantiza en todo momento durante la transición del nuevo Sistema de Salud?
51
- ¿En qué país se está implementando este Sistema de Salud?
52
- ¿Qué se debe realizar para garantizar la gestión de los recursos en el nivel nacional y desconcentrado?
53
- ¿Cómo se regirá el régimen de contratación de los contratos mencionados en el texto?
54
- ¿Qué son las cláusulas exorbitantes previstas en el estatuto General de Contratación de la administración pública?
55
- ¿Qué principios deben atender los contratos mencionados en el texto?
56
- ¿Cuál es el ámbito de aplicación de los contratos mencionados en el texto?
57
- ¿Quién tiene la responsabilidad de realizar la auditoría de las cuentas en relación a estos contratos?
58
- ¿Cuáles son las características que deben cumplir los contratos mencionados en el texto?
59
- ¿Qué se entiende por "coordinación" en el contexto de los contratos mencionados en el texto?
60
- ¿Qué objetivo se busca con los contratos mencionados en el texto?
61
- ¿Quién será el encargado de contratar los servicios de salud y otros requerimientos para el cumplimiento de su labor en el nivel regional?
62
- ¿Qué tipo de instituciones hospitalarias y ambulatorias se integran a la red de servicios del territorio?
63
- ¿Qué tarifas deben seguir las instituciones hospitalarias y ambulatorias para la prestación de servicios de salud?
64
- ¿Qué busca modular el régimen de tarifas y formas de pago para la prestación de servicios de salud?
65
- ¿Qué tipo de registro llevará el Fondo Regional de Salud?
66
- ¿Cuáles son algunas de las variables que se incluirán en el registro de cada servicio prestado y pagado?
67
- """
68
-
69
- extractive_query = PinecodeProposalQueries (es_host = Config.es_host, es_index = Config.proposals_index,
70
- es_user = Config.es_user, es_password = Config.es_password,
71
- reader_name_or_path = Config.reader_model_name_or_path,
72
- use_gpu = Config.use_gpu)
73
-
74
- def clear_submit():
75
- st.session_state["submit"] = False
76
-
77
- def fake_search(question, retriever_top_k, reader_top_k):
78
- #p1_result = query.search_by_query(query = question, retriever_top_k = retriever_top_k, reader_top_k = reader_top_k, es_index = "informecomisionverdad")
79
- result = []
80
- p = """
81
- La masacre de Bojayá fue perpetrada por el Frente José María Córdoba, de las FARC-EP, al lanzar un cilindro bomba que cayó en una iglesia en la que los pobladores se refugiaban del enfrentamiento de este grupo con el Bloque Élmer Cárdenas de las AUC. Las víctimas fueron 81 personas, 47 de ellas eran niñas, niños y adolescentes
82
- """
83
- for i in range(0, reader_top_k):
84
- result.append([[i+1],"81 personas", p[:250],"Las masacres","Comisión de la verdad - Informe de hallazgos y recomendaciones Junio 2022","5"])
85
-
86
- return result
87
-
88
- def search(question, retriever_top_k, reader_top_k):
89
- query_result = extractive_query.search_by_query(query = question, retriever_top_k = retriever_top_k, reader_top_k = reader_top_k)
90
- result = []
91
- for i in range(0, len(query_result)):
92
- item = query_result[i]
93
- result.append([[i+1], item.answer, item.context[:200], item.meta['title'], item.meta['source'], int(item.meta['page'])])
94
- #result.append([[i+1], item.answer, item.context[:200], item.meta['title']])
95
-
96
- return result
97
-
98
- def search_and_show_results():
99
- # set start time
100
- stt = time.time()
101
- # retrieve top 5 documents
102
- results = search(query, retriever_top_k=5, reader_top_k=3)
103
- # set endtime
104
- ent = time.time()
105
- # measure resulting time
106
- elapsed_time = round(ent - stt, 2)
107
-
108
- # show which query was entered, and what was searching time
109
- st.write(f"**Resultados relacionados con:** \"{query}\" ({elapsed_time} sec.)")
110
- # then we use loop to show results
111
- for i, answer in enumerate(results):
112
- # answer starts with header
113
- st.subheader(f"{answer[1]}")
114
- # cropped answer
115
- doc = answer[2][:250] + "..."
116
- # and url to the full answer
117
- #url = f"https://www.comisiondelaverdad.co/sites/default/files/descargables/2022-06/Informe%20Final%20capi%CC%81tulo%20Hallazgos%20y%20recomendaciones.pdf#page={answer[5]+1}"
118
- url = f"https://petro.presidencia.gov.co/Documents/230213-Reforma-salud.pdf"
119
- # then we display it
120
- #st.markdown(f'{doc}\n<br>Fuente: {answer[4]}\n<br>Capítulo: {answer[3]}\n<br>Página: {answer[5]}\n[**Lee más aquí**]({url})\n', unsafe_allow_html=True)
121
- st.markdown(f"{doc}[**Lee más aquí**]({url})")
122
- st.caption(f"Fuente: {answer[4]} - Capítulo: {answer[3]} - Página: {answer[5]}")
123
-
124
- st.markdown("---")
125
-
126
- #results = search("que es el adres", retriever_top_k=5, reader_top_k=3)
127
-
128
- # if __name__ == "__main__":
129
- # streamlit part starts here with title
130
-
131
- st.set_page_config(layout="wide", page_title="Buscar")
132
- title = """
133
- <h1 style='
134
- text-align: center;
135
- color: #39AA35'>
136
- Ask2Democracy 🇨🇴
137
- </h1>
138
- <p>
139
- Muchas de las discusiones que ocurren en Colombia terminan siendo artículos o pdfs que salvo excpciones, nadie lee.
140
- Este sistema de búsquedas usa inteligencia artificial para apoyar el entendimiendo de textos relevantes que suelen estar dispersos y poco accesibles.
141
- Como las propuestas presidenciales del 22, los hallazgos de la comisión de la verdad, los textos de las reformas, etc.
142
- """
143
- st.markdown(title, unsafe_allow_html=True)
144
- st.markdown("""<div align="right">
145
- Creado por Jorge Henao 🇨🇴 <a href="https://twitter.com/jhenaotw" target='_blank'>Twitter</a> <a href="https://www.linkedin.com/in/henaojorge" target='_blank'/>LinkedIn</a> </div>
146
- """, unsafe_allow_html=True)
147
- st.write(f"Cuanto más contexto le des a la pregunta mejor funciona el sistema.")
148
-
149
- # Sidebar
150
- selected_index = None
151
- query = st.text_area("Escribe tu pregunta", on_change=clear_submit)
152
- button = st.button("Buscar")
153
- if button or st.session_state.get("submit"):
154
- if not query:
155
- st.error("¡escribe una pregunta!")
156
- else:
157
- st.session_state["submit"] = True
158
- search_and_show_results()
159
-
160
- with st.sidebar:
161
- st.write("Ask2Democracy 🇨🇴")
162
- selected_index = st.selectbox("Seleccion la colección sobre el que deseas buscar",
163
- ["Propuesta Reforma de la salud 2023",
164
- "Hallazgos de la comisión de la verdad 2022"])
165
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
config.py CHANGED
@@ -1,9 +1,12 @@
1
  class Config():
2
  es_host = "saimon-askwdemocracy.es.us-central1.gcp.cloud.es.io"
3
  es_user = "elastic"
4
- es_password = "53f2a7a9-ea9d-4fd2-a8bc-f471b67f0262"
5
- proposals_index = "docsreloaded"
 
6
  reader_model_name_or_path = "deepset/xlm-roberta-base-squad2-distilled"
 
 
 
7
  #reader_model_name_or_path = "deepset/xlm-roberta-base-squad2"
8
- use_gpu = True
9
-
 
1
  class Config():
2
  es_host = "saimon-askwdemocracy.es.us-central1.gcp.cloud.es.io"
3
  es_user = "elastic"
4
+ #es_password = "53f2a7a9-ea9d-4fd2-a8bc-f471b67f0262"
5
+ es_password = "1f45bf76-b600-42b3-b2cc-ab6062693eb7"
6
+ index_name = "docsreloaded"
7
  reader_model_name_or_path = "deepset/xlm-roberta-base-squad2-distilled"
8
+ pinecone_environment="us-east-1-aws"
9
+ embedding_dim = 384
10
+ similarity="cosine"
11
  #reader_model_name_or_path = "deepset/xlm-roberta-base-squad2"
12
+ use_gpu = True
 
document_quieries.py DELETED
@@ -1,60 +0,0 @@
1
- from abc import ABC, abstractmethod
2
- from haystack.nodes import BM25Retriever, FARMReader
3
- from haystack.document_stores import ElasticsearchDocumentStore
4
- from haystack.pipelines import ExtractiveQAPipeline
5
- import certifi
6
- import datetime
7
- import requests
8
- from base64 import b64encode
9
-
10
- ca_certs=certifi.where()
11
-
12
- class DocumentQueries(ABC):
13
-
14
- @abstractmethod
15
- def search_by_query(self, query : str, retriever_top_k: int, reader_top_k: int, es_index: str):
16
- pass
17
-
18
- class ExtractiveProposalQueries(DocumentQueries):
19
-
20
- def __init__(self, es_host: str, es_index: str, es_user, es_password, reader_name_or_path: str, use_gpu = True) -> None:
21
- reader = FARMReader(model_name_or_path = reader_name_or_path, use_gpu = use_gpu, num_processes=1, context_window_size=200)
22
- self._initialize_pipeline(es_host, es_index, es_user, es_password, reader = reader)
23
- self.log = Log(es_host= es_host, es_index="log", es_user = es_user, es_password= es_password)
24
-
25
- def _initialize_pipeline(self, es_host, es_index, es_user, es_password, reader = None):
26
- if reader is not None:
27
- self.reader = reader
28
- self.es_host = es_host
29
- self.es_user = es_user
30
- self.es_password = es_password
31
- self.document_store = ElasticsearchDocumentStore(host = es_host, username=es_user, password=es_password, index = es_index, port = 443, scheme='https', verify_certs=True, ca_certs=ca_certs, create_index=False)
32
- self.retriever = BM25Retriever(document_store = self.document_store)
33
- self.pipe = ExtractiveQAPipeline(self.reader, self.retriever)
34
-
35
- def search_by_query(self, query : str, retriever_top_k: int, reader_top_k: int, es_index: str = None) :
36
- self.log.write_log(query, "hfspace-informecomision")
37
- #if es_index is not None:
38
- #self._initialize_pipeline(self.es_host, es_index, self.es_user, self.es_password)
39
- params = {"Retriever": {"top_k": retriever_top_k}, "Reader": {"top_k": reader_top_k}}
40
- prediction = self.pipe.run( query = query, params = params)
41
- return prediction["answers"]
42
-
43
- class Log():
44
-
45
- def __init__(self, es_host: str, es_index: str, es_user, es_password) -> None:
46
- self.elastic_endpoint = f"https://{es_host}:443/{es_index}/_doc"
47
- self.credentials = b64encode(b"3pvrzh9tl:4yl4vk9ijr").decode("ascii")
48
- self.auth_header = { 'Authorization' : 'Basic %s' % self.credentials }
49
-
50
- def write_log(self, message: str, source: str) -> None:
51
- created_date = datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ')
52
- post_data = {
53
- "message" : message,
54
- "createdDate": {
55
- "date" : created_date
56
- },
57
- "source": source
58
- }
59
- r = requests.post(self.elastic_endpoint, json = post_data, headers = self.auth_header)
60
- print(r.text)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
hallazgos.py ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from random import randint
2
+ import streamlit as st
3
+
4
+ import streamlit as st
5
+ import json
6
+ import time
7
+ from config import Config
8
+ from pinecode_quieries import PinecodeProposalQueries
9
+ import logging
10
+ logging.basicConfig(format="%(levelname)s - %(name)s - %(message)s", level=logging.WARNING)
11
+ logging.getLogger("haystack").setLevel(logging.INFO)
12
+
13
+ extractive_query = PinecodeProposalQueries (index_name= Config.index_name,
14
+ api_key = Config.es_password,
15
+ environment = Config.pinecone_environment,
16
+ embedding_dim = Config.embedding_dim,
17
+ reader_name_or_path = Config.reader_model_name_or_path,
18
+ use_gpu = Config.use_gpu)
19
+
20
+ def hallazgos_comision_verdad_2022():
21
+ title = """
22
+ <h1 style='
23
+ text-align: center;
24
+ color: #39AA35'>
25
+ Ask2Democracy 🇨🇴 - Hallazgos y recomendaciones de la comisión de la verdad
26
+ </h1>
27
+ <p>
28
+ El 28 de junio del 2022, la Comisión de la Verdad en Colombia liberó su informe final. Fue el resultado de más de 3 años de investigación sobre el conflicto armado interno durante los últimos 60 años. Apoyándose en modelos de lenguaje (sentence transformers, bert, ver más aquí). Este espacio pretende ayudar a explorar las más de 6000 páginas que conforman más de 10 libros del Informe, comenzando por el de Hallazgos y recomendaciones.
29
+ """
30
+ st.markdown(title, unsafe_allow_html=True)
31
+ st.markdown("""<div align="right">
32
+ Creado por Jorge Henao 🇨🇴 <a href="https://twitter.com/jhenaotw" target='_blank'>Twitter</a> <a href="https://www.linkedin.com/in/henaojorge" target='_blank'/>LinkedIn</a> </div>
33
+ """, unsafe_allow_html=True)
34
+
35
+ question_samples_str = """¿cantidad de víctimas en la masacre de bojayá?
36
+ ¿periodo con más detenciones arbitrarias registradas?
37
+ ¿cantidad de víctimas en la masacre de bojayá?
38
+ ¿cuantas víctimas de desplazamiento en antioquia?"""
39
+
40
+ question_samples = question_samples_str.splitlines()
41
+
42
+ def clear_submit():
43
+ st.session_state["submit"] = False
44
+
45
+ def fake_search(question, retriever_top_k, reader_top_k):
46
+ #p1_result = query.search_by_query(query = question, retriever_top_k = retriever_top_k, reader_top_k = reader_top_k, es_index = "informecomisionverdad")
47
+ result = []
48
+ p = """
49
+ La masacre de Bojayá fue perpetrada por el Frente José María Córdoba, de las FARC-EP, al lanzar un cilindro bomba que cayó en una iglesia en la que los pobladores se refugiaban del enfrentamiento de este grupo con el Bloque Élmer Cárdenas de las AUC. Las víctimas fueron 81 personas, 47 de ellas eran niñas, niños y adolescentes
50
+ """
51
+ for i in range(0, reader_top_k):
52
+ result.append([[i+1],"81 personas", p[:250],"Las masacres","Comisión de la verdad - Informe de hallazgos y recomendaciones Junio 2022","5"])
53
+
54
+ return result
55
+
56
+ def search(question, retriever_top_k, reader_top_k):
57
+ filters = {"source_title": "Hallazgos y recomendaciones - 28 de Junio 2022"}
58
+
59
+ query_result = extractive_query.search_by_query(query = question,
60
+ retriever_top_k = retriever_top_k,
61
+ reader_top_k = reader_top_k,
62
+ filters = filters)
63
+ result = []
64
+ for i in range(0, len(query_result)):
65
+ item = query_result[i]
66
+ result.append([[i+1], item.answer, item.context[:200],
67
+ item.meta['title'], item.meta['source_title'], int(item.meta['page'])])
68
+ #result.append([[i+1], item.answer, item.context[:200], item.meta['title']])
69
+ return result
70
+
71
+ def search_and_show_results():
72
+ # set start time
73
+ stt = time.time()
74
+ # retrieve top 5 documents
75
+ results = search(query, retriever_top_k=5, reader_top_k=3)
76
+ # set endtime
77
+ ent = time.time()
78
+ # measure resulting time
79
+ elapsed_time = round(ent - stt, 2)
80
+
81
+ # show which query was entered, and what was searching time
82
+ st.write(f"**Resultados relacionados con:** \"{query}\" ({elapsed_time} sec.)")
83
+ # then we use loop to show results
84
+ for i, answer in enumerate(results):
85
+ # answer starts with header
86
+ st.subheader(f"{answer[1]}")
87
+ # cropped answer
88
+ doc = answer[2][:250] + "..."
89
+ # and url to the full answer
90
+ #url = f"https://www.comisiondelaverdad.co/sites/default/files/descargables/2022-06/Informe%20Final%20capi%CC%81tulo%20Hallazgos%20y%20recomendaciones.pdf#page={answer[5]+1}"
91
+ url = f"https://petro.presidencia.gov.co/Documents/230213-Reforma-salud.pdf"
92
+ # then we display it
93
+ #st.markdown(f'{doc}\n<br>Fuente: {answer[4]}\n<br>Capítulo: {answer[3]}\n<br>Página: {answer[5]}\n[**Lee más aquí**]({url})\n', unsafe_allow_html=True)
94
+ st.markdown(f"{doc}[**Lee más aquí**]({url})")
95
+ st.caption(f"Fuente: {answer[4]} - Capítulo: {answer[3]} - Página: {answer[5]}")
96
+
97
+ st.markdown("---")
98
+
99
+ #results = search("que es el adres", retriever_top_k=5, reader_top_k=3)
100
+
101
+ st.markdown(f"""<br><p>Cuanto más contexto le des a la pregunta mejor funciona el sistema.
102
+ No es un sistema basado en palabras claves, puedes escribir preguntas elaboradas.
103
+ Una serie de modelos de lenguaje transformers intervienen en cada consulta para ayudar a entenderlas.""",
104
+ unsafe_allow_html=True)
105
+ selected_question = st.selectbox("Aquí algunos ejemplos:", question_samples)
106
+ query = st.text_area("Escribe tu pregunta", value = selected_question, on_change=clear_submit)
107
+ button = st.button("Buscar")
108
+ if button or st.session_state.get("submit"):
109
+ if not query:
110
+ st.error("¡escribe una pregunta!")
111
+ else:
112
+ st.session_state["submit"] = True
113
+ search_and_show_results()
main_page.py ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from about import about_ask2democracy
3
+ from hallazgos import hallazgos_comision_verdad_2022
4
+ from reformas import reforma_salud_febrero_2023
5
+ from pinecode_quieries import PinecodeProposalQueries
6
+ from config import Config
7
+
8
+ # Define the sidebar
9
+ api_key = st.sidebar.text_input("OpenAI API Key", type="password")
10
+
11
+ # Define the navigation between pages
12
+ page_options = {
13
+ "About": about_ask2democracy,
14
+ "Propuesta: Reforma a la salud febrero de 2023": reforma_salud_febrero_2023,
15
+ "Hallazgos de la comisión de la verdad 2022": hallazgos_comision_verdad_2022
16
+ }
17
+
18
+ # Define the page selector
19
+ selected_page = st.sidebar.radio("Selecciona la página que deseas explorar:", list(page_options.keys()))
20
+
21
+ # Render the selected page
22
+ page_options[selected_page]()
pinecode_quieries.py CHANGED
@@ -4,7 +4,7 @@ from haystack.nodes import BM25Retriever, FARMReader
4
  from haystack.document_stores import ElasticsearchDocumentStore
5
  from haystack.pipelines import ExtractiveQAPipeline, DocumentSearchPipeline
6
  from haystack.document_stores import PineconeDocumentStore
7
- from haystack.nodes import EmbeddingRetriever
8
 
9
  import json
10
  import logging
@@ -17,8 +17,6 @@ from pathlib import Path
17
  from typing import List, Optional
18
 
19
  import pandas as pd
20
- import pinecone
21
- import streamlit as st
22
 
23
  from haystack import BaseComponent, Document
24
  from haystack.document_stores import PineconeDocumentStore
@@ -26,7 +24,10 @@ from haystack.nodes import (
26
  EmbeddingRetriever,
27
  FARMReader
28
  )
29
- from haystack.pipelines import ExtractiveQAPipeline, Pipeline
 
 
 
30
  from sentence_transformers import SentenceTransformer
31
 
32
  import certifi
@@ -34,102 +35,109 @@ import datetime
34
  import requests
35
  from base64 import b64encode
36
 
37
- ca_certs=certifi.where()
38
-
39
- class PineconeRetriever(BaseComponent):
40
- outgoing_edges = 1
41
-
42
- def __init__(self, sentence_transformer_name: str, api_key:str, environment: str, index_name: str):
43
- # a small subset of the component's parameters is sent in an event after applying filters defined in haystack.telemetry.NonPrivateParameters
44
- self.sts_model = SentenceTransformer(sentence_transformer_name)
45
- pinecone.init(api_key = api_key, environment=environment)
46
- self.index = pinecone.Index(index_name)
47
-
48
- def run(self, query: str, top_k: Optional[int]):
49
- #TODO: problema de versiones del cliente de pinecone. en esta versión retorna una coleción de resutsl con los matches.
50
- #TODO2: no esta el contenido dentro de los metadatos, ni en ningun lado. normal? , workarround. guararlo en otrometado.
51
- #TODO3: hacer consulta por id, pastelarlo desde el colab que si retorna?
52
- # process the inputs
53
- vector_embeddings = self.sts_model.encode(query).tolist()
54
- response = self.index.query([vector_embeddings], top_k=top_k, include_metadata=True)
55
- docs = [
56
- Document(
57
- content=d["metadata"]['content'],
58
- meta={'title': d["metadata"]['title'],
59
- 'page': d["metadata"]['page'],
60
- 'source': d["metadata"]['source']
61
- }
62
- )
63
- for d in response['matches']
64
- ]
65
- output = {"documents": docs, "query": query}
66
- return output, "output_1"
67
-
68
- def run_batch(self, queries: List[str], top_k: Optional[int]):
69
- return {}, "output_1"
70
 
71
 
72
  class DocumentQueries(ABC):
73
 
74
  @abstractmethod
75
- def search_by_query(self, query : str, retriever_top_k: int, reader_top_k: int, es_index: str):
76
  pass
77
 
78
  class PinecodeProposalQueries(DocumentQueries):
79
 
80
- def __init__(self, es_host: str, es_index: str, es_user, es_password, reader_name_or_path: str, use_gpu = True) -> None:
81
- reader = FARMReader(model_name_or_path = reader_name_or_path, use_gpu = use_gpu, num_processes=1, context_window_size=200)
82
- self._initialize_pipeline(es_host, es_index, es_user, es_password, reader = reader)
 
 
 
 
 
 
83
  #self.log = Log(es_host= es_host, es_index="log", es_user = es_user, es_password= es_password)
84
 
85
- def _initialize_pipeline(self, es_host, es_index, es_user, es_password, reader = None):
 
 
 
86
  if reader is not None:
87
  self.reader = reader
88
-
 
89
  #pinecone.init(api_key=es_password, environment="us-east1-gcp")
90
- index_name = es_index
91
 
92
  self.document_store = PineconeDocumentStore(
93
- api_key=es_password,
94
- environment = "us-east1-gcp",
95
- index=index_name,
96
- similarity="cosine",
97
- embedding_dim=384,
98
- metadata_config = {"indexed": ["title", "content"]}
99
  )
100
- self.pipe = Pipeline()
101
- pinecone_retriever = PineconeRetriever("sentence-transformers/multi-qa-MiniLM-L6-cos-v1",
102
- es_password, "us-east1-gcp",
103
- index_name)
104
- #self.pipe.add_node(component=pinecone_retriever, name="Retriever", inputs=["Query"])
105
- #self.pipe.add_node(component=self.reader, name="Reader", inputs=["Retriever"])
106
-
107
- # #self.retriever = BM25Retriever(document_store = self.document_store)
108
  self.retriever = EmbeddingRetriever(
109
- document_store=self.document_store,
110
- #embedding_model="multi-qa-distilbert-dot-v1",
111
  embedding_model = "sentence-transformers/multi-qa-MiniLM-L6-cos-v1",
112
  model_format="sentence_transformers"
113
  )
 
 
 
 
 
114
 
115
- # retriever_model = "sentence-transformers/multi-qa-mpnet-base-dot-v1"
116
-
117
-
118
-
119
- #self.document_store.update_embeddings(self.retriever, update_existing_embeddings=False)
120
- self.pipe = ExtractiveQAPipeline (reader = self.reader, retriever = self.retriever)
121
- #self.pipe = DocumentSearchPipeline(self.retriever)
122
-
123
- def search_by_query(self, query : str, retriever_top_k: int, reader_top_k: int, es_index: str = None) :
124
- #self.document_store.update_embeddings(self.retriever, update_existing_embeddings=False)
125
-
126
- #if es_index is not None:
127
- #self._initialize_pipeline(self.es_host, es_index, self.es_user, self.es_password)
128
- params = {"Retriever": {"top_k": retriever_top_k}, "Reader": {"top_k": reader_top_k}}
129
- #params = {"Retriever": {"top_k": retriever_top_k}}
130
- prediction = self.pipe.run( query = query, params = params)
131
  return prediction["answers"]
132
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  class Log():
134
 
135
  def __init__(self, es_host: str, es_index: str, es_user, es_password) -> None:
 
4
  from haystack.document_stores import ElasticsearchDocumentStore
5
  from haystack.pipelines import ExtractiveQAPipeline, DocumentSearchPipeline
6
  from haystack.document_stores import PineconeDocumentStore
7
+ from haystack.nodes import EmbeddingRetriever, OpenAIAnswerGenerator
8
 
9
  import json
10
  import logging
 
17
  from typing import List, Optional
18
 
19
  import pandas as pd
 
 
20
 
21
  from haystack import BaseComponent, Document
22
  from haystack.document_stores import PineconeDocumentStore
 
24
  EmbeddingRetriever,
25
  FARMReader
26
  )
27
+ from haystack.pipelines import ExtractiveQAPipeline, Pipeline, GenerativeQAPipeline
28
+ from haystack.pipelines import BaseStandardPipeline
29
+ from haystack.nodes.reader import BaseReader
30
+ from haystack.nodes.retriever import BaseRetriever
31
  from sentence_transformers import SentenceTransformer
32
 
33
  import certifi
 
35
  import requests
36
  from base64 import b64encode
37
 
38
+ ca_certs = certifi.where()
39
+ class QAPipeline(BaseStandardPipeline):
40
+ """
41
+ Pipeline for Extractive Question Answering.
42
+ """
43
+
44
+ def __init__(self, reader: BaseReader, retriever: BaseRetriever):
45
+ """
46
+ :param reader: Reader instance
47
+ :param retriever: Retriever instance
48
+ """
49
+ self.pipeline = Pipeline()
50
+ self.pipeline.add_node(component=retriever, name="Retriever", inputs=["Query"])
51
+ self.pipeline.add_node(component=reader, name="Reader", inputs=["Retriever"])
52
+ self.metrics_filter = {"Retriever": ["recall_single_hit"]}
53
+
54
+ def run(self, query: str, params: Optional[dict] = None, debug: Optional[bool] = None):
55
+ """
56
+ :param query: The search query string.
57
+ :param params: Params for the `retriever` and `reader`. For instance,
58
+ params={"Retriever": {"top_k": 10}, "Reader": {"top_k": 5}}
59
+ :param debug: Whether the pipeline should instruct nodes to collect debug information
60
+ about their execution. By default these include the input parameters
61
+ they received and the output they generated.
62
+ All debug information can then be found in the dict returned
63
+ by this method under the key "_debug"
64
+ """
65
+
66
+ output = self.pipeline.run(query=query, params=params, debug=debug)
67
+ return output
 
 
 
68
 
69
 
70
  class DocumentQueries(ABC):
71
 
72
  @abstractmethod
73
+ def search_by_query(self, query : str, retriever_top_k: int, reader_top_k: int, index_name: str = None, filters = None):
74
  pass
75
 
76
  class PinecodeProposalQueries(DocumentQueries):
77
 
78
+ def __init__(self, index_name: str, api_key, reader_name_or_path: str, use_gpu = True,
79
+ embedding_dim = 384, environment = "us-east1-gcp") -> None:
80
+
81
+ reader = FARMReader(model_name_or_path = reader_name_or_path,
82
+ use_gpu = use_gpu, num_processes = 1,
83
+ context_window_size = 200)
84
+
85
+ self._initialize_pipeline(index_name, api_key, reader = reader, embedding_dim=
86
+ embedding_dim, environment = environment)
87
  #self.log = Log(es_host= es_host, es_index="log", es_user = es_user, es_password= es_password)
88
 
89
+ def _initialize_pipeline(self, index_name, api_key, similarity = "cosine",
90
+ embedding_dim = 384, reader = None,
91
+ environment = "us-east1-gcp",
92
+ metadata_config = {"indexed": ["title", "source_title"]}):
93
  if reader is not None:
94
  self.reader = reader
95
+ self.OPENAI_generator = OpenAIAnswerGenerator(api_key="",
96
+ model="text-davinci-003", temperature=.5, max_tokens=60)
97
  #pinecone.init(api_key=es_password, environment="us-east1-gcp")
 
98
 
99
  self.document_store = PineconeDocumentStore(
100
+ api_key = api_key,
101
+ environment = environment,
102
+ index = index_name,
103
+ similarity = similarity,
104
+ embedding_dim = embedding_dim,
105
+ metadata_config = {"indexed": ["title","source_title"]}
106
  )
107
+
 
 
 
 
 
 
 
108
  self.retriever = EmbeddingRetriever(
109
+ document_store= self.document_store,
 
110
  embedding_model = "sentence-transformers/multi-qa-MiniLM-L6-cos-v1",
111
  model_format="sentence_transformers"
112
  )
113
+
114
+ self.extractive_pipe = ExtractiveQAPipeline (reader = self.reader,
115
+ retriever = self.retriever)
116
+ self.generative_OPENAI_pipe = GenerativeQAPipeline(generator = self.OPENAI_generator,
117
+ retriever = self.retriever)
118
 
119
+ def search_by_query(self, query : str, retriever_top_k: int, reader_top_k: int, index_name: str = None, filters = None):
120
+ #self.document_store.update_embeddings(self.retriever, update_existing_embeddings=False)
121
+ params = {"Retriever": {"top_k": retriever_top_k,
122
+ "filters": filters},
123
+ "Reader": {"top_k": reader_top_k}}
124
+ prediction = self.extractive_pipe.run( query = query, params = params, debug = True)
 
 
 
 
 
 
 
 
 
 
125
  return prediction["answers"]
126
 
127
+ def genenerate_answer_OpenAI(self, query : str, retriever_top_k: int, reader_top_k: int, es_index: str = None, filters = None) :
128
+ params = {"Retriever": {"top_k": retriever_top_k,
129
+ "filters": filters},
130
+ "Generator": {"top_k": reader_top_k}}
131
+ prediction = self.generative_OPENAI_pipe.run( query = query, params = params)
132
+ return prediction
133
+
134
+ def genenerate_answer_HF(self, query : str, retriever_top_k: int, reader_top_k: int, es_index: str = None, filters = None) :
135
+ params = {"Retriever": {"top_k": retriever_top_k,
136
+ "filters": filters},
137
+ "Generator": {"top_k": reader_top_k}}
138
+ prediction = self.generative_HF_pipe.run( query = query, params = params)
139
+ return prediction
140
+
141
  class Log():
142
 
143
  def __init__(self, es_host: str, es_index: str, es_user, es_password) -> None:
reformas.py ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from random import randint
2
+ import streamlit as st
3
+
4
+ import streamlit as st
5
+ import json
6
+ import time
7
+ from config import Config
8
+ from pinecode_quieries import PinecodeProposalQueries
9
+ import logging
10
+ logging.basicConfig(format="%(levelname)s - %(name)s - %(message)s", level=logging.WARNING)
11
+ logging.getLogger("haystack").setLevel(logging.INFO)
12
+
13
+ extractive_query = PinecodeProposalQueries (index_name= Config.index_name,
14
+ api_key = Config.es_password,
15
+ environment = Config.pinecone_environment,
16
+ embedding_dim = Config.embedding_dim,
17
+ reader_name_or_path = Config.reader_model_name_or_path,
18
+ use_gpu = Config.use_gpu)
19
+
20
+ def reforma_salud_febrero_2023():
21
+ title = """
22
+ <h1 style='
23
+ text-align: center;
24
+ color: #39AA35'>
25
+ Ask2Democracy 🇨🇴 - Propuesta reforma a la salud 2023
26
+ </h1>
27
+ """
28
+ st.markdown(title, unsafe_allow_html=True)
29
+ st.markdown("""<div align="right">
30
+ Creado por Jorge Henao 🇨🇴 <a href="https://twitter.com/jhenaotw" target='_blank'>Twitter</a> <a href="https://www.linkedin.com/in/henaojorge" target='_blank'/>LinkedIn</a> </div>
31
+ """, unsafe_allow_html=True)
32
+
33
+ question_samples_str = """¿Cuándo se implementará el Sistema de Salud?
34
+ ¿Cómo se implementará el Sistema de Salud?
35
+ ¿Qué es principio de interpretación y fundamento de la transición en relación al Sistema de Salud?
36
+ ¿Qué se garantiza en todo momento con el nuevo Sistema de Salud?
37
+ ¿Qué son los Centros de Atención Primaria Integrales y Resolutivos en Salud - CAPIRS?
38
+ ¿Qué se garantiza durante el periodo de transición del nuevo Sistema de Salud?
39
+ ¿Puede haber personas sin protección de su salud durante el periodo de transición?
40
+ ¿Cuál es el derecho fundamental que se garantiza en todo momento durante la transición del nuevo Sistema de Salud?
41
+ ¿En qué país se está implementando este Sistema de Salud?
42
+ ¿Qué se debe realizar para garantizar la gestión de los recursos en el nivel nacional y desconcentrado?
43
+ ¿Cómo se regirá el régimen de contratación de los contratos mencionados en el texto?
44
+ ¿Qué son las cláusulas exorbitantes previstas en el estatuto General de Contratación de la administración pública?
45
+ ¿Qué principios deben atender los contratos mencionados en el texto?
46
+ ¿Cuál es el ámbito de aplicación de los contratos mencionados en el texto?
47
+ ¿Quién tiene la responsabilidad de realizar la auditoría de las cuentas en relación a estos contratos?
48
+ ¿Cuáles son las características que deben cumplir los contratos mencionados en el texto?
49
+ ¿Qué se entiende por "coordinación" en el contexto de los contratos mencionados en el texto?
50
+ ¿Qué objetivo se busca con los contratos mencionados en el texto?
51
+ ¿Quién será el encargado de contratar los servicios de salud y otros requerimientos para el cumplimiento de su labor en el nivel regional?
52
+ ¿Qué tipo de instituciones hospitalarias y ambulatorias se integran a la red de servicios del territorio?
53
+ ¿Qué tarifas deben seguir las instituciones hospitalarias y ambulatorias para la prestación de servicios de salud?
54
+ ¿Qué busca modular el régimen de tarifas y formas de pago para la prestación de servicios de salud?
55
+ ¿Qué tipo de registro llevará el Fondo Regional de Salud?
56
+ ¿Cuáles son algunas de las variables que se incluirán en el registro de cada servicio prestado y pagado?"""
57
+
58
+ question_samples = question_samples_str.splitlines()
59
+
60
+ def clear_submit():
61
+ st.session_state["submit"] = False
62
+
63
+ def fake_search(question, retriever_top_k, reader_top_k):
64
+ #p1_result = query.search_by_query(query = question, retriever_top_k = retriever_top_k, reader_top_k = reader_top_k, es_index = "informecomisionverdad")
65
+ result = []
66
+ p = """
67
+ La masacre de Bojayá fue perpetrada por el Frente José María Córdoba, de las FARC-EP, al lanzar un cilindro bomba que cayó en una iglesia en la que los pobladores se refugiaban del enfrentamiento de este grupo con el Bloque Élmer Cárdenas de las AUC. Las víctimas fueron 81 personas, 47 de ellas eran niñas, niños y adolescentes
68
+ """
69
+ for i in range(0, reader_top_k):
70
+ result.append([[i+1],"81 personas", p[:250],"Las masacres","Comisión de la verdad - Informe de hallazgos y recomendaciones Junio 2022","5"])
71
+
72
+ return result
73
+
74
+ def search(question, retriever_top_k, reader_top_k):
75
+ filters = {"source_title": "Reforma de la salud 13 Febrero 2023"}
76
+
77
+ query_result = extractive_query.search_by_query(query = question,
78
+ retriever_top_k = retriever_top_k,
79
+ reader_top_k = reader_top_k,
80
+ filters = filters)
81
+ result = []
82
+ for i in range(0, len(query_result)):
83
+ item = query_result[i]
84
+ result.append([[i+1], item.answer, item.context[:200],
85
+ item.meta['title'], item.meta['source_title'], int(item.meta['page'])])
86
+ #result.append([[i+1], item.answer, item.context[:200], item.meta['title']])
87
+ return result
88
+
89
+ def search_and_show_results():
90
+ # set start time
91
+ stt = time.time()
92
+ # retrieve top 5 documents
93
+ results = search(query, retriever_top_k=5, reader_top_k=3)
94
+ # set endtime
95
+ ent = time.time()
96
+ # measure resulting time
97
+ elapsed_time = round(ent - stt, 2)
98
+
99
+ # show which query was entered, and what was searching time
100
+ st.write(f"**Resultados relacionados con:** \"{query}\" ({elapsed_time} sec.)")
101
+ # then we use loop to show results
102
+ for i, answer in enumerate(results):
103
+ # answer starts with header
104
+ st.subheader(f"{answer[1]}")
105
+ # cropped answer
106
+ doc = answer[2][:250] + "..."
107
+ # and url to the full answer
108
+ #url = f"https://www.comisiondelaverdad.co/sites/default/files/descargables/2022-06/Informe%20Final%20capi%CC%81tulo%20Hallazgos%20y%20recomendaciones.pdf#page={answer[5]+1}"
109
+ url = f"https://petro.presidencia.gov.co/Documents/230213-Reforma-salud.pdf"
110
+ # then we display it
111
+ #st.markdown(f'{doc}\n<br>Fuente: {answer[4]}\n<br>Capítulo: {answer[3]}\n<br>Página: {answer[5]}\n[**Lee más aquí**]({url})\n', unsafe_allow_html=True)
112
+ st.markdown(f"{doc}[**Lee más aquí**]({url})")
113
+ st.caption(f"Fuente: {answer[4]} - Capítulo: {answer[3]} - Página: {answer[5]}")
114
+
115
+ st.markdown("---")
116
+
117
+ #results = search("que es el adres", retriever_top_k=5, reader_top_k=3)
118
+
119
+ st.write(f"""<br><p>Cuanto más contexto le des a la pregunta mejores resultados se obtienen.
120
+ No es un sistema basado en palabras claves, puedes escribir preguntas elaboradas.
121
+ Una serie de modelos de lenguaje transformers intervienen en cada consulta para ayudar a entenderlas."""
122
+ ,unsafe_allow_html=True)
123
+ selected_question = st.selectbox("Aquí algunos ejemplos:", question_samples)
124
+ query = st.text_area("Escribe tu pregunta", value = selected_question, on_change=clear_submit)
125
+ button = st.button("Buscar")
126
+ if button or st.session_state.get("submit"):
127
+ if not query:
128
+ st.error("¡escribe una pregunta!")
129
+ else:
130
+ st.session_state["submit"] = True
131
+ search_and_show_results()
requirements.txt CHANGED
@@ -1,4 +1,4 @@
1
- streamlit==1.15.0
2
  sentence-transformers
3
  farm-haystack[pinecone]
4
- pinecone-client
 
 
 
1
  sentence-transformers
2
  farm-haystack[pinecone]
3
+ pinecone-client
4
+ streamlit==1.15.0