Trabaje con sus datos en tiempo real usando Langchain
Tags: aws, llm, machinelearning, python
Published: 2023-10-06 23:14:19

🇻🇪🇨🇱 [Dev.to](https://dev.to/elizabethfuentes12) [Linkedin](https://www.linkedin.com/in/lizfue/) [GitHub](https://github.com/elizabethfuentes12/) [Twitter](https://twitter.com/elizabethfue12) [Instagram](https://www.instagram.com/elifue.tech) [Youtube](https://www.youtube.com/channel/UCr0Gnc-t30m4xyrvsQpNp2Q)
[Linktr](https://linktr.ee/elizabethfuentesleone)

> ✅ **Blog original:** [Working With Your Live Data Using LangChain](https://community.aws/posts/working-with-your-live-data-using-langchain)

Cuando se crean aplicaciones que aprovechan large language models (LLM), proporcionar el contexto completo de la conversación en cada mensaje es crucial para la coherencia y el diálogo natural. En lugar de tratar cada entrada del usuario como una pregunta aislada (figura 1), el modelo debe entender cómo encaja en la conversación en evolución.


![Architecture](https://community.aws/_next/image?url=https%3A%2F%2Fcommunity.aws%2Fraw-post-images%2Fposts%2Fworking-with-your-live-data-using-langchain%2Fimages%2Ffig_01.png&w=1920&q=75)

Almacenar cada nueva entrada y respuesta en el mensaje (figura 2) lo hace más grande y requiere más memoria y procesamiento. Si no se optimiza el almacenamiento del historial de los diálogos utilizando las técnicas adecuadas para equilibrar el rendimiento y la interacción natural, los recursos se estancarían rápidamente.


![Architecture](https://community.aws/_next/image?url=https%3A%2F%2Fcommunity.aws%2Fraw-post-images%2Fposts%2Fworking-with-your-live-data-using-langchain%2Fimages%2Ffig_02.png&w=1920&q=75)

En este blog, te mostraré cómo utilizar técnicas para proporcionar de manera eficiente el contexto de la conversación con LLM empleando [LangChain] (https://www.langchain.com/) a fin de crear un agente conversacional que pueda entablar un diálogo natural y mantener el contexto de la conversación añadiendo cada respuesta generada al mensaje para informar la siguiente respuesta. Esto nos permite mantener conversaciones prolongadas y coherentes con el agente a lo largo de varios turnos. Al final, tendrás la habilidad de crear tu propia aplicación conversacional basada en los últimos avances de la IA generativa.

## Empecemos!

### 1 - Instala la librería de [LangChain](https://www.langchain.com/)

```bash
pip install langchain
```

Una vez instalado, puede incluir [todos estos módulos] (https://python.langchain.com/docs/get_started) en tu aplicación.

### 2 - Crea la invocación al LLM

La invocación se realiza mediante [Amazon Bedrock] (https://docs.aws.amazon.com/bedrock/latest/userguide/what-is-service.html?sc_channel=el&sc_campaign=genaiwave&sc_content=working-with-your-live-data-using-langchain&sc_geo=mult&sc_country=mult&sc_outcome=acq), un servicio totalmente gestionado que permite acceder a los modelos base de Amazon y de proveedores de modelos de terceros a través de una API.

El modelo [Anthropic Claude V2 100K](https://www.anthropic.com/index/claude-2) es usado en este ejemplo.

Para utilizar las capacidades de Amazon Bedrock con LangChain importa:

```python
from langchain.llms.bedrock import Bedrock
```

Luego crea el cliente de Amazon Bedrock Runtime:

```python
bedrock_client = boto3.client(
    service_name='bedrock-runtime'
)
```

> 📚**Note:** Aprende mas sobre Amazon Bedrock y LangChain [here](https://python.langchain.com/docs/integrations/llms/bedrock), y del cliente Amazon Bedrock [here](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/bedrock-runtime.html) and [here](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/bedrock.html?sc_channel=el&sc_campaign=genaiwave&sc_content=working-with-your-live-data-using-langchain&sc_geo=mult&sc_country=mult&sc_outcome=acq).

Una [Chain](https://python.langchain.com/docs/modules/chains/), herramienta para llamar a los componentes de la aplicación, es necesaria para generar una conversación con el modelo, configurar `verbose = True` para realizar la depuración y ver los estados internos de la Chain:  

```python
from langchain.chains import ConversationChain
model_parameter = {"temperature": 0.0, "top_p": .5, "max_tokens_to_sample": 2000} #parameters define
llm = Bedrock(model_id="anthropic.claude-v2", model_kwargs=model_parameter,client=bedrock_client) #model define
conversation = ConversationChain(
    llm=llm, verbose=True
)
```

Prueba la Chain con estas lineas:

```python
conversation.predict(input="Hello world!")
```

![Amazon Bedrock Chain](https://community.aws/_next/image?url=https%3A%2F%2Fcommunity.aws%2Fraw-post-images%2Fposts%2Fworking-with-your-live-data-using-langchain%2Fimages%2Fgif_02.gif&w=1920&q=75)

Adicionalmente, puedes invocar la API de Amazon Bedrock API con [Invoke Model API](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/bedrock-runtime/client/invoke_model.html?sc_channel=el&sc_campaign=genaiwave&sc_content=working-with-your-live-data-using-langchain&sc_geo=mult&sc_country=mult&sc_outcome=acq):

```python
prompt = "Hello world!"
kwargs = {
  "modelId": "ai21.j2-ultra-v1",
  "contentType": "application/json",
  "accept": "*/*",
  "body": "{\"prompt\":\"Human:"+ prompt +"\\nAssistant:\",\"maxTokens\":200,\"temperature\":0.7,\"topP\":1,\"stopSequences\":[],\"countPenalty\":{\"scale\":0},\"presencePenalty\":{\"scale\":0},\"frequencyPenalty\":{\"scale\":0}}"
}
response = bedrock_client.invoke_model(**kwargs)
response_body = json.loads(response.get("body").read())
completetion = response_body.get("completions")[0].get("data").get("text")
completetion
```

![Amazon Bedrock invoke model](https://community.aws/_next/image?url=https%3A%2F%2Fcommunity.aws%2Fraw-post-images%2Fposts%2Fworking-with-your-live-data-using-langchain%2Fimages%2Fgif_01.gif&w=1920&q=75)

### 3 - Add Chat Memory To The Chain

Hay diferentes tipos de memoria en [LangChain] (https://python.langchain.com/docs/modules/memory/types/), pero en este blog vamos a revisar lo siguiente:

#### 3.1 ConversationBufferMemory

El uso de esta memoria permite almacenar todos los mensajes de la conversación.

```python
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory(return_messages=True)
```

#### 3.2 ConversationBufferWindowMemory

Limita el tamaño del historial de diálogos a las K interacciones más recientes. Las interacciones más antiguas se descartan a medida que se añaden nuevas para mantener el tamaño fijo en K.

```python
from langchain.memory import ConversationBufferWindowMemory
memory = ConversationBufferMemory(k=1,return_messages=True)
```

#### 3.3 ConversationSummaryMemory

Utiliza un modelo LLM para crear un resumen de la conversación, útil para conversaciones extensas.

```python
from langchain.memory import ConversationSummaryMemory
memory = ConversationSummaryMemory(llm=llm,return_messages=True)
```

#### 3.4 ConversationSummaryBufferMemory

Usa tanto el búfer como el resumen, almacena las conversaciones recientes completas en un búfer y también recopila las conversaciones más antiguas en un resumen.

```python
from langchain.memory import ConversationSummaryBufferMemory
memory = ConversationSummaryBufferMemory(llm=llm, max_token_limit=10,return_messages=True)
```

#### 3.5 ConversationTokenBufferMemory

Mantiene un búfer de las interacciones recientes en la memoria y utiliza la longitud del token en lugar del número de interacciones para determinar cuándo vaciar las interacciones.

```python
from langchain.memory import ConversationTokenBufferMemory
memory = ConversationTokenBufferMemory(llm=llm, max_token_limit=10,return_messages=True)
```

> 📚**Note:** In all types of memory belong the parameter return_messages=True is present, this to get the history as a list of messages

### 4 - Try it!

Para probar las diferentes configuraciones de memoria, agréguelas como parámetro en la cadena.

```python

#add the memory to the Chain
conversation = ConversationChain(
    llm=llm, verbose=True, memory=memory
)
```

Prueba la Chain:

```python
conversation.predict(input="Hi, my name is Elizabeth!")
conversation.predict(input="what's up?")
conversation.predict(input="cool, What is my name?")

memory.load_memory_variables({}) #To print the memory
```

En el siguiente gif puedes ver un ejemplo de ConversationBufferMemory.

![ConversationBufferMemory](https://community.aws/_next/image?url=https%3A%2F%2Fcommunity.aws%2Fraw-post-images%2Fposts%2Fworking-with-your-live-data-using-langchain%2Fimages%2Fgif_03.gif&w=1920&q=75)

Pruebe los diferentes tipos de memoria y compruebe la diferencia.

### 5 - Guarda la memoria de la conversación en una tabla de Amazon DynamoDB

Para eso emplea la integración de LangChain [module](https://python.langchain.com/docs/integrations/memory/aws_dynamodb?sc_channel=el&sc_campaign=genaiwave&sc_content=working-with-your-live-data-using-langchain&sc_geo=mult&sc_country=mult&sc_outcome=acq) con [Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html?sc_channel=el&sc_campaign=genaiwave&sc_content=working-with-your-live-data-using-langchain&sc_geo=mult&sc_country=mult&sc_outcome=acq)

Siguiendo las instrucciones de la documentación de LangChain:

- Crea la tabla de Amazon DynamoDB:

```python
# Get the service resource.
dynamodb = boto3.resource("dynamodb")

# Create the DynamoDB table.
table = dynamodb.create_table(
    TableName="SessionTable",
    KeySchema=[{"AttributeName": "SessionId", "KeyType": "HASH"}],
    AttributeDefinitions=[{"AttributeName": "SessionId", "AttributeType": "S"}],
    BillingMode="PAY_PER_REQUEST",
)
```

- Agrega la Moria a la Chain:

```python
from langchain.memory.chat_message_histories import DynamoDBChatMessageHistory
message_history = DynamoDBChatMessageHistory(table_name="SessionTable", session_id="1")
memory = ConversationBufferMemory(
    memory_key="history", chat_memory=message_history, return_messages=True,ai_prefix="A",human_prefix="H"
)
#add the memory to the Chain
conversation = ConversationChain(
    llm=llm, verbose=True, memory=memory
)
```

- Pruébalo!

```python
conversation.predict(input="Hi, my name is Elizabeth!")
conversation.predict(input="what's up?")
conversation.predict(input="cool, What is my name?")

# Print the memory
memory.load_memory_variables({}) 

# Print item count
print(table.item_count)
```

Un registro nuevo en la tabla de DynamoDB:

![Architecture](https://community.aws/_next/image?url=https%3A%2F%2Fcommunity.aws%2Fraw-post-images%2Fposts%2Fworking-with-your-live-data-using-langchain%2Fimages%2Ffig_03.png&w=1920&q=75)

## Conclusiones

Gracias por acompañarme en este viaje, donde adquiriste las habilidades necesarias para mantener una conversación coherente con los LLMs y entablar un diálogo natural mediante el módulo de memoria [LangChain] (https://www.langchain.com/), empleaste la API de Amazon Bedrock para invocar modelos de LLM y almacenar la memoria: historial de conversaciones, en un Amazon DynamoDB.

Algunos enlaces para que pueda seguir aprendiendo y desarrollando:

- [Integrating Foundation Models into Your Code with Amazon Bedrock](https://www.youtube.com/watch?v=ab1mbj0acDo)

- [Amazon Bedrock Workshop](https://github.com/aws-samples/amazon-bedrock-workshop)

- [AWS Kendra LangChain Extensions](https://github.com/aws-samples/amazon-kendra-langchain-extensions/tree/main)

- [Prompt Engineering Techniques](https://www.promptingguide.ai/techniques)

- [Learn the fundamentals of generative AI for real-world applications](https://www.deeplearning.ai/courses/generative-ai-with-llms/)

- [LangChain for LLM Application Development](https://www.deeplearning.ai/short-courses/langchain-for-llm-application-development/)