Ir al contenido principal

Construir chatbots con contexto: cómo aprovechar LangChain con ChatGPT

Descubre cómo crear chatbots con conciencia de contexto usando el framework LangChain y ChatGPT.
Actualizado 17 sept 2026  · 15 min leer

Explorar con IA

ChatGPTClaudePerplexity

En el vertiginoso panorama digital actual, con el auge de los Large Language Models (LLMs), las aplicaciones conversacionales han ganado una enorme popularidad. Los chatbots han transformado la forma en que interactuamos con aplicaciones, sitios web e incluso con los canales de atención al cliente en nuestro día a día.

La posibilidad de crear tu propio chatbot se ha convertido en un punto de inflexión, ya que permite a empresas y personas diseñar interfaces conversacionales personalizadas, eficientes y atractivas, adaptadas a sus necesidades concretas.

Este artículo pretende explicar cómo crear un chatbot en Python aprovechando la potencia de los LLMs. Veremos cómo construir nuestro propio chatbot con ChatGPT y cómo optimizarlo usando el popular framework LangChain.

Si eres nuevo en ChatGPT y LangChain, echa un vistazo a nuestro Introducción a los Large Language Models con GPT y LangChain: code-along a continuación: 

Este artículo cubre todos los aspectos clave para desarrollar un chatbot optimizado que utilice ChatGPT como modelo subyacente. Usaremos un Jupyter Notebook con las librerías openai y langchain instaladas. Puedes seguirlo en este cuaderno de DataLab.

En las siguientes secciones, veremos cómo usar la API de OpenAI para hacer llamadas básicas a ChatGPT como base de nuestra conversación. Además, implementaremos conciencia de contexto para nuestro chatbot con estructuras básicas de Python. Por último, optimizaremos tanto la implementación del chatbot como el historial de conversación con LangChain y exploraremos sus funciones de memoria.

Llamadas básicas a la API de ChatGPT

Vamos a usar ChatGPT como el modelo que da soporte a nuestro chatbot. Por eso, nuestra primera tarea práctica será escribir una llamada a la API de ChatGPT sencilla pero completa, para poder establecer una primera interacción.

La siguiente función de Python encapsula la llamada a la API que queremos hacer a ChatGPT usando solo la librería openai.

import os
import openai

openai_api_key = os.environ["OPENAI_API_KEY"]

def chatgpt_call(prompt, model="gpt-3.5-turbo"):
   response = openai.ChatCompletion.create(
       model=model,
       messages=[{"role": "user", "content": prompt}]
   )
   return response.choices[0].message["content"]

Fíjate en que en este caso usamos el modelo gpt-3.5-turbo porque es el GPT-3.5 más capaz y está optimizado para chat, además de ser de los más económicos. Puedes encontrar más información sobre los modelos disponibles en la documentación de OpenAI.

¿Necesitas ayuda para conseguir tus claves de la API de OpenAI? Entonces la formación Getting Started with the OpenAI API and ChatGPT es para ti.

¡Analicemos la implementación paso a paso!

La función chatgpt_call() actúa como un envoltorio de la llamada original de OpenAI ChatCompletion.create, que crea una solicitud de finalización de chat.

Dado el prompt deseado, la función devuelve la respuesta correspondiente de ChatGPT. Para una llamada correcta, solo hay que proporcionar el identificador del modelo a usar (model) y el prompt (prompt).

La finalización que devuelve ChatGPT contiene metadatos junto con la respuesta. Aun así, la respuesta como tal siempre viene en el campo response.choices[0].message[“content”]. Puedes ver más detalles sobre el contenido completo de la respuesta en la documentación de OpenAI.

Con esta implementación, podemos enviar un prompt a ChatGPT en una sola línea:

prompt = "My name is Andrea"
response = chatgpt_call(prompt)
print(response)

# Output: Nice to meet you, Andrea! How can I assist you today?

La llamada como interacción aislada

¿Ves algún inconveniente en la implementación anterior?

