Ingeniería de prompts

De cero a ingeniería de prompts avanzada con Langchain en Python

mm
Añade Unite.AI a tus fuentes preferidas en Google

Un aspecto importante de los grandes modelos de lenguaje (LLM) es la cantidad de parámetros que utilizan estos modelos para aprender. Cuantos más parámetros tenga un modelo, mejor podrá comprender la relación entre palabras y frases. Esto significa que los modelos con miles de millones de parámetros tienen la capacidad de generar diversos formatos de texto creativo y responder a preguntas abiertas y desafiantes de manera informativa.

Los LLM como ChatGPT, que utilizan el modelo Transformer, son proficientes en comprender y generar lenguaje humano, lo que los hace útiles para aplicaciones que requieren comprensión del lenguaje natural. Sin embargo, no están exentos de limitaciones, que incluyen conocimiento desactualizado, incapacidad para interactuar con sistemas externos, falta de comprensión del contexto y, a veces, generar respuestas plausibles pero incorrectas o sin sentido, entre otros.

Abordar estas limitaciones requiere integrar LLM con fuentes de datos y capacidades externas, lo que puede presentar complejidades y exigir habilidades de codificación y manejo de datos extensas. Esto, combinado con los desafíos de comprender conceptos de IA y algoritmos complejos, contribuye a la curva de aprendizaje asociada con el desarrollo de aplicaciones que utilizan LLM.

Sin embargo, la integración de LLM con otras herramientas para formar aplicaciones impulsadas por LLM podría redefinir nuestro paisaje digital. El potencial de dichas aplicaciones es vasto, incluyendo la mejora de la eficiencia y la productividad, la simplificación de tareas, la mejora de la toma de decisiones y la provisión de experiencias personalizadas.

En este artículo, profundizaremos en estos temas, explorando las técnicas avanzadas de ingeniería de prompts con Langchain, ofreciendo explicaciones claras, ejemplos prácticos y instrucciones paso a paso sobre cómo implementarlas.

Langchain, una biblioteca de última generación, aporta comodidad y flexibilidad al diseño, implementación y ajuste de prompts. A medida que desempacamos los principios y prácticas de la ingeniería de prompts, aprenderás a utilizar las poderosas características de Langchain para aprovechar las fortalezas de los modelos de IA generativos de última generación como GPT-4.

Comprendiendo los prompts

Antes de sumergirnos en las tecnicidades de la ingeniería de prompts, es esencial comprender el concepto de prompts y su importancia.

Un ‘prompt‘ es una secuencia de tokens que se utilizan como entrada para un modelo de lenguaje, instruyéndolo para generar un tipo específico de respuesta. Los prompts desempeñan un papel crucial en la dirección del comportamiento de un modelo. Pueden afectar la calidad del texto generado, y cuando se crean correctamente, pueden ayudar al modelo a proporcionar resultados precisos y relevantes.

La ingeniería de prompts es el arte y la ciencia de diseñar prompts efectivos. El objetivo es obtener la salida deseada de un modelo de lenguaje. Al seleccionar y estructurar cuidadosamente los prompts, se puede guiar al modelo hacia la generación de respuestas más precisas y relevantes. En la práctica, esto implica afinar las frases de entrada para adaptarse a los sesgos de entrenamiento y estructurales del modelo.

La sofisticación de la ingeniería de prompts va desde técnicas simples, como alimentar al modelo con palabras clave relevantes, hasta métodos más avanzados que involucran el diseño de prompts complejos y estructurados que utilizan la mecánica interna del modelo a su favor.

Langchain: La herramienta de prompts de más rápido crecimiento

LangChain, lanzado en octubre de 2022 por Harrison Chase, se ha convertido en uno de los marcos de código abierto más valorados en GitHub en 2023. Ofrece una interfaz simplificada y estandarizada para incorporar grandes modelos de lenguaje (LLM) en aplicaciones. También proporciona una interfaz enriquecida para la ingeniería de prompts, lo que permite a los desarrolladores experimentar con diferentes estrategias y evaluar sus resultados. Al utilizar Langchain, puedes realizar tareas de ingeniería de prompts de manera más efectiva e intuitiva.

LangFlow sirve como una interfaz de usuario para orquestar componentes de LangChain en un diagrama de flujo ejecutable, lo que permite una rápida prototipación y experimentación.

