DEV Community

Cover image for Automate IT Operations with Nylas and Amazon Bedrock
Davidđź’»
Davidđź’» Subscriber

Posted on

Automate IT Operations with Nylas and Amazon Bedrock

This article explores how IT operations can leverage Nylas APIs, AWS Lambda, and Amazon Bedrock to automate repetitive tasks and manage brief requirement queries efficiently. By integrating a Knowledge Base with Retrieval-Augmented Generation (RAG), the solution enables quick and accurate responses to common operational requests, streamlining processes and improving SLA compliance. This approach reduces onboarding time for new staff, enhances efficiency, and ensures that routine tasks are handled precisely, freeing up valuable time for more complex issues

What is a Knowledge Base?

A Knowledge Base in Amazon Bedrock, often used with Retrieval-Augmented Generation (RAG), is a structured repository of information that enhances the ability of AI models to generate accurate responses by pulling relevant data during the response process. RAG combines generative AI with specific data retrieval from the knowledge base, allowing the AI to generate contextually accurate and up-to-date answers, which is particularly useful in handling dynamic and domain-specific queries

What is Nylas?

Nylas is a platform that provides APIs for email, calendar, and contact management, enabling developers to seamlessly integrate communication capabilities into their applications. Nylas simplifies the process of reading, sending, and managing emails, scheduling calendar events, and accessing contact data from various providers, allowing businesses to automate workflows, improve productivity, and enhance communication processes with minimal backend setup

Requirements

  • AWS Account
  • Nylas Account
  • Gmail or any email account

Walkthrough

Architecture

First, start by enabling your email account with Nylas. You need to enable your Grant ID and API Token be sure to note these values !

Nylas

Next, inside your AWS Account, create an S3 bucket. It is fine to use the standard options; no extra configurations are necessary. After creating the S3 bucket, upload some PDF files for your knowledge base. For this, I created some examples that look like this:

How to Turn Off Instances in EC2
Step 1: Access the EC2 Dashboard
â—Ź Go to the AWS Management Console.
â—Ź Navigate to EC2 by searching for it in the search bar or selecting it from the list of AWS
services.
Step 2: Identify the Instance to Stop
â—Ź In the EC2 Dashboard, go to the Instances section.
â—Ź Look for the instance you wish to stop. You can use the search bar to filter by instance
ID, name, or other attributes.
Step 3: Check the Tags of the Instance
â—Ź Select the instance and go to the Tags tab.
â—Ź Look for a tag called "CanItBeTurnedOff". Ensure its value is "true". If the tag
does not exist or the value is not "true", do not turn off this instance.
Step 4: Stop the Instance
â—Ź If the tag value is "true", click on the Actions dropdown menu at the top right.
â—Ź Select Instance State > Stop Instance.
Step 5: Confirm the Action
â—Ź Confirm your choice in the popup dialog. The instance will begin to stop.
Step 6: Verify the Instance is Stopped
â—Ź Wait a few moments and refresh the instance state. Ensure the instance status is
stopped before proceeding with any other tasks.

S3

Now, let's use the Knowledge Base service inside Amazon Bedrock. For the configurations, feel free to create or reuse a service role—it needs access to S3. For the Data Source, be sure to select S3

Data Source

In the next window, be sure to select the S3 URI to the respective prefix or root folder where you uploaded your PDF examples

For the embedding model, I decided to use Amazon Titan Text Embedding v2 for its cost-effectiveness and reliability in determining vector dimensions

Vector dimension

Review and create your model !

For testing, be sure to enable model access. I used Titan Text G1 - Premier

Premier

Now, our setup is almost ready to start writing the code, but before this, log in to your email account. For this example, I used Gmail

Inside Gmail, be sure to create or have at least one contact. The purpose of this contact is to showcase how we can scale requirements that the Knowledge Base can't respond to, involving a human counterpart who can guide us on properly executing the requirement

Second email

Great ! We have everything set up. Now let's create the code!

This code connects the query from your emails, sends that query (in this example, the email subject) to the Knowledge Base, and returns a response based on the documents in your S3. If the model can't respond, it escalates the requirement to an "N2" support account or another person with more experience

Variables:
NYLAS_API_KEY = Your Nylas api key
NYLAS_GRANT_ID = Grant ID
SUPPORT_EMAIL_N1 = The email you used in Nylas
AWS_REGION = The region where the knowledge base is
BEDROCK_MODEL_ARN = The model of the model you gave access to (In this case Amazon Premier Text, it should look a bit like this: arn:aws:bedrock:us-east-1::foundation-model/amazon.titan-text-premier-v1:0
KNOWLEDGE_BASE_ID = The knowledge base ID that you created

from nylas import Client
from nylas.models.messages import ListMessagesQueryParams
from nylas.models.contacts import ListContactsQueryParams
import boto3
import os

nylas = Client(api_key=os.environ.get('NYLAS_API_KEY'))

# bedrock configuration be sure to create your knowledge base beforehand
region_name = os.environ.get('AWS_REGION')
model_arn = os.environ.get('BEDROCK_MODEL_ARN')
kb_id = os.environ.get('KNOWLEDGE_BASE_ID')
bedrock_agent_runtime_client = boto3.client("bedrock-agent-runtime", region_name=region_name)

# generate a response asking our RAG with the email content
def ask_bedrock_llm_with_knowledge_base(query: str) -> str:
    response = bedrock_agent_runtime_client.retrieve_and_generate(
        input={'text': query},
        retrieveAndGenerateConfiguration={
            'type': 'KNOWLEDGE_BASE',
            'knowledgeBaseConfiguration': {
                'knowledgeBaseId': kb_id,
                'modelArn': model_arn
            }
        }
    )
    return response.get('output', {}).get('text', 'No generated text found.')

# get this message if webhook nylas message.created is configured otherwise just pull the last message
def fetch_latest_message(nylas_client: Client, grant_id: str) -> list:
    query_params = ListMessagesQueryParams({'limit': 1})
    messages, _, _ = nylas_client.messages.list(grant_id, query_params)
    return messages

# you can fetch the contacts per company or description for this example we only have one contact
def fetch_contact(nylas_client: Client, grant_id: str) -> list:
    query_params = ListContactsQueryParams({'limit': 1})
    contacts, _, _ = nylas_client.contacts.list(grant_id, query_params)
    return contacts

def send_message(nylas_client: Client, grant_id: str, subject: str, body: str, recipient: str):
    request_body = {
        "subject": subject,
        "body": body,
        "to": [{"email": recipient}]
    }
    nylas_client.messages.send(grant_id, request_body=request_body)

def process_messages():
    grant_id = os.environ.get('NYLAS_GRANT_ID')
    messages = fetch_latest_message(nylas, grant_id)

    for message in messages:
        print(f"{message.subject}")
        response = ask_bedrock_llm_with_knowledge_base(message.subject)

        if "i could not find an exact answer to the question" in response.lower():
            contacts = fetch_contact(nylas, grant_id)
            for contact in contacts:
                send_message(
                    nylas,
                    grant_id,
                    f"Please {contact.given_name}, your help is needed with the following requirement",
                    message.subject,
                    contact.emails[0].email
                )
        else:
            send_message(
                nylas,
                grant_id,
                "Answer from RAG Model",
                response,
                os.environ.get('SUPPORT_EMAIL_N1')
            )


process_messages()
Enter fullscreen mode Exit fullscreen mode

That's it ! If you want to get an idea on how this work be sure to check this post
Code is here

Top comments (0)