Introducci贸n a LangChain

1

Desarrollo de aplicaciones con LLM utilizando LangChain

2

Estructura y m贸dulos de LangChain

3

Uso de modelos Open Source de Hugging Face

4

Uso de modelos de OpenAI API

5

Prompt templates de LangChain

6

Cadenas en LangChain

7

Utility chains

8

RetrievalQA chain

9

Foundational chains

Quiz: Introducci贸n a LangChain

Casos de uso de LangChain

10

Casos de uso de LangChain

11

驴C贸mo utilizar LangChain en mi equipo?

Quiz: Casos de uso de LangChain

Manejo de documentos con 铆ndices

12

驴C贸mo manejar documentos con 铆ndices en LangChain?

13

La clase Document

14

Document Loaders: PDF

15

Document Loaders: CSV con Pandas DataFrames

16

Document Loaders: JSONL

17

Document Transformers: TextSplitters

18

Proyecto de Chatbot: configuraci贸n de entorno para LangChain y obtenci贸n de datos

19

Proyecto de Chatbot: creaci贸n de documents de Hugging Face

Quiz: Manejo de documentos con 铆ndices

Embeddings y bases de datos vectoriales

20

Uso de embeddings y bases de datos vectoriales con LangChain

21

驴C贸mo usar embeddings de OpenAI en LangChain?

22

驴C贸mo usar embeddings de Hugging Face en LangChaing?

23

Chroma vector store en LangChain

24

Proyecto de Chatbot: ingesta de documents en Chroma

25

RetrievalQA: cadena para preguntar

26

Proyecto de Chatbot: cadena de conversaci贸n

27

Proyecto de Chatbot: RetrievalQA chain

Quiz: Embeddings y bases de datos vectoriales

Chats y memoria con LangChain

28

驴Para qu茅 sirve la memoria en cadenas y chats?

29

Uso de modelos de chat con LangChain

30

Chat prompt templates

31

ConversationBufferMemory

32

ConversationBufferWindowMemory

33

ConversationSummaryMemory

34

ConversationSummaryBufferMemory

35

Entity memory

36

Proyecto de Chatbot: chat history con ConversationalRetrievalChain

Quiz: Chats y memoria con LangChain

Evoluci贸n del uso de LLM

37

LangChain y LLM en evoluci贸n constante

No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Adquiere por un a帽o todos los cursos, escuelas y certificados por un precio especial.

Antes: $249

Currency
$219/a帽o

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Comprar ahora

Termina en:

0D
17H
15M
45S

Foundational chains

9/37
Recursos

Aportes 6

Preguntas 0

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Hola Este es mi aporte

Agregu茅 solo la parte de la nueva cadena que resume y la definici贸n de la cadena sequencial


## Plantilla para la cadena de resumen
## Decid铆 incluirle de nuevo el estilo para que mantenga la forma de hablar para generar el resumen

plantilla_resumen = """Resumir texto:

{texto_final}

En el estilo de una persona informal de {estilo}

resumen:
"""

# Definici贸n del template con sus variables de entrada {texto_final} que viene de la cadena anterior de parafraseo
prompt_resumen = PromptTemplate(
    template= plantilla_resumen,
    input_variables= ["texto_final","estilo"]
)

## Instancia de la cadena que resumne
cadena_que_resume = LLMChain(
    llm=llm_gpt3_5,
    prompt=prompt_resumen,
    output_key='texto_resumido'
)

from langchain.chains import SequentialChain

# Cadena secuencial agregando la cadena que resume
cadena_secuencial = SequentialChain(
    chains=[cadena_que_limpia, cadena_que_cambia_estilo,cadena_que_resume],
    input_variables=["texto", "estilo"],
    output_variables=["texto_resumido"]
)

Me di贸 mucha pereza escribir el texto, as铆 que le ped铆 al gpt-35-turbo que lo creara por mi especificando que quer铆a urls y emojis para probar que funcionara la cadena de transformaci贸n:

Me cost贸 un poco porque a este punto cre铆 que deb铆a usar una cadena de transformaci贸n, pero realmente requerimos usar un LLMChain con un nuevo template.

Antes de todo, cambi茅 el output de la chain de estilo a 鈥渢o_sum_text鈥 y cre茅 el template y el PromptTemplate.

summary_template = """Resume este texto lo m谩s posible:

{to_sum_text}

Resumiendo: 
"""

