AWS Builder Center
Build “Plan My Week”: A Multi-Step AI Workflow Agent with Amazon Bedrock AgentCore

Build “Plan My Week”: A Multi-Step AI Workflow Agent with Amazon Bedrock AgentCore

Learn how to build a practical AI study-planning agent on AWS using Amazon Bedrock AgentCore, AWS Lambda, Amazon S3, DynamoDB, and Amazon SES. The agent combines calendar events, course materials, deadlines, and user preferences to generate a realistic weekly study plan and deliver it through email or Slack. This hands-on project teaches students how to move beyond simple LLM chatbots and build tool-using, multi-step AI workflows with real AWS services.

Series: Lets go with AI and AWS (4 articles)

  1. 1
    Build “Plan My Week”: A Multi-Step AI Workflow Agent with Amazon Bedrock AgentCore This article
A few weeks ago I got tired of watching students (myself included, a while back) build the same first AI project over and over: send a prompt to a model, print the response, call it a portfolio piece. It's a fine starting point, but it doesn't look anything like the AI systems companies are actually shipping. Real applications pull in data from multiple places, call tools, reason over messy inputs, and sometimes take action on your behalf.
So here's a project that tries to close that gap: an agent that plans your week for you.
You tell it:
"Plan my next week."
And it looks at your calendar, checks what's due in your classes, pulls in relevant course material, considers when you actually like to study, and hands back a schedule you can use not a vague suggestion, an actual plan with times and tasks attached.
That's what we're building: Plan My Week, a multi-step agent built on Amazon Bedrock AgentCore.

What we're actually building

The agent pulls context from a handful of sources:
  • Google Calendar or Outlook, for existing commitments
  • Course syllabi and notes, stored in S3
  • Deadlines, whether from a syllabus or an LMS export
  • User preferences when you like to study, how long your sessions should be
  • Amazon Bedrock, to reason over all of it and produce a plan
The key difference between this and a typical chatbot project is the shape of the workflow. A chatbot looks like:
User → LLM → Response
This agent looks more like:
User → retrieve context → call tools → reason → generate a structured plan → notify → (optionally) act
That extra structure is the whole point of the exercise. It's where most of the useful learning happens.

Architecture at a glance

ComponentWhat it does
Amazon Bedrock AgentCoreRuns the agent itself
Amazon BedrockProvides the LLM reasoning
AWS LambdaImplements each external tool
Amazon S3Stores course materials and generated plans
DynamoDBStores preferences and plan history
Secrets ManagerHolds API credentials
Amazon SES / SlackDelivers the plan to the user
Google Calendar / OutlookSupplies calendar data
CloudWatchLogging and observability

Step 1: Set up storage

Start with an S3 bucket to separate the material the agent reads from the material it generates:
1
2
3
4
5
6
7
8
9
10
11
12
13
s3://plan-my-week/
├── courses/
│ ├── CS301/
│ │ ├── syllabus.pdf
│ │ ├── chapter-1.pdf
│ │ └── chapter-2.pdf
│ └── CS302/
│ ├── syllabus.pdf
│ └── notes.pdf
└── plans/
└── user123/
├── 2026-09-07.json
└── 2026-09-14.json
courses/ is input, plans/ is output. Simple, but it keeps things clean as you add more logic later.

Step 2: Store user preferences

Not everyone studies the same way. One person wants mornings free for gym and prefers afternoons; another refuses to touch coursework after 9pm. DynamoDB is a natural fit for this kind of per-user, semi-structured data:
1
2
3
4
5
6
7
8
{
"user_id": "user123",
"study_start": "08:00",
"study_end": "21:00",
"preferred_session_length": 90,
"preferred_days": ["Monday", "Tuesday", "Thursday", "Saturday"],
"break_duration": 15
}
This is what turns a generic schedule into a personal one the agent now has real constraints to work within instead of guessing.

Step 3: The calendar tool

