From 91154fa0946806c7e9b2e739bd512c04f6108e46 Mon Sep 17 00:00:00 2001 From: Manuel Vergara Date: Sat, 10 Jun 2023 22:11:57 +0200 Subject: [PATCH] Update python-chatGPT course Signed-off-by: Manuel Vergara --- python-chatgpt/README.md | 51 ++++++++++ python-chatgpt/img/python-chatgpt12.png | Bin 0 -> 33393 bytes python-chatgpt/src/08_filtrar_respuestas.py | 100 ++++++++++++++++++++ 3 files changed, 151 insertions(+) create mode 100644 python-chatgpt/img/python-chatgpt12.png create mode 100644 python-chatgpt/src/08_filtrar_respuestas.py diff --git a/python-chatgpt/README.md b/python-chatgpt/README.md index 84feddf..073cd79 100644 --- a/python-chatgpt/README.md +++ b/python-chatgpt/README.md @@ -617,5 +617,56 @@ El fichero del código completo es [traducir_texto.py](src/07_traducir_texto.py) ## TEMA 5 - Otras consideraciones para la integración +### 5.1. - Filtrar respuestas – Palabras prohibidas + +Vamos a recuperar el código del chatbot que creamos y le vamos a añadir la biblioteca spacy, que nos ayudará al procesamiento del lenguaje natural. Así que importamos spacy, añadimos la variable cargando el modelo de procesamiento de lenguaje natural y otra de palabras_prohibidas: +```python +import spacy +modelo_spacy = spacy.load("es_core_news_md") +palabras_prohibidas = ["palabra1", "palabra2"] +``` + +En palabras_prohibidas hemos creado una lista ficticia pero estás palabras podrían ser palabras malsonantes, palabras de la competencia, palabras de jerga o cualquier listado que creamos que no debe salir en el output que nos devuelve chatgpt. + +Ahora vamos a crear la función para el filtrado: +```python +def filtrar_lista_negra(texto, lista_negra): + token = modelo_spacy(texto) + resultado = [] + for t in token: + # Si el token no está en la lista negra, agregarlo al resultado + if t.text not in lista_negra: + resultado.append(t.text) + else: + resultado.append("[xxxxx]") + + return " ".join(resultado) +``` + +Ahora tenemos que retocar la función preguntar_chat_gpt para que llame a la función nueva de filtrado en cada respuesta cambiando el return que teníamos: +```python +respuesta_sin_filtrar = respuesta.choices[0].text.strip() +respuesta_filtrada = filtrar_lista_negra(respuesta_sin_filtrar, palabras_prohibidas) +return respuesta_filtrada +``` + +Antes de hacer la prueba, y para que quede más despejada la ejecución del programa en la terminal, vamos a añadir una función que limpie el terminal con la biblioteca que tenemos importada os: +```python +def clearConsole(): + # Función limpiar consola + os.system('clear') +``` + +Vamos a llamarla al inicio de la dinámica del programa, antes de la bienvenida. + +Y para probarlo, vamos a añadir en las palabras_prohibidas la palabra "paella" y le vamos a preguntar por el plato típico valenciano: + +![](img/python-chatgpt12.png) + +El fichero del código completo es [filtrar_palabras.py](src/08_filtrar_respuestas.py) + +### 5.2. - Verificar respuestas – Relevancia +### 5.3. - Limitaciones y consideraciones éticas + diff --git a/python-chatgpt/img/python-chatgpt12.png b/python-chatgpt/img/python-chatgpt12.png new file mode 100644 index 0000000000000000000000000000000000000000..6aa5b337d34d932fd0df7e54cb2818b2e7b1845d GIT binary patch literal 33393 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 literal 0 HcmV?d00001 diff --git a/python-chatgpt/src/08_filtrar_respuestas.py b/python-chatgpt/src/08_filtrar_respuestas.py new file mode 100644 index 0000000..e961842 --- /dev/null +++ b/python-chatgpt/src/08_filtrar_respuestas.py @@ -0,0 +1,100 @@ +""" +Chatbot con OpenAI GPT-3 +""" + +import openai +import os +import spacy +from dotenv import load_dotenv +from colorama import init, Fore + +load_dotenv() +api_key = os.getenv("OPENAI_API_KEY") + +openai.api_key = api_key + +preguntas_anteriores = [] +respuestas_anteriores = [] +modelo_spacy = spacy.load("es_core_news_md") +palabras_prohibidas = ["palabra1", "palabra2", "paella"] + + +# Inicializar colorama +init() + + +def clearConsole(): + # Función limpiar consola + os.system('clear') + + +def filtrar_lista_negra(texto, lista_negra): + """ + Filtra palabras de una lista negra + """ + + # Separar el texto en tokens + token = modelo_spacy(texto) + # Crear una lista vacía para guardar los tokens permitidos + resultado = [] + + for t in token: + # Si el token no está en la lista negra, agregarlo al resultado + if t.text not in lista_negra: + resultado.append(t.text) + + else: + # Si el token está en la lista negra, agregarlo al resultado + resultado.append("[xxxxx]") + + return " ".join(resultado) + + +def preguntar_chat_gpt(prompt, modelo="text-davinci-002"): + """ + Pregunta a la API de OpenAI GPT-3 + """ + + respuesta = openai.Completion.create( + engine=modelo, + prompt=prompt, + n=1, + temperature=1, + max_tokens=150 + ) + + respuesta_sin_filtrar = respuesta.choices[0].text.strip() + + respuesta_filtrada = filtrar_lista_negra( + respuesta_sin_filtrar, palabras_prohibidas) + + return respuesta_filtrada + + +# Bienvenida +clearConsole() +print(Fore.RED + "Bienvenido al chatbot de OpenAI GPT-3." + Fore.RESET) +print(Fore.RED + "Escribe \"salir\" cuando quieras terminar la conversación." + Fore.RESET) + +# Loop para controlar el flujo de la conversación +while True: + + conversacion_historica = "" + + ingreso_usuario = input(Fore.MAGENTA + "Tú: " + Fore.RESET) + + if ingreso_usuario == "salir": + break + + for pregunta, respuesta in zip(preguntas_anteriores, respuestas_anteriores): + conversacion_historica += f"{Fore.BLUE}Usuario pregunta: {Fore.RESET}{pregunta}" + conversacion_historica += f"{Fore.GREEN}Bot responde: {Fore.RESET}{respuesta}\n" + + prompt = f"{Fore.CYAN}Usuario pregunta: {Fore.RESET}{ingreso_usuario}" + conversacion_historica += prompt + respuesta_gpt = preguntar_chat_gpt(conversacion_historica) + + print(f"{respuesta_gpt}") + + preguntas_anteriores.append(ingreso_usuario) + respuestas_anteriores.append(respuesta_gpt)