THE SHAPE OF THE PROJECT
Keep the agent local and let Bedrock handle inference
A Strands agent does not have to be deployed before it can be useful. In this starter, the Python process runs locally, Strands coordinates the model and tools, and Amazon Bedrock performs inference in AWS.
The example has one deliberately small job: ask an agent to count the words in a sentence. That gives us a complete path—AWS authentication, model configuration, tool registration, and a real model invocation—without hiding the important pieces inside a larger application.
The complete starter is available in p-cap/special-octo-adventure on GitHub ↗.
LOCAL SETUP
Install the locked environment and sign in to AWS
The repository uses Python 3.13 and uv. Syncing the project installs the locked dependencies, including Strands Agents, Boto3, the CRT-enabled Botocore package, and python-dotenv.
git clone https://github.com/p-cap/special-octo-adventure.git
cd special-octo-adventure
uv sync
aws loginIf you use a named AWS profile, select it before running the application.
export AWS_PROFILE=your-profileBEDROCK CONFIGURATION
Keep the Region and model ID outside the code
The application loads its Bedrock settings from a local .env file. Choose a model or inference profile that is available to your AWS identity in the configured Region.
AWS_REGION=us-east-1
BEDROCK_MODEL_ID=your-bedrock-model-or-inference-profile-idThe repository excludes .env, virtual environments, and local AWS files from Git. Credentials remain in the normal AWS credential chain; they are not copied into the project.
FAIL FAST
Verify the AWS identity before creating the agent
A short STS request confirms that Boto3 can resolve credentials and reach AWS. It prints the account and caller ARN, then stops the program if authentication or SDK initialization fails.
def aws_connection_test():
try:
import boto3
sts = boto3.client("sts", region_name="us-east-1")
identity = sts.get_caller_identity()
print("Connected to AWS")
print("Account:", identity["Account"])
print("Identity:", identity["Arn"])
except BotoCoreError as error:
print("AWS SDK or connection error:", error)
raise
except LoginTokenLoadError as error:
print(error)
raiseThis is only an identity check. A successful STS call proves that the credentials work; the later model invocation proves that the identity can use the selected Bedrock model.
STRANDS + BEDROCK
Give the agent a model and one focused tool
The @tool decorator turns an ordinary typed Python function into a tool Strands can present to the model. The system prompt tells the agent when to use it, while BedrockModel supplies the model provider.
load_dotenv()
@tool
def count_words(text: str) -> int:
"""Count whitespace-separated words in the provided text."""
return len(text.split())
model = BedrockModel(
model_id=os.environ["BEDROCK_MODEL_ID"],
region_name=os.environ["AWS_REGION"],
)
agent = Agent(
model=model,
system_prompt=(
"You are a helpful assistant. "
"Use the count_words tool when asked to count words."
),
tools=[count_words],
)
agent(
'How many words are in this text: '
'"Strands makes building agents easy"?'
)The tool returns a deterministic integer; the model decides to call it and turns the result into a response. That separation is the useful pattern: let tools perform precise work, and let the model decide how to use their results.
RUN AND TROUBLESHOOT
One command exercises the full path
uv run main.pyThe script first prints the AWS account and caller ARN, then creates the agent and sends the sample question. If it stops before the greeting, refresh the AWS login or check the selected profile. If STS succeeds but Bedrock fails, verify the Region, model identifier, model access, and bedrock:InvokeModel permissions for that identity.
Model invocation uses your AWS account and may incur charges. The starter is intentionally local: there is no AgentCore deployment in this path.
SOURCE MATERIAL