Creando un chatbot de soporte técnico

,

Agregar un chatbot con IA a Discourse es fácil (gracias a 2 excelentes complementos). ¡Pero agregar un chatbot que realice soporte técnico es mucho más difícil! Este post comparte nuestra experiencia configurando un chatbot de soporte técnico para support.suretyhome.com — lo que queríamos, los problemas que tuvimos, cómo los resolvimos y hacia dónde iremos a partir de ahora.

Nuestro equipo de soporte solo está disponible durante el horario comercial, pero los clientes quieren ayuda las 24 horas del día, los 7 días de la semana. No estamos tratando de reemplazar al equipo de soporte. Nuestro objetivo es potenciar al equipo de soporte con un bot que:

  • Esté disponible 24/7, incluidas noches y fines de semana, al igual que nuestro foro
  • Responda de inmediato, mientras que nuestro equipo de soporte humano tarda un poco más
  • Podría ser capaz de responder preguntas que los usuarios no pudieron resolver con una búsqueda en el foro

Aquí está nuestra experiencia.

Elegir un complemento

Existen dos complementos realmente buenos que ofrecen un chatbot con IA.

  1. Discourse AI
  2. Discourse Chatbot

El complemento Discourse AI es el complemento oficial de IA del equipo de desarrollo de Discourse. Incluye un chatbot, además de otras funciones de IA. El complemento Discourse Chatbot es únicamente un chatbot. Fue creado antes que Discourse AI y se centra en hacer esa única tarea muy bien.

Inicialmente, no teníamos idea de cuál usar, así que hice la pregunta aquí para obtener algunos consejos.

Recibimos mucha ayuda excelente. Terminamos optando por Discourse Chatbot porque es más flexible como chatbot, con más opciones y características (opciones) para personalizar. Nuestro caso de uso tenía algunas demandas específicas que aún no parecían factibles con Discourse AI. Cualquiera puede ser una gran elección. La que sea adecuada para ti depende de las necesidades específicas de tu foro.

Configuración inicial

La configuración inicial de Discourse Chatbot puede ser un poco compleja porque hay muchas opciones entre las que elegir y personalizaciones que puedes realizar. Sigue las instrucciones de configuración cuidadosamente y asegúrate de revisar todas las configuraciones.

Nuestro objetivo era ofrecer una experiencia similar a un chat, por lo que solo queríamos que el bot funcionara en el Chat de Discourse, no en temas públicos o mensajes privados. Los primeros pasos que tuvimos que dar fueron:

  • Configurar Discourse Chat (Discourse Chatbot depende de ello)
  • En la configuración de Discourse Chatbot, chatbot permitido en chat: activado

Ingeniería de prompts

Discourse Chatbot es increíblemente personalizable. Cualquier cosa que no sea una configuración se personaliza en Discourse > Personalizar > Texto. Aquí es donde realizas toda tu ingeniería de prompts. En Personalizar > Texto, busca chatbot.prompt para filtrar todo el texto de prompts personalizable.

Para que el bot se comporte como queremos, necesitaremos editar el prompt del sistema. Pero hay 2 de ellos, uno para discusiones públicas y otro para privadas. Dado que solo estamos usando el bot en canales de chat privados, necesitábamos editar chatbot.prompt.system.rag.private.

Como bot de soporte técnico, necesitamos que sea más conservador y preciso de lo que suelen ser los LLMs por defecto. Nuestro prompt del sistema necesitaba ser relativamente largo para lograr esto. En el prompt del sistema, proporciona al LLM instrucciones y contexto que respondan preguntas como:

  • ¿Quién es tu bot? ¿Qué rol debe desempeñar?
  • ¿Qué información de fondo o contexto necesita conocer?
  • ¿Qué temas se supone que debe discutir? ¿Qué temas nunca debe discutir?
  • ¿Qué estilo de escritura o tono debe usar?
  • ¿Qué debe hacer cuando el usuario está frustrado?