The first tool the agent needs is get_calendar_events(). Its job is narrow: fetch the user's upcoming events and hand them back in a consistent format.
1
2
3
4
5
def get_calendar_events(start_date, end_date):
# authenticate with the calendar provider
# fetch events in the given range
# normalize into a standard structure
return events
Implement it as a Lambda function. The important design decision here is that the agent should never need to know how Google Calendar or Outlook's APIs work it just calls get_calendar_events() and gets structured data back. All the provider-specific mess stays inside the tool.

Step 4: The course materials tool

Next, fetch_course_materials(), which pulls relevant files or metadata out of S3 for a given course:
1
2
3
4
5
6
7
{
"course": "CS301",
"materials": [
{ "name": "Chapter 3", "topic": "Database Normalization" },
{ "name": "Assignment 2", "topic": "Normalization and SQL" }
]
}
You can eventually layer in embeddings and semantic search here, but resist the urge to start there. Get the basic version returning something usable first you can always make retrieval smarter later.

Step 5: Let Bedrock generate the plan

By this point the agent has calendar events, course materials, deadlines, and preferences in hand. Now it hands all of that to Bedrock and asks it to reason over the constraints.
A simplified version of the prompt:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
You are a study planning assistant.

Create a realistic weekly study plan using:
1. Upcoming calendar events
2. Course deadlines
3. Available study materials
4. User study preferences

Rules:
- Never schedule study sessions over existing calendar events.
- Prioritize approaching deadlines.
- Respect the user's preferred study hours.
- Include breaks between long sessions.
- Avoid unrealistic workloads.
- Break large assignments into smaller tasks.

Return the plan as structured JSON.
And the output should come back as something a downstream system can actually consume, not just a paragraph of prose:
1
2
3
4
5
6
7
8
9
10
{
"days": [
{
"date": "2026-09-10",
"blocks": [
{ "time": "08:30-10:00", "course": "CS301", "task": "Read Chapter 3", "priority": "high" }
]
}
]
}
Structured output matters here it's what lets you render the plan in a UI, write it to a calendar, or hand it to another process without any brittle text parsing.

Step 6: Wire it together with AgentCore

This is where the individual pieces become an agent rather than a pile of scripts. AgentCore decides, based on the user's request, which tools it needs and in what order:
1
2
3
4
5
6
User: "Plan my next week."
→ agent decides it needs calendar data → calls get_calendar_events()
→ agent decides it needs course context → calls fetch_course_materials()
→ agent has enough context → calls Bedrock to reason
→ returns a structured weekly plan
That dynamic tool selection the agent deciding what it needs rather than following a fixed script is the core idea behind a tool-using agent, and it's the part that's genuinely different from a traditional pipeline.

Step 7: Deliver the plan

Once the plan exists, send it somewhere useful Amazon SES for email, or Slack if that fits your audience better:
1
2
3
4
5
6
7
8
9
Your Study Plan — September 10–16

Monday
08:30–10:00 CS301: Read Chapter 3
14:00–15:00 CS302: Review lecture notes

Tuesday
09:00–10:30 CS301: Solve Q1–Q5
18:00–19:00 CS302: Assignment prep
At this point the agent has gone from raw, scattered data to something a person can actually act on.

Step 8 (optional): Write back to the calendar

You could stop at "email the plan," but it's more interesting to close the loop. Ask the user:
"Want me to add these study blocks to your calendar?"
If they say yes, a separate tool create_calendar_events() handles the write. This is a good place to slow down and think about the distinction between an AI suggesting an action and an AI performing one. Writing to someone's calendar is an external side effect, and it deserves explicit approval rather than happening automatically:
1
Generate plan → show user → user approves → create calendar events
This is the human-in-the-loop pattern in practice: the model does the reasoning, but a person stays in control of anything consequential.

An alternative: AWS Step Functions