Para darte una pista, hagamos una interacción de seguimiento:

prompt = "Do you remember my name?"
response = chatgpt_call(prompt)
print(response)

# Output: I'm sorry, as an AI language model, I don't have the ability to remember specific information about individual users.

Exacto, como podemos observar, cada llamada a la API es una interacción aislada. Es decir, el modelo no recuerda los prompts ni las respuestas anteriores. Cada vez que invocamos chatgpt_call(), arrancamos una conversación nueva.

Eso es un problema al intentar construir un chatbot, porque es imposible mantener una conversación si el modelo no recuerda de qué hemos hablado. Por eso, el siguiente paso será hacer que el modelo sea consciente de nuestras interacciones previas.

Conciencia de contexto

La conciencia de contexto permite a los chatbots entender y responder adecuadamente en función de una conversación en curso.

Al construir un contexto, las interacciones futuras pueden personalizarse en base a las anteriores, manteniendo la continuidad y evitando repeticiones. Además, con chatbots con contexto, la persona usuaria puede hacer preguntas aclaratorias de forma proactiva o proponer correcciones ante malentendidos.

En definitiva, la conciencia de contexto mejora la naturalidad, la eficacia y la experiencia de uso de los chatbots. A partir de ahora nos referiremos al conjunto de interacciones previas como historial de conversación o memoria.

La API original de OpenAI para ChatGPT ya permite enviar el historial de conversación al modelo junto con cada nuevo prompt. Además, el framework LangChain también ofrece una forma de gestionar la memoria de ChatGPT de manera más eficaz y optimizada en costes.

Entender los mensajes de sistema, asistente y usuario

Estructura del historial de conversación de ChatGPT

A estas alturas, podemos usar el método chatgpt_call() directamente proporcionando el prompt. Si miramos la implementación con más detalle, el prompt de entrada se formatea como parte de la lista messages. Esta lista está pensada para llevar el control del historial de conversación, y por eso debe tener un formato muy concreto.

¡Veámoslo de cerca!

Hasta ahora, hemos formateado la lista de mensajes en chatgpt_call() así:

messages = [{"role": "user", "content": prompt}]

La lista messages guarda el historial como una colección de diccionarios. Cada diccionario representa un mensaje de la conversación con dos pares clave-valor.

  • La clave role con el valor user indica que el mensaje lo envía la persona usuaria.
  • La clave content con el valor prompt contiene el prompt real del usuario.

Este es un ejemplo muy simple con una sola interacción. Aunque la clave content siempre almacena el prompt del usuario o la respuesta del chatbot, la clave role es mucho más versátil.

Roles de system, assistant y user

La clave role indica el emisor del mensaje en content. Al usar ChatGPT, podemos tener hasta tres roles:

  • User. Como ya hemos visto, el rol user corresponde a la persona que interactúa con el chatbot.
  • Assistant. El rol assistant corresponde al propio chatbot.
  • System. El rol system sirve para proporcionar instrucciones, pautas y contexto al chatbot. Los mensajes de sistema ayudan a guiar las interacciones, fijar el comportamiento del chatbot, aportar información contextual y gestionar interacciones específicas. Pueden verse como instrucciones de alto nivel para el chatbot, transparentes para el usuario.

Self-made image. Interaction of the different roles in the conversation chain when building a chatbot with chatGPT.

Imagen propia. Interacción de los distintos roles en la cadena de conversación al crear un chatbot con ChatGPT.

Construir un historial de conversación

Podemos crear nuestro historial usando los tres roles user, assistant y system en la lista messages.

Dadas nuestras pruebas, un historial correctamente formateado usando los tres roles podría quedar así:

messages =  [ 
{'role':'system', 'content':'You are friendly chatbot.'},
{'role':'user', 'content':'Hi, my name is Andrea'},
{'role':'assistant', 'content': "Nice to meet you, Andrea! How can I assist you today?"},
{'role':'user', 'content':'Do you remember my name?'}  ]