prompt_summary = PromptTemplate(
    input_variables=["to_sum_text"],
    template=summary_template
)

luego cre茅 la LLMChain con este nuevo prompt

summarize_chain = LLMChain(
    llm = llm_gpt_3_5,
    prompt=prompt_summary,
    output_key="final_text"
)

Y lo a帽ad铆 a la cadena secuencial.

sequential_chain = SequentialChain(
    chains=[cleaning_chain, style_changer_chain, summarize_chain],
    input_variables =  ["text", "style"],
    output_variables = ["final_text"],
)

Al final redujo todo el entry a esto:

'final_text': 'Monterrey es una ciudad incre铆ble, famosa por sus monta帽as imponentes, su cultura norte帽a y su Museo de Arte Contempor谩neo. Tambi茅n es conocida por los partidos de f煤tbol de los Rayados y los Tigres. 隆Monterrey te espera con los brazos abiertos!'

Notemos que el prompt final se deshizo de los espacios extra帽os que hab铆a generado el cleaner, por lo que indirectamente aplic贸 otra capa de limpieza.

Cumpliendo el reto

Invert铆 el orden, primero limpia, luego resume y finalmente cambia el estilo.

cadena_que_limpia = TransformChain(
	input_variables=["texto"],
	output_variables=["texto_limpio"],
	transform=fn_limpiar_texto
)

############################################
# Cadena que resume
summarize_prompt = """Resumir el siente texto:
{texto_limpio}
Resumen:"""

summarize_chain = LLMChain(
	llm=llm_gpt3_5,
	prompt=PromptTemplate(
      input_variables=["texto_limpio"],
      template=summarize_prompt
      ),
	output_key="summary"
)

############################################
# Cadena que cambia de estilo
from langchain.chains import LLMChain
from langchain import PromptTemplate

plantilla = """Parafrasea este texto:
{summary}
En el estilo de una persona informal de {estilo}.
Parafraseado: """

prompt = PromptTemplate(
	input_variables=["summary","estilo"],
	template=plantilla
)

cadena_que_cambia_estilo = LLMChain(
	llm = llm_gpt3_5,
	prompt=prompt,
	output_key="texto_final"
)

# Cadena secuencial
from langchain.chains import SequentialChain

cadena_secuencial = SequentialChain(
	chains = [cadena_que_limpia, summarize_chain, cadena_que_cambia_estilo],
	input_variables=["texto", "estilo"],
	output_variables=["texto_final"]
)

El texto de entrada:

texto_entrada = """
Osaka es una ciudad vibrante y llena de vida en Jap贸n 馃彲馃尭. Con su combinaci贸n 
煤nica de tradici贸n y modernidad, Osaka cautiva a sus visitantes. Puedes explorar 
el imponente castillo de Osaka, un verdadero s铆mbolo hist贸rico de la regi贸n 馃彴馃尦. 
Adem谩s, la deliciosa comida callejera en el distrito de Dotonbori te dejar谩 con el 
est贸mago lleno y una sonrisa en el rostro 馃構馃崳.

La gente en Osaka es conocida por su amabilidad y hospitalidad, lo que hace que los 
viajeros se sientan bienvenidos desde el momento en que llegan 鉁煈. Si eres un 
amante de las compras, la avenida Midosuji es el lugar perfecto para satisfacer tus 
deseos de compras y moda 馃憲馃泹锔.

Para obtener m谩s informaci贸n sobre los lugares para visitar en Osaka, puedes 
consultar el sitio web oficial de turismo: https://www.osaka-info.jp/en/ 馃寪馃摬. No puedes perderte la oportunidad de experimentar la energ铆a 煤nica y la cultura 
emocionante de Osaka!
"""

cadena_secuencial(
	{'texto': texto_entrada,
	 'estilo': 'Chile'}
)

El resultado:

 'texto_final': 'Osaka es una ciudad bac谩n y llena de vida en Jap贸n, que mezcla la onda tradicional con la modernidad. Su castillo gigante y la comida rica en la calle en el barrio de Dotonbori son un must. La buena onda de la gente y la avenida Midosuji para ir de shopping son bien destacables. No te pod铆s perder la oportunidad de vivir la energ铆a y cultura emocionante de Osaka.'}

En esta clase veremos como funcionan las cadenas Foundatinoal y como podemos unir varias de ellas para llevar procesos
m谩s complejos a trav茅s de cadenas secuenciales SequentialChain.