LangChain llena una brecha crucial en el desarrollo de IA para las masas. Permite una variedad de aplicaciones de NLP como asistentes virtuales, generadores de contenido, sistemas de respuesta a preguntas y más, para resolver una serie de problemas del mundo real.

En lugar de ser un modelo o proveedor independiente, LangChain simplifica la interacción con diversos modelos, extendiendo las capacidades de las aplicaciones de LLM más allá de las limitaciones de una simple llamada a la API.

La arquitectura de LangChain

 

Los componentes principales de LangChain incluyen Model I/O, Plantillas de prompts, Memoria, Agentes y Cadenas.

Model I/O

LangChain facilita una conexión sin problemas con varios modelos de lenguaje al envolverlos con una interfaz estandarizada conocida como Model I/O. Esto facilita un cambio de modelo sin esfuerzo para la optimización o un mejor rendimiento. LangChain admite varios proveedores de modelos de lenguaje, incluyendo OpenAI, HuggingFace, Azure, Fireworks y más.

Plantillas de prompts

Se utilizan para gestionar y optimizar las interacciones con LLM mediante la provisión de instrucciones o ejemplos concisos. La optimización de los prompts mejora el rendimiento del modelo, y su flexibilidad contribuye significativamente al proceso de entrada.

Un ejemplo simple de una plantilla de prompt:


<p>from langchain.prompts import PromptTemplate
prompt = PromptTemplate(input_variables=["subject"],
template="¿Cuáles son los avances recientes en el campo de {subject}?")
print(prompt.format(subject="Procesamiento de lenguaje natural"))</p>

A medida que avanzamos en complejidad, encontramos patrones más sofisticados en LangChain, como el patrón Reason and Act (ReAct). ReAct es un patrón vital para la ejecución de acciones donde el agente asigna una tarea a una herramienta adecuada, personaliza la entrada para ella y analiza su salida para lograr la tarea. El ejemplo de Python a continuación muestra un patrón ReAct. Demuestra cómo se estructura un prompt en LangChain, utilizando una serie de pensamientos y acciones para razonar a través de un problema y producir una respuesta final:

PREFIX = """Answer the following question using the given tools:"""
FORMAT_INSTRUCTIONS = """Follow this format:
Question: {input_question}
Thought: your initial thought on the question
Action: your chosen action from [{tool_names}]
Action Input: your input for the action
Observation: the action's outcome"""
SUFFIX = """Start!
Question: {input}
Thought:{agent_scratchpad}"""

Memoria

La memoria es un concepto crítico en LangChain, que permite a los LLM y las herramientas retener información con el tiempo. Este comportamiento con estado mejora el rendimiento de las aplicaciones de LangChain al almacenar respuestas anteriores, interacciones del usuario, el estado del entorno y los objetivos del agente. Las estrategias de ConversationBufferMemory y ConversationBufferWindowMemory ayudan a mantener un registro de la conversación completa o de las partes recientes de una conversación, respectivamente. Para un enfoque más sofisticado, la estrategia de ConversationKGMemory permite codificar la conversación como un grafo de conocimiento que se puede alimentar de nuevo a los prompts o utilizado para predecir respuestas sin llamar al LLM.

Agentes

Un agente interactúa con el mundo realizando acciones y tareas. En LangChain, los agentes combinan herramientas y cadenas para la ejecución de tareas. Puede establecer una conexión con el mundo exterior para la recuperación de información para aumentar el conocimiento de los LLM, superando así sus limitaciones inherentes. Pueden decidir pasar cálculos a una calculadora o intérprete de Python dependiendo de la situación.

Los agentes están equipados con subcomponentes:

  • Herramientas: Estos son componentes funcionales.
  • Conjuntos de herramientas: Colecciones de herramientas.
  • Ejecutores de agentes: Este es el mecanismo de ejecución que permite elegir entre herramientas.

Los agentes en LangChain también siguen el patrón de ReAct de cero disparos, donde la decisión se basa solo en la descripción de la herramienta. Este mecanismo se puede extender con memoria para tener en cuenta la historia completa de la conversación. Con ReAct, en lugar de pedirle a un LLM que complete su texto, puedes pedirle que responda en un bucle de pensamiento/acción/observación.

Cadenas

