This closing topic assembles everything from the module into one realistic pipeline: a messy, human-maintained spreadsheet goes in, and a reviewed stakeholder-ready summary comes out, with an AI agent doing the profiling, cleaning, analysis, and drafting — and a human doing the one thing that still requires judgment, which is deciding what's worth saying and confirming the numbers before they leave the building.
Workflow Overview: From Messy Spreadsheet to Reviewed Report
The scenario: a Support-Tickets spreadsheet fed by a helpdesk export, updated daily, with the usual real-world mess — inconsistent date formats from a tool migration eight months ago, a handful of duplicate ticket IDs from a sync bug that was fixed but left artifacts, blank priority fields on older rows, and three renamed columns nobody updated the downstream formulas for. The goal: a weekly summary for a leadership Slack channel covering ticket volume, resolution time trends, and any priority-1 tickets still open past SLA.
The pipeline has four stages, each a separate reviewed step rather than one long unattended prompt:
1. Profile → understand what's actually in the sheet, don't assume the schema
2. Clean → fix or flag data quality issues, in place or in a derived range
3. Analyze → compute the metrics that matter, write them somewhere durable
4. Summarize → turn numbers into a narrative, get it in front of a human, then send
Splitting these matters for a reason beyond caution: each stage has a different failure mode, and conflating them makes failures harder to attribute. A wrong number in the final summary could be a profiling miss (wrong column assumed), a cleaning bug (a date parsed wrong), an analysis error (wrong aggregation), or a summarization error (correct numbers, wrong framing). Four stages means four places to look, not one opaque one.
Run this as four separate prompts in one working session, reviewing output between each — not as background automation, at least not yet. This topic ends with a note on what it takes to eventually make stage 1–3 unattended and keep stage 4 human-reviewed permanently.
Tips
- Keep pipeline stages as separate, reviewable prompts rather than one compound instruction — when something's wrong in the output, you want to know which stage introduced it without re-deriving the whole chain.
- Name the stages in your prompts explicitly ("this is the profiling step," "this is the cleaning step") — it keeps the agent's own reasoning scoped to that stage's concerns rather than jumping ahead to analysis before cleaning is confirmed done.
- Budget for this as a 15–20 minute reviewed workflow the first several times you run it for a new sheet — the time investment drops sharply once you've validated the schema and logic, but don't expect full unattended trust on week one.
Step 1: Profiling the Sheet, Detecting Schema, and Cleaning Data
Never skip straight to analysis on a sheet you haven't profiled this session, even one you've worked with before — schemas drift.
Read Support-Tickets!A1:J1 (header row) and Support-Tickets!A2:J50
(a sample) from spreadsheet 1PqRsTuVwXyZaBcDeFgHiJkLmNoPq.
Tell me:
- The actual column headers and what data type each appears to hold
- Any column whose header looks renamed or inconsistent with what
you'd expect (compare to: ticket_id, created_at, resolved_at,
priority, status, assignee, category)
- Row count estimate for the full sheet (check the sheet's used range)
- Any obvious data quality issues visible in this 50-row sample:
blank required fields, inconsistent date formats, duplicate ticket_id
This surfaces the renamed-columns problem and the inconsistent-date-format problem before they corrupt anything downstream — exactly the kind of thing that would otherwise show up three steps later as "why is the resolution time negative for these twelve rows."
With the real schema confirmed, clean explicitly rather than assuming the agent's guess about intent is right:
Full read: Support-Tickets!A2:J[actual last row from profiling].
For cleaning, write results to new columns starting at K, don't
modify A-J:
- K: created_at normalized to ISO 8601 (handle both "MM/DD/YYYY" and
"DD-Mon-YYYY HH:mm" formats seen in the sample — flag anything
that matches neither as "UNPARSEABLE")
- L: duplicate_flag = "DUPLICATE" if this ticket_id appears more than
once in the sheet, else blank
- M: priority_filled = original priority value, or "UNSET" if blank
Show me counts: how many UNPARSEABLE dates, how many DUPLICATE flags,
how many UNSET priorities. Don't write to the sheet yet — show me
the summary counts first.
The "don't modify A-J" instruction is the load-bearing line in that prompt — it converts a genuinely risky cleaning operation (rewriting source columns) into a safe additive one (new columns holding cleaned/flagged derivatives), fully in line with the destructive-write guardrails from the first topic in this module. Review the counts — an UNPARSEABLE count that's suspiciously high usually means a third date format exists in the full dataset that wasn't in your 50-row sample — before committing the write:
Write columns K, L, M as designed to Support-Tickets!K2:M[last row].
Add headers "created_at_iso", "duplicate_flag", "priority_filled" to
K1:M1. Use valueInputOption RAW.
Tips
- Profile against a small sample before committing to a full-range read and clean — a 50-row sample surfaces schema drift and format inconsistencies cheaply, before they're baked into a full-sheet operation.
- Write cleaned/derived values to new columns, never overwrite source columns — this is non-negotiable for any sheet fed by an external, uncontrolled process like a helpdesk export.
- Treat an unexpectedly high error/flag count from the cleaning step as a signal to re-sample, not to proceed — it usually means your format assumptions don't cover the full dataset.
Step 2: Running Analysis and Writing Derived Metrics Back
With clean, flagged data available in columns K–M, the analysis step can trust its inputs — which is the entire point of not skipping steps 1 and the review pauses in the prompts above.
Read Support-Tickets!A2:M[last row] (now includes cleaned columns).
Exclude rows where duplicate_flag = "DUPLICATE" (keep only the first
occurrence per ticket_id) and where created_at_iso = "UNPARSEABLE".
Compute for the last 7 days (created_at_iso >= 2026-08-14):
- ticket_volume: count of tickets created
- avg_resolution_hours: for resolved tickets only, average of
(resolved_at - created_at_iso) in hours
- sla_breaches: count where priority_filled = "P1" and status = "Open"
and created_at_iso is more than 24 hours ago
- by_category: ticket_volume broken down by category column
Write and run a script for the resolution-time math rather than
computing it in your response — don't hand-calculate hour differences
across dozens of rows.
Show me all numbers before writing anywhere.
The explicit call to script-execute the date-math is a direct application of the analysis guidance from the Gemini CLI topic — resolution-time calculations across real timestamp data are exactly the kind of arithmetic an LLM will get subtly wrong at volume even when it's confident, and a five-line Python script removes the ambiguity entirely.
Review the sla_breaches number with particular care — this is the number most likely to trigger an actual leadership conversation, and it's worth a manual spot-check:
Show me the 3 tickets contributing to sla_breaches with the longest
open duration, so I can sanity-check them against what I remember
being open.
Once satisfied, write the metrics to a durable location — not just chat output, since next week's report will want to compare against this week's numbers:
Create tab "Weekly-Metrics" if it doesn't exist, with columns:
week_start, ticket_volume, avg_resolution_hours, sla_breaches.
Append one new row for week_start = 2026-08-14 with this week's
values — don't overwrite prior weeks' rows, only append.
Append-only is the right pattern for a metrics history tab specifically — it turns "what changed since last week" into a trivial two-row comparison later, and it makes an accidental overwrite of this week's row far less costly than an accidental overwrite of a whole tab would be.
Tips
- Script-execute any timestamp or duration math over more than a handful of rows — this is the single highest-value guardrail in the entire analysis stage.
- Spot-check the headline number most likely to drive a real decision or conversation (SLA breaches, in this example) against specific named rows before trusting the aggregate.
- Structure a recurring metrics tab as append-only with a clear period key (week_start) — it's safer to write to and it gives you trend history for free.
Step 3: Generating the Narrative Summary and Distributing It
The last stage turns validated numbers into something a non-technical stakeholder will actually read, and it's the stage most tempting to skip the human-review pause on — resist that temptation, because framing errors here are the ones that actually reach an audience.
Using this week's row from Weekly-Metrics (week_start 2026-08-14) and
the prior 4 weeks for trend context, draft a Slack-ready summary:
- One headline line: ticket volume vs. the 4-week average, with
direction (up/down/flat) and rough magnitude.
- One line on resolution time trend.
- One line on SLA breaches — call it out clearly if non-zero, don't
soften it, but don't editorialize with cause or blame, just the number
and a pointer to check the 3 flagged tickets.
- Keep it under 80 words total. No corporate hedging language, no
"as previously mentioned," no filler.
Show me the draft here. Don't send or post anything.
Explicitly banning "corporate hedging language" and cause-attribution in the prompt is doing real work — a model asked to summarize SLA breaches without that constraint will often reach for softening language ("there were a few tickets that experienced some delay") that actively obscures the number leadership needs to see plainly, or will speculate about causes it has no actual evidence for from the data alone.
Read the draft. This is the one step in the whole pipeline that stays a human judgment call indefinitely, even once you've fully automated steps 1–3 for a mature, trusted pipeline — a technically accurate summary can still be the wrong summary for the audience or the moment (a bad week right before a board meeting needs different framing consideration than a routine Tuesday), and that's not something to hand off.
Once approved, distribution is a separate, deliberate step — paste it into Slack yourself, or if you've built out messaging MCP integration elsewhere in your toolchain (see this course's Slack MCP module), route it there explicitly rather than letting a spreadsheet-focused session reach for a messaging tool it happens to have access to:
Also write this exact summary text to Weekly-Metrics!F[this week's row]
as a "summary_sent" column, so we have a record of exactly what was
communicated for this week alongside the numbers it was based on.
That last write is worth doing every time — it's cheap, and it means six months from now, when someone asks "what did we tell leadership about the ticket backlog in mid-August," the answer lives right next to the data it was drawn from, not buried in Slack history.
On eventually automating this end to end: once you've run this pipeline manually for 4–6 weeks and steps 1–3 have produced zero surprises, it's reasonable to script steps 1–3 as an unattended job (a scheduled script calling the Sheets API directly, not necessarily an MCP-based agent session) and keep step 4's narrative draft — and the decision to actually post it — as a permanent human checkpoint. The moment you fully automate the summary and its distribution, you've removed the one safeguard that catches "technically correct, wrong to say right now."
Tips
- Explicitly instruct the agent to avoid hedging language and cause-speculation in stakeholder-facing summaries — both are common LLM tendencies that actively reduce the usefulness of a report meant to inform a real decision.
- Keep the review-and-send decision on the narrative step as a permanent human checkpoint, even after you've automated the profiling, cleaning, and analysis stages for a mature pipeline.
- Write the exact distributed summary text back to your metrics tab alongside the numbers it describes — a small habit that pays off the first time someone needs to audit what was actually communicated and when.
Tips
The pattern underlying this whole pipeline — profile before you trust a schema, clean additively rather than destructively, script-execute math you'd otherwise eyeball, and keep a human checkpoint on anything that reaches an actual audience — generalizes past support tickets to nearly any recurring Google Sheets MCP reporting workflow you'll build. The AI does the tedious, error-prone parts reliably; the review pauses are what make the output trustworthy enough to actually ship.
Tips
- Reuse this four-stage shape (profile, clean, analyze, summarize) as your default template for any new recurring spreadsheet report, rather than improvising a new structure each time.
- Keep at least one review pause per pipeline run for the first month on any new sheet, even once individual stages feel reliable — schema and data-quality drift happens on the source side, outside your control.
- Automate what's safe to automate (profiling, additive cleaning, scripted analysis) well before you automate what isn't (final review and distribution) — collapsing that boundary too early is the most common way these pipelines produce an embarrassing wrong number in front of an audience.