Primero, vamos a construir una funci贸n personalizada para limpiar nuestros textos de URLs y emojis. Luego, utilizaremos esta funci贸n para crear una cadena en la que introduciremos nuestro texto y esperamos obtener un texto limpio como salida.

Debemos tener en cuenta que la funci贸n que hemos creado recibe como entrada un diccionario. En este diccionario, vamos a indicar los elementos que ser谩n procesados por la cadena que estamos creando. El resultado que obtendremos de la cadena ser谩 el texto limpio.

Esto es el principio fundamental de las cadenas fundacionales, nos proporcionan un marco para llevar a cabo una serie de transformaciones de manera ordenada y estructurada.

Partimos de los antecedentes que ya conocemos:

# Antecedentes 1: Cargar el API KEY de OpenAI como una variable de sistema.
import os
from dotenv import load_dotenv

load_dotenv("../secret/keys.env")
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
os.environ['OPENAI_API_KEY'] = OPENAI_API_KEY

# Antecedentes 2: Instanciar dos LLMs de OpenAI un GPT3.5 y un Davinci
from langchain.llms import OpenAI

llm_gpt3_5 = OpenAI(
    model_name="gpt-3.5-turbo",
    n=1,
    temperature=0.3
)

Vamos a empezar creando una funci贸n de limpieza de datos. La misma es una funci贸n que recibe un diccionario con una llave texto
que contiene el texto a limpiar y devuelve otro diccionario con la llave texto_limpio, el texto ya normalizado.

def limpiar_texto(entradas: dict) -> dict:
    texto = entradas["texto"]

    # Eliminamos los emojis utilizando un amplio rango unicode
    # Ten en cuenta que esto podr铆a potencialmente eliminar algunos caracteres v谩lidos que no son en ingl茅s
    patron_emoji = re.compile(
        "["
        "\U0001F600-\U0001F64F"  # emoticonos
        "\U0001F300-\U0001F5FF"  # s铆mbolos y pictogramas
        "\U0001F680-\U0001F6FF"  # s铆mbolos de transporte y mapas
        "\U0001F1E0-\U0001F1FF"  # banderas (iOS)
        "\U00002702-\U000027B0"
        "\U000024C2-\U0001F251"
        "]+", flags=re.UNICODE,
    )
    texto = patron_emoji.sub(r'', texto)

    # Removemos las URLs
    patron_url = re.compile(r'https?://\S+|www\.\S+')
    texto = patron_url.sub(r'', texto)

    return {"texto_limpio": texto}

Con base en esta funci贸n de python podemos crear nuestro primer bloque de Cadena utilizando TransformChain:

from langchain.chains import TransformChain

cadena_que_limpia = TransformChain(
    input_variables=["texto"],
    output_variables=["texto_limpio"],
    transform=limpiar_texto
)

clean = cadena_que_limpia.run('Chequen est谩 p谩gina https://twitter.com/home 馃檲')
print(clean)

Respuesta esperada:

Chequen est谩 p谩gina  

Ahora vamos a crear un par de cadenas m谩s y finalmente las vamos a unir todas para un flujo de informaci贸n completa.
Empecemos con una cadena de parafraseo de texto:

from langchain import PromptTemplate
from langchain.chains import LLMChain

# Empezamos creando nuestro prompt template que recibe como par谩metro un 'texto_limpio' (salida de de la cadena de limpieza)
# y lo parafrasea con un estilo informa de una persona (estilo).
plantilla_parafrasea = """Parafrasea este texto:

{texto_limpio}

En el estilo de una persona informal de {estilo}.

Parafraseado: """

# Dado que nuestro Template tiene 2 variables, debemos indicarlas en el par谩metro `input_variables
prompt_parafraseo = PromptTemplate(
    input_variables=["texto_limpio", "estilo"],
    template=plantilla_parafrasea 
)

# Ahora solo falta crear la cadena que cambia estilo utilizando como LLM a GPT3.5, esta cadena terminar谩 creando una variable
# a la salida llamada `texto_final`
cadena_que_cambia_estilo = LLMChain(
    llm=llm_gpt3_5,
    prompt=prompt_parafraseo,
    output_key='texto_final'
)

Ahora siguiendo la misma estructura l贸gica, vamos a crear una nueva Chain que se encargue de parafrasear un texto de entrada:

# Texto_final es la variable de entrada, puesto que as铆 la definimos en la cadena de parafraseo
plantilla_resumen = """Resume este texto:

{texto_final}

Resumen: """

prompt_resumen = PromptTemplate(
    input_variables=["texto_final"],
    template=plantilla_resumen
)

# Texto resumido ser谩 la variable final con la que termina nuestra secuencia de cadenas
cadena_que_resume = LLMChain(
    llm=llm_gpt3_5,
    prompt=prompt_resumen,
    output_key="texto_resumido"
)

Finalmente, para concluir vamos a unir todas nuestras cadenas entre ellas utilizando SequentialChain:

from langchain.chains import SequentialChain

cadena_secuencial = SequentialChain(
    chains=[cadena_que_limpia, cadena_que_cambia_estilo, cadena_que_resume],
    input_variables=["texto", "estilo"],
    output_variables=["texto_resumido"]
)

Nota:
Esta estructura de pensamiento es MUY similar a como PyTorch Organiza las capas de un modelo de DL.

Probemos entonces nuestra SequentialChain:

texto_entrada = """
隆Monterrey es una ciudad impresionante! 馃彊锔
Es conocida por su impresionante paisaje de monta帽as 鉀帮笍 y su vibrante cultura norte帽a.
隆No olvides visitar el famoso Museo de Arte Contempor谩neo (MARCO)!
馃柤锔 Si eres fan谩tico del f煤tbol, no puedes perderte un partido de los Rayados o de los Tigres. 鈿
Aqu铆 te dejo algunos enlaces para que puedas conocer m谩s sobre esta maravillosa ciudad:
https://visitamonterrey.com, https://museomarco.org, https://rayados.com, https://www.tigres.com.mx.
隆Monterrey te espera con los brazos abiertos! 馃槂馃嚥馃嚱

Monterrey es la capital y ciudad m谩s poblada del estado mexicano de Nuevo Le贸n, adem谩s de la cabecera del 
municipio del mismo nombre. Se encuentra en las faldas de la Sierra Madre Oriental en la regi贸n noreste de 
M茅xico. La ciudad cuenta seg煤n datos del XIV Censo de Poblaci贸n y Vivienda del Instituto Nacional de 
Estad铆stica y Geograf铆a de M茅xico (INEGI) en 2020 con una poblaci贸n de 3 142 952 habitantes, por lo cual 
de manera individual es la 9.陋 ciudad m谩s poblada de M茅xico, mientras que la zona metropolitana de Monterrey 
cuenta con una poblaci贸n de 5 341 175 habitantes, la cual la convierte en la 2.陋 谩rea metropolitana m谩s 
poblada de M茅xico, solo detr谩s de la Ciudad de M茅xico.8鈥

La ciudad fue fundada el 20 de septiembre de 1596 por Diego de Montemayor y nombrada as铆 en honor al castillo 
de Monterrey en Espa帽a. Considerada hoy en d铆a una ciudad global, es el segundo centro de negocios y finanzas 
del pa铆s, as铆 como una de sus ciudades m谩s desarrolladas, cosmopolitas y competitivas. Sirve como el 
epicentro industrial, comercial y econ贸mico para el Norte de M茅xico.9鈥 Seg煤n un estudio de Mercer Human 
Resource Consulting, en 2019, fue la ciudad con mejor calidad de vida en M茅xico y la 113.陋 en el mundo.10鈥 
La ciudad de Monterrey alberga en su zona metropolitana la ciudad de San Pedro Garza Garc铆a, la cual es el 
谩rea con m谩s riqueza en M茅xico y Am茅rica Latina.11鈥
"""

ans = cadena_secuencial({'texto': texto_entrada, 'estilo': 'ciudad de m茅xico'})
print(ans)

Respuesta esperada:

