Create Your Own “ChatGPT” in 10 Minutes with AWS Bedrock & LangChain

You are currently viewing Create Your Own “ChatGPT” in 10 Minutes with AWS Bedrock & LangChain

Introduction

Let’s be real for a second: managing OpenAI API keys in a production environment is a headache. You have to worry about credit limits, rotating keys, and accidentally committing them to GitHub.

If you are already in the AWS ecosystem, there is a better way.

Amazon Bedrock has completely changed the game. It allows you to access top-tier LLMs (like Anthropic’s Claude 3) using standard AWS IAM permissions. No more hardcoded API keys. No more “rate limit exceeded” on your personal credit card. Just secure, serverless AI integration.

In this guide, we are going to build a custom, context-aware chatbot using Python, LangChain, and AWS Bedrock. By the end of this tutorial (which should take you about 10 minutes), you will have a CLI-based assistant that runs locally but is powered by the same infrastructure used by enterprise giants.

Here is what we are building:

  • A Python-based chatbot that runs in your terminal.
  • It uses Anthropic Claude 3 (via Bedrock) as the “brain.”
  • It features Conversation Memory (so it remembers what you said two messages ago).
  • It uses IAM Roles for security—zero API keys required.

Prerequisites

Before we write a single line of code, we need to handle the boring (but critical) setup. If you skip this, your code will fail with an AccessDenied error.

1. AWS CLI Configured

You need the AWS Command Line Interface installed and configured on your machine. This allows our Python script to grab your credentials automatically.

  • Verify it: Run aws sts get-caller-identity in your terminal. If you see your UserID and Account number, you are good to go.

2. Enable Model Access (CRITICAL STEP)

By default, AWS Bedrock blocks access to all models. You must manually enable them.

  1. Log in to the AWS Console and search for Amazon Bedrock.
  2. In the left sidebar, scroll down and click Model access.
  3. Click the orange “Manage model access” button.
  4. Check the box next to Anthropic (you may need to submit a quick use-case form, just say “Testing for development”).
  5. Important: Make sure Claude 3 Sonnet or Claude 3.5 Sonnet shows “Access granted” (green text).

3. Check Your Region

Bedrock models aren’t available everywhere yet. For this tutorial, I highly recommend using us-east-1 (N. Virginia) or us-west-2 (Oregon).

  • Note: If you are in a different region, your code will fail unless you explicitly tell Boto3 to look at us-east-1.

The Tech Stack

We need a few Python libraries. I recommend creating a fresh virtual environment so you don’t mess up your system packages.

# Create and activate a virtual environment
python3 -m venv venv
source venv/bin/activate  # On Windows use: venv\Scripts\activate

# Install the required libraries
# We use 'langchain-aws' which is the modern standard for 2025
pip install boto3 langchain-aws langchain-community

Setting up the AWS Environment

Technically, we already installed the CLI in the prerequisites, but now we need to make sure our Python script knows which user to act as.

I cannot stress this enough: Never hardcode your AWS Access Keys and Secret Keys into your Python script. It’s the number one security mistake I see developers make. If you push that script to a public GitHub repo, bots will scrape your keys and spin up crypto-mining EC2 instances in seconds.

Instead, we will rely on Boto3’s default credential chain.

If you are running this locally, Boto3 will automatically look for the credentials you set up via aws configure. If you are running this on an EC2 instance or inside a Lambda function later, it will automatically use the attached IAM Role.

This means our code stays clean, portable, and secure.

Initialize the Bedrock Client

Now, let’s write some code. We aren’t going to use the raw boto3 client directly because it requires a lot of JSON formatting. Instead, we’ll use LangChain’s ChatBedrock wrapper, which handles the heavy lifting for us.

Create a file named chatbot.py and add the following:

Python

import boto3
from langchain_aws import ChatBedrock

# 1. Setup the Bedrock Client
# We use boto3 to establish the connection, ensuring we target the right region.
bedrock_runtime = boto3.client(
    service_name="bedrock-runtime",
    region_name="us-east-1" # Make sure this matches where you enabled the model!
)

# 2. Initialize the Language Model
# We are using Claude 3 Sonnet here. It's the "Goldilocks" model—
# smarter than Instant, but faster/cheaper than Opus.
llm = ChatBedrock(
    client=bedrock_runtime,
    model_id="anthropic.claude-3-sonnet-20240229-v1:0",
    model_kwargs={
        "temperature": 0.5, # 0.0 is precise, 1.0 is creative. 0.5 is balanced.
        "max_tokens": 512,
    }
)

# Quick Test to ensure connection works
print("Bot: AI Model initialized successfully...")