Las cadenas, como sugiere el término, son secuencias de operaciones que permiten a la biblioteca LangChain procesar entradas y salidas de modelos de lenguaje de manera fluida. Estos componentes integrales de LangChain están fundamentalmente compuestos por enlaces, que pueden ser otras cadenas o primitivas como prompts, modelos de lenguaje o utilidades.

Imagina una cadena como una cinta transportadora en una fábrica. Cada paso en esta cinta representa una operación específica, que podría ser invocar un modelo de lenguaje, aplicar una función de Python a un texto o incluso dar un prompt al modelo de una manera particular.

LangChain clasifica sus cadenas en tres tipos: Cadenas de utilidad, Cadenas genéricas y Cadenas de combinación de documentos. Nos centraremos en Cadenas de utilidad y Cadenas genéricas para nuestra discusión.

  • Cadenas de utilidad están diseñadas específicamente para extraer respuestas precisas de modelos de lenguaje para tareas estrechamente definidas. Por ejemplo, tomemos un vistazo a la LLMMathChain. Esta cadena de utilidad permite que los modelos de lenguaje realicen cálculos matemáticos. Acepta una pregunta en lenguaje natural, y el modelo de lenguaje a su vez genera un fragmento de código de Python que se ejecuta para producir la respuesta.
  • Cadenas genéricas, por otro lado, sirven como bloques de construcción para otras cadenas pero no se pueden utilizar de forma independiente. Estas cadenas, como la LLMChain, son fundamentales y a menudo se combinan con otras cadenas para realizar tareas intrincadas. Por ejemplo, la LLMChain se utiliza con frecuencia para consultar un objeto de modelo de lenguaje mediante la formación de la entrada según una plantilla de prompt proporcionada y luego pasándola al modelo de lenguaje.

Implementación paso a paso de la ingeniería de prompts con Langchain

Te guiaremos a través del proceso de implementar la ingeniería de prompts utilizando Langchain. Antes de proceder, asegúrate de haber instalado el software y los paquetes necesarios.

Puedes aprovechar herramientas populares como Docker, Conda, Pip y Poetry para configurar LangChain. Los archivos de instalación relevantes para cada uno de estos métodos se pueden encontrar dentro del repositorio de LangChain en https://github.com/benman1/generative_ai_with_langchain. Esto incluye un Dockerfile para Docker, un requirements.txt para Pip, un pyproject.toml para Poetry y un archivo langchain_ai.yml para Conda.

En nuestro artículo, utilizaremos Pip, el administrador de paquetes estándar para Python, para facilitar la instalación y el manejo de bibliotecas de terceros. Si no se incluye en tu distribución de Python, puedes instalar Pip siguiendo las instrucciones en https://pip.pypa.io/.

Para instalar una biblioteca con Pip, usa el comando pip install nombre_de_la_biblioteca.

Sin embargo, Pip no administra entornos por sí solo. Para manejar diferentes entornos, usamos la herramienta virtualenv.

En la siguiente sección, discutiremos las integraciones de modelos.

Paso 1: Configuración de Langchain

Primero, debes instalar el paquete Langchain. Estamos utilizando el sistema operativo Windows. Ejecuta el siguiente comando en tu terminal para instalarlo:


pip install langchain

Paso 2: Importación de Langchain y otros módulos necesarios

A continuación, importa Langchain junto con otros módulos necesarios. Aquí, también importamos la biblioteca transformers, que se utiliza ampliamente en tareas de NLP.


<p>import langchain
from transformers import AutoModelWithLMHead, AutoTokenizer

Paso 3: Carga del modelo preentrenado

Open AI

OpenAI modelos pueden ser convenientemente interfaz con la biblioteca LangChain o la biblioteca de cliente de Python de OpenAI. Notablemente, OpenAI proporciona una clase de incrustación para modelos de incrustación de texto. Dos modelos de LLM clave son GPT-3.5 y GPT-4, que difieren principalmente en la longitud del token. El precio para cada modelo se puede encontrar en el sitio web de OpenAI. Mientras que hay modelos más sofisticados como GPT-4-32K que tienen una aceptación de token más alta, su disponibilidad a través de la API no siempre está garantizada.

Acceder a estos modelos requiere una clave de API de OpenAI. Esto se puede hacer creando una cuenta en la plataforma de OpenAI, configurando la información de facturación y generando una nueva clave secreta.


<p>import os
os.environ["OPENAI_API_KEY"] = 'tu-token-de-openai'</p>

