<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Somil Gupta</title>
    <description>The latest articles on DEV Community by Somil Gupta (@somilgupta).</description>
    <link>https://dev.to/somilgupta</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1336278%2F9993f473-ae5c-41e2-90ec-43af6028d333.png</url>
      <title>DEV Community: Somil Gupta</title>
      <link>https://dev.to/somilgupta</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/somilgupta"/>
    <language>en</language>
    <item>
      <title>I would love to get some feedback on this.</title>
      <dc:creator>Somil Gupta</dc:creator>
      <pubDate>Mon, 23 Dec 2024 23:57:19 +0000</pubDate>
      <link>https://dev.to/somilgupta/i-would-love-to-get-some-feedback-on-this-110k</link>
      <guid>https://dev.to/somilgupta/i-would-love-to-get-some-feedback-on-this-110k</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/aws-builders" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__org__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F2794%2F88da75b6-aadd-4ea1-8083-ae2dfca8be94.png" alt="AWS Community Builders " width="350" height="350"&gt;
      &lt;div class="ltag__link__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1336278%2F9993f473-ae5c-41e2-90ec-43af6028d333.png" alt="" width="500" height="500"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/aws-builders/understanding-amazon-bedrocks-new-feature-flows-1ohd" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Understanding Amazon Bedrock's New Feature - "Flows"&lt;/h2&gt;
      &lt;h3&gt;Somil Gupta for AWS Community Builders  ・ Nov 29&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#ai&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#aws&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#bedrock&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#beginners&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>discuss</category>
      <category>aws</category>
    </item>
    <item>
      <title>Understanding Amazon Bedrock's New Feature - "Flows"</title>
      <dc:creator>Somil Gupta</dc:creator>
      <pubDate>Fri, 29 Nov 2024 13:12:24 +0000</pubDate>
      <link>https://dev.to/aws-builders/understanding-amazon-bedrocks-new-feature-flows-1ohd</link>
      <guid>https://dev.to/aws-builders/understanding-amazon-bedrocks-new-feature-flows-1ohd</guid>
      <description>&lt;p&gt;Amazon Bedrock continues to evolve its capabilities with the introduction of Flows, a powerful new feature that enables developers to orchestrate complex AI workflows efficiently. This post will explore Flows, how they work, and how you can leverage them in your applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Amazon Bedrock Flows?
&lt;/h2&gt;

&lt;p&gt;Flows are a new orchestration tool within Amazon Bedrock that allows developers to create sequences of connected events and actions. Think of it as a visual workflow builder for AI operations, where you can chain together different services and define how they interact.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp7we2emlf3cqiblv9hz6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp7we2emlf3cqiblv9hz6.png" alt="Screenshot captured by the Author from AWS console" width="800" height="235"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;PREREQUISITES&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic experience navigating the AWS Management Console.&lt;/li&gt;
&lt;li&gt;Fundamental understanding of AWS Bedrock service, including AI Agents, Prompts, and Knowledge Bases.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Let's try to create a basic application using Flow Builder - customer_service_flow. In this application, we will take the user input, and based on that, we will decide whether they want to book a new appointment or have a query that we can answer based on our FAQs knowledge base.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzcsfmzqsxwgf5si0w75f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzcsfmzqsxwgf5si0w75f.png" alt="Step:1 Create a flow by providing a name and a service role." width="800" height="601"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;After creating a flow, let's examine the types of nodes available and how to use them to create our desired application.&lt;/p&gt;

&lt;p&gt;All the nodes in the flow builder are bucketed into six categories:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Logic&lt;/strong&gt; - Nodes to control the logic of your flow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Orchestration&lt;/strong&gt; - Nodes for LLM agents and prompts, helps use a specific prompt or call a particular agent with an input.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code&lt;/strong&gt; - A simple node triggers the Lambda function and gets the output.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data&lt;/strong&gt; - Everything related to data retrieval, storage, and sending a query to a knowledge base.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Services&lt;/strong&gt; - An Amazon Lex node sends the input to an Amazon Lex bot for interpretation.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkm5ju6tk4lq67cgq4d60.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkm5ju6tk4lq67cgq4d60.png" alt="Screenshot captured by the Author from AWS Bedrock console" width="800" height="814"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Firstly, we will start with a basic prompt node to help us classify whether the user wants to book an appointment or if the query is related to something else. Prompt we will be using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Take the user {{input}} and analyze whether they want to book an 
appointment or have any other query.

Output "APPOINTMENT" if they want to book a new service appointment 
else, output "OTHER"