Understanding the Parameters:

  • model_id: This string is crucial. If you want to use Amazon Titan or Meta Llama 3 instead, you just swap this ID. (You can find IDs by running aws bedrock list-foundation-models in your terminal.
  • temperature: I’ve set this to 0.5. Since we are building a chatbot, we want it to be a little conversational. If you were building a code generator, you’d want this closer to 0.0.

Adding “Memory” (The Secret Sauce)

If you stop at Step 2 and just send prompts to the model, you don’t have a chatbot—you have a question-answering machine.

By default, Large Language Models are stateless. If you ask, “Hi, my name is Atiq,” and then ask, “What is my name?”, the model will have no idea who you are because it treats every request as a brand new interaction.

To fix this, we need Memory.

LangChain makes this incredibly easy with ConversationBufferMemory. It stores the history of the chat and re-sends it to the model with every new question, giving the AI “context.”

Add this to your chatbot.py file:

from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory

# 3. Create the Memory
# This will store the history of messages between "Human" and "AI"
memory = ConversationBufferMemory()

# 4. Create the Conversation Chain
# This binds the LLM and the Memory together into a single execution chain.
conversation = ConversationChain(
    llm=llm,
    memory=memory,
    verbose=True # Set to False if you don't want to see the "Thinking" logs
)

print("Bot: System is ready! Type 'exit' to stop.")

Why we use ConversationChain: This is a pre-built chain provided by LangChain specifically for chat applications. It automatically handles:

  1. Taking your new input.
  2. Reading the previous history from memory.
  3. Bundling everything into a prompt specifically formatted for Claude.
  4. Sending it to AWS Bedrock.
  5. Updating the memory with the new answer.

If you tried to write this logic manually in raw Python, it would take 50+ lines of code. With LangChain, it’s just two lines.

The Full Chatbot Script

We have the pieces—the client, the model, and the memory. Now, let’s wrap it all in a simple while loop so we can actually talk to it.

Here is the complete code. I’ve added comments so you can see exactly what is happening at each stage. Save this file as main.py.

import boto3
import sys
from langchain_aws import ChatBedrock
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory

def init_chatbot():
    # 1. Setup the Bedrock Client
    # Ensure region matches where you requested Model Access!
    bedrock_runtime = boto3.client(
        service_name="bedrock-runtime",
        region_name="us-east-1" 
    )

    # 2. Initialize the Language Model (Claude 3 Sonnet)
    llm = ChatBedrock(
        client=bedrock_runtime,
        model_id="anthropic.claude-3-sonnet-20240229-v1:0",
        model_kwargs={
            "temperature": 0.5,
            "max_tokens": 512,
        }
    )

    # 3. Add Memory so the bot remembers the conversation
    memory = ConversationBufferMemory()

    # 4. Create the Conversation Chain
    # We turn off 'verbose' to keep the terminal output clean
    conversation = ConversationChain(
        llm=llm,
        memory=memory,
        verbose=False 
    )
    
    return conversation

def main():
    try:
        print("--- initializing AWS Bedrock Chatbot ---")
        bot = init_chatbot()
        print("Bot Ready! Type 'exit' or 'quit' to stop.")
        print("------------------------------------------")

        while True:
            # Get user input
            user_input = input("You: ")
            
            # Check for exit condition
            if user_input.lower() in ["exit", "quit"]:
                print("Bot: Goodbye!")
                sys.exit()

            # Generate response
            # This is where the magic happens: LangChain sends history + new input to AWS
            response = bot.invoke(input=user_input)
            
            # Print the AI's reply
            print(f"Bot: {response['response']}")
            print("")

    except KeyboardInterrupt:
        print("\nBot: Interrupted by user. Exiting...")
    except Exception as e:
        print(f" Error: {e}")

if __name__ == "__main__":
    main()

Open your terminal and type:

python main.py

Boom. You are now chatting with Claude 3, running on AWS infrastructure, directly from your terminal.

Common Errors & Troubleshooting

If you are seeing red text instead of a chatbot, don’t panic. 90% of AWS Bedrock issues come down to permissions or regions. Here are the fixes for the errors I see most often.

1. Error: AccessDeniedException

  • The Message: “Your account is not authorized to invoke this API operation.”
  • The Fix: This almost always means you skipped the Model Access step in the AWS Console. Go back to Bedrock > Model Access and ensure “Claude 3 Sonnet” has a green checkmark next to it.
  • Note: It can take 1-2 minutes for access to propagate after you click “Save.

2. Error: ResourceNotFoundException

  • The Message: “The specified model does not exist in this Region.”
  • The Fix: Check your code: region_name="us-east-1". If your AWS Console is set to us-east-2 (Ohio) But you are trying to call a model that is only in Virginia; this will fail. Always match your code region to your console region.

3. Error: ValidationException

  • The Message: “The provided model identifier is invalid.”
  • The Fix: You might have a typo in the model_id. AWS changes these strings occasionally.
    • Wrong: anthropic.claude-v3
    • Right: anthropic.claude-3-sonnet-20240229-v1:0
    • Tip: Run aws bedrock list-foundation-models In your CLI, to get the exact ID you need.

4. Error: ThrottlingException

  • The Message: “Too many requests.”
  • The Fix: Bedrock has default quotas (limits) on how many tokens you can process per minute. If you are just testing, wait 10 seconds and try again. For production, you will need to request a quota increase via the Service Quotas console.

Conclusion & Next Steps

Congratulations! You just built a private, secure, and intelligent chatbot without managing a single API key or worrying about data privacy compliance.

Because this is running on AWS Bedrock, your data remains within your AWS boundary. It isn’t being used to train the public models, which makes this architecture perfect for building internal enterprise tools or handling sensitive data.

Where to go from here? Now that you have the core logic working, you can take this to the next level:

  1. Give it a Voice: Hook this script up to Amazon Polly to make your chatbot speak back to you.
  2. Make it an App: Wrap this Python script in Streamlit to give it a web UI.
  3. Chat with your Data: This is the “Holy Grail” of AI. In my next tutorial, I will show you how to use RAG (Retrieval-Augmented Generation) to let this chatbot read your PDF documents and answer questions about them.

Did you find this guide helpful? If you ran into any issues or have questions about AWS Bedrock, drop a comment below or reach out to me on LinkedIn. Happy coding!

Atiqur Rahman

I am MD. Atiqur Rahman graduated from BUET and is an AWS-certified solutions architect. I have successfully achieved 6 certifications from AWS including Cloud Practitioner, Solutions Architect, SysOps Administrator, and Developer Associate. I have more than 8 years of working experience as a DevOps engineer designing complex SAAS applications.

Leave a Reply