Everything above assumes the agent decides its own workflow dynamically. You could instead hard-code the sequence with Step Functions:
1
GetCalendar → FetchMaterials → GeneratePlan → SendNotification → CreateEvents
This trades flexibility for predictability useful when you want a workflow that's deterministic, easy to audit, and easy to visualize in the console.
AgentCoreStep Functions
BehaviorDynamicDeterministic
Tool callingNatural fitExplicit states
Conversational interactionStrongLimited
Workflow visibilityDepends on the agentExcellent
Human approvalPossibleExcellent
Best forAI agentsBusiness workflows
I'd build the core project on AgentCore and treat Step Functions as a worthwhile extension once the basics work, it's a good way to compare the two approaches directly instead of just reading about the trade-offs.

Plan for things to fail

Google Calendar's API will go down at some point, or rate-limit you, or just time out. When that happens, the agent shouldn't crash, it should degrade gracefully:
1
2
3
Calendar API fails → retry → still failing?
→ tell the user: "Couldn't reach your calendar. Here's a plan
based on what I could find."

The same goes for S3 outages, failed email delivery, malformed JSON from the model, or rate-limited external APIs. Build in retries, timeouts, validation, and a sane fallback path. None of this is AI-specific, it's just what separates a demo from something you'd trust to run unattended.

A word on cost

This project scales down nicely. At, say, 100 users generating one plan a week, roughly 400 plans a month your dominant cost is LLM inference; Lambda, S3, DynamoDB, and Step Functions stay cheap at that volume. Rather than trying to pin down an exact monthly number for a portfolio project, focus on showing you understand what drives the cost:
  • pick a Bedrock model sized for the task, not the biggest one available
  • keep prompts lean : send relevant snippets, not entire documents
  • cache anything that doesn't change often
  • avoid regenerating a whole plan when only one input changed
  • keep CloudWatch logs useful, not bloated

What you'll actually learn

  • Agent architecture : the real difference between a chatbot, a tool-using agent, and a deterministic workflow
  • Amazon Bedrock : using a foundation model for reasoning, not just Q&A
  • AgentCore : designing around tools, sessions, and runtime execution
  • Lambda : exposing capabilities as independent, composable functions
  • S3 : organizing unstructured source material alongside generated output
  • DynamoDB : using NoSQL for preferences and state
  • API integration : working with real external services like Google Calendar
  • Structured output : getting the model to return JSON you can actually use downstream, instead of prose you'd have to parse
  • Human-in-the-loop design : knowing which actions need explicit approval
  • Reliability : logging, retries, and validation matter as much as the prompt

Taking it further

Once the basic loop works, there's a lot of room to grow it:
Beginner: just Calendar → Bedrock → Plan.
Intermediate: add S3 course materials, DynamoDB preferences, and SES notifications.
Advanced: add deadline extraction, real document retrieval, calendar write-back, approval flows, and plan history.
If you want a real challenge: support something like "I only have two hours free Thursday, move my database session." That means the agent has to pull up the existing plan, understand the requested change, re-check the calendar, find a new slot, update the plan, get approval, and push the change back to the calendar. At that point you're not building a demo anymore, you're building a system with real state, constraints, and consequences.
While you're testing, try feeding it awkward inputs on purpose: conflicting events, five deadlines in the same week, an empty syllabus, a missed session that needs rescheduling. Watching how the agent handles the edge cases is usually more instructive than watching it handle the happy path.

Mistakes worth avoiding

Building everything at once. It's tempting to sketch out an architecture with RAG, multi-agent coordination, a vector database, Slack, calendar write-back, and a full frontend before you've written a single Lambda function. Build the smallest working loop first, then expand it.
Letting the LLM decide everything. Not every question needs a model. "Does this time slot overlap an existing event?" is a plain conditional, write it in code. Save the LLM for the parts that genuinely need reasoning or language understanding.
Giving the agent more permission than it needs. Scope tool access tightly, and require approval before anything with a real-world side effect, like writing to a calendar.
Trusting model output blindly. LLMs occasionally return malformed JSON. Validate before you use it, and have a retry or repair path ready for when it fails.

What I'd change next time

