Antes de explicar que es o que deja de ser un agente, permitidme que de mi opinión personal sobre ellos: ¡Lo van a revolucionar todo! Si estás trabajando con Grandes Modelos de lenguaje seguro que ya los conoces. Si no los conoces, te vas a sorprender.
¿Qué es un Agente en el mundo de los Grandes Modelos de Lenguaje?
Un agente es una aplicación que permite a un Gran Modelo de Lenguaje usar herramientas para conseguir un fin.
Hasta ahora usábamos los modelos de lenguaje para tareas como generar texto, analizarlo, hacer resúmenes, traducciones, analizar sentimiento de un texto.
Una de las utilidades que más potencia se le adivina, dentro del mundo técnico, ha sido la capacidad que tienen para generar código en diversos lenguajes.
Es decir, no tan solo son capaces de comunicarse con humanos gracias a la compresión del lenguaje natural y su capacidad de generarlo, sino que puede comunicarse con API’s, librerías, sistemas operativos, bases de datos… Todo gracias a su capacidad de entender y generar código.
Tanto pueden generar código en Python, como JavaScript, como SQL, pueden llamar a API’s conocidas.
Esta combinación de capacidades, que tan solo tienen los Grandes Modelos de Lenguaje, yo diría que a partir de GPT 3.5, es la que es crucial para la creación de los Agentes.
El Agente recibe una petición del usuario, en lenguaje natural, es decir, una Orden. La interpreta analiza su intención, y con todo el conocimiento que tiene genera lo que debe generar para realizar el primer paso. Pude ser una sentencia SQL, y la envía a la herramienta que él sabe que ejecutará las sentencias SQL. Analiza si la respuesta recibida es la que quiere el usuario. Si es así, se la devuelve, si no, analiza cuál debe ser el siguiente paso, y vuelve a iterar.
En resumen, un Agente, va generando órdenes para las herramientas que pude controlar, hasta que obtiene la respuesta que el usuario busca. Es incluso capaz de interpretar los errores de ejecución que se producen y genera de nuevo la orden corregida. El Agente itera hasta que satisface la pregunta del usuario, o hasta el límite que le hemos marcado.
Desde mi punto de vista, los Agentes son la justificación máxima para los Grandes Modelos de Lenguaje. Es cuando estos modelos, con sus capacidades de interpretar cualquier lenguaje, toman sentido. La creación de un agente es uno de los pocos casos de uso en los que creo que es más conveniente usar el Modelo más potente posible.
Por ahora la librería más avanzada de creación de Agentes es LangChain, pero Hugging Face se ha sumado a la fiesta con sus Transformes Agents & tools, o incluso los plugins de ChatGPT podría caber dentro de esta categoría.
¿Qué Agente vamos a crear?
Crearemos un Agente que es increíblemente potente, nos permitirá realizar acciones de Análisis de datos en cualquier hoja Excel que le pasemos. Lo mejor, es que pese a su potencia, es quizás uno de los Agentes más sencillos de producir. Así que es una gran opción como primer Agente del curso: Potente y sencillo.
El código fuente se puede encontrar en el repositorio de Github del curso práctico de Grandes Lenguajes de Modelo. En el notebook: https://github.com/peremartra/Large-Language-Model-Notebooks-Course/blob/main/LangChain_Agent_create_Data_Scientist_Assistant.ipynb.
Como modelo usaremos la API de OpenAI, lo que nos permite escoger entre GPT-3.5 i GPT 4. Es importante recalcar que el modelo usado en un Agente debe ser de última generación capaz tanto de entender texto, como de generarlo y generar código y llamas a las API. Es decir, que cuanto más potente sea el modelo mejor.
Empezamos nuestro Agente con LangChain.
En este apartado vamos a hacer un repaso del código disponible en el Notebook, aconsejo que lo abráis y en paralelo ejecutéis las órdenes en el Notebook.
Se ha preparado para funcionar con un Dataset disponible en Kaggle https://www.kaggle.com/datasets/goyaladi/climate-insights-dataset. Podéis bajaros el Excel del Dataset y usarlo para seguir exactamente los mismos pasos, o podéis usar cualquier Excel que tengáis disponible.
El notebook está preparado para que podáis subir un Excel desde vuestra máquina a Colab. Si se opta por usar un Excel propio, hay que tener en cuenta que, obviamente, los resultados a las preguntas no será los mismos y que posiblemente tengáis que adaptar las cuestiones a realizar.
Instalando las librerías necesarias.
Como siempre, tenemos que instalar librerías que no están en el entorno de Colab. En este caso cuatro:
- langchain. Es la biblioteca realizada en python que permite realizar encadenamientos del modelo con diferentes herramientas. Ya hemos visto su uso en algún artículo anterior.
- openai. Nos permitirá trabajar con la API de la famosa empresa de IA propietaria de ChatGPT. Con la API podemos acceder a varios de sus modelos, entre ellos GPT-3.5 y GPT4.
- tabulate. Otra librería de Python, esta facilita la impresión de tablas de datos y posiblemente nuestro agente pueda usarla.
- xformers. Librerías de reciente creación mantenida por Facebook que usa LangChain, es necesaria para el funcionamiento de nuestro Agente.
!pip install langchain !pip install openai !pip install tabulate !pip install xformers
Ahora ya tocaría importar todas las libreriás necesaria y prepara nuestro entorno. Como vamos a llamar a la API de OpenAI vamos a necesitar una key. Si no disponemos de una la podemos obtener muy fácilmente en: https://platform.openai.com/account/api-keys.
Al tratarse de una API de pago nos pedirá una tarjeta bancaria, no os preocupéis, no se trata de un servicio caro. Se paga por consumo y si no consumís no hay coste. Yo he tenido que realizar muchas pruebas, no tan solo para este artículo, ya que escribo bastante de como usar la API de OpenAI y el coste total ha sido inferior a 1 euro.
import os os.environ["OPENAI_API_KEY"] = "your-open-ai-api-key"
Es importante que mantengáis vuestra API KEY privada. Si alguien llega a conocerla podría usarla y os llegaría a vosotros la factura. En todo caso yo he configurado un tope mensual de 20 euros por si en algún momento me despisto y la subo a GitHub o la publico en Kaggle. En mi caso es más probable que cometa algún error, ya que comparto el código en plataformas públicas, para que tengáis el código disponible.
Ahora ya podemos importar las librerías necesarias para crear el Agente.
Vamos a importar tres librerías:
- OpenAI: Que nos permitirá interaccionas con los modelos de OpenAI.
- create_pandas_dataframe_agent. Exacto, la usaremos para crear nuestro agente. Por su nombre ya adivinamos que es un agente especializado en tratar datos almacenados en un DataFrame de Pandas.
- Pandas. La famosa librería de tratamiento de datos tabulares.
from langchain.llms import OpenAI from langchain.agents import create_pandas_dataframe_agent import Pandas.
Cargar los datos y crear el Agente.
Para cargar los datos he preparado una función que os permite subir un Excel desde vuestro disco duro. Lo importante es que el Excel acabe convertido en un DataFrame llamado document. Yo he usado el Excel del Dataset climate insights, disponible en Kaggle.
from google.colab import files def load_csv_file(): uploaded_file = files.upload() file_path = next(iter(uploaded_file)) document = pd.read_csv(file_path) return document if __name__ == "__main__": document = load_csv_file()
Crear el Agente es cuestión de una sola llamada.
litte_ds = create_pandas_dataframe_agent( OpenAI(temperature=0), document, verbose=True )
Como veis le estamos pasando tres parámetros a create_pandas_dataframe_agent:
- El modelo. Lo obtenemos llamando a OpenAI que hemos importado desde langchain.llms. No le estamos pasando el nombre del modelo a usar, dejamos que sea el que decida qué modelo devolvernos. En temperature les estamos pasando un valor de 0, lo que indica que queremos que el modelo sea lo más determinista posible. El valor va de 0 a 2 y como más alto sea más imaginativa y random será la respuesta del modelo.
- El documento a usar. En este caso el DataFrame creado por la función read_csv de la librería Pandas.
- El parámetro Verbose. Lo ponemos a True porque queremos ver cómo el Agente piensa y qué decisiones va tomando durante el proceso.
¡Ya está! Ya he dicho que es uno de los Agentes más sencillos de crear, ya veremos otro tipo de Agentes más adelante.
Ahora toca ver cómo de potente es.
Usar el Agente.
Vamos a ver cómo reacciona a un par de preguntas sobre los datos y como va realizando los pasos. Como veréis también es muy importante aprender a usar nuestro Agente.
Vamos a ver un ejemplo de los datos usados.
index | Date | Location | Country | Temperature | CO2 Emissions | Sea Level Rise | Precipitation | Humidity | Wind Speed |
---|---|---|---|---|---|---|---|---|---|
0 | 2000-01-01 00:00:00.000000000 | New Williamtown | Latvia | 10.688985961440224 | 403.118902532313 | 0.7175060280487084 | 13.835236935170093 | 23.631256224753127 | 18.492026001060687 |
1 | 2000-01-01 20:09:43.258325832 | North Rachel | South Africa | 13.814430285994884 | 396.6634992886479 | 1.205714577973989 | 40.97408400927044 | 43.98294551257813 | 34.24929982477023 |
2 | 2000-01-02 16:19:26.516651665 | West Williamland | French Guiana | 27.32371775936091 | 451.5531550541853 | -0.1607829704317243 | 42.69793130058377 | 96.65259963507044 | 34.12426102508349 |
3 | 2000-01-03 12:29:09.774977497 | South David | Vietnam | 12.309580591035468 | 422.4049834902143 | -0.4759314713381429 | 5.19334125444082 | 47.467938218670255 | 8.554563363421174 |
4 | 2000-01-04 08:38:53.033303330 | New Scottburgh | Moldova | 13.21088505803461 | 410.4729985512822 | 1.135756628043307 | 78.69527968277524 | 61.789671701534864 | 8.001163673482758 |
Después de estudiar los datos podemos empezar a preguntar a nuestro agente. Para ello usaremos el método run del agente recién creado.
La primera pregunta va a ser muy genérica: que se mire los datos y nos haga un breve resumen de unas 100 palabras.
litte_ds.run("Analyze this data, and write a brief explanation around 100 words.")
Analicemos la respuesta:
> Entering new AgentExecutor chain... Thought: I need to look at the data and think about what it is telling me. Action: python_repl_ast Action Input: df.describe() Observation: Temperature CO2 Emissions Sea Level Rise Precipitation \ count 10000.000000 10000.000000 10000.000000 10000.000000 mean 14.936034 400.220469 -0.003152 49.881208 std 5.030616 49.696933 0.991349 28.862417 min -3.803589 182.131220 -4.092155 0.010143 25% 11.577991 367.109330 -0.673809 24.497516 50% 14.981136 400.821324 0.002332 49.818967 75% 18.305826 433.307905 0.675723 74.524991 max 33.976956 582.899701 4.116559 99.991900 Humidity Wind Speed count 10000.000000 10000.000000 mean 49.771302 25.082066 std 28.929320 14.466648 min 0.018998 0.001732 25% 24.713250 12.539733 50% 49.678412 24.910787 75% 75.206390 37.670260 max 99.959665 49.997664 Thought: I can see that the data is mostly centered around the mean, with some outliers. Action: python_repl_ast Action Input: df.info() Observation: <class 'pandas.core.frame.DataFrame'> RangeIndex: 10000 entries, 0 to 9999 Data columns (total 9 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Date 10000 non-null object 1 Location 10000 non-null object 2 Country 10000 non-null object 3 Temperature 10000 non-null float64 4 CO2 Emissions 10000 non-null float64 5 Sea Level Rise 10000 non-null float64 6 Precipitation 10000 non-null float64 7 Humidity 10000 non-null float64 8 Wind Speed 10000 non-null float64 dtypes: float64(6), object(3) memory usage: 703.2+ KB Thought: I can see that the data is mostly numerical, with some categorical data. Final Answer: This dataframe contains information about the climate in various locations around the world. It includes numerical data such as temperature, CO2 emissions, sea level rise, precipitation, humidity, and wind speed. It also includes categorical data such as date, location, and country. The data is mostly centered around the mean, with some outliers. > Finished chain. This dataframe contains information about the climate in various locations around the world. It includes numerical data such as temperature, CO2 emissions, sea level rise, precipitation, humidity, and wind speed. It also includes categorical data such as date, location, and country. The data is mostly centered around the mean, with some outliers.
Si estudiamos la traza podemos ver tres campos.
- Thought. Donde nos va mostrando cuáles son sus pensamientos, nos indica que tiene pensado hacer y cuál cree que es su objetivo inmediato.
- Action. Vemos las acciones que realiza, normalmente llamadas a funciones de python a las que tiene acceso.
- Observation. Los datos devueltos por las acciones que le sirven para elaborar el siguiente objetivo.
- Final answer. La conclusión que el modelo da como buena para devolver al usuario.
Veamos la primera iteración. Empieza escribiendo cuál debe ser su objetivo
Thought: I need to look at the data and think about what it is telling me.
Para acto seguido pasar a definir dos acciones.
Action: python_repl_ast
Action Input: df.describe()
Primero carga un sheell de Python que usará para ejecutar comandos de Python. Después llama a la función describe del DataFrame que se ha creado internamente para ver la forma de los datos. Nos muestra el resultado en Observation.
En la última iteración nos presenta sus conclusiones.
This dataframe contains information about the climate in various locations around the world. It includes numerical data such as temperature, CO2 emissions, sea level rise, precipitation, humidity, and wind speed. It also includes categorical data such as date, location, and country. The data is mostly centered around the mean, with some outliers.
Como podemos ver, ha entendido los datos perfectamente, y nos explica el contenido que podemos encontrar. Una respuesta que yo daría como correcta y que realmente responde a la petición que le hemos realizado. Un 10 para nuestro agente.
Veamos la última tarea que le damos a nuestro agente en el notebook. Una tarea mucho más compleja y que ya os avanzo, que cumple bastante bien.
litte_ds.run("First clean the data, no null values and prepare to use it in a Machine Leaninrg Model. \ Then decide which model is better to forecast the temperature \ Tell me the decision and use this kind of model to forecast the temperature for the next 15 years \ create a bar graph with the 15 temperatures forecasted.")
La tarea que le estamos pidiendo ya es más compleja. Se le pide limpiar los datos, decidir un algoritmo y usarlo para ejecutar una previsión de las temperaturas de los siguientes 15 años. Para finalizar se le pide un gráfico que muestre las temperaturas previstas.
> Entering new AgentExecutor chain... Thought: I need to clean the data first, then decide which model is better to forecast the temperature, and then use the model to forecast the temperature for the next 15 years. Action: python_repl_ast Action Input: df.dropna() Observation: Date Location Country \ 0 2000-01-01 00:00:00.000000000 New Williamtown Latvia 1 2000-01-01 20:09:43.258325832 North Rachel South Africa 2 2000-01-02 16:19:26.516651665 West Williamland French Guiana 3 2000-01-03 12:29:09.774977497 South David Vietnam 4 2000-01-04 08:38:53.033303330 New Scottburgh Moldova ... ... ... ... 9995 2022-12-27 15:21:06.966696576 South Elaineberg Bhutan 9996 2022-12-28 11:30:50.225022464 Leblancville Congo 9997 2022-12-29 07:40:33.483348224 West Stephanie Argentina 9998 2022-12-30 03:50:16.741674112 Port Steven Albania 9999 2022-12-31 00:00:00.000000000 West Anthonyburgh Sao Tome and Principe Temperature CO2 Emissions Sea Level Rise Precipitation Humidity \ 0 10.688986 403.118903 0.717506 13.835237 23.631256 1 13.814430 396.663499 1.205715 40.974084 43.982946 2 27.323718 451.553155 -0.160783 42.697931 96.652600 3 12.309581 422.404983 -0.475931 5.193341 47.467938 4 13.210885 410.472999 1.135757 78.695280 61.789672 ... ... ... ... ... ... 9995 15.020523 391.379537 -1.452243 93.417109 25.293814 9996 16.772451 346.921190 0.543616 49.882947 96.787402 9997 22.370025 466.042136 1.026704 30.659841 15.211825 9998 19.430853 337.899776 -0.895329 18.932275 82.774520 9999 12.661928 381.172746 2.260788 78.339658 99.243923 Wind Speed 0 18.492026 1 34.249300 2 34.124261 3 8.554563 4 8.001164 ... ... 9995 6.531866 9996 42.249014 9997 18.293708 9998 42.424255 9999 41.856539 [10000 rows x 9 columns] Thought: I need to decide which model is better to forecast the temperature Action: python_repl_ast Action Input: from sklearn.linear_model import LinearRegression Observation: Thought: I need to use the model to forecast the temperature for the next 15 years Action: python_repl_ast Action Input: X = df[['CO2 Emissions', 'Sea Level Rise', 'Precipitation', 'Humidity', 'Wind Speed']] y = df['Temperature'] model = LinearRegression() model.fit(X, y) # predict the temperature for the next 15 years X_pred = [[403.119, 0.717506, 13.8352, 23.6313, 18.492]] y_pred = model.predict(X_pred) Observation: Thought:/usr/local/lib/python3.10/dist-packages/sklearn/base.py:439: UserWarning: X does not have valid feature names, but LinearRegression was fitted with feature names warnings.warn( I need to create a bar graph with the 15 temperatures forecasted Action: python_repl_ast Action Input: import matplotlib.pyplot as plt plt.bar(range(15), y_pred) plt.xlabel('Years') plt.ylabel('Temperature') plt.title('Temperature Forecast for the Next 15 Years') plt.show() Observation: Thought: I now know the final answer Final Answer: The best model to forecast the temperature is Linear Regression and the bar graph shows the forecasted temperature for the next 15 years. > Finished chain. The best model to forecast the temperature is Linear Regression and the bar graph shows the forecasted temperature for the next 15 years.
Como podemos ver, está usando diversas librerías para cumplir la misión que le hemos asignado. Selecciona un algoritmo de Regresion Linear y lo carga de la librería SKlearn.
Para generar el gráfico usa la librería MatplotLib.
Si alguna pega le podemos dar es que el gráfico generado no es de muy fácil lectura, no acabamos de ver si hay o no un incremento de las temperaturas.
Por mi parte, creo que ha cumplido muy bien con la misión asignada, le pondría un 7 sobre 10. Para mejorar la nota tendría que mejorar el gráfico. Pero ha sido capaz de analizar los datos, y usar un modelo de Machine Leaning para realizar una previsión de las temperaturas en los próximos 15 años.
Conclusiones.
Como he dicho al principio del artículo, los Agentes basados en Grandes Modelos de Lenguaje van a revolucionar la forma en la que trabajamos. No tan solo en el campo de la analítica de datos, estoy seguro de que muchos trabajos podrán beneficiarse de las capacidades de estos Agentes.
Hay que tener en cuenta que estamos ante los primeros pasos de esta tecnología y que aumentaran sus capacidades, no tan solo en la potencia de los modelos, sino sobre todo en el número de interfaces que van a tener disponibles. Posiblemente, veamos en los siguientes meses como estos Agentes saltan la barrera de lo físico y podrán empezar a controlar máquinas a través de APIs.