Después de crear la clave con éxito, puedes establecerla como una variable de entorno (OPENAI_API_KEY) o pasarla como parámetro durante la instanciación de la clase para las llamadas a OpenAI.

Considera un script de LangChain para mostrar la interacción con los modelos de OpenAI:

from langchain.llms import OpenAI
llm = OpenAI(model_name="text-davinci-003")
# El LLM toma un prompt como entrada y produce una respuesta
prompt = "¿quién es el presidente de los Estados Unidos de América?"
completion = llm(prompt)

<p>El presidente actual de los Estados Unidos de América es Joe Biden.</p>

En este ejemplo, se inicializa un agente para realizar cálculos. El agente toma una entrada, una tarea de suma simple, la procesa utilizando el modelo de OpenAI proporcionado y devuelve el resultado.

Hugging

Hugging Face es una biblioteca de Transformers de Python de código abierto, compatible con PyTorch, TensorFlow y JAX, e incluye implementaciones de modelos como BERT, T5, etc.

Hugging Face también ofrece el Hugging Face Hub, una plataforma para alojar repositorios de código, modelos de aprendizaje automático, conjuntos de datos y aplicaciones web.

Para utilizar Hugging Face como proveedor de tus modelos, necesitarás una cuenta y claves de API, que se pueden obtener desde su sitio web. El token se puede hacer disponible en tu entorno como HUGGINGFACEHUB_API_TOKEN.

Considera el siguiente fragmento de Python que utiliza un modelo de código abierto desarrollado por Google (GOOGL ), el modelo Flan-T5-XXL:

from langchain.llms import HuggingFaceHub

<p>llm = HuggingFaceHub(model_kwargs={"temperature": 0.5, "max_length": 64}, repo_id="google/flan-t5-xxl")
prompt = "¿En qué país se encuentra Tokio?"
completion = llm(prompt)
print(completion)</p>

Este script toma una pregunta como entrada y devuelve una respuesta, mostrando las capacidades de conocimiento y predicción del modelo.

Paso 4: Ingeniería de prompts básica

Para empezar, generaremos un prompt simple y veremos cómo responde el modelo.

prompt = 'Traduce el siguiente texto en inglés al francés: "{0}"'
input_text = 'Hola, ¿cómo estás?'
input_ids = tokenizer.encode(prompt.format(input_text), return_tensors='pt')

<p>generated_ids = model.generate(input_ids, max_length=100, temperature=0.9)
print(tokenizer.decode(generated_ids[0], skip_special_tokens=True))

En el código anterior, proporcionamos un prompt para traducir texto en inglés al francés. El modelo de lenguaje intenta traducir el texto dado según el prompt.

Paso 5: Ingeniería de prompts avanzada

Si bien el enfoque anterior funciona bien, no aprovecha completamente el poder de la ingeniería de prompts. Mejoremos esto introduciendo estructuras de prompts más complejas.

prompt = 'Como un traductor de francés altamente capacitado, traduce el siguiente texto en inglés al francés: "{0}"'
input_text = 'Hola, ¿cómo estás?'
input_ids = tokenizer.encode(prompt.format(input_text), return_tensors='pt')

<p>generated_ids = model.generate(input_ids, max_length=100, temperature=0.9)
print(tokenizer.decode(generated_ids[0], skip_special_tokens=True))

En este código, modificamos el prompt para sugerir que la traducción la realiza un ‘traductor de francés altamente capacitado’. El cambio en el prompt puede conducir a mejores traducciones, ya que el modelo ahora asume la personalidad de un experto.

Construyendo un sistema de preguntas y respuestas de literatura académica con Langchain

Construiremos un sistema de preguntas y respuestas de literatura académica utilizando LangChain que pueda responder preguntas sobre artículos académicos recientemente publicados.

Primero, para configurar nuestro entorno, instalamos las dependencias necesarias.

pip install langchain arxiv openai transformers faiss-cpu

Después de la instalación, creamos un nuevo cuaderno de Python e importamos las bibliotecas necesarias:

from langchain.llms import OpenAI
from langchain.chains.qa_with_sources import load_qa_with_sources_chain
from langchain.docstore.document import Document
import arxiv

