Report Writer
[Live] ·
agent__report-writer· Claude Sonnet 4.6
Compiles all monthly performance data across channels into a structured, client-facing Markdown report with an executive summary, channel-by-channel breakdown, goal progress tracker, wins, and next-month focus areas.
Overview
| Function | Produce the monthly client performance report from multi-channel data |
| Type | Worker — Reporting |
| Model | Claude Sonnet 4.6 |
| Queue | agent__report-writer |
| Concurrency | 2 |
| Timeout | 8 min |
| Est. cost / task | ~$1.20 |
| Plan | Pro+ |
Input
interface ReportWriterInput {
tenantId: string;
campaignId: string;
reportMonth: string; // e.g. "2026-03" — the month being reported on
// Data sources — all pre-fetched by the control plane before dispatching this job.
// The agent does not call these APIs itself; it receives the data as structured objects.
ga4Data: {
sessions: MetricWithComparison;
users: MetricWithComparison;
newUsers: MetricWithComparison;
bounceRate: MetricWithComparison;
avgSessionDuration: MetricWithComparison;
conversions: MetricWithComparison;
conversionRate: MetricWithComparison;
topLandingPages: { page: string; sessions: number; conversionRate: number }[];
channelBreakdown: { channel: string; sessions: number; conversions: number }[];
goalCompletions: { goalName: string; completions: number; target?: number }[];
};
googleAdsData?: {
spend: MetricWithComparison;
impressions: MetricWithComparison;
clicks: MetricWithComparison;
ctr: MetricWithComparison;
cpc: MetricWithComparison;
conversions: MetricWithComparison;
cpa: MetricWithComparison;
roas?: MetricWithComparison;
topCampaigns: { name: string; spend: number; conversions: number; roas?: number }[];
};
metaAdsData?: {
spend: MetricWithComparison;
reach: MetricWithComparison;
impressions: MetricWithComparison;
clicks: MetricWithComparison;
ctr: MetricWithComparison;
conversions: MetricWithComparison;
cpa: MetricWithComparison;
roas?: MetricWithComparison;
topCampaigns: { name: string; spend: number; reach: number; conversions: number }[];
};
socialMetrics?: {
[platform: string]: {
followers: MetricWithComparison;
postsCount: number;
reach: MetricWithComparison;
impressions: MetricWithComparison;
engagements: MetricWithComparison;
engagementRate: MetricWithComparison;
topPost: { content: string; engagements: number; reach: number };
};
};
emailMetrics?: {
campaignsSent: number;
totalSent: MetricWithComparison;
openRate: MetricWithComparison;
clickRate: MetricWithComparison;
unsubscribeRate: MetricWithComparison;
topCampaign: { subject: string; openRate: number; clickRate: number };
};
goalProgress: {
goalId: string;
goalName: string;
target: number;
actual: number;
unit: string; // e.g. "leads", "revenue", "sessions"
period: 'monthly' | 'quarterly' | 'annual';
onTrack: boolean;
}[];
previousMonthReportId?: string; // used to fetch prior report for context via RAG
}
interface MetricWithComparison {
current: number;
previous: number;
changePct: number; // positive = improvement; negative = decline
changeDir: 'up' | 'down' | 'flat';
}Output
interface ReportWriterOutput {
reportTitle: string; // e.g. "Acme Corp — March 2026 Performance Report"
reportMonth: string;
generatedAt: string;
markdownContent: string; // full Markdown report ready for HTML rendering
metadata: {
wordCount: number;
sectionsIncluded: string[];
metricsReferenced: number;
winsCount: number;
attentionItemsCount: number;
};
}Sample output excerpt
# Acme Corp — March 2026 Performance Report
**Period:** 1 March – 31 March 2026 | Prepared by Leadmetrics
---
## Executive Summary
- **Traffic grew 18% MoM** (12,400 sessions vs. 10,500 in February), driven by a strong Google Ads
push and one organic blog post that ranked on page 1 for "SaaS onboarding software" — generating
1,840 sessions alone.
- **Lead generation hit its monthly target** with 94 form completions vs. a 90-lead goal (104%),
though cost-per-lead on Meta increased 22% to $38.40 — creative fatigue on the primary ad set
requires attention heading into April.
- **Email engagement was the standout channel** this month: the "Spring Offer" campaign achieved
a 41.2% open rate and 8.7% click rate, both significantly above industry benchmarks — recommend
deploying a follow-up nurture sequence to the engaged segment.
---
## Goal Progress
| Goal | Target | Actual | Progress | Status |
|---|---|---|---|---|
| Monthly leads | 90 | 94 | 104% | On track |
| Website sessions | 11,000 | 12,400 | 113% | On track |
| Email open rate | 35% | 38.6% avg | 110% | On track |
| Google Ads ROAS | 4.0x | 4.8x | 120% | On track |
| Meta Ads CPA | $32 | $38.40 | 80% | Needs attention |
---
## Wins This Month
1. Blog post "7 SaaS Onboarding Mistakes" ranked position 4 for its target keyword within 3 weeks
of publication, generating 1,840 organic sessions.
2. Google Brand Search campaign ROAS reached 7.2x — highest on record.
3. Email "Spring Offer" campaign: 41.2% open rate — 18 points above the 23% industry average.How It Works
-
Load all input data. The control plane pre-fetches all API data (GA4, Google Ads, Meta Ads, social, email) before dispatching this job. The agent receives all data as structured objects in the job payload — it does not make external API calls.
-
RAG: what content was produced this month. Query Published Content to retrieve all blog posts, social posts, and emails published in the report month. These feed the content production summary section.
-
RAG: client goals and KPIs. Query Client Documents to confirm the client’s stated goals, KPI targets, and any context (e.g. a planned promotion) that should be acknowledged in the executive summary narrative.
-
RAG: competitor context. Query Competitor Research for any notable competitor activity or industry trends in the report month that are worth surfacing for the client as context.
-
Fetch previous report for comparison narrative. If
previousMonthReportIdis provided, query Published Content for the prior report to extract last month’s “focus areas” — the current report should close the loop on whether those focus areas were actioned. -
Write the executive summary. Exactly 3 bullet points. Each bullet leads with the most important insight from a single channel or theme. Bullets must be specific — cite numbers, name the campaign or piece of content responsible.
-
Write channel-by-channel breakdown. For each active channel (GA4/organic, Google Ads, Meta Ads, social, email), write a structured section with: key metrics vs. prior month, top performer, concern or opportunity, and a 1–2 sentence narrative assessment.
-
Write goal progress tracker, wins, attention items, and next-month focus. Pull from the
goalProgressinput for the tracker. Wins and attention items are synthesised from across all channel data. Next-month focus is forward-looking — 3 specific, prioritised actions.
System Prompt
You are a senior marketing analyst writing the monthly performance report for a digital marketing
agency's client. This report is client-facing — it will be rendered as a branded HTML document
and delivered directly to the client. Your tone should be clear, confident, and constructive.
Present data accurately. Frame challenges as opportunities where genuine, but do not spin poor
results as positive.
CLIENT CONTEXT:
{{CLIENT_CONTEXT}}
KNOWLEDGE BASE CONTEXT:
{{RAG_CONTEXT}}
You have been provided with pre-fetched data for the report month covering: GA4 website analytics,
Google Ads performance, Meta Ads performance, social media metrics, email metrics, goal progress
records, and published content produced this month.
Report structure requirements (every section is MANDATORY):
1. Title and period header
2. Executive Summary — EXACTLY 3 bullet points. Each must be specific: name the number, name the
channel or asset responsible. No vague statements.
3. Goal Progress — table format; every goal with target, actual, % progress, and on-track status
4. Channel Breakdown — one section per active channel; include key metrics, MoM comparison, top
performer, and one concern or opportunity
5. Content Produced This Month — list all blog posts, major social posts, and email campaigns
6. Wins of the Month — 3–5 specific wins with data to back each one
7. Areas Needing Attention — 2–4 items with specific metrics and recommended actions
8. Next Month Focus — 3 prioritised, specific actions with expected outcomes
Rules:
- Every metric cited must show its MoM comparison (e.g. "12,400 sessions (+18% MoM)")
- No section may be omitted, even if data is limited — note data limitations explicitly
- Executive summary must be written last, summarising the full report
- Do not include raw numbers without context — always interpret what the number means
- Match the client's brand voice and communication style from the client context
- Output the full report as a single Markdown document with proper heading hierarchySkills Injected
| Skill file | Purpose |
|---|---|
client-context-file.md | Company, brand, audience — always injected |
report-structure-guide.md | Mandatory section list, heading hierarchy, formatting rules for the HTML-rendered report |
kpi-definitions.md | Canonical metric definitions to ensure consistent interpretation across months |
performance-benchmarks.md | Industry-average benchmarks for contextualising metrics in the narrative |
report-structure-guide.md — content
# Monthly Performance Report — Structure Guide
## Mandatory Sections (in order)
### 1. Report Header
- Client name — Month Year Performance Report
- Period: [start date] – [end date]
- Prepared by: Leadmetrics
### 2. Executive Summary
- Exactly 3 bullet points
- Each bullet = one key insight from the month
- Format: **[Bold insight label]** followed by the insight sentence with specific numbers
- Written last — summarises the full report
- Maximum 40 words per bullet
### 3. Goal Progress Table
- Columns: Goal | Target | Actual | Progress % | Status
- Status values: "On track" (green) / "Needs attention" (amber) / "Off track" (red)
- Include every goal in the client's goals record — even if no data is available
### 4. Channel Breakdown
One subsection per active channel. Each subsection must contain:
- Key metrics table (metric | this month | last month | change %)
- Top performer callout (campaign, post, or keyword that led performance)
- One concern or opportunity statement
- 2–3 sentence narrative
Active channels: Organic/GA4, Google Ads (if connected), Meta Ads (if connected),
Social Media (if connected), Email (if connected)
### 5. Content Produced This Month
- Bulleted list: blog posts published (title + publish date), email campaigns sent (subject + date),
notable social content
- Link to Published Content dataset entries where available
### 6. Wins of the Month
- 3–5 wins with supporting data
- Format: bold win statement + one sentence with the numbers
### 7. Areas Needing Attention
- 2–4 items
- Format: **[Metric/channel]:** what happened + recommended action
- Do not include items without a recommended action
### 8. Next Month Focus
- 3 prioritised actions
- Format: numbered list, each with: action + expected outcome
- Must be specific enough to assign to a team member
## Formatting Rules
- Use Markdown H2 for sections, H3 for subsections
- Use tables for all multi-metric comparisons
- Bold all metric values on first mention in a section
- Never use passive voice in recommendationsRAG Usage
| Dataset | Query | When |
|---|---|---|
| Published Content | "blog posts emails social posts published [month year]" | Step 2 — to populate the “Content Produced This Month” section |
| Published Content | "performance report [previous month]" | Step 5 — to retrieve last month’s focus areas and close the loop |
| Client Documents | "monthly goals KPIs targets [client name]" | Step 3 — to confirm goal targets and any context behind them |
| Client Documents | "promotions campaigns planned [month year]" | Step 3 — to note planned activity that influenced this month’s numbers |
| Competitor Research | "competitor activity industry trends [month year]" | Step 4 — to provide market context in the narrative where relevant |
RAG query strategy: Run Published Content and Client Documents queries in parallel before the generation call. These two datasets provide the raw material for the content summary and goal sections. Competitor Research is queried last and used selectively — only include competitor context in the report if it meaningfully explains a client metric movement.
Tools Required
| Tool | Method | Purpose | Required? |
|---|---|---|---|
rag_search | search | Query published content, client goals, competitor context | Yes |
ga4_reports | getTrafficReport | Fetch GA4 website analytics | Yes (if GA4 connected) |
google_ads_reports | getCampaignPerformance | Fetch Google Ads data | Optional |
meta_ads_insights | getCampaignInsights | Fetch Meta Ads data | Optional |
Note: The data tools above are called by the control plane before dispatching this job. The agent receives pre-fetched data in the job payload. The tool entries here document the upstream data dependencies, not direct agent calls.
HITL Gates
- Review type:
report_review - Risk level:
medium - Trigger: Always — monthly reports are always reviewed before client delivery.
- Reviewer sees: Rendered Markdown report in the dashboard preview. Reviewer can edit any section inline.
- Approval triggers: Report is locked and queued for delivery via the configured delivery method (email, Google Drive link, Slack, or dashboard notification).
- Rejection triggers: Entire report is re-queued with reviewer feedback. Specific section feedback is appended to the generation prompt.
Guardrails
| Rule | Enforcement |
|---|---|
| All 8 mandatory sections must be present | Structural check against section heading list; missing sections trigger regeneration |
| Executive summary must have exactly 3 bullet points | Count check on bullet points under Executive Summary heading |
| Every metric must show MoM comparison | Regex scan for metric values without a preceding or following comparison; violations flagged for regeneration |
| No section shorter than 50 words (except tables) | Word count per section; stub sections trigger regeneration with explicit instruction to expand |
| Goal Progress table must include every goal from input | Cross-check goalProgress input array vs. table rows |
Tenant Settings Used
| Setting | How it’s used |
|---|---|
brandVoice | Applied to narrative tone — e.g. a formal B2B client gets measured language; a consumer brand gets warmer, more enthusiastic framing |
industry | Selects the correct benchmark comparisons from performance-benchmarks.md |
targetAudience | Informs which metrics to lead with in the executive summary (e.g. leads for B2B, revenue for e-commerce) |
Cost Profile
| Avg input tokens | ~18,000 (all channel data + RAG results + skills + prior report) |
| Avg output tokens | ~8,000 (full Markdown report) |
| Est. cost / task | ~$1.20 |
Error Handling
| Error | Response |
|---|---|
| GA4 data missing | Include organic section with note: “GA4 data unavailable this month — verify integration” |
| All ad platform data missing | Include ads section with note: “Paid media data unavailable — check platform connections” |
| Goal progress array is empty | Include goal tracker section with note: “No goals configured — set up goals in Settings > Goals” |
| RAG returns no Published Content results | Include content section with note: “No published content found for this period” |
| Report fails section validation after 2 retries | Return partial report with missing sections flagged; create HITL record noting the failure |
| Output exceeds 10,000 tokens | Truncate at section boundaries (never mid-section); append note listing omitted sections |