Only respond with a category.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our flow structure will look like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp3tar34kkkj3te41wn4i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp3tar34kkkj3te41wn4i.png" alt="Screenshot captured by the Author from Flow console" width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's enhance our flow by adding some logic to it with the help of the "Condition" node. After classification, this node will point the flow in that respective direction. Think of it as a traffic controller that directs conversations down different paths depending on their content.&lt;br&gt;
For example, after classifying incoming messages, we'll create two distinct paths: one for appointment requests and another for general inquiries. Let's test this with the message "Do you guys do plumbing work?" Since this is a general service inquiry rather than an appointment request, our prompt node classifies it as "OTHER." The Condition node then routes it to "FlowOutputNode_2" where we display the prompt output (for demonstration purposes).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxz3n75xz0zss2i372ohy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxz3n75xz0zss2i372ohy.png" alt="Screenshot captured by the Author from Flow console" width="800" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add our knowledge base and AI agent to the flow to handle the respective route. After doing so, our flow will look something like the below diagram.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu8uprt037ttgk7cb2jkz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu8uprt037ttgk7cb2jkz.png" alt="Flow diagram created by the author - Somil Gupta" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And YES, that's it. We have successfully created our desired application using the new flow builder.&lt;/p&gt;

&lt;p&gt;Flows for Amazon Bedrock makes it easy to link foundation models (FMs), prompts, and other AWS services to quickly create, test, and run your flows. You can manage flows using the visual builder in the Amazon Bedrock console, which saves a lot of time when creating a generative AI workflow.&lt;/p&gt;

&lt;p&gt;Do try it out on your own. Happy Building!!&lt;/p&gt;




&lt;p&gt;Thanks for reading my story. If you want to read more stories like this, I invite you to follow me.&lt;br&gt;
Till then, Sayonara! I wish you the best in your learning journey.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>aws</category>
      <category>bedrock</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How I Used Bedrock Agents to Create a Tool — Medium2Markdown</title>
      <dc:creator>Somil Gupta</dc:creator>
      <pubDate>Sun, 15 Sep 2024 00:11:26 +0000</pubDate>
      <link>https://dev.to/aws-builders/how-i-created-a-tool-medium2markdown-40k</link>
      <guid>https://dev.to/aws-builders/how-i-created-a-tool-medium2markdown-40k</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvkn9pwhoycaczv7lzv0r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvkn9pwhoycaczv7lzv0r.png" alt="Screenshot of the tool"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Recently, I faced a problem when I was creating my personal blog which was using Markdown for all my written content. Every blog was on Medium, and it was taking a lot of time to convert those blogs to Markdown files. Hence, I worked on this project.&lt;/p&gt;

&lt;p&gt;This application is a simple way to generate markdown files using your blogs on Medium. This tool provides a solution for fetching HTML content from URLs and converting it to Markdown format using AWS Bedrock agents with any FM of your choice. It consists of two main components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A Flask-based API for fetching HTML content&lt;/li&gt;
&lt;li&gt;A Next.js application (using App Router) that handles the Bedrock integration for converting HTML to Markdown&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Step 1 — Flask API for HTML Fetching
&lt;/h3&gt;

&lt;p&gt;We are using Selenium to scrape the HTML from the webpage because the Medium ‘GET’ call for a medium-story page returns a partial result that doesn’t contain complete story content. So we render the page in headless Chrome, wait for it to load, and then get the HTML page. This will allow us to get the complete story in the HTML file.&lt;/p&gt;

&lt;p&gt;Below is the simple code using Selenium and Flask to create a simple API that takes in the URL and returns the HTML body.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;selenium&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;webdriver&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;selenium.webdriver.chrome.service&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Service&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;ChromeService&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;selenium.webdriver.chrome.options&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Options&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;webdriver_manager.chrome&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChromeDriverManager&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;bs4&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BeautifulSoup&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_website_html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Set up headless Chrome options
&lt;/span&gt;    &lt;span class="n"&gt;chrome_options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Options&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;# chrome_options.add_argument("--headless")
&lt;/span&gt;    &lt;span class="n"&gt;chrome_options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--no-sandbox&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;chrome_options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--disable-dev-shm-usage&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Initialize the WebDriver with ChromeDriverManager
&lt;/span&gt;    &lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;webdriver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Chrome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;ChromeService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ChromeDriverManager&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;install&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;chrome_options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Pausing for 5 seconds to allow the page to load...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Pause for 5 seconds
&lt;/span&gt;
    &lt;span class="c1"&gt;# Get the HTML content of the page
&lt;/span&gt;    &lt;span class="n"&gt;html_content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;page_source&lt;/span&gt;

    &lt;span class="c1"&gt;# Close the WebDriver
&lt;/span&gt;    &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;html_content&lt;/span&gt;