El núcleo de nuestro sistema de preguntas y respuestas es la capacidad de recuperar artículos académicos relevantes relacionados con un campo determinado, aquí consideramos el Procesamiento de lenguaje natural (NLP), utilizando la base de datos académica arXiv. Para realizar esto, definimos una función get_arxiv_data(max_results=10). Esta función recopila los resúmenes de los artículos de NLP más recientes de arXiv y los encapsula en objetos de documento de LangChain, utilizando el resumen como contenido y el ID de entrada único como fuente.

Utilizaremos la API de arXiv para recuperar artículos recientes relacionados con NLP:


<p>def get_arxiv_data(max_results=10):
search = arxiv.Search(
query="NLP",
max_results=max_results,
sort_by=arxiv.SortCriterion.SubmittedDate,
)</p>

documents = []

<p>for result in search.results():
documents.append(Document(
page_content=result.summary,
metadata={"source": result.entry_id},
))</p>

return documents

Esta función recupera los resúmenes de los artículos de NLP más recientes de arXiv y los convierte en objetos de documento de LangChain. Estamos utilizando el resumen del artículo y su ID de entrada único (URL del artículo) como contenido y fuente, respectivamente.

def print_answer(question):
print(
chain(
{
"input_documents": sources,
"question": question,
},
return_only_outputs=True,
)["output_text"]
)

Definamos nuestro corpus y configuremos LangChain:

sources = get_arxiv_data(2)
chain = load_qa_with_sources_chain(OpenAI(temperature=0))

Con nuestro sistema de preguntas y respuestas académico listo, podemos probarlo haciendo una pregunta:

print_answer("¿Cuáles son los avances recientes en NLP?")

La salida será la respuesta a tu pregunta, citando las fuentes de las que se extrajo la información. Por ejemplo:


<p>Los avances recientes en NLP incluyen modelos de recuperación reforzada y un marco computacional novedoso para resolver problemas de flujo de potencia óptimo alternos (ACOPF) utilizando unidades de procesamiento gráfico (GPUs).
FUENTES: http://arxiv.org/abs/2307.16877v1, http://arxiv.org/abs/2307.16830v1

Puedes cambiar fácilmente de modelo o alterar el sistema según tus necesidades. Por ejemplo, aquí cambiamos a GPT-4, lo que nos da una respuesta mucho mejor y más detallada.

sources = get_arxiv_data(2)
chain = load_qa_with_sources_chain(OpenAI(model_name="gpt-4", temperature=0))

<p>Los avances recientes en Procesamiento de lenguaje natural (NLP) incluyen el desarrollo de modelos de recuperación reforzada para tareas de búsqueda de información como la respuesta a preguntas (QA). Estos modelos se pueden adaptar a varios dominios de información y tareas sin necesidad de un nuevo ajuste. Sin embargo, a menudo luchan por ceñirse al conocimiento proporcionado y pueden alucinar en sus respuestas. Otro avance es la introducción de un marco computacional para resolver problemas de flujo de potencia óptimo alternos (ACOPF) utilizando unidades de procesamiento gráfico (GPUs). Este enfoque utiliza una abstracción de datos único de programas no lineales (NLP) y emplea un método de punto interior con una estrategia de relajación de desigualdad. Esta estrategia permite la factorización de la matriz KKT sin pivoteo numérico, lo que anteriormente obstaculizó la paralelización del algoritmo IPM.
FUENTES: http://arxiv.org/abs/2307.16877v1, http://arxiv.org/abs/2307.16830v1

Un token en GPT-4 puede ser tan corto como un carácter o tan largo como una palabra. Por ejemplo, GPT-4-32K puede procesar hasta 32,000 tokens en una sola ejecución, mientras que GPT-4-8K y GPT-3.5-turbo admiten 8,000 y 4,000 tokens, respectivamente. Sin embargo, es importante tener en cuenta que cada interacción con estos modelos conlleva un costo que es directamente proporcional al número de tokens procesados, ya sea de entrada o de salida.

En el contexto de nuestro sistema de preguntas y respuestas, si un artículo académico supera el límite de tokens máximo, el sistema no podrá procesarlo en su totalidad, afectando así la calidad y la completitud de las respuestas. Para trabajar alrededor de este problema, el texto se puede dividir en partes más pequeñas que cumplan con el límite de tokens.

FAISS (Facebook AI Similarity Search) (META ) ayuda a encontrar rápidamente los fragmentos de texto más relevantes relacionados con la consulta del usuario. Crea una representación vectorial de cada fragmento de texto y utiliza estos vectores para identificar y recuperar los fragmentos más similares a la representación vectorial de una pregunta dada.