Además de esta ingeniería de prompts general, el prompt del sistema también es un lugar donde puedes intentar resolver problemas que descubras durante las pruebas. Si encuentras que tu bot comete un error grave, quizás puedas solucionarlo añadiendo instrucciones al prompt del sistema. Pero ten cuidado: el prompting es meramente una sugerencia para el LLM. No lo estás programando. Solo le estás pidiendo que se comporte de cierta manera. Es posible que no te haga caso.

Temperatura y Top P

Otra herramienta para hacer que el bot sea más conservador y menos propenso a inventar cosas es la configuración de temperatura. Por defecto, la configuración de temperatura es 100, que es el 50% de la temperatura máxima. Puedes reducirla aún más para hacer que el bot sea más conservador o determinista, y menos propenso a cometer errores. Pero cuando la temperatura se establece muy baja (como 0), el LLM no suena tan impresionante. Es una decisión de compensación que tendrás que tomar.

Además de la temperatura, existe la configuración Top P. Probablemente no la necesites, pero está ahí por si acaso. Consulta la documentación de OpenAI para obtener más información.

Las configuraciones de Discourse Chatbot para esta sección son:

  • chatbot request temperature
  • chatbot request top p

Problema: LLM inexacto y desactualizado

El LLM fue entrenado con una gran cantidad de datos generales hace algún tiempo. Necesitamos que tenga la información más actualizada y específica sobre nuestro foro y sea lo más preciso posible. La solución es la Generación Aumentada por Recuperación (RAG).

RAG buscará información adicional en el foro antes de responder al usuario. Como bot de soporte técnico, no podemos confiar únicamente en el conocimiento entrenado del LLM; necesitamos que el bot busque información técnica en nuestro foro antes de responder.

Para realizar RAG, Discourse Chatbot necesita crear una base de datos de «incrustaciones» (embeddings) que representen cada publicación de nuestro foro como un vector de «características» semánticas. Esto debe estar activado, pero recomiendo esperar a activarlo hasta después de configurar tu estrategia de incrustaciones, que cubriremos en la siguiente sección.

Las configuraciones de Discourse Chatbot para esta sección son:

  • chatbot bot type high trust: RAG
  • chatbot bot type medium trust: RAG
  • chatbot bot type low trust: RAG
  • chatbot embeddings enabled: activado (después de configurar la estrategia de incrustaciones)

Problema: Muchas publicaciones del foro no son útiles

Que el bot busque en tu foro antes de responder (RAG) es genial, pero introduce un nuevo problema. Muchas de las publicaciones en un foro no son muy útiles. Algunas son útiles, y esas son las que quieres que el bot encuentre, pero muchas son simplemente conversacionales, confusas o directamente incorrectas. Nuestra solución es curar una base de conocimientos (KB) que contenga solo las publicaciones que queremos que el bot encuentre.

Para hacer esto en Discourse Chatbot, usamos la estrategia de incrustaciones por categorías. La estrategia de incrustaciones determina qué publicaciones están disponibles para el chatbot cuando busca en el foro. Nuestro enfoque es tener una sola categoría no pública que sirva como base de conocimientos del chatbot, por lo que elegimos categorías como estrategia de incrustaciones. La categoría de la base de conocimientos también debe identificarse en la configuración embeddings categories.

Usamos una categoría no pública (visible solo para el personal) porque estamos duplicando muchos temas públicos en esta categoría y no queremos que los usuarios vean los duplicados. Duplicar temas en una categoría privada introduce otros problemas:

  1. Es mucho trabajo copiarlos y aún peor mantener las copias cuando los temas se actualizan o se les responde.
  2. Los temas que el bot encuentra al buscar en el foro no son temas públicos a los que se deba dar enlaces a los usuarios como referencia. Necesitamos enviar al LLM enlaces a los temas públicos.

Para resolver estos dos problemas, creamos herramientas mínimas para ayudarnos a copiar temas de categorías públicas a nuestra categoría privada de KB del chatbot y mantener las copias de KB actualizadas cuando se actualizan los temas públicos. Están disponibles aquí si deseas usar el mismo enfoque que nosotros.