&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/get_html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_html&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Fetching the HTML content of a website...&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Get the URL from the request body
&lt;/span&gt;    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;error&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;URL is required in the request body&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;

    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;html_content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_website_html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Parse the HTML content with BeautifulSoup
&lt;/span&gt;    &lt;span class="n"&gt;soup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BeautifulSoup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html_content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;html.parser&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Return the HTML content as a JSON response
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;soup&lt;/span&gt;&lt;span class="p"&gt;)})&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You can host this flask server using an AWS EC2 instance or any other cloud provider. Just expose this API with some authorization for security reasons.&lt;/p&gt;

&lt;p&gt;After we have the HTML, the next step is to create beautiful markdown content using the HTML body content. We will use Bedrock agent for this, with Claude as the FM.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 2 — Setup AWS Bedrock "Agent"
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv5ifbz40sub1tenke74q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv5ifbz40sub1tenke74q.png" alt="Bedrock Agent Config"&gt;&lt;/a&gt;&lt;br&gt;
I have created a basic agent using the Bedrock console with the below prompt. You can modify the prompt further for better results.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

You are a helpful assistant who takes HTML as input and then parses it 
and returns the blog as a Markdown blog, and the blog should just contain 
the main content body without the title and subtitle. 
Also, remove the first image of the article from the markdown body, 
as we are putting that in the header.

* In the main content markdown, just keep the main body, remove the title 
and subtitle published date, etc.

On top of the markdown, add these things:
* decide on the title and description of the content
* categories can be travel or engineering
* remove the title and description from the main markdown body
* The image will be the first URL of the markdown blog

Sample to put on the top of the markdown
---
title: The Time When I Got Scammed in Georgia
description: A Reminder to Dodge Scams… Or Collect Them Like Souvenirs?
image: /images/blog/blog-post-4.1.png
date: 2024/6/28
authors:
  - nomadic_bug
categories:
  - travel
---


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This prompt will help us get the beautiful markdown file in our desired format.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 3 — Next.js App with Bedrock Integration
&lt;/h3&gt;

&lt;p&gt;I used Next.js with an app router to create the basic UI for this project. Below is the primary API to run the agent we have created earlier on AWS Bedrock.&lt;/p&gt;

&lt;p&gt;The complete code is available &lt;a href="https://github.com/somilg050/medium2markdown/blob/main/app_router_with_bedrock.ts" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

// Outline of what we are doing.
// Initialize Bedrock Agent Client with AWS credentials
Initialize BedrockAgentClient with:
    region = "us-east-1"
    access_key = AWS_ACCESS_KEY_ID from environment
    secret_key = AWS_SECRET_ACCESS_KEY from environment

// Set up Agent details
agent_id = "your-agent-id"
agent_alias_id = "your-agent-alias-id"

// Function to invoke Bedrock Agent
Function InvokeBedrockAgent(session_id, input_text):
    Create new InvokeAgentCommand with:
        agent_id = agent_id
        agent_alias_id = agent_alias_id
        session_id = session_id
        input_text = input_text
    Send command to BedrockAgentClient
        Return the completion from the response

// Main API Handler
Function HandlePostRequest(request):
    Extract message and session_id from request body

    If message is missing OR session_id is missing:
        Return error response:
            status = 400
            message = "Please provide both a message and a sessionId."
    response = InvokeBedrockAgent(session_id, message)
        Return success response:
            status = 200
            data = {
                response: response,
                sessionId: session_id
            }


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7eq7rb0tnb9c4ytdmn93.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7eq7rb0tnb9c4ytdmn93.png" alt="Output screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The complete code is available on my &lt;a href="https://github.com/somilg050/medium2markdown" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;This HTML Fetcher and Markdown Converter is a prototype project that converts web content into easily readable and editable Markdown format. My goal was to make this work, and it does. Some improvements can be made, but this project gave me an idea of how to start.&lt;/p&gt;




&lt;p&gt;Thanks for reading my story. If you want to read more stories like this, I invite you to follow me.&lt;/p&gt;

&lt;p&gt;Till then, Sayonara! I wish you the best in your learning journey.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>medium</category>
      <category>aws</category>
      <category>bedrock</category>
    </item>
    <item>
      <title>Configuring Multiple Ports With Nginx Reverse Proxies on the Same Domain</title>
      <dc:creator>Somil Gupta</dc:creator>
      <pubDate>Mon, 12 Aug 2024 18:25:59 +0000</pubDate>
      <link>https://dev.to/aws-builders/configuring-multiple-ports-with-nginx-reverse-proxies-on-the-same-domain-57ga</link>
      <guid>https://dev.to/aws-builders/configuring-multiple-ports-with-nginx-reverse-proxies-on-the-same-domain-57ga</guid>
      <description>&lt;p&gt;Recently, while working on one of the projects, I was stuck in a situation where I wanted to run two applications on the same server and then consume the application using two different ports.&lt;br&gt;