Podemos modificar ligeramente nuestra función call_chatgpt() para incluir el historial como parámetro de entrada:

def call_chatgpt_with_memory(messages, model="gpt-3.5-turbo"):
   response = openai.ChatCompletion.create(
       model=model,
       messages=messages,
   )
   return response.choices[0].message["content"]

¡Probemos esta nueva implementación!

messages =  [ 
{'role':'system', 'content':'You are friendly chatbot.'},
{'role':'user', 'content':'Hi, my name is Andrea'},
{'role':'assistant', 'content': "Nice to meet you, Andrea! How can I assist you today?"},
{'role':'user', 'content':'Do you remember my name?'}  ]

response = call_chatgpt_with_memory(messages)
print(response)

# Output: Yes, your name is Andrea.

¡Genial! Hemos conseguido que el modelo tenga en cuenta las interacciones pasadas para poder mantener una conversación. Aun así, necesitamos una forma de actualizar la lista messages automáticamente.

Historial automático

Podemos recopilar los mensajes de forma automática mejorando un poco nuestra función de llamada a la API:

def chatgpt_conversation(prompt):
   context.append({'role':'user', 'content':f"{prompt}"})
   response = call_chatgpt_with_memory(context)
   context.append({'role':'assistant',
   'content':f"{response}"})
   return response

¡Probemos ahora!

chatgpt_conversation("Hello, my name is Andrea")

# Output: 'Nice to meet you, Andrea! How can I assist you today?'

Y una interacción de seguimiento:

chatgpt_conversation("Do you remember my name?")

# Output: 'Yes, your name is Andrea.'

Ahora el historial se actualiza automáticamente. Por último, ten en cuenta que puedes consultar el historial —y su estructura— en cualquier momento imprimiendo la lista messages.

print(messages)

# Output:
[{'role': 'user', 'content': 'Hello, my name is Andrea'},
{'role': 'assistant', 'content': 'Nice to meet you, Andrea! How can I assist you today?'},
{'role': 'user', 'content': 'Do you remember my name?'},
{'role': 'assistant', 'content': 'Yes, your name is Andrea.'}]

El framework LangChain

Hasta aquí, estaremos de acuerdo en que nuestra implementación da lugar a un chatbot útil, pero quizá no sea la versión más optimizada.

Incorporar todos y cada uno de los prompts y respuestas anteriores puede hacer que el número de tokens crezca rápidamente, y ChatGPT tendrá que procesarlos todos antes de devolver la última respuesta.

Hasta ahora hemos usado operaciones .append para agrupar las interacciones pasadas y dotar al chatbot de cierta memoria. Sin embargo, la gestión de memoria puede hacerse de forma más eficaz con paquetes dedicados como LangChain.

LangChain es un framework para desarrollar aplicaciones impulsadas por modelos de lenguaje. Como los chatbots son una de las aplicaciones más populares hoy en día, LangChain ofrece una implementación más limpia para construir el historial de conversación, además de alternativas para gestionarlo con mayor eficiencia.

Si quieres saber más sobre LangChain, te recomiendo el artículo introductorio Introduction to LangChain for Data Engineering & Data Applications.

Historial sencillo con LangChain

En esta sección veremos cómo usar LangChain para construir un chatbot.

La librería langchain puede sustituir a openai usada arriba, ya que el módulo langchain.llms te permite interactuar con ChatGPT en dos líneas:

# OpenAI key from environment
from langchain.llms import OpenAI
llm = OpenAI()

Una vez cargado el modelo llm, importemos el objeto de memoria que almacenará nuestro historial. Para guardar cada interacción pasada, LangChain proporciona ConversationBufferMemory:

from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory()

Ahora toca importar ConversationChain, un envoltorio que usará el llm y la memory para enviar el prompt del usuario a ChatGPT y devolver sus respuestas:

from langchain.chains import ConversationChain

conversation = ConversationChain(
   llm=llm,
   memory=memory
)

Por último, para enviar un prompt a ChatGPT, podemos usar el método .predict así:

conversation.predict(input="Hello, my name is Andrea")

# Output: "Hi Andrea, I'm an AI created to help you with whatever you may need. What can I do for you today?"

Activemos verbose=True para ver la información que el modelo tiene en cuenta al generar la respuesta. Probémoslo en una interacción de seguimiento:

Screenshot of the context available to ChatGPT when creating a completion. Verbose output in green.

Captura de pantalla del contexto disponible para ChatGPT al crear una respuesta. Salida detallada en verde.

Por último, comprobemos que recuerda perfectamente las interacciones previas:

Screenshot of the context available to ChatGPT when creating a completion. Verbose output in green.

Captura de pantalla del contexto disponible para ChatGPT al crear una respuesta. Salida detallada en verde.

Rellenar el historial

Podemos añadir contexto adicional al chatbot usando el método memory.save_context(). Así, podemos hacer que el chatbot conozca cualquier información sin necesidad de proporcionarla en conversación. En LangChain, las claves para este fin son input y output. Por ejemplo,

memory.save_context({"input": "Hi"},
                   {"output": "What's up"})
memory.save_context({"input": "Not much, just hanging"},
                   {"output": "Cool"})

Además, podemos consultar la memoria en cualquier momento ejecutando print(memory.buffer) o memory.load_memory_variables({}).

Tipos de memoria en LangChain

LangChain implementa distintos tipos de memoria para ChatGPT. La ConversationBufferMemory que hemos usado guarda todas y cada una de las interacciones con ChatGPT. Sin embargo, ya hemos comentado que enviar todo el historial en cada interacción puede disparar el número de tokens a procesar.

Ten en cuenta que, además de que ChatGPT tiene un límite de tokens por interacción, el coste de uso también depende del número de tokens. Procesar todo el historial en cada turno puede salir caro con el tiempo.

Para evitar procesar continuamente todo el historial, LangChain implementa otras formas optimizadas de gestionar la memoria de ChatGPT. Veremos uno de los tipos más avanzados en la siguiente sección.

Historial avanzado con LangChain

Una forma avanzada de gestionar la memoria sin almacenar cada interacción consiste en guardar un resumen de las interacciones.

Este tipo de memoria es de mis favoritos porque permite una gestión optimizada sin sacrificar información previa.

¡Vamos a ello!

# OpenAI key from environment
from langchain.llms import OpenAI
llm = OpenAI()

from langchain.memory import ConversationSummaryBufferMemory
memory = ConversationSummaryBufferMemory(llm=llm, max_token_limit=100)

Ten en cuenta que este tipo de memoria utiliza el llm definido para generar el resumen de las interacciones previas.

Además, esta memoria puede almacenar interacciones completas hasta un máximo de tokens (max_token_limit). A partir de ese límite, incorpora la información de esos mensajes al resumen.

Para probarlo, creemos una interacción con un gran número de tokens. Considerando el siguiente schedule:

schedule = "There is a meeting at 8am with your product team. \
You will need your powerpoint presentation prepared. \
9am-12pm have time to work on your LangChain \
project which will go quickly because Langchain is such a powerful tool. \
At Noon, lunch at the italian resturant with a customer who is driving \
from over an hour away to meet you to understand the latest in AI. \
Be sure to bring your laptop to show the latest LLM demo."

memory = ConversationSummaryBufferMemory(llm=llm, max_token_limit=100)
memory.save_context({"input": "Hello"}, {"output": "What's up"})
memory.save_context({"input": "Not much, just hanging"}, {"output": "Cool"})
memory.save_context({"input": "What is on the schedule today?"}, {"output": f"{schedule}"})

Ahora solo necesitamos declarar una nueva cadena de conversación con el llm y la memory como en los ejemplos anteriores.

conversation = ConversationChain(
   llm=llm,
   memory=memory,
   verbose=True
)

Podemos usar .predict para enviar el prompt a ChatGPT:

Screenshot of the context available to ChatGPT when creating a completion. Verbose output in green.

