Table of Contents
Introduction
Upgrading a TravelGuide App with Generative AI
Some Basic Concepts Before We Proceed (Skip If You Want)
Amazon Bedrock: The Problems It Actually Solves
Custom Knowledge Bases And Model Customization in Amazon Bedrock
Hands On Lab: Creating a Knowledge Base
AI Safety Controls with Amazon Bedrock Guardrails
Integrating AI Models Through the Bedrock API
Engineering Better Conversations: Prompt Engineering
Next Steps
Introduction
I wanted to sharpen my AWS skills and understand where GenAI actually fits in the DevOps pipeline, not just the hype around it. I did some research and came across this blog post.
Two things were on my mind: deepen my AWS expertise and understand how to responsibly integrate GenAI into production systems.
This is the first blog post in a series of three, where I share my experience studying and earning the DevOps and AI on AWS Specialization from Coursera.
Upgrading A TravelGuide App with Generative AI
The first course is called "DevOps and AI on AWS: Upgrading Apps with Generative AI”, the title is pretty self explanatory but, to be completely honest, I’ve never used an AWS GenAI service like Amazon Bedrock before.
I had some experience integrating the Gemini API into a frontend app. If you've been following my previous blog posts, you probably know that I used to be a developer and because I wanted to learn how to integrate AI into a Next.js app, I built an app called SummarAI. This app lets you upload a PDF and instantly extracts key insights using AI. In that occation, I worked with the Gemini AI API, but I knew AWS offers an interesting set of tools when it comes to AI, the absolute star is Amazon Bedrock.
This first course focuses on creating a travel guide application that collects travel information for various destinations. It also helps create itineraries for travelers to follow and allows them to leave reviews of the cities they visit.
It’s a python app hosted on an EC2 instance, that currently reads items with Boto3 from DynamoDB tables and displays them.
Some Basic Concepts Before We Proceed (Skip If You Want)
What is Generative AI?
Generative artificial intelligence (generative AI) is a type of AI that can create new content and ideas, including conversations, stories, images, videos, and music. It can learn human language, programming languages, art, chemistry, biology, or any complex subject matter. It reuses what it knows to solve new problems.
What is LLM (Large Language Model)?
Large language models, also known as LLMs, are very large deep learning models that are pre-trained on vast amounts of data. The underlying transformer is a set of neural networks that consist of an encoder and a decoder with self-attention capabilities. The encoder and decoder extract meanings from a sequence of text and understand the relationships between words and phrases in it.
Amazon Bedrock: The Problems It Actually Solves
As I go through the course, I can tell this TravelGuide app comes with some limitations: For each city, the the content needs to be written and edited, there’s a manual step that requires researching and crafting the itineraries, this takes a lot of time. Can you imagine if we want to add more cities as the app scales? This process is very time consuming and limits how quickly we can escalate the app. Another limitation is that the itineraries can't be personalized for individual needs. This is static content, so an itinerary for someone interested in pubs would look very different from one created for someone more into museums who doesn't like nights out.
We could solve these issues and enhance the app by using a service called Amazon Bedrock to generate travel recommendations or itineraries. As its own web page says, Amazon Bedrock is “The platform for building generative AI applications and agents at production scale”. It’s a fully managed AWS service that enables building generative AI apps using foundation models.
We could use the foundation models provided by Bedrock through an API to create content and generate results in real-time with prompts. This would allow us to create travel recommendations and itineraries, while AWS takes care of the infrastructure needed to run and manage these models.
Amazon Bedrock provides several different foundation models (I'll refer to them as FMs from now on), and you might feel the same way I did when I started learning about this, it's hard to choose the right model for the use case. How do you pick the right FM for the task you need to complete? Fortunately, we can categorize FMs by the inputs and outputs they can handle.
👉 Inputs are generally text and image.
👉 Outputs can be text, chat, image, and embeddings.
You might see the term "embeddings" and wonder what it means. I wanted to share a great website that explains embeddings in a very creative way: LLM Embeddings Explained: A Visual and Intuitive Guide .
In a nutshell, embedding vectors are used to find related content when retrieving and enhancing information. Amazon Bedrock Knowledge Bases implement Retrieval-Augmented Generation (RAG) using embeddings.
With Amazon Bedrock Knowledge Bases, you can provide foundation models and agents with contextual information from your company’s private data sources to deliver more relevant, accurate, and customized responses.
Here’s a comparative table of the supported foundation models in Amazon Bedrock.
Custom Knowledge Bases And Model Customization in Amazon Bedrock
Let’s say we want to integrate our private company’s owns data with Bedrock, so the reviews are more relevant for the users. We are talking about private and proprietary data that is owned by a company, and by default, Amazon Bedrock doesn’t have access to this data.
You can integrate your private data by either customize the model or use Knowledge Bases.
Customize the model
Train the model on private data, this would lead to better performance for specific use-cases and create a better customer experience. Amazon Bedrock provides the following methods:
Distillation → Transfers knowledge from a larger, more intelligent model (teacher) to a smaller, faster, and cost-efficient model (student).
Reinforcement fine-tuning → Improves foundation model alignment with your specific use case through feedback-based learning. Unlike supervised learning, you don't provide labeled input-output pairs.
Supervised fine-tuning → Trains a model to improve performance on specific tasks by providing labeled data. The model learns from explicit examples of correct input-output associations.
Continued pre-training → Provides unlabeled data to pre-train a foundation model by familiarizing it with certain types of inputs. This improves the model's domain knowledge without requiring labeled examples.
Heads-up: There are some costs related to customization, refer to Amazon Bedrock endpoints and quotas.
Knowledge Bases
As its own website says, "you can give foundation models and agents contextual information from your company’s private data sources to deliver more relevant, accurate, and customized responses." In this use case, it allows us to connect to private data sources, enabling users to interact and ask questions without needing to fine-tune or retrain the model. The model has access to this data and can provide the answers users need.
So, it works by uploading your custom data sources to create a repository of information that is used to enhance your prompts. It uses something called Retrieval Augmented Generation (RAG) to achieve this.
RAG is a technique that retrieves data from company sources to augment the prompt, providing more relevant and accurate responses. Amazon Bedrock Knowledge Bases use a vector database to store data as embeddings (numerical representations of text). The knowledge base connects Bedrock with private company data by retrieving the most relevant information at query time. It searches the data using semantic similarity, retrieves the most useful chunks, and uses them as additional context so the model can generate natural language answers. Instead of matching exact keywords, the system understands the meaning and context of a user’s query to return relevant information.
Hands On Lab: Creating a Knowledge Base
In this course, there was a hands-on lab where I needed to create the Amazon Bedrock knowledge base and configure it for use by the app.
To create a knowledge base is pretty straight forward. On the console, head over to Amazon Bedrock and click on Create . Choose Knowledge Base with vector store and you will see this screen:
Knowledge bases sync with documents, in this case, the app uses Amazon S3. You can choose different data source options and you can have up to five different data source in a knowledge base.
Configure the S3 bucket as your data source and upload the necessary data. Make sure to add the correct data source name and select the appropriate S3 bucket.
Select the vector store, review and create.
By selecting the following option, Bedrock will create an Amazon OpenSearch Serverless cluster for us to store these embeddings.
Review details and Create Knowledge Base🎉
Once it's created, remember to sync the data sources to index the content for searching.
You can test the model by clicking the Test Knowledge Base button on the console. Choose the model, enter a prompt, and watch the magic happen.
You can use a Knowledge Base In Two Ways
Use the Retrieve API to query and get information from the Knowledge Base directly without an additional response.
Use the RetrieveAndGenerate API, which takes a prompt as input and generates a response based on the retrieved information.
AI Safety Controls with Amazon Bedrock Guardrails
Guardrails offer protection and control over LLM responses, going beyond what can be managed through prompt design alone. Bedrock provides configurable guardrails to ensure responsible AI behavior:
Some of the content filters:
- Block harmful categories such as hate, insults, or violence.
Grounding and Relevance:
Grounding: Confidence threshold for factual accuracy.
Relevance: Checks if the model response is relevant to the user query
Integrating AI Models Through the Bedrock API
Here's an example from the AWS documentation on how to integrate a Python app with the Amazon Bedrock API using the Amazon Titan Text model.
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
"""
Shows how to create a list of action items from a meeting transcript
with the Amazon Titan Text model (on demand).
"""
import json
import logging
import boto3
from botocore.exceptions import ClientError
class ImageError(Exception):
"Custom exception for errors returned by Amazon Titan Text models"
def __init__(self, message):
self.message = message
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)
def generate_text(model_id, body):
"""
Generate text using Amazon Titan Text models on demand.
Args:
model_id (str): The model ID to use.
body (str) : The request body to use.
Returns:
response (json): The response from the model.
"""
logger.info(
"Generating text with Amazon Titan Text model %s", model_id)
bedrock = boto3.client(service_name='bedrock-runtime')
accept = "application/json"
content_type = "application/json"
response = bedrock.invoke_model(
body=body, modelId=model_id, accept=accept, contentType=content_type
)
response_body = json.loads(response.get("body").read())
finish_reason = response_body.get("error")
if finish_reason is not None:
raise ImageError(f"Text generation error. Error is {finish_reason}")
logger.info(
"Successfully generated text with Amazon Titan Text model %s", model_id)
return response_body
def main():
"""
Entrypoint for Amazon Titan Text model example.
"""
try:
logging.basicConfig(level=logging.INFO,
format="%(levelname)s: %(message)s")
# You can replace the model_id with any other Titan Text Models
# Titan Text Model family model_id is as mentioned below:
# amazon.titan-text-premier-v1:0, amazon.titan-text-express-v1, amazon.titan-text-lite-v1
model_id = 'amazon.titan-text-premier-v1:0'
prompt = """Meeting transcript: Miguel: Hi Brant, I want to discuss the workstream
for our new product launch Brant: Sure Miguel, is there anything in particular you want
to discuss? Miguel: Yes, I want to talk about how users enter into the product.
Brant: Ok, in that case let me add in Namita. Namita: Hey everyone
Brant: Hi Namita, Miguel wants to discuss how users enter into the product. """
body = json.dumps({
"inputText": prompt,
"textGenerationConfig": {
"maxTokenCount": 3072,
"stopSequences": [],
"temperature": 0.7,
"topP": 0.9
}
})
response_body = generate_text(model_id, body)
print(f"Input token count: {response_body['inputTextTokenCount']}")
for result in response_body['results']:
print(f"Token count: {result['tokenCount']}")
print(f"Output text: {result['outputText']}")
print(f"Completion reason: {result['completionReason']}")
except ClientError as err:
message = err.response["Error"]["Message"]
logger.error("A client error occurred: %s", message)
print("A client error occured: " +
format(message))
except ImageError as err:
logger.error(err.message)
print(err.message)
else:
print(
f"Finished generating text with the Amazon Titan Text Premier model {model_id}.")
if __name__ == "__main__":
main()
Engineering Better Conversations: Prompt Engineering
Prompts in Large Language Models (LLMs) are the input texts, instructions, or questions users provide to guide the AI to generate specific, relevant, and accurate responses.
With Amazon Bedrock, the LLMs are already built and trained for us. The simplest way to get better results from these LLMs is to improve the prompts we provide to them.
To write good prompts, a good strategy and easy to remember is the CO-STAR technique (Context → Objective → Style → Tone → Audience → Response). Here’s an example of a strong Prompt:
Context: We're launching Wandr, a travel review app that focuses on authentic, local experiences rather than tourist traps. Unlike TripAdvisor, we verify that reviewers actually visited the location through GPS check-ins and require photo proof. Our community consists of adventure travelers and culture enthusiasts who want to discover hidden gems.
Objective: Write an engaging "About Us" section for our app store listing that will convince potential users to download the app. Target length: 200-250 words. Must include our key value propositions: verified reviews, local discovery focus, and spam-free community.
Style: Storytelling approach that paints a picture of the problem we solve. Use vivid, sensory language that evokes the feeling of travel. Structure: problem → solution → benefit. Include a specific example or scenario travelers can relate to.
Tone: Adventurous and inspiring, but trustworthy and grounded. Think "experienced travel buddy giving insider tips" rather than "corporate travel company." Avoid clichés like "wanderlust". Be warm and enthusiastic without being cheesy.
Audience: Millennials and Gen Z travelers who are tired of showing up to "hidden" restaurants only to find them packed with tourists from the same Google search. They value authenticity over luxury, experiences over amenities, and trust peer recommendations more than professional critics.
Response: Provide the app store description, followed by 3-5 bullet points summarizing our key features that could appear below the main description in the app store listing.
We can include instructions on the desired length or formatting of the results we want. Additionally, we can provide sample results in the prompt.
Next Steps
This wraps up the first part of my three-part series on AI and AWS Coursera Specialization. I have to admit, I'm really excited about the upcoming course “DevOps and AI on AWS: CI/CD for Generative AI Applications”. I can't wait to share what I learn with you🙌. Stay tuned!











