import spacy import gradio as gr import json import re from typing import Dict, List, Set class ProcesadorAutodiagnostico: def __init__(self): # Cargar modelo spaCy en español self.nlp = spacy.load("es_core_news_sm") # Patrones de dominio específico self.DOMINIOS = { "legal": { "términos": ["contrato", "legal", "documento", "cláusula", "gestión documental"], "procesos": ["firma", "revisión", "archivo", "clasificación"], "roles": ["abogado", "notario", "asesor legal"] }, "ia": { "términos": ["GPT", "inteligencia artificial", "IA", "machine learning", "automatización"], "herramientas": ["chat", "procesamiento", "clasificación", "análisis"], "conceptos": ["modelo", "entrenamiento", "dataset", "algoritmo"] }, "negocio": { "términos": ["empresa", "negocio", "emprendimiento", "startup"], "procesos": ["constitución", "asociación", "implementación"], "roles": ["profesional", "técnico", "consultor"] } } # Patrones para identificar entrampes self.PATRONES_ENTRAMPE = { "duda": r"(?i)(duda|pregunta|cómo|qué|cuál|donde|cuándo|por qué)", "necesidad": r"(?i)(necesito|requiero|busco|quiero)", "problema": r"(?i)(problema|dificultad|obstáculo|limitación)", "preocupación": r"(?i)(preocupa|inquieta|temo|desconfío)" } def extraer_ubicacion(self, doc) -> Dict[str, str]: """Extrae información de ubicación del texto""" ubicacion = {"ciudad": "", "pais": ""} for ent in doc.ents: if ent.label_ in ["GPE", "LOC"]: # Asumimos que la última palabra es el país si hay más de una palabras = ent.text.split() if len(palabras) > 1: ubicacion["ciudad"] = " ".join(palabras[:-1]) ubicacion["pais"] = palabras[-1] else: ubicacion["pais"] = ent.text return ubicacion def identificar_dominio_principal(self, texto: str) -> str: """Identifica el dominio principal del texto basado en la frecuencia de términos""" conteo_dominios = {dominio: 0 for dominio in self.DOMINIOS} texto_lower = texto.lower() for dominio, categorias in self.DOMINIOS.items(): for categoria, términos in categorias.items(): for término in términos: conteo_dominios[dominio] += texto_lower.count(término.lower()) return max(conteo_dominios.items(), key=lambda x: x[1])[0] def extraer_terminos_tecnicos(self, texto: str) -> Dict[str, List[str]]: """Extrae términos técnicos clasificados por tipo""" términos = { "desconocidos": set(), "dudosos": set(), "mencionados": set() } # Buscar términos en el texto texto_lower = texto.lower() for dominio, categorias in self.DOMINIOS.items(): for término in categorias["términos"]: if término.lower() in texto_lower: # Si el término aparece cerca de palabras de duda for patron in self.PATRONES_ENTRAMPE["duda"]: if re.search(f"{patron}.*?{término}|{término}.*?{patron}", texto_lower, re.IGNORECASE): términos["dudosos"].add(término) break else: términos["mencionados"].add(término) return {k: list(v) for k, v in términos.items()} def identificar_entrampes(self, doc) -> Dict[str, List[str]]: """Identifica diferentes tipos de entrampes en el texto""" entrampes = { "tecnicos": [], "implementacion": [], "organizacionales": [] } for sent in doc.sents: sent_text = sent.text # Clasificar el tipo de entrampe if any(term in sent_text.lower() for term in self.DOMINIOS["ia"]["términos"]): if re.search(self.PATRONES_ENTRAMPE["duda"], sent_text): entrampes["tecnicos"].append(sent_text) elif any(term in sent_text.lower() for term in self.DOMINIOS["negocio"]["procesos"]): if re.search(self.PATRONES_ENTRAMPE["problema"], sent_text): entrampes["implementacion"].append(sent_text) elif any(term in sent_text.lower() for term in self.DOMINIOS["negocio"]["términos"]): if re.search(self.PATRONES_ENTRAMPE["preocupación"], sent_text): entrampes["organizacionales"].append(sent_text) return entrampes def extraer_objetivos(self, doc) -> Dict[str, List[str]]: """Extrae objetivos explícitos e implícitos del texto""" objetivos = { "corto_plazo": [], "esperados_microtaller": [] } for sent in doc.sents: sent_text = sent.text # Objetivos explícitos if re.search(self.PATRONES_ENTRAMPE["necesidad"], sent_text): objetivos["corto_plazo"].append(sent_text) # Objetivos implícitos relacionados con el microtaller if "microtaller" in sent_text.lower() or "taller" in sent_text.lower(): objetivos["esperados_microtaller"].append(sent_text) return objetivos def procesar_texto(self, texto: str) -> Dict: """Procesa el texto completo y genera el autodiagnóstico""" doc = self.nlp(texto) # Identificar dominio principal dominio = self.identificar_dominio_principal(texto) # Extraer ubicación ubicacion = self.extraer_ubicacion(doc) # Procesar el texto terminos = self.extraer_terminos_tecnicos(texto) entrampes = self.identificar_entrampes(doc) objetivos = self.extraer_objetivos(doc) # Construir el autodiagnóstico autodiagnostico = { "datos_generales": { "nombre": "", "sector": dominio, "ubicacion": ubicacion, "fecha": "" }, "reto": { "descripcion": texto[:500], "contexto": f"Sector {dominio.capitalize()} en {ubicacion['ciudad']}, {ubicacion['pais']}" if ubicacion['ciudad'] else "", "alcance": "" }, "conocimientos_cogtech": { "terminos_desconocidos": terminos["desconocidos"], "conceptos_dudosos": terminos["dudosos"], "areas_desconfianza": [] }, "dominio_actual": { "aspectos_dominados": terminos["mencionados"], "experiencia_previa": [], "recursos_disponibles": [] }, "entrampes": entrampes, "objetivos": objetivos } return autodiagnostico # Uso en la interfaz Gradio def procesar_con_gradio(texto_input: str) -> str: procesador = ProcesadorAutodiagnostico() resultado = procesador.procesar_texto(texto_input) return json.dumps(resultado, indent=2, ensure_ascii=False) # Create the Gradio interface with gr.Blocks() as app: gr.Markdown("# Autodiagnóstico CogTech") gr.Markdown(""" ## Instrucciones Describe tu situación considerando: - Tu reto o necesidad principal - Qué conoces y qué dudas tienes sobre tecnologías cognitivas - Qué obstáculos o dificultades enfrentas - Qué esperas lograr """) with gr.Row(): texto_input = gr.Textbox( label="Tu descripción", placeholder="Describe tu situación...", lines=10 ) json_output = gr.JSON(label="Autodiagnóstico Estructurado") analizar_btn = gr.Button("Generar Autodiagnóstico") analizar_btn.click( fn=procesar_con_gradio, # This uses our new processor inputs=texto_input, outputs=json_output ) gr.Markdown(""" ### Notas: - El sistema identificará automáticamente términos técnicos, entrampes y objetivos - Puedes copiar el JSON generado o descargarlo - Revisa y ajusta el resultado según sea necesario """) # Launch the app if __name__ == "__main__": app.launch()