Something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; Fowarding http://example.com:PORTA -&amp;gt; 127.0.0.1:8080

&amp;gt; Fowarding http://example.com:PORTB -&amp;gt; 127.0.0.1:8081
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usually, when I have one server and one port mapping, I go to Ngrok because of its hassle-free setup. But this time, it was a new challenge.&lt;/p&gt;

&lt;p&gt;After some research, I found out that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Free ngrok.io subdomains: These only work with port 80 (standard HTTP).&lt;/li&gt;
&lt;li&gt;Ngrok's TLS "reserved" domains:

&lt;ul&gt;
&lt;li&gt;These are better for using non-standard HTTP ports.&lt;/li&gt;
&lt;li&gt;When you set one up, ngrok assigns you a random port.&lt;/li&gt;
&lt;li&gt;This port is different from your local service's port.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Separate domains: The HTTP tunnel (port 80) and the custom port tunnel will have different domain names. You can't use one domain for both.&lt;/li&gt;

&lt;li&gt;Free account limitations: 

&lt;ul&gt;
&lt;li&gt;With a free ngrok account, you can only use the standard HTTP tunnel on port 80.&lt;/li&gt;
&lt;li&gt;You cannot use TLS "reserved" domains or expose services on non-standard ports without upgrading to a paid plan.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;This setup means that if you need to expose services on multiple ports or use custom domains, you'll need to upgrade to a paid ngrok plan. With a free account, you're limited to a single HTTP tunnel on the standard web port. &lt;strong&gt;In short, it was not possible.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After losing hope with Ngrok, I started looking into Nginx w/ multiple ports. And was finally able to achieve it. Let's dive into the approach.&lt;/p&gt;




&lt;h3&gt;
  
  
  Understanding Nginx as a reverse proxy:
&lt;/h3&gt;