If I rebuilt this from scratch, I'd spend more time on deadline extraction, smarter document retrieval, and better calendar-conflict detection. I'd also want some way to evaluate plan quality over time, a feedback loop from actual usage, and cost tracking broken out by workflow step rather than lumped together. None of that makes the agent more complicated for the sake of it - it makes it more useful, which is the actual goal.

Suggested repo layout

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
plan-my-week/
├── agent/
│ ├── agent.py
│ ├── prompts/
│ │ └── study_planner.txt
│ └── tools/
│ ├── calendar.py
│ ├── materials.py
│ ├── notification.py
│ └── calendar_writer.py
├── infrastructure/
│ ├── s3/
│ ├── dynamodb/
│ ├── lambda/
│ └── agentcore/
├── tests/
├── docs/
│ ├── architecture.md
│ └── architecture.png
├── requirements.txt
└── README.md
Your README should cover the problem statement, the architecture, the AWS services involved, setup steps, a sample input and generated plan, screenshots, cost notes, and what you learned along the way ; that last part is often what makes a portfolio project actually memorable to a reviewer.

Where to start

If you want to build this, start small: Lambda, S3, DynamoDB, Bedrock, AgentCore, in roughly that order, one piece at a time. Your first version doesn't need to be production-ready it just needs to work end to end. Then break it on purpose: conflicting events, an empty syllabus, five deadlines crammed into one week. Fixing what breaks is where you actually learn the material.
There's a real difference between knowing what AWS services exist and knowing how to put them together into something that works. This project is a reasonable-sized bridge between the two useful for internship applications, hackathons, or just a portfolio piece that isn't another wrapper around a single prompt.

Architecture diagram (PlantUML)

For a cover image, a UML component diagram communicates the system better than a generic flowchart:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
@startuml
title Plan My Week — AI Study Planning Agent

skinparam componentStyle rectangle
skinparam shadowing false
skinparam defaultTextAlignment center

actor Student

rectangle "User Interface" {
component "Web UI / API" as UI
}

package "Amazon Bedrock" {
component "Amazon Bedrock\nAgentCore Runtime" as Agent
component "Foundation Model\n(Planning & Reasoning)" as LLM
}

package "Agent Tools" {
component "Calendar Tool" as CalendarTool
component "Course Materials Tool" as MaterialTool
component "Notification Tool" as NotifyTool
component "Calendar Update Tool" as CalendarWrite
}

package "AWS Services" {
database "Amazon S3\nCourse Materials\n& Study Plans" as S3
database "Amazon DynamoDB\nUser Preferences\n& Plan History" as DDB
component "AWS Lambda" as Lambda
component "AWS Secrets Manager" as Secrets
component "Amazon CloudWatch" as CW
}

cloud "Google Calendar /\nMicrosoft Outlook" as Calendar
cloud "Email / Slack" as Notification

Student --> UI : "Plan my week"
UI --> Agent : Request

Agent --> CalendarTool : Get events
Agent --> MaterialTool : Fetch materials
Agent --> DDB : Get preferences

CalendarTool --> Lambda
MaterialTool --> Lambda
NotifyTool --> Lambda
CalendarWrite --> Lambda

Lambda --> Calendar : Calendar API
Lambda --> S3 : Course files
Lambda --> Secrets : Credentials

Agent --> LLM : Context + constraints
LLM --> Agent : Structured study plan

Agent --> NotifyTool : Send plan
NotifyTool --> Notification

Agent --> CalendarWrite : After approval
CalendarWrite --> Calendar : Create study blocks

Agent --> S3 : Store generated plan
Agent --> CW : Logs & traces

@enduml
#AWS #Amazon Bedrock #Amazon Bedrock #AgentCore #Generative AI #AI Agents #Agentic AI #AWS Lambda #Amazon S3 #Amazon DynamoDB #AWS Step Functions #Cloud Computing #Serverless #Student Projects #AI Projects #Machine Learning #AWS Builder Center

Series: Lets go with AI and AWS (4 articles)

  1. 1
    Build “Plan My Week”: A Multi-Step AI Workflow Agent with Amazon Bedrock AgentCore 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