Así que quieres crear un chatbot con inteligencia artificial. Tal vez fue mi artículo anterior sobre casos de uso de chatbot lo que te trajo aquí, o ya tenías la idea en la cabeza y sólo necesitas algunos consejos sobre cómo puedes hacerlo. Pues bien, has llegado al lugar adecuado.

Antes de empezar, sólo una nota rápida que este artículo está diseñado para ayudar a la gente de tecnología (es decir, las personas que se sienten cómodos con la codificación) iniciar un proyecto de desarrollo Chatbot AI. Asumiré que te sientes cómodo con un lenguaje de programación (Python o JavaScript), sabes lo que es una API, cómo usarla y qué es un LLM.

Principalmente, hablaré de 3 formas diferentes de desarrollar un Chatbot de IA:

     

      • utilizando una API

      • afinando un modelo

      • utilizando RAG

    Si estás buscando una manera de construir un chatbot que utilice IA pero no te sientes cómodo con la codificación, entonces echa un vistazo a mi otro artículo pensado para no desarrolladores. (próximamente)

    Ahora vayamos al grano:

    Tabla de contenidos

    El chatbot «Quiero ChatGPT en mi sitio web»

    Esta es la opción más sencilla. Prácticamente sólo quieres que tu cliente pueda hablar con ChatGPT directamente desde tu sitio web. Tal vez tengas un sitio web de temática clara  y sólo quieras ofrecer al usuario la posibilidad de hablar con un asistente. Si ignoras la posibilidad de alucinaciones (podría inventarse fechas o acontecimientos históricos), entonces ésta es la opción perfecta. Fácil de implementar, bajos costes, gran base de conocimientos.

    Así es como se hace:

        1. Construyes la interfaz del chatbot de IA usando HTML, CSS, JavaScript, React o cualquier otro framework de tu elección.

        1. Elige tu LLM teniendo en cuenta las capacidades y los costes. Échales un vistazo en HuggingFace.

        1. Consigue una clave API (HuggingFace u OpenAI).

        1. Consulta la documentación y comprueba cómo tendrás que enviar la información a la API. Por ejemplo, para ChatGPT tendrás que darle un formato parecido al del código de abajo.

      let conversationHistory = [];
      // store here all the user questions and the answers from GPT to have context

      of previous questions and answers
      // store as { role: "user", content: userMessage } for user message
      // store as { role: "assistant", content: gptMessage } for answers

      const systemMessage={
      role:'system',
      content:'Answer me like a pirate'
      }
      // this will be the initial prompt.
      // it can be simple like in example or very complex with multiple instructions

      const generateResponse = (chatElement) => {
      const API_URL = "https://api.openai.com/v1/chat/completions";
      const messageElement = chatElement.querySelector("p");
      // or however you decide to extract the text from the user input

      conversationHistory.push({ role: "user", content: userMessage });
      // push user message to conversationHistory before making the request

      // Define the properties and message for the API request
      const requestOptions = {
      method: "POST",
      headers: {
      "Content-Type": "application/json",
      "Authorization": `Bearer ${YOUR_API_KEY}`
      },
      body: JSON.stringify({
      model: "gpt-3.5-turbo",
      messages: [systemMessage, ...conversationHistory],
      })
      }

      // Send POST request to API, get response and set the reponse as paragraph text
      fetch(API_URL, requestOptions)
      .then(res => res.json())
      .then(data => {
      messageElement.textContent = data.choices[0].message.content.trim();
      // although it looks weird .choices[0],message.content is where you will find the text answer to the request
      conversationHistory.push({ role: "assistant", content: messageElement.textContent });
      // add the answer to the conversation history
      }).catch(() => {
      messageElement.classList.add("error");
      messageElement.textContent = "Oops! Something went wrong. Please try again."
      }

      Puede que haya mejores formas de implementar esto. Sólo quería darle un vistazo rápido de cómo enviar y recibir mensajes desde y hacia la API con el fin de construir su chatbot AI. Ahora sólo tienes que mostrar la respuesta al usuario y ¡listo!

      Para una explicación más detallada de cómo trabajar con la API de OpenAI, echa un vistazo a la documentación.

      El chatbot «Sigue siendo ChatGPT pero con respuestas más específicas»

      Si no consigues que el chatbot se comporte de la manera que deseas mediante el envío de preguntas, quizá quieras pensar en afinar un modelo. El ajuste fino consiste en utilizar un modelo preentrenado y entrenarlo en un conjunto de datos específico para su tarea. Obtendrá un chatbot de IA con respuestas más específicas para su caso de uso. Sin embargo, le costará más tiempo y dinero.

      Así que, antes de afinar, intenta encontrar otras formas de resolver el problema. He aquí algunas estrategias para obtener mejores resultados con ChatGPT que puede probar antes de realizar el ajuste fino. Si la ingeniería de avisos o el encadenamiento de avisos (dividir tareas complejas en varios avisos) no funcionan, el siguiente paso es el ajuste fino.

      Los casos de uso para ajustar un chatbot de IA pueden ser:

        • Establecer el estilo y el tono del chatbot de IA (quieres que suene como un pirata sarcástico, pero las instrucciones no te dan el tipo específico de sarcasmo que quieres).

        • Conseguir que responda en un formato específico (tal vez quieras darle un texto y que el chatbot responda sólo con viñetas que contengan información específica de ese texto, como personas mencionadas en el texto, tareas mencionadas, plazos, etc.).

        • Conseguir que el chatbot de IA siga instrucciones complejas (esto puede ser útil si quieres aumentar la seguridad, reducir las alucinaciones y las posibilidades de fuga).

        • Manejar casos extremos de forma específica (puedes especificar exactamente cómo quieres que responda en determinadas situaciones)

        • Realizar tareas que son difíciles de articular en un prompt.

      Dependiendo del LLM que quieras afinar, el proceso variará. Puedes usar TensorFlow con Keras, PyTorch o simplemente Python. Aquí puedes encontrar un tutorial para el ajuste fino en HuggingFace, y aquí está la documentación para el ajuste fino de OpenAI.

      Independientemente del LLM que elijas, necesitarás 1 cosa para afinar tu chatbot de IA: un conjunto de datos.

        • El conjunto de datos que utilices determinará la forma en que se afina el modelo y la manera en que tu chatbot de IA responderá a las preguntas.

        • El conjunto de datos debe ser del tipo pregunta-respuesta.

        • El conjunto de datos debe contener al menos entre 50 y 100 entradas para que el modelo pueda entrenarse de forma eficaz.

        • Asegúrate de incluir todas las preguntas relevantes que crees que podrían hacer tus clientes, todos los casos extremos que quieres que se traten de forma diferente y todas las preguntas que podrían plantear riesgos de seguridad.

        • El modelo aprenderá de tu conjunto de datos cómo responder a preguntas específicas, pero también en general (estilo, tono) y ofrecerá un resultado mejor que el modelo normal en consultas específicas del usuario.

      Si quieres ser más específico, siempre puedes incluir indicaciones cuando utilices el modelo en tu chatbot de IA, igual que haces cuando utilizas el modelo normal. Después de la puesta a punto, recibirá un nombre de modelo que puede insertar en su solicitud de API de la siguiente manera.

      const systemMessage={
      role:‘system’,
      content:‘Answer me like a pirate’
      }
      // prompt it however you like
      // use prompt engineering techniques on top of fine-tuning for better results

      const requestOptions = {
      method: «POST»,
      headers: {
      «Content-Type»: «application/json»,
      «Authorization»: `Bearer ${YOUR_API_KEY}`
      },
      body: JSON.stringify({
      model: ‘${YOUR_MODEL_NAME}’,
      messages: [systemMessage, …conversationHistory],
      })
      }

      Si quieres poner a punto un modelo OpenAI también te recomiendo que utilices este proyecto de Google Colab que te lleva paso a paso por todo lo que necesitas hacer e incluso crea el conjunto de datos por ti.

      El chatbot «ChatGPT pero conoce mi negocio»

      El problema con los modelos normales e incluso con los modelos ajustados (aunque puedes añadir información específica de tu negocio al ajustarlos) es que funcionan con una base de conocimiento general. Esto puede ser útil para la forma en que quieres que se comporte tu chatbot de IA, o puede apestar por completo y hacerlo inútil.

      Por ejemplo, pensemos en el siguiente escenario. Tienes una tienda online con cientos de productos y quieres crear un Chatbot de IA para tus clientes. No podrás poner toda la información sobre tus productos en un prompt y necesitarías miles de entradas en tu conjunto de datos para afinar. La solución es sencilla: «¡Ríndete! Esto no es para ti».

      Es broma. Hay una manera de entrenar un modelo específicamente en su base de conocimientos (que puede ser de miles de documentos) y crear un Chatbot de IA específico para su negocio.

      La generación aumentada por recuperación (RAG) es un marco de IA para mejorar la calidad de las respuestas generadas por LLM basando el modelo en fuentes externas de conocimiento. El desarrollo de un Chatbot RAG es más difícil, pero no tanto como para asustarte.

      Hay múltiples maneras de construir un Chatbot RAG pero los pasos principales son los mismos:

      Chatbot
        • El primer paso consiste en dividir toda la información en fragmentos de texto manejables. Los fragmentos más relevantes se enviarán al LLM junto con la pregunta del usuario. Por ello, debes utilizar trozos de entre 1.000 y 2.000 tokens.

        • En segundo lugar, los LLM no utilizan realmente texto, sino incrustaciones, que son una representación vectorial de la información (texto en nuestro caso). Tendrás que pasar todos los chunks por un Embedding Model para vectorizarlos. Ten en cuenta que el modelo de incrustación de OpenAI sólo ocupa el puesto 13 (en el momento de escribir esto) en la clasificación de incrustación. Echa un vistazo a su clasificación y elige el modelo que más te convenga.

        • A continuación, tendrás que añadir las incrustaciones en un almacén vectorial de tu elección. Pinecone es el más popular, pero existen alternativas de código abierto como Chroma o Qdrant que puedes utilizar. Echa un vistazo a este artículo para entender mejor qué es un Vector Store y cuál deberías utilizar.

        • Lo mismo hay que hacer con la pregunta del usuario: pasarla por un modelo de incrustación.

        • A continuación, realizará una búsqueda semántica en el almacén vectorial para recibir los trozos de texto que contengan la información más relevante, clasificados por su pertinencia con respecto a su pregunta.

        • La pregunta y los fragmentos de texto relevantes se introducen en el LLM de su elección, que puede hacer su magia y crear una buena respuesta a su pregunta.

        • También se le puede pedir al LLM que responda de forma específica e incluso que lo ajuste si lo deseas.

      Puedes hacer esto de muchas maneras diferentes usando Python o JavaScript. Te recomiendo que utilices el framework LangChain o EmbedChain ya que facilitan mucho el proceso.

      Aquí hay un ejemplo usando Python, LangChain y streamlit con FAISS como base de datos vectorial:

      from dotenv import load_dotenv
      from PyPDF2 import PdfReader
      from langchain.text_splitter import CharacterTextSplitter
      from langchain.embeddings.openai import OpenAIEmbeddings
      from langchain.vectorstores import FAISS
      from langchain.chains.question_answering import load_qa_chain
      from langchain.llms import OpenAI
      import streamlit as st

      def main():
      load_dotenv()
      st.set_page_config(page_title=«Chat with a PDF»)
      st.header(«Chat with a PDF «)

      # upload file that you want to «talk» to
      pdf = st.file_uploader(«Upload your PDF file here», type=«pdf»)

      # extract the text and put it in a variable
      if pdf is not None:
      pdf_reader = PdfReader(pdf)
      text = «»
      for page in pdf_reader.pages:
      text += page.extract_text()

      # split into chunks with chunk size 1000 and overlap 200
      char_text_splitter = CharacterTextSplitter(separator=«\n», chunk_size=1000,
      chunk_overlap=200,length_function=len)
      text_chunks = char_text_splitter.split_text(text)

      # create embeddings and upload them into FAISS vector database
      embeddings = OpenAIEmbeddings()
      docsearch = FAISS.from_texts(text_chunks, embeddings)
      llm = OpenAI()
      chain = load_qa_chain(llm, chain_type=«stuff»)

      # take user input and make similarity search in vector database
      query = st.text_input(«Type your question:»)
      if query:
      docs = docsearch.similarity_search(query)
      response = chain.run(input_documents=docs, question=query)

      st.write(response)

      if __name__ == ‘__main__’:
      main()

      Ventajas de cada implementación

      Es hora de poner las 3 posibles implementaciones de Chatbot de IA y ver cuáles son los pros y los contras de cada una.

      Costes

        • Llamada a la API: los costes de esta implementación son los más bajos, ya que sólo se paga por el número de tokens utilizados en las preguntas y respuestas.

        • Puesta a punto: los costes de la puesta a punto son más elevados. No sólo hay que pagar para ajustar el modelo, sino que, en el caso de OpenAI, hay que pagar unas 4 veces más por los tokens utilizados en las preguntas y respuestas de los modelos ajustados.

        • RAG: el coste en este caso también es mayor que el de una simple llamada a la API y también podría ser mayor que el del ajuste fino. Dependerá de la cantidad de información que contenga su base de conocimientos. Tendrás que pagar por incrustar la información y también por el número de tokens con los que alimentas al LLM cuando busca una respuesta a la pregunta.

      Dificultad de desarrollo: 

        • Llamada a la API: muy fácil de implementar. Nivel principiante.

        • Puesta a punto: fácil de implementar pero puede requerir mucho trabajo para crear el conjunto de datos.

        • RAG: dificultad media, necesitará cierta experiencia con Python o el framework LangChain.

      Interacción con el usuario

        • Llamada a la API: interactuará igual que ChatGPT (o cualquier otro modelo) cuando se le pida que responda de una manera específica. Ofrecerá principalmente información general.

        • Fine-tune: interacción más personalizada. Además de las preguntas clásicas, puede gestionar mejor los casos extremos. Se puede ajustar para que sea más seguro y más difícil de piratear o alucinar. También puede responder a preguntas de negocio específicas si están presentes en el conjunto de datos, pero sobre todo ofrecerá información general. Esto dependerá de lo grande y complejo que sea el conjunto de datos con el que lo afines.

        • RAG: mejor para situaciones en las que se desean respuestas precisas con información procedente de una base de conocimientos personalizada. Ofrecerá la mejor interacción con el usuario si éste desea obtener información detallada sobre su empresa y no sólo información general.

      Así que, esto es todo. Estas son las 3 técnicas que yo usaría para el desarrollo de Chatbot AI, si quisiera ensuciarme las manos y escribir algo de código. Hay alternativas sin código (o de bajo código) que presentaré en un futuro artículo (próximamente). Si quieres algo de inspiración en cuanto a casos de uso para chatbots, entonces echa un vistazo a este artículo que ya está publicado.

      ¡Que tengas un buen día!

      Deja una respuesta

      Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *