{"id":570447,"date":"2025-05-26T23:40:39","date_gmt":"2025-05-26T22:40:39","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=pycharm&#038;p=570447"},"modified":"2025-05-27T00:10:22","modified_gmt":"2025-05-26T23:10:22","slug":"como-crear-chatbots-con-langchain","status":"publish","type":"pycharm","link":"https:\/\/blog.jetbrains.com\/es\/pycharm\/2025\/05\/como-crear-chatbots-con-langchain\/","title":{"rendered":"C\u00f3mo crear chatbots con LangChain"},"content":{"rendered":"<p><em>Este es un art\u00edculo de nuestro invitado <a href=\"https:\/\/blog.jetbrains.com\/pycharm\/2024\/08\/how-to-build-chatbots-with-langchain\/#author\" data-type=\"link\" data-id=\"https:\/\/blog.jetbrains.com\/pycharm\/2024\/08\/how-to-build-chatbots-with-langchain\/#author\">Dido Grigorov<\/a>, ingeniero de aprendizaje profundo y programador de Python con 17 a\u00f1os de experiencia en el campo.<\/em><\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-570455\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/05\/PC-social-BlogFeatured-1280x720-2x-4.png\" alt=\"\" width=\"2560\" height=\"1440\" \/><\/figure>\n<p>Los chatbots han evolucionado y son mucho m\u00e1s que simples herramientas de preguntas y respuestas. Con la potencia de los modelos de lenguaje de gran tama\u00f1o (LLM), pueden comprender el contexto de las conversaciones y generar respuestas similares a las humanas, lo que los convierte en una herramienta inestimable para las aplicaciones de atenci\u00f3n al cliente y otros tipos de asistencia virtual.\u00a0<\/p>\n<p>LangChain, un marco de trabajo de c\u00f3digo abierto, agiliza el proceso de creaci\u00f3n de estos chatbots conversacionales proporcionando herramientas para la integraci\u00f3n perfecta de modelos, la gesti\u00f3n de contextos y la ingenier\u00eda de peticiones.<\/p>\n<p>En este art\u00edculo del blog, exploraremos c\u00f3mo funciona LangChain y c\u00f3mo interact\u00faan los chatbots con los LLM. Tambi\u00e9n le guiaremos paso a paso en la creaci\u00f3n de un chatbot que tiene en cuenta el contexto y que ofrezca respuestas precisas y relevantes utilizando LangChain y GPT-3.<\/p>\n<p><!--more--><\/p>\n<h2 class=\"wp-block-heading\"><strong>\u00bfQu\u00e9 son los chatbots en el \u00e1mbito de los <\/strong>LLM<strong>?<\/strong><\/h2>\n<p>Los chatbots en el \u00e1mbito de los LLM son programas inform\u00e1ticos de \u00faltima generaci\u00f3n que simulan conversaciones de tipo humano con los usuarios a trav\u00e9s de interfaces de texto o voz. Esos chatbots explotan las capacidades avanzadas de los LLM, que son redes neuronales entrenadas con enormes cantidades de datos de texto que les permiten producir respuestas similares a las humanas a una amplia variedad de peticiones.<\/p>\n<p>Entre otras cosas, los chatbots basados en LLM pueden tener en cuenta el contexto de una conversaci\u00f3n a la hora de generar una respuesta. Esto significa que pueden mantener la coherencia entre varios intercambios y pueden procesar consultas complejas para producir resultados que respondan a las intenciones de los usuarios. Adem\u00e1s, estos chatbots eval\u00faan el tono emocional de las peticiones del usuario y ajustan sus respuestas para que coincidan con sus sentimientos.<\/p>\n<p>Los chatbots son muy adaptables y personalizables. Aprenden de la forma en que los usuarios interact\u00faan con ellos, mejorando as\u00ed sus respuestas para ajustarlas a las preferencias y necesidades individuales.\u00a0<\/p>\n<h2 class=\"wp-block-heading\"><strong>\u00bfQu\u00e9 es LangChain?<\/strong><\/h2>\n<p>LangChain es un marco de trabajo de c\u00f3digo abierto desarrollado para crear aplicaciones que utilicen modelos de lenguaje de gran tama\u00f1o (LLM). Incorpora herramientas y abstracciones para personalizar mejor la informaci\u00f3n producida a partir de estos modelos, manteniendo al mismo tiempo la precisi\u00f3n y la pertinencia.\u00a0<\/p>\n<p>Un t\u00e9rmino com\u00fan que puede ver si lee sobre los LLM es \u00abcadenas de peticiones\u00bb. Una cadena de peticiones es una secuencia de peticiones o instrucciones utilizadas en el contexto de la inteligencia artificial y el aprendizaje autom\u00e1tico, con el fin de orientar al modelo de IA a trav\u00e9s de un proceso de varios pasos para generar resultados m\u00e1s precisos, detallados o pulidos. Este m\u00e9todo puede emplearse para diversas tareas, como la escritura, la resoluci\u00f3n de problemas o la generaci\u00f3n de c\u00f3digo.\u00a0<\/p>\n<p>Los desarrolladores pueden crear nuevas cadenas de peticiones utilizando LangChain, que es uno de los puntos fuertes del marco de trabajo. Incluso pueden modificar las plantillas de peticiones existentes sin necesidad de volver a entrenar el modelo al utilizar nuevos conjuntos de datos.<\/p>\n<h2 class=\"wp-block-heading\"><strong>\u00bfC\u00f3mo funciona LangChain?<\/strong><\/h2>\n<p>LangChain es un marco de trabajo dise\u00f1ado para simplificar el desarrollo de aplicaciones que utilizan modelos ling\u00fc\u00edsticos. Ofrece un conjunto de herramientas que ayudan a los desarrolladores a crear y gestionar eficazmente aplicaciones que implican el procesamiento del lenguaje natural (PLN) y modelos ling\u00fc\u00edsticos de gran tama\u00f1o. Al definir los pasos necesarios para lograr el resultado deseado (puede tratarse de un chatbot, automatizaci\u00f3n de tareas, asistente virtual, atenci\u00f3n al cliente, etc.), los desarrolladores pueden adaptar los modelos ling\u00fc\u00edsticos de forma flexible a contextos empresariales espec\u00edficos utilizando LangChain.\u00a0<\/p>\n<p>A continuaci\u00f3n tiene una visi\u00f3n general de c\u00f3mo funciona LangChain.<\/p>\n<h3 class=\"wp-block-heading\"><strong>Integraci\u00f3n de modelos<\/strong><\/h3>\n<p>LangChain es compatible con varios modelos ling\u00fc\u00edsticos, incluidos los de<em> OpenAI, Hugging Face, Cohere, Anyscale, Azure Models, Databricks, Ollama, Llama, GPT4All, Spacy, Pinecone, AWS Bedrock y MistralAI<\/em>, entre otros. Los desarrolladores pueden cambiar f\u00e1cilmente entre distintos modelos o utilizar varios en una misma aplicaci\u00f3n. Pueden crear soluciones de integraci\u00f3n de modelos desarrolladas a medida, que permiten a los desarrolladores aprovechar capacidades espec\u00edficas adaptadas a sus aplicaciones concretas.<\/p>\n<h3 class=\"wp-block-heading\"><strong>Cadenas<\/strong><\/h3>\n<p>El concepto central de LangChain son las <strong>cadenas<\/strong>, que re\u00fanen diferentes componentes de IA para dar respuestas que tienen en cuenta el contexto. Una cadena representa un conjunto de acciones automatizadas entre una petici\u00f3n del usuario y la respuesta final del modelo. LangChain proporciona dos tipos de cadenas:<\/p>\n<ul>\n<li><strong>Cadenas secuenciales:<\/strong> estas cadenas permiten utilizar el resultado de un modelo o funci\u00f3n como entrada para otro. Esto es especialmente \u00fatil para realizar procesos de varios pasos que dependen unos de otros.<\/li>\n<li><strong>Cadenas paralelas:<\/strong> permiten la ejecuci\u00f3n simult\u00e1nea de varias tareas, y sus resultados se fusionan al final. Por ello resultan perfectas para realizar tareas que pueden dividirse en subtareas que son completamente independientes.<\/li>\n<\/ul>\n<h3 class=\"wp-block-heading\"><strong>Memoria<\/strong><\/h3>\n<p>LangChain facilita el almacenamiento y la recuperaci\u00f3n de informaci\u00f3n a trav\u00e9s de diversas interacciones, lo cual resulta esencial cuando se necesita la persistencia del contexto, como ocurre con los chatbots o los agentes interactivos. Tambi\u00e9n se ofrecen dos tipos de memoria:<\/p>\n<ul>\n<li><strong>Memoria a corto plazo<\/strong>: ayuda a mantener un registro de las sesiones recientes.<\/li>\n<li><strong>Memoria a largo plazo<strong>: permite retener informaci\u00f3n de sesiones previas, lo que mejora la capacidad del sistema para recuperar chats anteriores y las preferencias del usuario.<\/strong><\/strong><\/li>\n<\/ul>\n<h3 class=\"wp-block-heading\"><strong>Herramientas y utilidades<\/strong><\/h3>\n<p>LangChain proporciona muchas herramientas, pero las m\u00e1s utilizadas son Prompt Engineering, Data Loaders y Evaluators.\u00a0 En cuanto a Prompt Engineering (ingenier\u00eda de peticiones), LangChain contiene utilidades para desarrollar peticiones correctas, que son muy importantes para obtener las mejores respuestas de los modelos ling\u00fc\u00edsticos.<\/p>\n<p>Si desea cargar archivos como csv, pdf u otros formatos, los <strong>Data Loaders<\/strong> (cargadores de datos) le ayudar\u00e1n a cargar y preprocesar distintos tipos de datos y hacerlos as\u00ed utilizables en las interacciones con los modelos.<\/p>\n<p>La evaluaci\u00f3n es una parte esencial del trabajo con modelos de aprendizaje autom\u00e1tico y modelos de lenguaje de gran tama\u00f1o. Por eso LangChain proporciona <strong>Evaluators<\/strong> (evaluadores): unas herramientas que se utilizan para probar los modelos ling\u00fc\u00edsticos y las cadenas de modo que los resultados generados cumplan los criterios requeridos, que pueden incluir:<\/p>\n<p><strong>Criterios de los conjuntos de datos:<\/strong><\/p>\n<ul>\n<li><strong>Ejemplos elegidos manualmente:<\/strong> Comience con aportaciones diversas y de alta calidad.<\/li>\n<li><strong>Registros hist\u00f3ricos:<\/strong> Utilice datos y comentarios reales de los usuarios.<\/li>\n<li><strong>Datos sint\u00e9ticos: <\/strong>Genere ejemplos a partir de datos iniciales.<\/li>\n<\/ul>\n<p><strong>Tipos de evaluaciones:<\/strong><\/p>\n<ul>\n<li><strong>Humanas:<\/strong> Retroalimentaci\u00f3n y puntuaci\u00f3n manual.<\/li>\n<li><strong>Heur\u00edstica:<\/strong> Funciones basadas en reglas, tanto sin referencias como basadas en referencias.<\/li>\n<li><strong>LLM como juez: <\/strong>Los LLM punt\u00faan los resultados seg\u00fan criterios codificados.<\/li>\n<li><strong>Por pares: <\/strong>Compare dos resultados para elegir el mejor.<\/li>\n<\/ul>\n<p><strong>Evaluaciones de la aplicaci\u00f3n:<\/strong><\/p>\n<ul>\n<li><strong>Pruebas de unidad:<\/strong> Comprobaciones r\u00e1pidas y heur\u00edsticas.<\/li>\n<li><strong>Pruebas de regresi\u00f3n: <\/strong>Mida los cambios de rendimiento a lo largo del tiempo.<\/li>\n<li><strong>Pruebas retrospectivas: <\/strong>Vuelva a ejecutar los datos de producci\u00f3n en las nuevas versiones.<\/li>\n<li><strong>Evaluaci\u00f3n en l\u00ednea: <\/strong>Evaluaciones en tiempo real, a menudo con fines de protecci\u00f3n y clasificaci\u00f3n.<\/li>\n<\/ul>\n<p><strong>Agentes<\/strong><strong><br \/><\/strong>Los agentes de LangChain son esencialmente entidades aut\u00f3nomas que aprovechan los LLM para interactuar con los usuarios, realizar tareas y tomar decisiones basadas en peticiones en lenguaje natural.<\/p>\n<p><strong>Los agentes orientados a la acci\u00f3n<\/strong> utilizan modelos ling\u00fc\u00edsticos para decidir las acciones \u00f3ptimas para tareas predefinidas. Por otro lado, los <strong>agentes interactivos<\/strong> o las aplicaciones interactivas como los chatbots hacen uso de estos agentes, que tambi\u00e9n tienen en cuenta lo que introduce el usuario y la memoria almacenada a la hora de responder las consultas.<\/p>\n<h2 class=\"wp-block-heading\"><strong>\u00bfC\u00f3mo funcionan los chatbots con los LLM?<\/strong><\/h2>\n<p>Los LLM subyacentes a los chatbots utilizan la comprensi\u00f3n del lenguaje natural (NLU) y la generaci\u00f3n del lenguaje natural (NLG), que son posibles gracias al entrenamiento previo de los modelos con un inmenso volumen de datos de texto.<\/p>\n<h3 class=\"wp-block-heading\"><strong>Comprensi\u00f3n del lenguaje natural (NLU)<\/strong><\/h3>\n<ul>\n<li><strong>Conocimiento del contexto:<\/strong> Los LLM pueden comprender las sutilezas y las alusiones en una conversaci\u00f3n, y pueden seguir el hilo de la conversaci\u00f3n de un turno al siguiente. Esto hace posible que los chatbots generen respuestas l\u00f3gicas y adecuadas contextualmente para los clientes.<\/li>\n<li><strong>Reconocimiento de la intenci\u00f3n: <\/strong>Estos modelos deben ser capaces de comprender la intenci\u00f3n del usuario a partir de sus consultas, tanto si el lenguaje es muy espec\u00edfico como si es bastante general. Pueden discernir lo que el usuario quiere conseguir y determinar la mejor manera de ayudarle a alcanzar ese objetivo.<\/li>\n<li><strong>An\u00e1lisis de sentimientos: <\/strong>Los chatbots pueden determinar la emoci\u00f3n del usuario a trav\u00e9s del tono del lenguaje utilizado y adaptarse a su estado emocional, lo que aumenta la implicaci\u00f3n del usuario.<\/li>\n<\/ul>\n<h3 class=\"wp-block-heading\"><strong>Generaci\u00f3n de lenguaje natural (NLG)<\/strong><\/h3>\n<ul>\n<li><strong>Generaci\u00f3n de respuestas: <\/strong>Cuando se formulan preguntas a los LLM, las respuestas que proporcionan son correctas tanto desde el punto de vista gramatical como del contexto. Esto se debe a que las respuestas que producen estos modelos imitan la comunicaci\u00f3n humana, debido al entrenamiento de los modelos con enormes cantidades de datos de texto en lenguaje natural.<\/li>\n<li><strong>Creatividad y flexibilidad:<\/strong> Aparte de dar respuestas sencillas, los chatbots basados en LLM pueden contar una historia, crear un poema o proporcionar una descripci\u00f3n detallada de un problema t\u00e9cnico espec\u00edfico y, por lo tanto, puede considerarse que son muy flexibles en cuanto al material proporcionado.<\/li>\n<\/ul>\n<h3 class=\"wp-block-heading\"><strong>Personalizaci\u00f3n y adaptabilidad<\/strong><\/h3>\n<ul>\n<li><strong>Aprender de las interacciones: <\/strong>Los chatbots personalizan la interacci\u00f3n porque tienen la capacidad de aprender del comportamiento de los usuarios, as\u00ed como de sus elecciones. Se puede decir que aprende constantemente, lo que hace que el chatbot sea m\u00e1s eficaz y preciso a la hora de responder a las preguntas.<\/li>\n<li><strong>Adaptaci\u00f3n a distintos dominios: <\/strong>Los LLM pueden ajustarse a \u00e1reas o especialidades concretas que permitan a los chatbots actuar como expertos en la materia en las relaciones con los clientes, el soporte t\u00e9cnico o el \u00e1mbito sanitario.<\/li>\n<\/ul>\n<p>Los LLM son capaces de comprender y generar texto en varios idiomas, lo que los hace adecuados para aplicaciones en contextos ling\u00fc\u00edsticos diversos.<\/p>\n<h2 class=\"wp-block-heading\"><strong>Cree su propio chatbot con LangChain en cinco pasos<\/strong><\/h2>\n<p>El objetivo de este proyecto es crear un chatbot que aproveche GPT-3 para buscar respuestas dentro de documentos. En primer lugar, vamos a extraer contenidos de art\u00edculos en l\u00ednea, dividirlos en trozos peque\u00f1os, calcular sus integraciones y almacenarlos en Deep Lake. A continuaci\u00f3n, utilizamos una consulta del usuario para recuperar los fragmentos m\u00e1s relevantes de Deep Lake, que se incorporan a una petici\u00f3n para generar la respuesta final con el LLM.<\/p>\n<p>Es importante tener en cuenta que utilizar los LLM conlleva el riesgo de generar incorrecciones o informaci\u00f3n falsa. Aunque esto puede ser inaceptable para muchos escenarios de atenci\u00f3n al cliente, el chatbot puede seguir siendo valioso para ayudar a los operadores a redactar respuestas que puedan verificar antes de enviarlas a los usuarios.<\/p>\n<p>A continuaci\u00f3n, exploraremos c\u00f3mo gestionar las conversaciones con GPT-3 y ofreceremos ejemplos para demostrar la eficacia de este flujo de trabajo.<\/p>\n<h3 class=\"wp-block-heading\"><strong>Paso 1: Creaci\u00f3n del proyecto, requisitos previos e instalaci\u00f3n de las bibliotecas necesarias<\/strong><\/h3>\n<p>Primero cree su proyecto PyCharm para el chatbot. Abra <a href=\"https:\/\/www.jetbrains.com\/pycharm\/\" target=\"_blank\" rel=\"noopener\" data-type=\"link\" data-id=\"https:\/\/www.jetbrains.com\/pycharm\/\">Pycharm<\/a> y haga clic en \u00abNew Project\u00bb. A continuaci\u00f3n, indique el nombre de su proyecto.<\/p>\n<figure class=\"wp-block-image size-full is-style-default\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-504042\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/08\/unnamed-1.png\" alt=\"Cree un proyecto de PyCharm\" width=\"780\" height=\"638\" \/><\/figure>\n<p>Una vez listo con el proyecto configurado, genere su \u00ab<code>OPENAI_API_KEY<\/code>\u00bb en el <a href=\"https:\/\/platform.openai.com\/docs\/overview\" target=\"_blank\" rel=\"noopener\">sitio web de la plataforma de API de OpenAI<\/a>, una vez que haya iniciado sesi\u00f3n (o se haya registrado en el sitio web de OpenAI para ello). Para ello, vaya a la secci\u00f3n \u00abAPI Keys\u00bb del men\u00fa de navegaci\u00f3n de la izquierda y, a continuaci\u00f3n, haga clic en el bot\u00f3n \u00ab+Create new secret key\u00bb. No olvide copiar su clave.<\/p>\n<p>Despu\u00e9s, obtenga su \u00ab<code>ACTIVELOOP_TOKEN<\/code>\u00bb registr\u00e1ndose en la <a href=\"https:\/\/www.activeloop.ai\/\" target=\"_blank\" rel=\"noopener\">web de Activeloop<\/a>. Una vez iniciada la sesi\u00f3n, pulse el bot\u00f3n \u00abCreate API Token\u00bb y acceder\u00e1 a la p\u00e1gina de creaci\u00f3n del token. Copie tambi\u00e9n este token.<\/p>\n<p>Una vez que tenga tanto el token como la clave, abra sus ajustes de configuraci\u00f3n en PyCharm, haciendo clic en el bot\u00f3n de los 3 puntos situado junto a los botones de ejecuci\u00f3n y depuraci\u00f3n, y seleccione \u00abEdit\u00bb. Deber\u00eda ver la siguiente ventana:<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-504079\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/08\/unnamed-3.png\" alt=\"Ejecutar\/depurar configuraciones en PyCharm\" width=\"1382\" height=\"989\" \/><\/figure>\n<p>Ahora localice el campo \u00abEnvironment variables\u00bb y busque el icono a la derecha del campo. A continuaci\u00f3n, haga clic ah\u00ed; ver\u00e1 la siguiente ventana:<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-544577\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/02\/unnamed-1.png\" alt=\"Variables de entorno en PyCharm\" width=\"1382\" height=\"989\" \/><\/figure>\n<p>Y ahora, pulsando el bot\u00f3n +, comience a a\u00f1adir sus variables de entorno y tenga cuidado con sus nombres. Deben ser los mismos que los indicados anteriormente: \u00ab<code>OPENAI_API_KEY<\/code>\u00bb y \u00ab<code>ACTIVELOOP_TOKEN<\/code>\u00bb. Cuando est\u00e9 listo, haga clic en \u00abOK\u00bb en la primera ventana y, luego, en \u00abApply\u00bb y \u00abOK\u00bb en la segunda.<\/p>\n<p>Esa es una gran ventaja de PyCharm y me encanta, porque maneja las variables de entorno por nosotros de forma autom\u00e1tica sin necesidad de realizar llamadas adicionales a ellas, lo que nos permite pensar m\u00e1s en la parte creativa del c\u00f3digo.<\/p>\n<p><em>Nota: <\/em><strong><em>Activeloop<\/em><\/strong><em> es una empresa tecnol\u00f3gica centrada en el desarrollo de infraestructuras de datos y herramientas para el aprendizaje autom\u00e1tico y la inteligencia artificial. El objetivo de la empresa es agilizar el proceso de gesti\u00f3n, almacenamiento y procesamiento de conjuntos de datos a gran escala, en particular para el aprendizaje profundo y otras aplicaciones de IA.<\/em><\/p>\n<p><strong><em>Deep Lake<\/em><\/strong><em> es un producto insignia de Activeloop. Proporciona capacidades eficaces de almacenamiento, gesti\u00f3n y acceso a los datos, optimizadas para los conjuntos de datos a gran escala que suelen utilizarse en la IA.<\/em><\/p>\n<h4 class=\"wp-block-heading\"><strong>Instale las bibliotecas necesarias<\/strong><\/h4>\n<p>Utilizaremos la clase \u00ab<code>SeleniumURLLoader<\/code>\u00bb de LangChain, que depende de las bibliotecas \u00ab<code>unstructured<\/code>\u00bb y \u00ab<code>selenium<\/code>\u00bb de Python. Inst\u00e1lelos utilizando pip.\u00a0 Se recomienda instalar la versi\u00f3n m\u00e1s reciente, aunque el c\u00f3digo se ha probado espec\u00edficamente con la versi\u00f3n 0.7.7.\u00a0<\/p>\n<p>Para ello utilice el siguiente comando en su terminal de PyCharm:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">pip install unstructured selenium<\/pre>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-544604\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/02\/Install-Selenium-1.png\" alt=\"\" width=\"1385\" height=\"991\" \/><\/figure>\n<p>Ahora necesitamos instalar <code>langchain<\/code>, <code>deeplake<\/code> y <code>openai<\/code>. Para ello solo tiene que utilizar este comando en su terminal (la misma ventana que utiliz\u00f3 para Selenium) y esperar un poco hasta que todo se haya instalado correctamente:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">pip install langchain==0.0.208 deeplake openai==0.27.8 psutil tiktoken<\/pre>\n<p>Para asegurarnos de que todas las bibliotecas est\u00e1n correctamente instaladas, basta con a\u00f1adir las siguientes l\u00edneas necesarias para nuestra aplicaci\u00f3n de chatbot y pulsar el bot\u00f3n de ejecutar:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">from langchain.embeddings.openai import OpenAIEmbeddings\n\nfrom langchain.vectorstores import DeepLake\n\nfrom langchain.text_splitter import CharacterTextSplitter\n\nfrom langchain import OpenAI\n\nfrom langchain.document_loaders import SeleniumURLLoader\n\nfrom langchain import PromptTemplate<\/pre>\n<p>Otra forma de instalar sus bibliotecas es a trav\u00e9s de la configuraci\u00f3n de PyCharm. \u00c1bralas y vaya a la secci\u00f3n Project -&gt; Python Interpreter. A continuaci\u00f3n, localice el bot\u00f3n +, busque su paquete y pulse el bot\u00f3n \u00abInstall Package\u00bb. Una vez listo, ci\u00e9rrelo y, en la siguiente ventana, haga clic en \u00abApply\u00bb y despu\u00e9s en \u00abOK\u00bb.<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-503888\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/08\/image-38.png\" alt=\"Int\u00e9rprete de Python en PyCharm\" width=\"1012\" height=\"759\" \/><\/figure>\n<h3 class=\"wp-block-heading\"><strong>Paso 2: Dividir el contenido en trozos y calcular sus integraciones<\/strong><\/h3>\n<p>Como ya hemos mencionado, nuestro chatbot se \u00abcomunicar\u00e1\u00bb con contenidos procedentes de art\u00edculos en l\u00ednea, por eso eleg\u00ed Digitaltrends.com como fuente de datos y seleccion\u00e9 8 art\u00edculos para empezar. Todos ellos se organizan en una lista de Python y se asignan a una variable llamada \u00abarticles\u00bb.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">articles = ['https:\/\/www.digitaltrends.com\/computing\/claude-sonnet-vs-gpt-4o-comparison\/',\n           'https:\/\/www.digitaltrends.com\/computing\/apple-intelligence-proves-that-macbooks-need-something-more\/',\n           'https:\/\/www.digitaltrends.com\/computing\/how-to-use-openai-chatgpt-text-generation-chatbot\/',\n           'https:\/\/www.digitaltrends.com\/computing\/character-ai-how-to-use\/',\n           'https:\/\/www.digitaltrends.com\/computing\/how-to-upload-pdf-to-chatgpt\/']<\/pre>\n<p>Cargamos los documentos desde las URL proporcionadas y los dividimos en trozos utilizando el \u00ab<code>CharacterTextSplitter<\/code>\u00bb con un tama\u00f1o de trozo de 1000 y sin solapamiento:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Use the selenium to load the documents\nloader = SeleniumURLLoader(urls=articles)\ndocs_not_splitted = loader.load()\n\n# Split the documents into smaller chunks\ntext_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)\ndocs = text_splitter.split_documents(docs_not_splitted)<\/pre>\n<p>Si ejecuta el c\u00f3digo hasta ahora deber\u00eda recibir el siguiente resultado, si todo funciona bien:<\/p>\n<p><em><code>[Document(page_content=\"techcrunchnntechcrunchnnWe, TechCrunch, are part of the Yahoo family of brandsThe sites and apps that we own and operate, including Yahoo and AOL, and our digital advertising service, Yahoo Advertising.Yahoo family of brands.nn\u00a0 \u00a0 When you use our sites and apps, we use nnCookiesCookies (including similar technologies such as web storage) allow the operators of websites and apps to store and read information from your device. Learn more in our cookie policy.cookies to:nnprovide our sites and apps to younnauthenticate users, apply security measures, and prevent spam and abuse, andnnmeasure your use of our sites and appsnn\u00a0 \u00a0 If you click '\", metadata={'source':\u00a0\u2026\u2026\u2026\u2026\u2026]<\/code><\/em><\/p>\n<p>A continuaci\u00f3n, generamos las integraciones utilizando OpenAIEmbeddings y las guardamos en un almac\u00e9n vectorial de Deep Lake alojado en la nube. Lo ideal ser\u00eda que, en un entorno de producci\u00f3n, pudi\u00e9ramos cargar todo un sitio web o una lecci\u00f3n de un curso en un conjunto de datos de Deep Lake, lo que permitir\u00eda realizar b\u00fasquedas en miles o incluso en millones de documentos.\u00a0<\/p>\n<p>Al aprovechar un conjunto de datos de Deep Lake sin servidor en la nube, las aplicaciones de varias ubicaciones pueden acceder sin problemas a un conjunto de datos centralizado sin necesidad de configurar un almac\u00e9n vectorial en una m\u00e1quina dedicada.<\/p>\n<h4 class=\"wp-block-heading\"><strong>\u00bfPor qu\u00e9 necesitamos integraciones y documentos en trozos?<\/strong><\/h4>\n<p>Cuando se construyen chatbots con LangChain, los documentos integrados y fragmentados son esenciales por varias razones relacionadas con la eficacia, la precisi\u00f3n y el rendimiento del chatbot.<\/p>\n<p>Las <strong>integraciones<\/strong> son representaciones vectoriales del texto (palabras, frases, p\u00e1rrafos o documentos) que reflejan su sem\u00e1ntica. Encapsulan el contexto y el significado de las palabras de forma num\u00e9rica. Esto permite que el chatbot comprenda y genere respuestas adecuadas al contexto mediante la captura de matices, sin\u00f3nimos y relaciones entre palabras.<\/p>\n<p>Gracias a las integraciones, el chatbot tambi\u00e9n puede identificar y recuperar r\u00e1pidamente las respuestas o la informaci\u00f3n m\u00e1s relevantes de una base de conocimientos, ya que permiten emparejar las consultas de los usuarios con los trozos de informaci\u00f3n m\u00e1s relevantes desde el punto de vista sem\u00e1ntico, aunque la redacci\u00f3n de la consulta sea diferente.<\/p>\n<p>La <strong>divisi\u00f3n en trozos<\/strong>, por su parte<strong>,<\/strong> consiste en dividir los documentos de gran tama\u00f1o en piezas o trozos m\u00e1s peque\u00f1os y manejables. Los trozos m\u00e1s peque\u00f1os son m\u00e1s r\u00e1pidos de procesar y analizar en comparaci\u00f3n con los documentos grandes y monol\u00edticos. Esto se traduce en tiempos de respuesta m\u00e1s r\u00e1pidos por parte del chatbot.<\/p>\n<p>La fragmentaci\u00f3n de documentos contribuye tambi\u00e9n a la pertinencia del resultado, ya que cuando un usuario formula una pregunta, a menudo solo se encuentra en una parte espec\u00edfica de un documento. La divisi\u00f3n en trozos permite al sistema localizar y recuperar solo las secciones relevantes, y el chatbot puede proporcionar respuestas m\u00e1s precisas y exactas.<\/p>\n<p>Ahora volvamos a nuestra aplicaci\u00f3n y actualicemos el siguiente c\u00f3digo incluyendo el ID de su organizaci\u00f3n Activeloop. Tenga en cuenta que, de forma predeterminada, el ID de su organizaci\u00f3n es el mismo que su nombre de usuario.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># TODO: use your organization id here. (by default, org id is your username)\nmy_activeloop_org_id = \"didogrigorov\"\nmy_activeloop_dataset_name = \"jetbrains_article_dataset\"\ndataset_path = f\"hub:\/\/{my_activeloop_org_id}\/{my_activeloop_dataset_name}\"\ndb = DeepLake(dataset_path=dataset_path, embedding_function=embeddings)\n\n\n# add documents to our Deep Lake dataset\ndb.add_documents(docs)<\/pre>\n<p>Otra gran caracter\u00edstica de PyCharm que me encanta es la posibilidad de a\u00f1adir notas TODO directamente en los comentarios de Python. Una vez que escriba TODO con may\u00fasculas, las notas ir\u00e1n a una secci\u00f3n de PyCharm donde podr\u00e1 verlas todas:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># TODO: use your organization id here. (by default, org id is your username)<\/pre>\n<p>Puede hacer clic en ellas y PyCharm le mostrar\u00e1 directamente d\u00f3nde se encuentran en su c\u00f3digo. Me resulta muy c\u00f3modo para los desarrolladores y lo utilizo todo el tiempo:<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-503899\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/08\/image-39.png\" alt=\"Notas TODO en los comentarios de Python en PyCharm\" width=\"1445\" height=\"993\" \/><\/figure>\n<p>Si ejecuta el c\u00f3digo hasta ahora deber\u00eda ver el siguiente resultado, si todo funciona con normalidad:<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-504068\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/08\/unnamed-2.png\" alt=\"Ejecuci\u00f3n de c\u00f3digo del chatbot en PyCharm\" width=\"1377\" height=\"989\" \/><\/figure>\n<p>Para encontrar los trozos m\u00e1s similares a una consulta determinada, podemos utilizar el m\u00e9todo similarity_search proporcionado por el almac\u00e9n de vectores de Deep Lake:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Check the top relevant documents to a specific query\nquery = \"how to check disk usage in linux?\"\ndocs = db.similarity_search(query)\nprint(docs[0].page_content)<\/pre>\n<h3 class=\"wp-block-heading\"><strong>Paso 3: Redactemos la petici\u00f3n para GPT-3<\/strong><\/h3>\n<p>Dise\u00f1aremos una plantilla de peticiones que integre las peticiones de funci\u00f3n, los datos pertinentes de la base de conocimientos y la consulta del usuario. Esta plantilla establece la personalidad del chatbot como un excelente agente de atenci\u00f3n al cliente. Acepta dos variables de entrada: chunks_formatted, que contiene los extractos preformateados de los art\u00edculos, y query, que representa la pregunta del cliente. El objetivo es producir una respuesta precisa basada \u00fanicamente en los trozos indicados, y evitar cualquier informaci\u00f3n inventada o incorrecta.<\/p>\n<h3 class=\"wp-block-heading\"><strong>Paso 4: Crear la funcionalidad del chatbot<\/strong><\/h3>\n<p>Para generar una respuesta, comenzamos recuperando los \u00abk\u00bb trozos (por ejemplo, los 3 trozos) m\u00e1s similares a la consulta del usuario. A continuaci\u00f3n, estos trozos se formatean en una petici\u00f3n, que se env\u00eda al modelo GPT-3 con un ajuste de temperatura de 0.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># user question\nquery = \"How to check disk usage in linux?\"\n\n# retrieve relevant chunks\ndocs = db.similarity_search(query)\nretrieved_chunks = [doc.page_content for doc in docs]\n\n# format the prompt\nchunks_formatted = \"nn\".join(retrieved_chunks)\nprompt_formatted = prompt.format(chunks_formatted=chunks_formatted, query=query)\n\n# generate answer\nllm = OpenAI(model=\"gpt-3.5-turbo-instruct\", temperature=0)\nanswer = llm(prompt_formatted)\nprint(answer)<\/pre>\n<p>Si todo funciona bien, su resultado deber\u00eda ser el siguiente:<\/p>\n<p><em><code>Para cargar un PDF en ChatGPT, acceda primero al sitio web y haga clic en el icono del clip situado junto al campo de introducci\u00f3n de texto. A continuaci\u00f3n, seleccione el PDF de su disco duro local, Google Drive o Microsoft OneDrive. Once attached, type your query or question into the prompt field and click the upload button. Give the system time to analyze the PDF and provide you with a response.<\/code><\/em><\/p>\n<h3 class=\"wp-block-heading\"><strong>Paso 5: Crear un historial de conversaciones<\/strong><\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Create conversational memory\nmemory = ConversationBufferMemory(memory_key=\"chat_history\", input_key=\"input\")\n\n# Define a prompt template that includes memory\ntemplate = \"\"\"You are an exceptional customer support chatbot that gently answers questions.\n\n{chat_history}\n\nYou know the following context information.\n\n{chunks_formatted}\n\nAnswer the following question from a customer. Use only information from the previous context information. Do not invent stuff.\n\nQuestion: {input}\n\nAnswer:\"\"\"\n\nprompt = PromptTemplate(\n    input_variables=[\"chat_history\", \"chunks_formatted\", \"input\"],\n    template=template,\n)\n\n# Initialize the OpenAI model\nllm = OpenAI(openai_api_key=\"YOUR API KEY\", model=\"gpt-3.5-turbo-instruct\", temperature=0)\n\n# Create the LLMChain with memory\nchain = LLMChain(\n    llm=llm,\n    prompt=prompt,\n    memory=memory\n)\n\n# User query\nquery = \"What was the 5th point about on the question how to remove spotify account?\"\n\n# Retrieve relevant chunks\ndocs = db.similarity_search(query)\nretrieved_chunks = [doc.page_content for doc in docs]\n\n# Format the chunks for the prompt\nchunks_formatted = \"nn\".join(retrieved_chunks)\n\n# Prepare the input for the chain\ninput_data = {\n    \"input\": query,\n    \"chunks_formatted\": chunks_formatted,\n    \"chat_history\": memory.buffer\n}\n\n# Simulate a conversation\nresponse = chain.predict(**input_data)\n\nprint(response)<\/pre>\n<p>Recorramos el c\u00f3digo de una manera m\u00e1s conversacional.<\/p>\n<p>Para empezar, creamos una memoria de las conversaciones utilizando \u00ab<code>ConversationBufferMemory<\/code>\u00bb. Esto permite a nuestro chatbot recordar el historial de chat en curso, utilizando \u00ab<code>input_key=\"input\"<\/code>\u00bb para gestionar las peticiones entrantes del usuario.<\/p>\n<p>A continuaci\u00f3n, dise\u00f1amos una plantilla de peticiones. Esta plantilla es como un gui\u00f3n para el chatbot, que incluye secciones para el historial de chat, los trozos de informaci\u00f3n que hemos recopilado y la pregunta actual del usuario (entrada). Esta estructura ayuda al chatbot a saber exactamente qu\u00e9 contexto tiene y qu\u00e9 pregunta debe responder.<\/p>\n<p>A continuaci\u00f3n, pasamos a inicializar la cadena de nuestro modelo ling\u00fc\u00edstico, o \u00ab<code>LLMChain<\/code>\u00bb. Piense en ello como si ensambl\u00e1ramos los componentes: tomamos nuestra plantilla de peticiones, el modelo ling\u00fc\u00edstico y la memoria que configuramos anteriormente, y los combinamos en un \u00fanico flujo de trabajo.<\/p>\n<p>Cuando llega el momento de gestionar una consulta de usuario, preparamos la entrada. Se trata de crear un diccionario que incluya la pregunta del usuario (\u00ab<code>input<\/code>\u00bb) y los trozos de informaci\u00f3n relevantes (\u00ab<code>chunks_formatted<\/code>\u00bb). Esta configuraci\u00f3n garantiza que el chatbot disponga de todos los detalles que necesita para elaborar una respuesta bien informada.<\/p>\n<p>Por \u00faltimo, generamos una respuesta. Llamamos al m\u00e9todo \u00ab<code>chain.predict<\/code>\u00bb, pas\u00e1ndole nuestros datos de entrada preparados. El m\u00e9todo procesa esta entrada a trav\u00e9s del flujo de trabajo que hemos creado, y de ah\u00ed sale la respuesta del chatbot, que luego mostramos.<\/p>\n<p>Este enfoque permite a nuestro chatbot mantener una conversaci\u00f3n fluida e informada, recordando interacciones anteriores y proporcionando respuestas relevantes basadas en el contexto.<\/p>\n<p>Otro de mis trucos favoritos de PyCharm, que me ayud\u00f3 mucho a construir esta funcionalidad, fue la posibilidad de situar el cursor sobre un m\u00e9todo, pulsar la tecla \u00abCTRL\u00bb y hacer clic sobre \u00e9l.<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-544616\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/02\/put-my-cursor-over-a-method.gif\" alt=\"Sit\u00fae el cursor sobre un m\u00e9todo\" width=\"1200\" height=\"805\" \/><\/figure>\n<h2 class=\"wp-block-heading\"><strong>En conclusi\u00f3n<\/strong><\/h2>\n<p>GPT-3 destaca en la creaci\u00f3n de chatbots conversacionales capaces de responder a preguntas espec\u00edficas bas\u00e1ndose en la informaci\u00f3n contextual proporcionada en la petici\u00f3n. Sin embargo, asegurarse de que el modelo genera respuestas bas\u00e1ndose \u00fanicamente en este contexto puede ser todo un reto, ya que a menudo tiende a generar alucinaciones (es decir, generar informaci\u00f3n nueva y potencialmente falsa). El impacto de esta informaci\u00f3n err\u00f3nea var\u00eda en funci\u00f3n del uso.<\/p>\n<p>En resumen, desarrollamos un sistema de respuesta a preguntas que tiene en cuenta el contexto utilizando LangChain, siguiendo el c\u00f3digo y las estrategias proporcionadas. El proceso inclu\u00eda dividir los documentos en trozos, calcular sus integraciones, implementar un recuperador para encontrar trozos similares, elaborar una petici\u00f3n para GPT-3 y utilizar el modelo GPT-3 para la generaci\u00f3n de texto. Este enfoque muestra el potencial de aprovechar GPT-3 para crear chatbots potentes y precisos contextualmente, al tiempo que subraya la importancia de estar alerta ante el riesgo de generar informaci\u00f3n falsa.<\/p>\n<h2 id=\"author\" class=\"wp-block-heading\"><strong>Sobre el autor<\/strong><\/h2>\n<div class=\"about-author \">\n<div class=\"about-author__box\">\n<div class=\"row\">\n<div class=\"about-author__box-img\"><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/08\/dido-grigorov.jpeg\" alt=\"Dido Grigorov\" \/><\/div>\n<div class=\"about-author__box-text\">\n<h4>Dido Grigorov<\/h4>\n<p><i><span style=\"font-weight: 400;\">Dido es un experimentado ingeniero de aprendizaje profundo y programador de Python con unos impresionantes 17 a\u00f1os de experiencia en este campo. Actualmente cursa estudios avanzados en la prestigiosa Universidad de Stanford, donde est\u00e1 inscrito en un programa de IA de vanguardia, dirigido por expertos de renombre como Andrew Ng, Christopher Manning, Fei-Fei Li y Chelsea Finn, lo que proporciona a Dido una perspectiva y una tutor\u00eda inigualables.<\/span><\/i><\/p>\n<p><i><span style=\"font-weight: 400;\">La pasi\u00f3n de Dido por la inteligencia artificial queda patente en su dedicaci\u00f3n tanto al trabajo como a la experimentaci\u00f3n. A lo largo de los a\u00f1os, ha desarrollado una vasta experiencia en el dise\u00f1o, la implementaci\u00f3n y la optimizaci\u00f3n de modelos de aprendizaje autom\u00e1tico. Su dominio de Python le ha permitido abordar problemas complejos y contribuir a soluciones innovadoras de IA en diversos \u00e1mbitos.<\/span><\/i><\/p>\n<p>A<em>rt\u00edculo original en ingl\u00e9s de:<\/em><\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n\n    <div class=\"about-author \">\n        <div class=\"about-author__box\">\n            <div class=\"row\">\n                <div class=\"about-author__box-img\">\n                    <img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/evgenia-200x200.jpg\" width=\"200\" height=\"200\" alt=\"Evgenia Verbina\" loading=\"lazy\"  class=\"avatar avatar-200 wp-user-avatar wp-user-avatar-200 photo avatar-default\">\n                <\/div>\n                <div class=\"about-author__box-text\">\n                                            <h4>Evgenia Verbina<\/h4>\n                                                        <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n","protected":false},"author":1086,"featured_media":570478,"comment_status":"closed","ping_status":"closed","template":"","categories":[952,1401],"tags":[6230,8556,8557],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/pycharm\/570447"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/pycharm"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/types\/pycharm"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/users\/1086"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/comments?post=570447"}],"version-history":[{"count":10,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/pycharm\/570447\/revisions"}],"predecessor-version":[{"id":570485,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/pycharm\/570447\/revisions\/570485"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/media\/570478"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/media?parent=570447"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/categories?post=570447"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/tags?post=570447"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/cross-post-tag?post=570447"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}