&lt;p&gt;When NGINX proxies a request, it sends it to a specified proxied server, fetches the response, and sends it back to the client. This makes it an ideal solution for exposing multiple applications running on different ports.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;location /some/path/ &lt;span class="o"&gt;{&lt;/span&gt;
    proxy_pass http://www.example.com/link/&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's start with the &lt;strong&gt;Nginx setup&lt;/strong&gt; and then move on to the configuration for multiple applications.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install Nginx:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# For Amazon Linux (AL2)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nb"&gt;install &lt;/span&gt;nginx

&lt;span class="c"&gt;# For Ubuntu&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Start and enable Nginx:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start nginx
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;nginx
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;For monitoring logs:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/nginx/error.log
&lt;span class="nb"&gt;sudo tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/nginx/access.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Now, let's configure Nginx to act as a reverse proxy for multiple applications:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;http &lt;span class="o"&gt;{&lt;/span&gt;
    server &lt;span class="o"&gt;{&lt;/span&gt;
        listen 7233&lt;span class="p"&gt;;&lt;/span&gt;
        server_name example.com&lt;span class="p"&gt;;&lt;/span&gt;

        location / &lt;span class="o"&gt;{&lt;/span&gt;
            proxy_pass http://127.0.0.1:8080&lt;span class="p"&gt;;&lt;/span&gt;
            proxy_set_header Host &lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            proxy_set_header X-Real-IP &lt;span class="nv"&gt;$remote_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            proxy_set_header X-Forwarded-For &lt;span class="nv"&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            proxy_set_header X-Forwarded-Proto &lt;span class="nv"&gt;$scheme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    server &lt;span class="o"&gt;{&lt;/span&gt;
        listen 8233&lt;span class="p"&gt;;&lt;/span&gt;
        server_name example.com&lt;span class="p"&gt;;&lt;/span&gt;

        location / &lt;span class="o"&gt;{&lt;/span&gt;
            proxy_pass http://127.0.0.1:8081&lt;span class="p"&gt;;&lt;/span&gt;
            proxy_set_header Host &lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            proxy_set_header X-Real-IP &lt;span class="nv"&gt;$remote_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            proxy_set_header X-Forwarded-For &lt;span class="nv"&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            proxy_set_header X-Forwarded-Proto &lt;span class="nv"&gt;$scheme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Here's what this configuration does:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It sets up two server blocks, each listening on a different port (7233 and 8233). Each server block forwards all traffic (location /) to a different local port (8080 and 8081 respectively).&lt;/li&gt;
&lt;li&gt;The proxy_pass directive specifies where the traffic should be forwarded.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;To use this configuration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Save this configuration to /etc/nginx/nginx.conf or include it in your main Nginx configuration file.&lt;/li&gt;
&lt;li&gt;Ensure that your applications are running on 127.0.0.1:8080 and 127.0.0.1:8081.&lt;/li&gt;
&lt;li&gt;Test the Nginx configuration: sudo nginx -t If the test passes, reload Nginx:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl reload nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;We've configured Nginx as a reverse proxy to forward traffic from two external ports to two separate internal applications.&lt;/li&gt;
&lt;li&gt;This setup exposes multiple services through a single server, enhancing flexibility and security.&lt;/li&gt;
&lt;li&gt;Using Nginx, we've created a scalable solution that can be easily extended to accommodate more applications.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Thanks for reading my story. If you want to read more stories like this, I invite you to follow me.&lt;br&gt;
Till then, Sayonara! I wish you the best in your learning journey.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>nginx</category>
      <category>ec2</category>
      <category>reverseproxy</category>
    </item>
    <item>
      <title>When I Tackled Rate Limiting Using AWS Step Functions and Lambda</title>
      <dc:creator>Somil Gupta</dc:creator>
      <pubDate>Fri, 09 Aug 2024 17:37:27 +0000</pubDate>
      <link>https://dev.to/aws-builders/when-i-tackled-rate-limiting-using-aws-step-functions-and-lambda-354a</link>
      <guid>https://dev.to/aws-builders/when-i-tackled-rate-limiting-using-aws-step-functions-and-lambda-354a</guid>
      <description>&lt;p&gt;In the world of cloud computing, managing API request rates efficiently can make or break your application's performance. Today, I'll share my journey of &lt;strong&gt;implementing a robust rate-limiting solution using AWS Step Functions and Lambda&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I have been working with external API calls for a while and have noticed they can sometimes fail for various reasons, such as network issues, server downtime, or rate limits on the server. So, I have built this solution to have a robust system to tackle this problem.&lt;/p&gt;

&lt;p&gt;In this solution, we will leverage the &lt;strong&gt;AWS Step Function and Lambda Functions&lt;/strong&gt; to construct a reliable retry mechanism. The State Machine will consist of a collection of Lambda functions invoked and stitched together to produce results. This article will walk you through the step-by-step guide.&lt;/p&gt;

&lt;h3&gt;
  
  
  The main objective we are trying to solve:
&lt;/h3&gt;

&lt;p&gt;While Step Functions inherently support retries within tasks, our specific challenge involves handling API rate limits from the server we are communicating with. The server imposes a rate limit and responds with a 429 status code if too many requests are made from the same IP address within a short period.&lt;/p&gt;




&lt;p&gt;For the simplicity of the architecture, I have shown one retry using two lambda functions; this can be increased easily during implementation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Architecture Overview&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnccm68sf03iue7rro63m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnccm68sf03iue7rro63m.png" alt="The Architecture of our Solution | Created by the Author using Exaclidraw." width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Workflow Explanation&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;User Invokes Step Function State Machine:&lt;/strong&gt; The process begins when a user initiates the step function state machine. This could be triggered through an API call, a scheduled event, or another AWS service.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step Function Invokes Lambda (1st Attempt):&lt;/strong&gt; The step function invokes the first Lambda function (Lambda 1). This Lambda function is responsible for making the API call.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Response: Status:&lt;/strong&gt; Lambda 1 Executes the API call and returns a status response. This response indicates whether the API call was successful (e.g., status code 200) or failed (e.g., any status code other than 200).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If Failure Status ≠ 200 (2nd Attempt):&lt;/strong&gt; If the response from Lambda 1 indicates a failure (status code not equal to 200), the step function will proceed to invoke a retry mechanism. This could involve retrying the same Lambda function or invoking a different Lambda function (Lambda 2) to handle the retry attempt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Response: Status:&lt;/strong&gt; Lambda 2 It attempts to execute the API call and returns a status response. Similar to the first Attempt, this response will indicate whether the retry was successful.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If Success Status = 200:&lt;/strong&gt; If either Lambda 1 or Lambda 2 Successfully executes the API call and returns a status code of 200, the step function completes successfully, and the user is notified of the success.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If Failure Even After Retries:&lt;/strong&gt; Then we will fail the step function and forward the API error to the user with the appropriate status code.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To explain the architecture easily, I have created the above diagram with one retry only, but we will build the solution with two retries. Below is the state machine diagram.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftczihhs3kps1c1u6syak.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftczihhs3kps1c1u6syak.png" alt="Step function diagram to explain the flow | This flow consists of two retries." width="800" height="972"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Step-by-Step Guide
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Create a base lambda &lt;a href="https://github.com/somilg050/aws_lambda_functions/blob/main/orchestrator_lambda.py" rel="noopener noreferrer"&gt;orchestrator function&lt;/a&gt;:&lt;/strong&gt;&lt;br&gt;
This lambda function will help us in orchestrating the state machine. Executing the state machine and handling logic based on the execution status.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Create a function URL for the lambda function:&lt;/strong&gt;&lt;br&gt;
Now that the lambda function is ready, we can set up a function URL to trigger/send a request to the lambda function using it. Refer to the article below to turn any lambda function into an API with a function URL.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="https://medium.com/technology-hits/how-to-use-aws-lambda-to-trigger-any-script-as-an-api-call-64f13d8b36e5" class="ltag__link__link" rel="noopener noreferrer"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IyVL-CFE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fill:88:88/1%2Ad-5flMLM65LX03lrj6EsVw.jpeg" alt="Somil Gupta"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://medium.com/technology-hits/how-to-use-aws-lambda-to-trigger-any-script-as-an-api-call-64f13d8b36e5" class="ltag__link__link" rel="noopener noreferrer"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;How to use AWS Lambda to trigger “any” script as an API call | by Somil Gupta | Technology Hits | Medium&lt;/h2&gt;
      &lt;h3&gt;Somil Gupta ・ &lt;time&gt;Nov 10, 2023&lt;/time&gt; ・ 
      &lt;div class="ltag__link__servicename"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YjpYcCMa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/medium-f709f79cf29704f9f4c2a83f950b2964e95007a3e311b77f686915c71574fef2.svg" alt="Medium Logo"&gt;
        Medium
      &lt;/div&gt;
    &lt;/h3&gt;
&lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Create child lambda functions:&lt;/strong&gt;
These will be simple lambda functions acting as a proxy; they will not handle any logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We have to create the same three lambda functions using the &lt;a href="https://github.com/somilg050/aws_lambda_functions/blob/main/step_function_child_lambda.py" rel="noopener noreferrer"&gt;step_function_child_lambda&lt;/a&gt; code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Define Step Function State Machine:&lt;/strong&gt;
Next, we'll create a Step Functions state machine with a retry mechanism. &lt;a href="https://github.com/somilg050/aws_lambda_functions/blob/main/state_machine.json" rel="noopener noreferrer"&gt;Here is an example definition in JSON.&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Complete code to implement this is available here:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/somilg050" rel="noopener noreferrer"&gt;
        somilg050
      &lt;/a&gt; / &lt;a href="https://github.com/somilg050/aws_lambda_functions" rel="noopener noreferrer"&gt;
        aws_lambda_functions
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;





&lt;h3&gt;
  
  
  Testing the State Machine
&lt;/h3&gt;

&lt;p&gt;Trigger the state machine execution using the first lambda function URL and monitor it through the AWS State Machine Console. You should see the retries and the final result, whether it succeeds or fails.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fae8z36h2nebg8qvmutw9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fae8z36h2nebg8qvmutw9.png" alt="Sample screenshot to show when the first try failed but the second worked | AWS Step Function Console" width="800" height="685"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Conclusion —
&lt;/h3&gt;

&lt;p&gt;Implementing a robust API retry mechanism using AWS Step Functions and Lambda is a powerful way to enhance the reliability of your external unreliable API integrations. I have worked too much with the vendor APIs, and their reliability is something you can not trust. They have rate limits, server IP-based wait times, and so on. This retry using different lambda functions will give us different server URLs, preventing IP-based wait time blocking plus the retry mechanism. I hope my experience inspires you to explore innovative solutions for your own cloud computing challenges.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Robust API Retry Mechanism with AWS Step Functions and Lambda</title>
      <dc:creator>Somil Gupta</dc:creator>
      <pubDate>Wed, 29 May 2024 12:31:15 +0000</pubDate>
      <link>https://dev.to/aws-builders/robust-api-retry-mechanism-with-aws-step-functions-and-lambda-4lap</link>
      <guid>https://dev.to/aws-builders/robust-api-retry-mechanism-with-aws-step-functions-and-lambda-4lap</guid>
      <description></description>
      <category>aws</category>
      <category>lambda</category>
      <category>stepfunctions</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>RAG Application using AWS Bedrock and LangChain</title>
      <dc:creator>Somil Gupta</dc:creator>
      <pubDate>Sat, 06 Apr 2024 15:16:55 +0000</pubDate>
      <link>https://dev.to/aws-builders/rag-application-using-aws-bedrock-and-langchain-140b</link>
      <guid>https://dev.to/aws-builders/rag-application-using-aws-bedrock-and-langchain-140b</guid>
      <description>&lt;p&gt;Hello, good folks!!&lt;br&gt;
In this part of building the RAG application series, we will leverage Mistral's new model Large using AWS Bedrock and LangChain framework to query over the pdfs.&lt;br&gt;
In the previous article of the series, we learned to build an RAG application using AWS Bedrock and LlamaIndex. To learn more about "&lt;strong&gt;what RAG is&lt;/strong&gt;", please refer to the below article.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://aws.plainenglish.io/rag-implementation-using-aws-bedrock-and-llamaindex-62b346fd0156" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A1200%2F1%2AVdShzJsBeSLw_iyYBBir5g.png" height="auto" class="m-0"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://aws.plainenglish.io/rag-implementation-using-aws-bedrock-and-llamaindex-62b346fd0156" rel="noopener noreferrer" class="c-link"&gt;
          Learn to Build a Basic RAG Application | by Somil Gupta | AWS in Plain English
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          End-to-end Guide Using AWS Bedrock and LlamaIndex to Query Over Your Own PDFs
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afill%3A256%3A256%2F1%2AyF780R4FqshMPgcz2ISVYw%402x.png"&gt;
        aws.plainenglish.io
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Let's get the learning started.&lt;/p&gt;




&lt;p&gt;The implementation of this application involves three components:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Create a Vector Store&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5s8mfxoui30i675l3pa2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5s8mfxoui30i675l3pa2.png" alt="Created by the Author using Excalidraw."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;
&lt;b&gt;Load -&amp;gt; Transform -&amp;gt; Embed&lt;/b&gt;
&lt;/center&gt;

&lt;p&gt;&lt;br&gt;
We will be using the FAISS vector database, which uses the Facebook AI Similarity Search (FAISS) library. There are many excellent vector store options that you can use, such as ChromaDB or LanceDB.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Query Vector Store and 'Retrieve Most Similar.'&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8rerb7vo5pdgfcwf8ixr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8rerb7vo5pdgfcwf8ixr.png" alt="Created by the Author using Excalidraw."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The way to handle this is at query time, embed the unstructured query and retrieve the embedding vectors that are 'most similar' to the embedded query. A vector store takes care of storing embedded data and performing vector search for you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Frame the response using LLM and 'Enhanced Context'&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4skrtc8bg66darq2ldi6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4skrtc8bg66darq2ldi6.png" alt="Created by the Author using Excalidraw."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Response Generation Using LLM (Large Language Model): Once the relevant documents are retrieved from Vector Store, a large language model uses the information from these documents to generate a coherent and contextually appropriate response.&lt;br&gt;
These three steps clearly explain the application we are going to build now.&lt;/p&gt;




&lt;p&gt;First and foremost, we will set up our AWS SDK for Python using Boto3 and AWS CLI. If you have not installed them before -&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

(base) ➜  ~ pip3 install boto3
(base) ➜  ~ pip3 install awscli

(base) ➜  ~ aws configure


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In this example, we'll use the AWS Titan Embeddings model to generate embeddings. You can use any model that generates embeddings.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;

&lt;span class="c1"&gt;# Load the Bedrock client using Boto3.
&lt;/span&gt;&lt;span class="n"&gt;bedrock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;service_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;bedrock-runtime&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_community.embeddings.bedrock&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BedrockEmbeddings&lt;/span&gt;
&lt;span class="n"&gt;titan_embeddings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BedrockEmbeddings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amazon.titan-embed-text-v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                     &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bedrock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now, we will set up the Vector Store to store and retrieve embeddings. We have our PDF stored in the "data" folder of the root directory.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In this case we'll split our documents into chunks of 1000 characters with 200 characters of overlap between chunks. The overlap helps mitigate the possibility of separating a statement from an important context related to it. &lt;/li&gt;
&lt;li&gt;We will leverage RecursiveCharacterTextSplitter from LangChain, which will recursively split the document using common separators like new lines until each chunk is the appropriate size.&lt;/li&gt;
&lt;li&gt;We can embed and store all of our document splits in a single command using the FAISS vector store and titan embedding model.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="c1"&gt;# Vector Store for Vector Embeddings
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_community.vectorstores.faiss&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FAISS&lt;/span&gt;

&lt;span class="c1"&gt;# Imports for Data Ingestion
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.text_splitter&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RecursiveCharacterTextSplitter&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_community.document_loaders.pdf&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PyPDFDirectoryLoader&lt;/span&gt;

&lt;span class="c1"&gt;# Load the PDFs from the directory
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;data_ingestion&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;loader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PyPDFDirectoryLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;documents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;# Split the text into chunks
&lt;/span&gt;    &lt;span class="n"&gt;text_splitter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RecursiveCharacterTextSplitter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunk_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                                   &lt;span class="n"&gt;chunk_overlap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;text_splitter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;docs&lt;/span&gt;

&lt;span class="c1"&gt;# Vector Store for Vector Embeddings
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;setup_vector_store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Create a vector store using the documents and the embeddings
&lt;/span&gt;    &lt;span class="n"&gt;vector_store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FAISS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;titan_embeddings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Save the vector store locally
&lt;/span&gt;    &lt;span class="n"&gt;vector_store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save_local&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;faiss_index&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The next step is to import and load the LLM via Bedrock.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="c1"&gt;# Import Bedrock for LLM
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_community.llms.bedrock&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Bedrock&lt;/span&gt;

&lt;span class="c1"&gt;# Load the LLM from the Bedrock
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;load_llm&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Bedrock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mistral.mistral-large-2402-v1:0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                    &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bedrock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model_kwargs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;max_tokens&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;512&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We will be using LangChain PromptTemplate to create the prompt template for our LLM. We will produce an answer using a prompt that includes the question and the retrieved data (context).&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PromptTemplate&lt;/span&gt;

&lt;span class="c1"&gt;# Create a prompt template
&lt;/span&gt;&lt;span class="n"&gt;prompt_template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Use the following pieces of context to answer the 
question at the end. Please follow the following rules:
1. If the answer is not within the context knowledge, kindly state 
that you do not know, rather than attempting to fabricate a response.
2. If you find the answer, please craft a detailed and concise response 
to the question at the end. Aim for a summary of max 250 words, ensuring
 that your explanation is thorough.

{context}

Question: {question}
Helpful Answer:&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="n"&gt;PROMPT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PromptTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;prompt_template&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;input_variables&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;context&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;question&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now, let's write the actual application logic. We want to create a simple application that takes a user question, searches for documents relevant to that question, passes the retrieved documents and initial question to a model, and returns an answer.&lt;br&gt;
We need to define the LangChain Retriever interface. Load RetrievalQA from LangChain as it provides a simple interface for interacting with the LLM.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.chains.retrieval_qa.base&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RetrievalQA&lt;/span&gt;

&lt;span class="c1"&gt;# Create a RetrievalQA chain and invoke the LLM
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vector_store&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;retrieval_qa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RetrievalQA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_chain_type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;chain_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stuff&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;retriever&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;vector_store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;as_retriever&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;search_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;similarity&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;search_kwargs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;k&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;chain_type_kwargs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prompt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PROMPT&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;return_source_documents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;retrieval_qa&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let's put it all together into a chain. This tutorial will use Streamlit to create a UI that interacts with our RAG.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We will provide a simple button in the sidebar to create and update a vector store and store it in the local storage.&lt;/li&gt;
&lt;li&gt;Whenever a user enters a query, we will first get the faiss_index from our local storage and then query our LLM using the retrieved context.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;streamlit_ui&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_page_config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;My Gita RAG&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;RAG implementation using AWS Bedrock and Langchain&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;user_question&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text_input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Ask me anything from My Gita e.g. 
                                          What is the meaning of life?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sidebar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Update Or Create Vector Embeddings&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Update Vector Store&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;spinner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Processing...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;data_ingestion&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="nf"&gt;setup_vector_store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Done&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Generate Response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;user_question&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# first check if the vector store exists
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;faiss_index&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Please create the vector store 
                                first from the sidebar.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;user_question&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Please enter a question.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;
        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;spinner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Processing...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;faiss_index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FAISS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load_local&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;faiss_index&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                                          &lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;titan_embeddings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                      &lt;span class="n"&gt;allow_dangerous_deserialization&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;load_llm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;get_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;faiss_index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_question&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Done&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is how our Streamlit application will look.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frwdx9u2bokzahpvktgsr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frwdx9u2bokzahpvktgsr.png" alt="Screenshot by the Author."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The complete code for the application is available here on my github: &lt;a href="https://github.com/somilg050/rag-aws-bedrock/blob/master/using_langchain.py" rel="noopener noreferrer"&gt;somilg050&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7qs7j4izshccoutlr3rz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7qs7j4izshccoutlr3rz.png" alt="Screenshot by the Author."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can play around with the code by customizing the prompt and changing the parameters to the LLM.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In conclusion, we have created an application that takes a question, retrieves relevant documents, constructs a prompt, passes that to a model, and parses the output.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;Thanks for reading the tutorial. I hope you learn something new today. If you want to read more stories like this, I invite you to follow me.&lt;/p&gt;

&lt;p&gt;Till then, Sayonara! I wish you the best in your learning journey.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>langchain</category>
      <category>ai</category>
      <category>awscommunitybuild</category>
    </item>
  </channel>
</rss>