Las herramientas de KB importan un tema público completo a la categoría privada de KB como un nuevo tema con solo 1 publicación, concatenando todas las publicaciones del tema público y añadiendo un enlace a cada publicación pública antes de su contenido. De esta manera, cuando el bot encuentra la publicación privada de KB en una búsqueda RAG, obtiene el contenido de todo el tema público y las URL de las publicaciones públicas que puede incluir en la respuesta como referencias.

Las configuraciones de Discourse Chatbot para esta sección son:

  • chatbot embeddings strategy: categories
  • chatbot embeddings categories: (tu categoría privada de KB)
  • chatbot forum search function include topic titles: desactivado (por defecto)

Adicionalmente, debes eliminar algunas claves de interpolación del prompt de búsqueda del foro porque no son relevantes cuando las publicaciones están en una categoría privada.

  • chatbot.prompt.function.forum_search.answer.topic.each.post: Elimina %{username} y %{date}
  • chatbot.prompt.function.forum_search.answer.topic.each.topic: Elimina %{title} y %{url}

Problema: El LLM no realiza búsquedas RAG suficientes

Ahora que tenemos una categoría privada con publicaciones curadas llenas de buena información para servir como nuestra base de conocimientos del chatbot, todo debería estar bien, ¿verdad? Incorrecto. El siguiente problema que encontramos fue que la función de búsqueda RAG no se utilizaba casi nunca por parte del LLM.

Los LLMs como GPT-4 son lo suficientemente inteligentes como para ser peligrosos. A menudo «piensan» que ya saben la respuesta y no necesitan pedir ayuda, cuando en realidad deberían realizar una búsqueda RAG y buscar la respuesta en la base de conocimientos. Para resolver esto, usamos la opción de elección de herramientas y forzamos al LLM a llamar a una función.

Podríamos forzar una búsqueda local en el foro, pero descubrimos que simplemente forzar una llamada a función es suficiente, y queremos darle al LLM la libertad de llamar a veces a otra función en lugar de realizar una búsqueda en el foro.

Las configuraciones de Discourse Chatbot para esta sección son:

  • chatbot tool choice first iteration: force_a_function

Problema: Rendimiento de la búsqueda en el foro

Al forzar una llamada a función, el LLM realiza de manera confiable una búsqueda RAG para casi cada respuesta. Pero aún estábamos obteniendo malos resultados. El bot no encontraba las publicaciones correctas en la base de conocimientos. Con tanta información en nuestras publicaciones, había mucho «ruido» interfiriendo con la capacidad de la función de búsqueda para encontrar la mejor publicación.

Por ejemplo, imagina que el usuario le pregunta al bot cómo detener el pitido de su impresora HP Laser Jet. El LLM podría realizar una búsqueda en el foro con la consulta «HP LaserJet detener pitido». Podría haber una publicación en la base de conocimientos que aborde perfectamente ese problema, pero la parte de la «pregunta» de la misma (que coincidiría estrechamente con la consulta) es solo el 2% del texto de la publicación. El 98% restante del texto son los pasos de solución de problemas y las respuestas.

La búsqueda local en el foro de Discourse Chatbot es una búsqueda semántica que utiliza las incrustaciones vectoriales para encontrar la publicación (o pocas publicaciones) más similar a la consulta. La parte de la pregunta de la mejor publicación es muy similar a la consulta, pero es solo el 2% del texto general. El 98% restante del texto hace que la publicación no sea tan similar a la consulta, por lo que la publicación no se clasifica alto en una búsqueda para esa consulta.

Nuestra solución a este problema es añadir «publicaciones señuelo» a los temas de nuestra base de conocimientos que solo contengan texto similar a la consulta de búsqueda. En nuestro ejemplo anterior, podríamos añadir una publicación señuelo con solo «HP Laser Jet pitido». La función de búsqueda local en el foro encontrará fácilmente la publicación señuelo porque es muy similar a la consulta. Luego, Discourse Chatbot enviará el contenido de la publicación real, que incluye la respuesta, de vuelta al LLM en lugar de la publicación señuelo.

Dado que nuestros temas de KB tienen todo su contenido en la primera publicación, podemos usar las respuestas en los temas de KB como publicaciones señuelo. Después de usar nuestras herramientas de KB para importar temas a la base de conocimientos, podemos simplemente responder a los temas de KB para crear publicaciones señuelo.

