AWS Builder Center

Writing Reusable Prompts with Amazon Bedrock Prompt Management

Learn how to store, version and reuse prompts with Amazon Bedrock Prompt Management. Create a prompt with variables, test it, publish a version and call it from Python with the Converse API.

Series: Amazon Bedrock (13 articles)

  1. …
  2. 3
    Writing Reusable Prompts with Amazon Bedrock Prompt Management This article
Stop burying prompts inside your code. Store them, version them and call them by ARN, so you can improve a prompt without redeploying your app.
There's a point in almost every Bedrock project where the prompts start to sprawl. One lives in a Lambda function, another in a config file, a third in a notebook nobody remembers. Someone tweaks the wording, the output changes, and nobody can say which version was running last Tuesday.
Amazon Bedrock Prompt Management is the tidy answer. You save a prompt once, give it variables, create numbered versions, and call the one you want from your code. In this article we'll build one, test it, version it and invoke it from Python.
[Add a sentence or two here about a time prompts got out of hand in your own work, or why you wanted this.]

What you need

  • The setup from the first two articles: Python, boto3 and working Bedrock credentials
  • A model you can invoke in your chosen Region, with its ID copied from the model's card
  • About twenty minutes
As always, check the current Amazon Bedrock documentation for Region availability and pricing before you start.

Why bother?

Three practical reasons.
You change prompts without changing code. Improving a prompt becomes an edit and a new version, not a code change and a deployment.
You know what was running. Each version is a snapshot. If quality drops, you can see which version your app was calling and roll back to the previous one.
Your team shares one source of truth. Instead of three slightly different copies of the same prompt, there's one place to look.

Step 1: Create a prompt in the console

  1. Open the Amazon Bedrock console and choose Prompt management under Builder tools.
  1. Choose Create prompt and give it a name, such as  invoice-reminder .
  1. Pick the model you want to use and set any inference settings, such as temperature.
  1. Write the prompt text, using double curly braces for anything that should change from call to call.
Here's a simple example:
Plain text
Write a {{tone}} reminder email for invoice {{invoice_number}},
which was due on {{due_date}}. Keep it under 120 words.
The three names in double braces are your variables. Whatever you pass in when you call the prompt gets dropped into those spots.

Step 2: Test it before you save a version

The prompt builder lets you fill in values for each variable and run the prompt right there. Try a few different inputs: a friendly tone, a firm one, a missing due date. You're looking for two things: output you'd be happy to send, and behaviour that doesn't fall apart on unusual input.
This is the cheapest place to find problems, so spend a few minutes here.

Step 3: Create a version

When you're happy, choose Create version. This saves a snapshot of the prompt that won't change underneath you. Keep editing the working draft as much as you like. Your production code should call a numbered version, not the draft.
Copy the ARN of the version you just created. It looks like this, with your own Region, account number, prompt ID and version number:
Plain text
arn:aws:bedrock:us-east-1:123456789012:prompt/PROMPT_ID:1

Step 4: Call it from Python

In the Converse API, you pass the prompt version's ARN as the  modelId , and the variable values in a field called  promptVariables . Each value is wrapped in a small object with a  text  key.
Python
import boto3

REGION = "us-east-1" # use your Region
PROMPT_VERSION_ARN = "arn:aws:bedrock:us-east-1:123456789012:prompt/PROMPT_ID:1"

client = boto3.client("bedrock-runtime", region_name=REGION)

response = client.converse(
modelId=PROMPT_VERSION_ARN,
promptVariables={
"tone": {"text": "friendly"},
"invoice_number": {"text": "INV-1042"},
"due_date": {"text": "15 March"},
},
)

print(response["output"]["message"]["content"][0]["text"])
usage = response["usage"]
print(f"Input tokens: {usage['inputTokens']}, output tokens: {usage['outputTokens']}")
Notice what's missing. There's no model ID and no message in the request, because the model and its settings live inside the prompt. Your app only decides which prompt version to call and what values to fill in. You only need to provide values for the variables the prompt actually defines.
There are some restrictions on which Converse fields you can combine with a managed prompt. For example, settings that belong to the prompt must be set in Prompt management, not in the request. Check the current documentation if you want to override anything.

Step 5: Improve it without touching your code

Here's where it pays off. Say the emails are a bit stiff.
  1. Edit the draft in the console and test the change.
  1. Create a new version. It will be number 2.
  1. Point your app at the version 2 ARN.
If you keep the ARN in an environment variable or a config setting, step three doesn't even need a code change. And if version 2 turns out worse, switching back to version 1 takes a minute.

Prefer to do it in code?

You can also create prompts and versions with the SDK. These calls use the  bedrock-agent  client, not  bedrock-runtime . It's the same kind of mix-up as in the first article: one client manages things, the other runs them.
Python
import boto3

agent = boto3.client("bedrock-agent", region_name="us-east-1")

prompt = agent.create_prompt(
name="invoice-reminder",
description="Polite payment reminder email.",
variants=[
{
"name": "Variant1",
"modelId": "YOUR_MODEL_ID",
"templateType": "TEXT",
"inferenceConfiguration": {"text": {"temperature": 0.3}},
"templateConfiguration": {
"text": {
"text": "Write a {{tone}} reminder email for invoice {{invoice_number}}, due on {{due_date}}."
}
},
}
],
)

version = agent.create_prompt_version(promptIdentifier=prompt["id"])
print(version["arn"])
The version ARN it prints is what you pass as  modelId  in the Converse call above.

Mistakes to avoid

Calling the draft in production. Drafts change. Always call a numbered version so your app behaves the same tomorrow as it does today.
Forgetting a variable. If the prompt defines a variable and you don't supply a value, you'll get an error or an odd result. Keep a short note of each prompt's variables next to the code that calls it.
Putting secrets in prompts. A prompt is stored text. Don't paste API keys, personal data or confidential figures into it.
Skipping the test step. It takes two minutes in the console and saves a bad surprise in production.
Getting an access error. Make sure the identity you're using can invoke models and use the prompt. If you see  AccessDeniedException , check your IAM permissions first.

Where we are now

You've turned a loose piece of text into a versioned, reusable asset that your app calls by ARN. That's a small change that makes everything after it easier to manage.
In the next article we'll add guardrails to a Bedrock app and test how well they hold up.
Features, Region availability, restrictions and pricing change often. Check the current Amazon Bedrock documentation before you follow any step here.

Series: Amazon Bedrock (13 articles)

  1. …
  2. 3
    Writing Reusable Prompts with Amazon Bedrock Prompt Management This article
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article