{'texto': 

'\n隆Monterrey es una ciudad impresionante! 馃彊锔廫nEs conocida por su impresionante paisaje de monta帽as 鉀帮笍 y su vibrante 
cultura norte帽a.\nNo olvides visitar el famoso Museo de Arte Contempor谩neo (MARCO)!\n馃柤锔 Si eres fan谩tico del f煤tbol, no 
puedes perderte un partido de los Rayados o de los Tigres. 鈿絓nAqu铆 te dejo algunos enlaces para que puedas conocer m谩s 
sobre esta maravillosa ciudad:\nhttps://visitamonterrey.com, https://museomarco.org, https://rayados.com, https://www.tigres.com.mx.
隆Monterrey te espera con los brazos abiertos! 馃槂馃嚥馃嚱\n\nMonterrey es la capital y ciudad m谩s poblada del estado mexicano de 
Nuevo Le贸n, adem谩s de la cabecera del \nmunicipio del mismo nombre. Se encuentra en las faldas de la Sierra Madre Oriental en 
la regi贸n noreste de \nM茅xico. La ciudad cuenta seg煤n datos del XIV Censo de Poblaci贸n y Vivienda del Instituto Nacional de 
\nEstad铆stica y Geograf铆a de M茅xico (INEGI) en 2020 con una poblaci贸n de 3 142 952 habitantes, por lo cual \nde manera 
individual es la 9.陋 ciudad m谩s poblada de M茅xico, mientras que la zona metropolitana de Monterrey \ncuenta con una poblaci贸n 
de 5 341 175 habitantes, la cual la convierte en la 2.陋 谩rea metropolitana m谩s \npoblada de M茅xico, solo detr谩s de la Ciudad 
de M茅xico.8\u200b\n\nLa ciudad fue fundada el 20 de septiembre de 1596 por Diego de Montemayor y nombrada asen honor al 
castillo \nde Monterrey en Espa帽a. Considerada hoy en d铆a una ciudad global, es el segundo centro de negocios y finanzas 
\ndel pa铆s, as铆 como una de sus ciudades m谩s desarrolladas, cosmopolitas y competitivas. Sirve como el \nepicentro industrial, 
comercial y econ贸mico para el Norte de M茅xico.9\u200b Seg煤n un estudio de Mercer Human \nResource Consulting, en 2019, fue 
la ciudad con mejor calidad de vida en M茅xico y la 113.陋 en el mundo.10\u200b \nLa ciudad de Monterrey alberga en su zona 
metropolitana la ciudad de San Pedro Garza Garc铆a, la cual es el \n谩rea con m谩s riqueza en M茅xico y Am茅rica Latina.11\u200b\n', 

'estilo': 
'ciudad de m茅xico', 

'texto_resumido': '
Monterrey es una ciudad incre铆blemente hermosa y llena de vida, famosa por sus monta帽as y su cultura norte帽a. Es conocida 
por su Museo de Arte Contempor谩neo y por los equipos de f煤tbol Rayados y Tigres. Es la capital y la ciudad m谩s grande del 
estado de Nuevo Le贸n, con una poblaci贸n de m谩s de 3 millones de habitantes. Es considerada una ciudad global y un importante 
centro de negocios y finanzas en M茅xico. Tambi茅n es una de las ciudades m谩s desarrolladas y con mejor calidad de vida en 
el pa铆s. En resumen, Monterrey es una ciudad impresionante y llena de oportunidades.'}

Excelente, hemos podido aprender como unir varias cadenas entre ellas para crear un flujo de informaci贸n efectivo a trav茅s
de SequentialChains

Tambi茅n dejo el input final.

entry = """
隆Monterrey es una ciudad impresionante!馃彊锔
Es conocida por su impresionante paisaje de monta帽as鉀帮笍 y su vibrante cultura norte帽a.
隆No olvides visitar el famoso Museo de Arte Contempor谩neo (MARCO)!
馃柤锔廠i eres fan谩tico del f煤tbol, no puedes perderte un partido de los Rayados o de los Tigres鈿
Aqu铆 te dejo algunos enlaces para que puedas conocer m谩s sobre esta maravillosa ciudad:
https://visitamonterrey.com, https://museomarco.org, https://rayados.com, https://www.tigres.com.mx.
隆Monterrey te espera con los brazos abiertos! 馃槂馃嚥馃嚱
"""

Dejo por aqu铆 el patr贸n de emojis por si alguien no lo quiere transcribir o tomar del notebook.

emoji_pattern = re.compile(
      "["
      "\U0001F600-\U0001F64F" #emotes
      "\U0001F300-\U0001F5FF" #symbols and pictograms
      "\U0001F680-\U0001F6FF" #transport and map symbols
      "\U0001F1E0-\U0001F1FF" #flags (on iOS)
      "\U00002702-\U000027B0"
      "\U000024C2-\U0001F251"
      "]+", flags=re.UNICODE
  )