Las configuraciones de Discourse Chatbot para esta sección son:

  • chatbot forum search function results content type: topic
  • chatbot forum search function results topic max posts count strategy: just_enough
  • chatbot forum search function results topic max posts count: 1

Las publicaciones señuelo proporcionan un mecanismo poderoso para optimizar la base de conocimientos para la búsqueda, pero estás atado a hacerlo a ciegas. No puedes ver las búsquedas a medida que ocurren, por lo que es difícil decir exactamente cómo tus publicaciones señuelo están impactando en los rankings de búsqueda. Para ayudar a resolver este problema, creamos un pequeño programa que realiza la misma búsqueda semántica que usa Discourse Chatbot, pero lo hace localmente en tu computadora y muestra todos los detalles, como puntuaciones de similitud y clasificación. Esto hace que sea mucho más fácil crear publicaciones señuelo que realmente mejoren el rendimiento de la búsqueda y optimicen la base de conocimientos.

La combinación de RAG, una base de conocimientos curada, forzar al LLM a llamar a una función y publicaciones señuelo finalmente dio como resultado un chatbot de soporte técnico bastante bueno! :boom: :tada: :partying_face:

El LLM alucina URLs

Aunque el bot estaba funcionando bien al responder preguntas técnicas, todavía tenía un problema molesto de alucinación. Frecuentemente alucinaba URLs en las respuestas al usuario. Este es un problema conocido con los LLMs y el consenso general es que simplemente tienes que lidiar con ello. No queríamos que nuestros usuarios tuvieran que lidiar con ello.

Dado que nuestro bot proporciona soporte técnico, dependemos en gran medida de RAG para proporcionar al LLM información precisa y actualizada. Lo forzamos a realizar una búsqueda RAG antes de cada respuesta. Confiamos en que el LLM «entienda» y se comunique con el usuario, pero dependemos casi por completo de nuestra base de conocimientos para la información técnica utilizada para responder sus preguntas. Podemos aprovechar esto para evitar que el bot alucine URLs.

Nuestra solución es añadir una restricción al bot para que solo pueda incluir una URL en su respuesta si esa URL provino de un resultado de búsqueda en el foro. Si el LLM intenta incluir una URL que ya no estaba en un resultado de búsqueda en el foro, entonces Discourse Chatbot le informará al LLM sobre el problema y le pedirá que intente de nuevo. Esta solución sencilla ha eliminado efectivamente las alucinaciones de URLs.

Las configuraciones de Discourse Chatbot para esta sección son:

  • chatbot url integrity check: enabled

Problema: El chatbot no puede manejar todo

Algunas preguntas de soporte no pueden ser manejadas por el chatbot porque requieren que se tome una acción. Por ejemplo, si se necesita realizar un cambio de cuenta o devolver un producto (lo que requiere un reembolso y/o una autorización), entonces el bot no puede hacerlo.

También depende de la complejidad. Muchas preguntas son sencillas: si el usuario hubiera buscado en el foro con la consulta correcta, habría encontrado la respuesta. En ese caso, el bot es bastante bueno buscando en el foro, encontrando la respuesta y presentándosela. Pero cuando el problema requiere investigación o análisis complejo, el bot a menudo da una respuesta genérica que no aporta mucho valor.

En cualquiera de estas situaciones donde el bot no puede manejar el problema, necesitamos que escalé el chat a nuestro equipo de soporte humano. Discourse Chatbot tiene una función para que el LLM haga exactamente eso, llamada escalate to staff.

Las configuraciones de Discourse Chatbot para esta sección son:

  • chatbot escalate to staff function: enabled
  • chatbot escalate to staff groups: (el grupo al que se desea escalar)

Ya estamos forzando al LLM a llamar a una función antes de responder, pero ahora surge la pregunta de qué función llamar. ¿Debe el LLM llamar a la función local forum search (RAG) o a la función escalate to staff? Debe tomar esta decisión cada vez que un usuario le envía un mensaje. La mayoría de las veces queremos que llame a local forum search. Solo queremos que escalate to staff cuando no pueda manejar el problema, note que el usuario está frustrado o el usuario lo solicita explícitamente.

