A production-shaped starter template for AI agents on Amazon Bedrock. Tools, memory, observability, Terraform IaC, evals. Fork it, set AWS_PROFILE, ship a working agent in 30 minutes.
Docs · Landing · Quickstart · Adding a tool · Deploying
- Production: Bedrock Agent Starter
- Documentation: Project docs
- GitHub: fernandofatech/bedrock-agent-starter
- Author: Fernando Francisco Azevedo · LinkedIn · GitHub
This public repository is part of a bilingual portfolio focused on solution architecture, AWS, AI, MCP/tooling, DevSecOps, and production-ready engineering practices.
Este repositório público faz parte de um portfólio bilíngue focado em arquitetura de soluções, AWS, IA, MCP/tools, DevSecOps e boas práticas de engenharia para produção.
Bedrock makes it easy to call a model. It does not make it easy to ship a real agent: tool registry, multi-turn memory, structured observability, eval harness, IaC, error handling, prompt caching, model fallbacks — all yours to wire up.
This starter wires them up. Opinionated where it should be, replaceable where it shouldn't.
- Agent loop using the Bedrock Converse API — stable across Claude / Nova / Llama / Mistral, with first-class tool use.
- Tool registry with three working tools (
calculator,get_time,web_searchstub) and a four-line pattern to add your own. - Pluggable memory — in-memory for local dev, DynamoDB for prod.
- Structured observability — JSON logs with
session_id,turn,model_id; CloudWatch EMF metrics for tokens, latency, tool calls. - Local CLI (
agent chat) to iterate without leaving the terminal. - AWS Lambda handler + API Gateway wiring via Terraform.
- Eval harness with a golden JSONL set and a
pytest-driven runner. - CI (ruff + mypy + pytest), docs (MkDocs Material), dependency-free static landing.
git clone git@github.com:fernandofatech/bedrock-agent-starter.git
cd bedrock-agent-starter
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
# Set AWS creds and the model id (Claude Sonnet by default).
export AWS_REGION=us-east-1
export BEDROCK_MODEL_ID=anthropic.claude-3-5-sonnet-20241022-v2:0
# Chat with the agent locally.
agent chatType a question. Hit Enter. The agent reasons, calls tools, replies.
> what time is it in Tokyo, and what is (123 * 456) - 789?
[tool] get_time(tz="Asia/Tokyo") → "2026-05-15T22:41:09+09:00"
[tool] calculator(expression="(123 * 456) - 789") → 55299
It is 22:41 in Tokyo, and (123 × 456) − 789 = 55 299.
A tool is one decorator + one function:
# src/agent/tools.py
from agent.tools import tool
@tool(description="Translate text between languages using a deterministic table.")
def translate(text: str, source_lang: str, target_lang: str) -> str:
...
return translatedThe agent picks it up automatically. Pydantic infers the JSON schema from your annotations. Full guide: docs/adding-a-tool.
cd terraform
terraform init
terraform apply -var="project=my-agent"Provisioned: Lambda (Python 3.12), API Gateway HTTP API, DynamoDB sessions table, IAM roles, CloudWatch log group. State backend, tags, naming and IAM boundaries are intentionally left for you.
Every turn emits a structured JSON log line:
{
"level": "info",
"session_id": "s_abc...",
"turn": 3,
"model_id": "anthropic.claude-3-5-sonnet-20241022-v2:0",
"input_tokens": 420,
"output_tokens": 88,
"tool_calls": ["calculator"],
"duration_ms": 1830
}EMF metrics published to CloudWatch namespace BedrockAgent:
Turns(Count)InputTokens,OutputTokens(Count)Duration(Milliseconds)ToolErrors(Count)
pytest tests/evals/The runner replays the prompts in tests/evals/golden.jsonl and checks each expected substring / tool-call against the actual output. Fail on regressions.
.
├── src/agent/ # agent core, tools, memory, observability, CLI, Lambda handler
├── tests/ # unit tests + eval harness
├── terraform/ # IaC skeleton (Lambda, API Gateway, DynamoDB, IAM)
├── docs/ # MkDocs Material (GitHub Pages)
├── frontend/ # dependency-free static landing (Vercel)
└── .github/workflows/ # CI + docs deploy
This portfolio repo ships with automated checks for production-shaped engineering hygiene:
- Python: Ruff, mypy, pytest.
- Terraform: recursive
terraform fmtcheck. - Frontend: lint, static build, and
npm audit. - Docs: strict MkDocs build and GitHub Pages deploy.
- Security: CodeQL, pip-audit, dependency review, Trivy filesystem scan, and Gitleaks secret scan.
- Maintenance: Dependabot for GitHub Actions, Python dependencies, and frontend dependencies.
- Vercel: automatic preview and production deploys are connected through Vercel Git integration.
See OPERATIONS.md for the full workflow and required secrets.
- Bedrock Guardrails wiring (off by default).
- Streaming responses (Converse Stream API).
- Multi-model fallback (Sonnet → Haiku on throttle).
- Vector retrieval tool (Bedrock Knowledge Base).
- OpenTelemetry exporter for traces.
Issues and PRs welcome. See CONTRIBUTING.md — Conventional Commits required.
MIT © Fernando Francisco Azevedo
Fernando Francisco Azevedo — Solution Architect, AWS & AI focus. fernando@moretes.com · LinkedIn · fernando.moretes.com