vmoras commited on
Commit
2c807ae
·
1 Parent(s): 06ab988

Initial commit

Browse files
.gitignore ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ .idea/
2
+ .venv/
3
+ .env
4
+
5
+ tests.ipynb
app.py ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import pinecone
3
+ import gradio as gr
4
+ from openai import OpenAI
5
+ from dotenv import load_dotenv
6
+
7
+ load_dotenv()
8
+
9
+ openai_client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
10
+ pinecone.init(api_key=os.getenv("PINECONE_API_TOKEN"), environment=os.getenv("PINECONE_ENVIRONMENT"))
11
+ index = pinecone.Index(os.getenv("PINECONE_INDEX"))
12
+
13
+
14
+ def init_prompt(type_prompt: str) -> str:
15
+ if type_prompt == "main":
16
+ name_file = 'main_prompt.txt'
17
+ else:
18
+ name_file = 'standalone_question.txt'
19
+
20
+ with open(f"prompts/{name_file}", mode='r', encoding='utf-8') as infile:
21
+ prompt = infile.read()
22
+
23
+ return prompt
24
+
25
+
26
+ def get_embedding(text: str) -> list[float]:
27
+ response = openai_client.embeddings.create(
28
+ input=text,
29
+ model='text-embedding-ada-002'
30
+ )
31
+ return response.data[0].embedding
32
+
33
+
34
+ def call_api(message_history: list[dict]) -> str:
35
+ response = openai_client.chat.completions.create(
36
+ model='gpt-4-1106-preview',
37
+ temperature=0.7,
38
+ messages=message_history
39
+ )
40
+ return response.choices[0].message.content
41
+
42
+
43
+ def get_standalone_question(question: str, message_history: list[dict], prompt_q: str) -> str:
44
+ # Format the message history like: Human: blablablá \nAssistant: blablablá
45
+ history = ''
46
+ for i, msg in enumerate(message_history):
47
+ if i == 0:
48
+ continue # Omit the prompt
49
+ if i % 2 == 0:
50
+ history += f'Human: {msg["content"]}\n'
51
+ else:
52
+ history += f'Assistant: {msg["content"]}\n'
53
+
54
+ # Add history and question to the prompt and call chatgpt
55
+ prompt = [{'role': 'system', 'content': ''}]
56
+ content = prompt_q.replace('HISTORY', history).replace('QUESTION', question)
57
+ prompt[0]['content'] = content
58
+
59
+ return call_api(prompt)
60
+
61
+
62
+ def get_context(question: str) -> str:
63
+ q_embedding = get_embedding(question)
64
+
65
+ # Get most similar vectors
66
+ result = index.query(
67
+ vector=q_embedding,
68
+ top_k=10,
69
+ include_metadata=True
70
+ )['matches']
71
+
72
+ # Crete a string based on the text of each vector
73
+ context = ''
74
+ for r in result:
75
+ context += r['metadata']['Text'] + '\n'
76
+ return context
77
+
78
+
79
+ def get_answer(context: str, message_history: list[dict], question: str, prompt_m: str) -> str:
80
+ message_history[0]['content'] = prompt_m.replace('CONTEXT', context)
81
+ message_history.append({'role': 'user', 'content': question})
82
+ return call_api(message_history)
83
+
84
+
85
+ def ask_query(
86
+ msg: str, chat_history: list[list[str | None]], message_history: list[dict], prompt_q: str, prompt_m: str
87
+ ) -> tuple[str, list[list[str | None]], list[dict]]:
88
+
89
+ if len(chat_history) == 5:
90
+ answer = 'Un placer haberte ayudado, hasta luego!'
91
+
92
+ else:
93
+ question = get_standalone_question(msg, message_history, prompt_q)
94
+ print(question)
95
+ context = get_context(question)
96
+ print(context)
97
+ answer = get_answer(context, message_history, question, prompt_m)
98
+
99
+ message_history.append({'role': 'assistant', 'content': answer})
100
+ chat_history.append([msg, answer])
101
+
102
+ return "", chat_history, message_history
103
+
104
+
105
+ def start_chat(chat_history: list[list[str | None]], prompt_m: str):
106
+ greeting = ('Hola 👋, ¡estoy encantada de conversar contigo! Antes de empezar, quiero asegurarte algo '
107
+ 'importante: tu privacidad y confidencialidad son mi máxima prioridad. Puedes estar '
108
+ 'tranquila sabiendo que nuestras conversaciones son completamente seguras y nunca '
109
+ 'serán compartidas con terceros. ¿En qué puedo ayudarte hoy?')
110
+
111
+ message_history = [
112
+ {'role': 'system', 'content': prompt_m},
113
+ {'role': 'assistant', 'content': greeting}
114
+ ]
115
+
116
+ chat_history.append(['', greeting])
117
+
118
+ return message_history, chat_history, gr.Button(visible=False), gr.Text(visible=True)
119
+
120
+
121
+ with gr.Blocks() as app:
122
+ prompt_questions = gr.State(init_prompt('questions'))
123
+ prompt_main = gr.State(init_prompt('main'))
124
+ msg_history = gr.State([])
125
+
126
+ chatbot = gr.Chatbot(label='Bella Nosotras')
127
+ start_button = gr.Button()
128
+ message = gr.Textbox(visible=False)
129
+
130
+ start_button.click(
131
+ start_chat,
132
+ [chatbot, prompt_main],
133
+ [msg_history, chatbot, start_button, message]
134
+ )
135
+
136
+ message.submit(
137
+ ask_query,
138
+ [message, chatbot, msg_history, prompt_questions, prompt_main],
139
+ [message, chatbot, msg_history]
140
+ )
141
+
142
+
143
+ app.launch(debug=True, auth=(os.environ.get("SPACE_USERNAME"), os.environ.get("SPACE_PASSWORD")))
prompts/main_prompt.txt ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Tu eres Bella es una mujer de 32 años, amigable, sensible y comprensiva. Eres una confidente que entiende todo lo relacionado con el tema de la menstruación y la higiene íntima de la marca Nosotras, también comprendes las emociones de las mujeres durante la menstruación y el ciclo menstrual. Eres la amiga que necesita cualquier mujer para ser escuchada y validada en cualquier momento de tu ciclo menstrual, y a la que le consultan sobre productos de higiene menstrual e íntima de la marca Nosotras, cuáles son los mejores y se adecuan a sus necesidades.
2
+
3
+ Tono de Comunicación: Tu tono debe ser amigable, empático y sensible. Debes comunicarte de manera natural y fácil de entender. Usa palabras simples y un lenguaje que se sienta cercano. Además, no repites información dada anteriormente.
4
+ Objetivo de Bella: Tu objetivo es brindar información y apoyo relacionado con productos de higiene menstrual e higiene íntima, recomendando productos específicos de la marca Nosotras.
5
+
6
+ Si te preguntan sobre situaciones donde se requiera asesoramiento médico o psicológico e invita a la usuaria a visitar el consultorio virtual de Nosotras: https://www.nosotrasonline.com.co/entre-nosotras/consultorios/ . Evita dar consejos o información relacionados con prácticas médicas, remite a profesionales de la salud.
7
+
8
+ Instrucciones para tener cualquier conversación. Debes hacer siempre lo siguiente:
9
+
10
+ Describe los diferentes tipos de productos de higiene menstrual disponibles hablando de sus materiales, beneficios, para qué sirven y en qué tiendas comprarlos según la información de www.nosotrasonline.com.co . Explica todo máximo en 5 frases.
11
+ Pregunta a las usuarias sobre sus alergias o sensibilidades relacionadas con ciertos materiales y evita recomendarles productos que contengan dichos materiales cuando te digan que son alérgicas a ellos.
12
+ Promueve el respeto a la autonomía y decisiones individuales de las usuarias.
13
+ Muéstrate sensible a la diversidad de experiencias y circunstancias de las usuarias.
14
+
15
+ Estos son algunos ejemplos de los usuarios que tendrías:
16
+
17
+ Soy una mujer adolescente entre los 12 y los 18 que menstrua por primera vez, tengo muchas dudas sobre qué productos usar y preguntas sobre la menstruación y el ciclo menstrual.
18
+ Soy una mujer entre los 18 y los 40 años que lleva un tiempo menstruando, quiere mejorar mi calidad de vida con productos cómodos y que me protejan de manchas en cualquier momento del día. También tengo preguntas y dudas relacionadas con mitos o tabúes que quiero desvirtuar o cambios en mi ciclo menstrual.
19
+ Soy una mujer entre los 40 y 55 años que está cerca de la menopausia o está pasando por una, y tengo dudas sobre qué productos de higiene menstrual e íntima debería comenzar a usar, además de preguntas relacionadas con los diferentes cambios que vienen con la menopausia.
20
+
21
+
22
+ Para responder las preguntas, utiliza la siguiente información. Si la informacion dada no es suficiente, no inventes información y dile al usuario que visite esta página: https://www.nosotrasonline.com.co/
23
+
24
+ =========
25
+ Contexto:
26
+ CONTEXT
27
+ =========
prompts/standalone_question.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ Your goal is to rephrase questions related to the brand Nosotras (which is a brand for feminine hygiene products) to show what is the best advice for the customer. Given the following conversation and a follow up question, rephrase the follow up question to be a standalone phrase where you show the best recommendation for the customer. Always include all the important information, specially all name of the nouns and the intention of the customer. For example, if the user says "Me siento incomoda con las toallas gruesas, cual me recomiendas?" The standalone phrase should me something like "necesito toallas menos gruesas y más cómodas". There might be moments when there isn't a question in those cases return a standalone phrase: for example if the user says "hello" (or something similar) then the output would be "the user wants to say hello", or if the user says "thank you" (or something similar) then it would be "the user is saying thank you", or if the user says "great", "it is very helpfully" (or something similar) then it would be "user thinks the recommendation is great". Your answer will always be in spanish.
2
+ Chat History:
3
+
4
+ HISTORY
5
+ Follow-up Input: QUESTION
6
+ Standalone question:
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ pinecone-client==2.2.4
2
+ python-dotenv==1.0.0
3
+ openai==1.6.1