Daily automation with Agent Flows
As part of my role at Microsoft, being on the customer-facing field team, we’re encouraged to use agentic AI to improve how we work internally. One place I’ve leaned into that is automating the more administrative parts of my personal planning and note-taking system.
I keep most of my notes as plain Markdown files stored in OneDrive for Business. That includes weekly plans, project notes with links to key systems, and a handful of other durable artifacts. One note I create every day is a Daily Note. It’s where I think through the day, set priorities, and make sure I’m focused on the right things.
The biggest drawback to this system is the manual setup. Gathering meeting details, formatting them, pulling in project context–it all adds up. I spend 5–15 minutes a day just getting the information into place. Once it’s there, it’s incredibly helpful. Getting there is the tax.
Copilot can already help with some of this information gathering, but I haven’t found a single prompt that reliably does everything I want, every day.
Enter: Agent Flows
The steps I follow are pretty straightforward. If I had an admin, much of this prep work could be delegated. But I don’t, and even if I did, I’d rather have them focused on higher-value work.
Copilot Studio’s Agent Flows turn out to be a great fit for exactly this kind of problem:
- Deterministic data shaping
- Predictable inputs for downstream AI prompts
- Explicit control over APIs and transformations
- Reusable, composable building blocks (including prompt templates)
- The ability to interact with Copilot or other agents
I recently built a pattern for summarizing today’s meetings directly into my Daily Note. That exercise surfaced a handful of design and technical decisions that are worth calling out. The output I want includes both a simple list of meetings and a short narrative summary derived from that list.
1. Retrieve broad, normalize narrow
The flow retrieves all calendar events for a defined time window using a calendar API action. Importantly, retrieval is intentionally broad; filtering happens afterward.
Why this matters:
- Calendar APIs differ in how they classify events (busy vs. free, focus blocks, working time, etc.).
- Decoupling retrieval from filtering makes the flow more resilient to schema or metadata changes.
- In-flow filtering is easier to reason about, debug, and evolve over time.
Implementation note:
I use the Office 365 Outlook Get Calendar View of Events (v3) action. It returns individual instances of recurring meetings, which is essential for this workflow.
2. Normalize early, normalize hard
The most critical step is normalization. Calendar events are rich, deeply nested objects–great for machines, awkward for models.
Each event is intentionally collapsed into a single, compact line of text that contains only what’s relevant for summarization:
- Start time → end time (explicitly normalized to a single time zone)
- Meeting title
- Optional context (organizer, location, online indicator)
This transformation happens before any summarization prompt runs.
Why this helps:
- Less structural noise means better accuracy and fewer hallucinations
- The output becomes reusable across multiple prompts (daily summary, prep view, recap)
I implemented this using the Select data operation, concatenating the relevant properties into a single string per event.
3. Use “value-only” outputs for prompt inputs
A subtle but important decision was ensuring the normalization step outputs an array of strings, not objects.
Instead of:
{ "line": "08:30–08:55 Internal Sync" }
The flow emits:
08:30–08:55 Internal Sync
This makes it trivial to use a Join operation to produce a newline-delimited block of text–something language models handle extremely well.
Why this pattern scales:
- No schema interpretation required inside the prompt
- Works across models and prompt frameworks
- Allows iteration on the flow without rewriting prompts
Rule of thumb: If an LLM doesn’t need structure, don’t give it structure. Plain text is usually the right abstraction.
Getting this right took some trial and error. The Select action prefers structured JSON output, so I had to switch the Map field into Text mode and return only the final expression. Any other approach I tried resulted in invalid JSON.
4. Time zones are a first-class concern
Calendar data almost always comes back in UTC, and relying on a prompt to “figure it out” has never worked well for me.
The flow explicitly converts time zones during normalization rather than leaving it to model interpretation.
That ensures:
- The output matches my lived experience of the day
- Summaries reference actionable, correct times
- There’s no ambiguity about which time zone is being used
I handle this by using the start and end time values that include time zone metadata, wrapped with the ConvertTimeZone function, before the text is ever passed downstream.
Closing
This flow isn’t flashy, but it saves me time every single day and gives me a much cleaner foundation for using AI where it actually adds value. The key takeaway for me wasn’t “use a better prompt,” but shape the data so the prompt can be boring.
So far, my Agent Flows shine when you treat them less like magic and more like a dependable assistant: gather broadly, normalize aggressively, and hand the model exactly what it needs–no more, no less. Once you do that, the AI part becomes the easy part.
#Copilot-Studio #Agent-Flows #Automation #Microsoft-365 #Productivity #Calendar-Integration #Ai-Workflows