Captura de pantalla del contexto disponible para ChatGPT al crear una respuesta. Salida detallada en verde.

Como vemos, el chatbot mantiene un resumen del historial original, reduciendo el número de tokens que ChatGPT procesa en cada turno.

¡Listo! Ahora podemos seguir hablando con nuestro chatbot optimizado durante horas.

Pon verbose=False para una experiencia de preguntas y respuestas más limpia en tu cuaderno.

Conclusión

En este artículo hemos visto cómo construir un chatbot con conciencia de contexto usando el conocido modelo ChatGPT.

Hemos comprobado cómo crear tu propio chatbot con contexto permite mantener interacciones continuas. Este enfoque iterativo fomenta un bucle de feedback constante, que te ayuda a tener en cuenta necesidades y preferencias del usuario a lo largo de la conversación.

Hemos cubierto dos enfoques principales para gestionar el historial: primero, usando la API nativa de ChatGPT para un chatbot funcional; y segundo, usando el framework LangChain con un tipo de memoria optimizado.

¡Ahora te toca a ti! Es el momento de usar las piezas que hemos visto para personalizar un chatbot a tu caso de uso.

Si te interesa crear otras aplicaciones con LangChain y ChatGPT, el webinar Building AI Applications with LangChain and GPT es para ti. ¿Quieres ponerte al día con NLP? Entonces echa un vistazo a los módulos de Natural Language Processing in Python.


Andrea Valenzuela's photo
Author
Andrea Valenzuela
LinkedIn
Twitter

Andrea Valenzuela trabaja actualmente en el experimento CMS en el acelerador de partículas (CERN) de Ginebra (Suiza). Con experiencia en ingeniería y análisis de datos durante los últimos seis años, sus funciones incluyen el análisis de datos y el desarrollo de software. Ahora trabaja para democratizar el aprendizaje de las tecnologías relacionadas con los datos a través de la publicación en Medium ForCode'Sake.

Es licenciada en Ingeniería Física por la Universidad Politécnica de Cataluña, así como Máster en Sistemas Interactivos Inteligentes por la Universidad Pompeu Fabra. Su experiencia investigadora incluye el trabajo profesional con algoritmos anteriores de OpenAI para la generación de imágenes, como Flujos Normalizadores.

Temas
Inteligencia Artificial
Relacionado

blog

10 maneras de utilizar ChatGPT para las finanzas

Descubre cómo los modelos lingüísticos de IA como ChatGPT pueden revolucionar tus operaciones financieras, desde la generación de informes hasta la traducción de jerga financiera.
Matt Crabtree's photo

Matt Crabtree

13 min

Tutorial

Tutorial sobre cómo crear aplicaciones LLM con LangChain

Explore el potencial sin explotar de los grandes modelos lingüísticos con LangChain, un marco Python de código abierto para crear aplicaciones avanzadas de IA.
Moez Ali's photo

Moez Ali

12 min

Tutorial

Construir agentes LangChain para automatizar tareas en Python

Un tutorial completo sobre la construcción de agentes LangChain multiherramienta para automatizar tareas en Python utilizando LLMs y modelos de chat utilizando OpenAI.
ChatGPT Code Interpreter

Tutorial

Cómo utilizar ChatGPT Code Interpreter

Todo lo que necesitas saber sobre ChatGPT Code Interpreter de OpenAI
Adel Nehme's photo

Adel Nehme

9 min

Tutorial

Guía para principiantes sobre la ingeniería de avisos ChatGPT

Descubra cómo conseguir que ChatGPT le proporcione los resultados que desea dándole las entradas que necesita.
Matt Crabtree's photo

Matt Crabtree

6 min

Tutorial

Guía para principiantes sobre el uso de la API ChatGPT

Esta guía te acompanya a través de los fundamentos de la API ChatGPT, demostrando su potencial en el procesamiento del lenguaje natural y la comunicación impulsada por la IA.
Moez Ali's photo

Moez Ali

11 min

Ver MásVer Más