Los que me conocéis sabéis que me gusta jugar con la tecnología. En los últimos años he trabajado en IA (tecnologías Watson) con varios clientes de IBM. Pasé por mi «fase chatbot» durante la pandemia, y ayudé a muchos clientes de IBM a responder y construir un chatbot durante este periodo de tiempo. Muchos de ellos utilizaron chatbots para comunicarse constantemente con la gente de sus comunidades. Fue divertido trabajar con la gente y saber que tu trabajo tenía un impacto real en la vida de las personas. La llamé mi «fase chatbot» porque tenía la sensación de que todo tipo de problemas podían resolverse con chatbots y asistentes virtuales.
Después de esa «fase chatbot» inicial, empecé a fijarme en los modelos ML y en otras técnicas relacionadas con el ámbito de la Data Science. Ahí es donde he estado durante un año más o menos. Hace poco, tuve una conversación con alguien sobre las herramientas que utilizamos en el trabajo. Entramos en una discusión sobre Slack, y cómo funcionaba (o no funcionaba) con otras herramientas y repositorios de información que utilizamos. Mi amigo dijo: «Si hubiera una forma de consolidar todas las mejores fuentes de información…«. DING, DING, DING. Cuando oí eso, volví a mi antigua mentalidad de chatbot.
Pensé en cómo el conocimiento institucional en nuestro entorno parece estar capturado por Slack, que tiene un montón de preguntas del tipo «con quién hablo…», y «dónde está el proceso para…». Muchas de esas preguntas las responden los responsables técnicos de la comunidad. También tenemos varias bases de conocimientos con distintos tipos de información técnica. ¿No sería estupendo poder encontrar rápidamente esa información? De repente, esto suena como el tipo de caso de uso en el que solía trabajar con mis clientes, cuando utilizábamos chatbots y asistentes virtuales para resolver sus problemas de comunicación e intercambio de conocimientos.
Tabla de contenidos
Decidir el alcance
He creado MUCHOS chatbots, casi todos basados en el motor de Watson Assistant. Con cualquier buen chatbot, siempre es de ayuda tener una idea del dominio de conocimiento que quieres abordar, y una idea de cómo te gustaría que fuera tu experiencia de usuario. Te ayuda a tomar decisiones más adelante y a mantenerte centrado. En este momento tenía un par de «requisitos» que me rondaban la cabeza. Eran más o menos así:
- Necesitas ser capaz de hacer tu pregunta y obtener una respuesta desde el interior de Slack, o desde un navegador Web. Quería que las cosas se pudieran hacer «al paso» o «en contexto».
- No me preocupa tanto una respuesta real como que me indiquen DÓNDE está la respuesta. La conversación y la gente en torno a un tema son igual de importantes para mí (me dice con quién puedo ir a hablar). ¿Dónde puedo aprender de forma productiva?
- Quiero poder señalar muchos «depósitos de conocimiento» diferentes. Los que se me ocurren de inmediato son Slack (pero sólo determinados canales de «alta calidad»), GitHub (de nuevo, sólo determinados repositorios de páginas markdown o páginas GitHub) y, posiblemente, algún repositorio de notas técnicas o base de conocimientos.
Mi proceso de pensamiento era que el usuario final quería hacer una pregunta, con la esperanza de que alguien hubiera hecho una pregunta similar antes en Slack, o que tuviéramos contenido sobre el mismo tema general en algún repositorio de conocimiento. Si el usuario final recibía un conjunto de enlaces con una breve descripción, podía determinar si el enlace devuelto era algo en lo que valía la pena profundizar para buscar una respuesta, o si estaba escrito por un experto que podría ayudarle a responder a su pregunta. Nos interesa el CONTEXTO (quién es el autor de un artículo, quién ha formulado una pregunta, quién ha respondido a una pregunta, etc.) tanto como la respuesta.
Este fue un punto importante para mí. Me permitió tener éxito por varias razones:
- No tenía que analizar el texto y buscar preguntas y respuestas, sólo tenía que mirar el contenido y buscar conceptos similares. Esto es MUCHO más fácil y requiere mucho menos procesamiento.
- Mis usuarios no esperaban RESPUESTAS, esperaban ORIENTACIÓN. Tenía licencia para ser un poco menos preciso, pero a cambio tenía que proporcionar más contexto a mis usuarios finales.
- Esto me permitió planificarlo como una serie de sprints ágiles, en los que podía centrarme en desplegar «dominios de conocimiento», en lugar de mejoras incrementales de la precisión. Seguiría mejorando la precisión con el tiempo, pero el objetivo de cada sprint sería la inclusión de algún dominio o subdominio de conocimiento. Así, el proceso de desarrollo era más fácil de entender y de describir.
Una vez definido el ámbito de aplicación, mi proyecto fue bastante fácil de imaginar. Toda la arquitectura se reducía a esto:
Tendría un Watson Assistant front-end para proporcionar soporte de integración y soporte para una variedad de posibles experiencias de usuario final (Slack-bot, chatbot, móvil, etc.). Empezaría con un bot de Slack. Watson Discovery sería el motor que devolvería resultados de búsqueda basados en la pregunta del usuario final. Discovery puede extraer palabras clave, relaciones y conceptos, y debería ser capaz de devolver una lista de materiales relevantes. El «músculo» de la solución sería la minería de la amplia variedad de repositorios, de modo que podamos ingerir el contenido, enriquecerlo y proporcionar la información básica para el usuario final.
Esta minería de repositorios necesitaría código (adiós a mi chatbot «sin código»). Una vez configurado, quería que fuera fácil de mantener para cualquiera, no sólo para alguien que supiera Python.
Implementación de las piezas fáciles – Watson Assistant
El primer paso fue empezar a implementar las piezas de Watson Assistant. Para mis pruebas, podía utilizar la capacidad de prueba de «sample website» disponible en Watson Assistant. También pude utilizar la integración con Slack para ofrecer una interfaz coherente (y fácil de usar) a mis usuarios finales. Hacer todo esto fue bastante fácil y sencillo.
Lo siguiente fue configurar la integración de Watson Discovery. Esto también es muy fácil. En la documentación se denomina «deploying a search skill«. Se trata de proporcionar un nodo de diálogo «catch all» que dirija la pregunta del usuario directamente a una búsqueda en una colección de Watson Discovery. La parte más difícil de esto es saber cómo configurar esta habilidad. Compartiré cómo hacerlo más adelante, así que por ahora, simplemente despliega esa habilidad de búsqueda y utiliza la configuración por defecto.
Toda esta configuración es bastante similar a la del Chatbot de Preguntas Frecuentes que se cubre en la documentación del producto. Sólo hacemos algunas cosas diferentes en torno a lo que proporcionamos al usuario final, y cómo ingerimos el contenido en la colección Watson Discovery.
Implementación de la parte difícil: mejora e ingestión
La parte difícil es obtener la información que necesitamos en nuestra colección Discovery. Intenté utilizar un rastreador web en un par de repositorios diferentes, pero tuve muy poca suerte con ellos porque la mayoría ofrecían contenido dinámico, y el rastreador web no podía acceder al contenido dinámico. También tuve problemas para proporcionar un enlace correcto al contenido de la página. Los rastreadores web no funcionaban para la minería de canales de Slack.
Así que me quedaba hacer algo de código Python. Uno de mis compañeros me proporcionó un código muy bueno para acceder a un canal en particular en Slack, durante un período de tiempo determinado. Esto fue genial – me permitió obtener el contenido de un mensaje de Slack, así como un enlace a la propia publicación.
A continuación, desarrollé un par de rutinas que me permitían obtener información de markdown y de páginas de un repositorio de GitHub, junto con un enlace a la fuente de información. Esto cubría mi capacidad de «rastrear» repositorios de GitHub.
La parte clave aquí fue un pequeño cambio que hice en el repositorio Discovery. Es clave para todo mi caso de uso. Añado algunos campos a los metadatos con CADA elemento que añado a mi corpus Discovery (la colección que utilizo). Con cada elemento, añado metadatos para la URL donde se encuentra el contenido original (para que pueda proporcionar enlaces al contenido original para mis usuarios), una fecha de ingestión (para que pueda «envejecer» o eliminar los datos antiguos en mi corpus), y un tipo de repositorio (porque voy a manejar diferentes repositorios de manera diferente). Con este sencillo paso, puedo podar los datos de mi corpus y hacer que los datos devueltos por Watson Discovery se ajusten a la forma que quiero mostrar con mi Watson Assistant.
Podando la base de conocimientos
Al principio del diseño de mi robot de conocimiento, supe que la reducción de los datos de mi corpus sería fundamental. El problema era que el conocimiento tiende a cambiar con bastante rapidez: cosas que hoy pueden ser ciertas, mañana son falsas. Las buenas prácticas cambian con el tiempo. Así que tenía que asegurarme de que mi corpus contuviera sólo los mejores datos y los más oportunos. Afronté el problema desde dos direcciones distintas.
En primer lugar, creé un algoritmo rápido que recorría todo el contenido de mi corpus (la colección Watson Discovery) y lo clasificaba por tiempos. Como algunos de mis repositorios eran más fluidos que otros, establecí un tiempo de caducidad específico para cada repositorio. Así, mientras que en un repositorio sólo podía tener en cuenta las cosas que tenían 90 días o menos, en otro repositorio sólo podía confiar en las cosas que tenían 45 días. Esto me dio la flexibilidad de adaptar mis criterios de retención para cada repositorio.
La segunda dirección desde la que abordé esta cuestión fue más estratégica. La mayoría de las aplicaciones de inteligencia artificial ingieren tantos datos como pueden, en un intento de «aprender» todo lo posible. Yo iba a hacer lo contrario. Iba a ser muy específico en mi selección de repositorios de datos. Sólo quería canales de Slack ESPECÍFICOS, los que tuvieran los mejores debates y el mayor número de expertos participantes. También quería únicamente repositorios de información ESPECÍFICOS. No iba a indexar toda la información que encontrara. Quería los repositorios que tuvieran reputación de tener materiales precisos y de alta calidad. Esto significaba que podría obtener menos respuestas, pero tenía el efecto de proporcionar resultados más específicos y de mayor calidad a mis usuarios finales.
Configurar correctamente la habilidad de búsqueda
La otra pieza que es un poco diferente es la configuración de la habilidad de búsqueda en Watson Assistant. Dado que mis resultados se mostrarían en Slack o en una página web, quería asegurarme de que los usuarios de ambas plataformas pudieran acceder fácilmente a ellos. Así que acabé devolviendo información muy específica.
Fui a la parte de integración de búsqueda de Watson Assistant y elegí metadata: repository_type para el título devuelto, seleccioné metadata:summary para el cuerpo y devolví metadata: URL para la URL devuelta. A continuación, configuré la cantidad para que devolviera sólo los tres primeros resultados.
Esto probablemente parezca muy extraño, ya que en realidad devuelvo muy poco texto (el resumen debe configurarse explícitamente durante la ingesta) o información al usuario final. Cuando se utiliza esto en Slack, o en un navegador web, lo que se devuelve es un conjunto de tres enlaces, con el título del repositorio del que proviene la respuesta, un pequeño resumen y un enlace a la fuente de información. A continuación, Slack ampliará uno o dos de los enlaces devueltos y el usuario final obtendrá una buena serie de enlaces que podrá utilizar para encontrar las respuestas o las personas que podrían ayudarle. Recuerda que, cuando analizamos nuestros requisitos, nos preocupaba más la ORIENTACIÓN que las respuestas. En el futuro, si veo que estamos devolviendo respuestas relevantes con un alto grado de precisión, puede que sólo devuelva los dos primeros enlaces.
Dejarse llevar
Una vez que lo tuve todo listo, solo tuve que dirigirlo a los repositorios adecuados, vincularlo a una instancia de Slack disponible, seleccionar los canales de Slack apropiados para recopilar conocimientos y ponerlo en marcha. Lo desplegué en una instancia de Watson Studio en la nube de IBM y lo convertí inmediatamente en una tarea que se ejecutaría una vez al día. El resultado fue que, una vez que todo estaba conectado, tenía una tarea por lotes que se ejecutaba una vez al día y actualizaba automáticamente mi corpus en función de los repositorios que quería consultar. Incorporaba nuevos contenidos, actualizaba los actuales si habían cambiado y eliminaba los datos antiguos. Se mantenía solo, exactamente lo que yo quería.
Así que ahora todo lo que tengo que hacer es echar un vistazo a mi proyecto en Watson Studio una vez cada pocos días, y asegurarme de que los registros de mis trabajos nocturnos son agradables y limpios. Una vez al mes, más o menos, revisaré la lista de fuentes de información «fiables» y añadiré o eliminaré repositorios en función de lo que me digan mis expertos en la materia.
Entonces, ¿cómo te ayuda esto a ti?
Escribí esto como una manera de capturar lo que aprendí a través de este proceso, y como una manera de compartir algunos enfoques que funcionaron para mí. Hice esto porque veo un montón de organizaciones que luchan por conseguir que el aprendizaje automático y la IA trabajen para ellos de una manera muy real o significativa. Muchas organizaciones tratan erróneamente de seguir el consejo y el enfoque de las personas que crean las GRANDES aplicaciones de IA (como GPT-3). Esas aplicaciones y enfoques son válidos para las áreas problemáticas a las que se dirigen, pero la mayoría de las personas tendrán problemas DIFERENTES que están tratando de resolver, y por lo tanto necesitan adoptar enfoques DIFERENTES.
Si estás buscando algo similar a esto, y te gustaría ver el código que he utilizado para este proyecto, por favor ponte en contacto conmigo. Estaré encantado de discutir el enfoque aquí, y para compartir mi cuaderno de Python y el código con todos vosotros.