Usamos el prompting para guiar al LLM sobre cómo decidir qué función llamar. Los textos de prompts que puedes editar para esto en Personalizar > Texto son:

  • chatbot.prompt.system.rag.private
  • chatbot.prompt.function.forum_search.description
  • chatbot.prompt.function.escalate_to_staff.description

Problema: No se pueden monitorear los chats

Cuando los usuarios están usando realmente el chatbot, es útil ver las conversaciones y vigilar respuestas malas o oportunidades de mejora. Pero Discourse no proporciona una forma para que los administradores lean los chats, lo cual tiene sentido porque los chats son típicamente conversaciones privadas entre personas. Los chats con el bot de soporte, sin embargo, no son conversaciones privadas y si no podemos revisarlos, no podemos mejorar continuamente el bot.

La buena noticia es que Discourse ofrece a los administradores una forma de exportar todo el historial de chats del foro como un archivo CSV.

Para resolver este problema, creamos un pequeño programa que convierte el archivo CSV del historial de chats en una serie de archivos HTML, uno para cada usuario que chateó con el bot. No podemos vigilar el uso del bot en tiempo real, pero con esta solución podemos exportar periódicamente el historial de chats, convertirlo a archivos HTML y revisarlos para trabajar en la mejora de nuestro bot.

Conclusión

Después de lidiar con cada uno de estos problemas y curar la base de conocimientos lo suficiente, finalmente pudimos permitir que los usuarios comenzaran a usar el chatbot.

Hasta ahora, los resultados han sido mixtos. Es emocionante cuando vemos a personas usando el chatbot durante noches y fines de semana, obteniendo respuestas a sus preguntas y resolviendo problemas. Es revelador cuando vemos a personas intentando usar el chatbot y no teniendo una gran experiencia. Por lo general, significa que algo falta o no está claro en nuestra base de conocimientos. Ocasionalmente vemos un problema que requiere una mejora en el prompt del sistema. Y a veces es evidente que hay confusión y necesitamos mejorar cómo presentamos el chatbot al usuario.

Hemos visto que aproximadamente la mitad de los chats requieren una escalada al personal. Aproximadamente la mitad de esas escaladas son casos donde el bot no podría haber manejado la situación. La otra mitad (aproximadamente el 25% de los chats) son casos donde el bot podría haber resuelto el problema pero falló, lo cual son oportunidades de mejora.

De los chats que no resultan en una escalada al personal, puede ser difícil decir si el usuario realmente resolvió su problema o simplemente se rindió y se fue. Es obvio cuando el bot da una respuesta incorrecta qué necesita mejorarse. No siempre es obvio cuando está dando respuestas razonables y buenas si el usuario entendió completamente y su problema fue resuelto, a menos que nos lo digan.

En general, estamos contentos con esta primera iteración del chatbot de soporte de Surety y esperamos que el LLM mejore, así como nuestra base de conocimientos se vuelva mejor con el tiempo. Trabajar en la base de conocimientos es nuestro trabajo más importante ahora.

Discourse Chatbot ha añadido soporte para búsqueda híbrida (búsqueda semántica y de texto) desde que comenzamos a trabajar en este proyecto, así que probablemente experimentaremos con eso pronto.

¡Gracias a @merefield por todo su arduo trabajo en el complemento Discourse Chatbot! Ha sido muy divertido trabajar con él y ha demostrado estar a la altura de la tarea.

¡Si alguien más decide construir un chatbot de soporte técnico para su foro, por favor contáctame y házmelo saber! Sería genial tener a otros con quienes colaborar y compartir ideas. Actualizaré nuevamente a medida que ocurran cosas interesantes, se realicen cambios o aprendamos algo nuevo.

14 Me gusta

Para tu información, esto se implementará en Discourse AI según:

Estoy de acuerdo en que esta es una característica bastante importante para los RAG, los LLM son perezosos y a menudo se niegan a buscar.

6 Me gusta