Es importante recordar que, incluso con el uso de herramientas como FAISS, la necesidad de dividir el texto en fragmentos más pequeños debido a las limitaciones de tokens puede llevar a la pérdida de contexto, afectando la calidad de las respuestas. Por lo tanto, la gestión y optimización cuidadosas del uso de tokens son cruciales al trabajar con estos grandes modelos de lenguaje.

pip install faiss-cpu langchain CharacterTextSplitter

Después de asegurarte de que las bibliotecas anteriores estén instaladas, ejecuta

from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores.faiss import FAISS
from langchain.text_splitter import CharacterTextSplitter
documents = get_arxiv_data(max_results=10) # Ahora podemos usar más datos
document_chunks = []
splitter = CharacterTextSplitter(separator=" ", chunk_size=1024, chunk_overlap=0)
for document in documents:
for chunk in splitter.split_text(document.page_content):
document_chunks.append(Document(page_content=chunk, metadata=document.metadata))

<p>search_index = FAISS.from_documents(document_chunks, OpenAIEmbeddings())</p>

<p>chain = load_qa_with_sources_chain(OpenAI(temperature=0))</p>

<p>def print_answer(question):
print(
chain(
{
"input_documents": search_index.similarity_search(question, k=4),
"question": question,
},
return_only_outputs=True,
)["output_text"]
)

Con el código completo, ahora tenemos una herramienta poderosa para consultar la literatura académica más reciente en el campo de NLP.

Los avances recientes en NLP incluyen el uso de redes neuronales profundas (DNN) para el análisis automático de texto y tareas de NLP como la detección de lenguaje, extracción de entidades, detección de autor y respuesta a preguntas, entre otras.
FUENTES: http://arxiv.org/abs/2307.10652v1, http://arxiv.org/abs/2307.07002v1, http://arxiv.org/abs/2307.12114v1, http://arxiv.org/abs/2307.16217v1

Conclusión

La integración de grandes modelos de lenguaje (LLM) en aplicaciones ha acelerado la adopción en varios dominios, incluyendo la traducción de lenguaje, el análisis de sentimiento y la recuperación de información. La ingeniería de prompts es una herramienta poderosa para maximizar el potencial de estos modelos, y Langchain está liderando el camino en la simplificación de esta tarea compleja. Su interfaz estandarizada, plantillas de prompts flexibles, integración de modelos robusta y el uso innovador de agentes y cadenas garantizan resultados óptimos para el rendimiento de los LLM.

Sin embargo, a pesar de estos avances, hay algunos consejos que debes tener en cuenta. Al utilizar Langchain, es esencial comprender que la calidad de la salida depende en gran medida de la redacción del prompt. Experimentar con diferentes estilos y estructuras de prompts puede conducir a mejores resultados. También recuerda que, aunque Langchain admite una variedad de modelos de lenguaje, cada uno tiene sus fortalezas y debilidades. Elegir el adecuado para tu tarea específica es crucial. Finalmente, es importante recordar que el uso de estos modelos conlleva consideraciones de costo, ya que el procesamiento de tokens afecta directamente el costo de las interacciones.

Como se demostró en la guía paso a paso, Langchain puede impulsar aplicaciones robustas, como el sistema de preguntas y respuestas de literatura académica. Con una creciente comunidad de usuarios y una creciente prominencia en el paisaje de código abierto, Langchain promete ser una herramienta fundamental en la explotación del potencial completo de los LLM como GPT-4.

interacciones. Como se demostró en la guía paso a paso, Langchain puede impulsar aplicaciones robustas, como el sistema de preguntas y respuestas de literatura académica. Con una creciente comunidad de usuarios y una creciente prominencia en el paisaje de código abierto, Langchain promete ser una herramienta fundamental en la explotación del potencial completo de los LLM como GPT-4.

He dedicado los últimos cinco años sumergiéndome en el fascinante mundo de Machine Learning y Deep Learning. Mi pasión y experiencia me han llevado a contribuir a más de 50 proyectos de ingeniería de software diversos, con un enfoque particular en AI/ML. Mi curiosidad en curso también me ha llevado hacia el Procesamiento de Lenguaje Natural, un campo que estoy ansioso por explorar más a fondo.