Skip to content
Talk to an engineer

Recipes

Recipe: report insights with a routing action

An Insights capability: the user points the agent at a reporting or analytics report and gets back decisions — the drivers, the anomalies, and what to do next — not just a summary.

The trick is a single routing action. Instead of one giant “analyze everything” prompt, the action first has the agent ask a qualifying questionwhat goal or KPI do you want to optimize? — and then its handler routes that intent to the right specialized task agent: a revenue analyst, a funnel analyst, a retention analyst, and so on. One action, many specialized analysts.

Why route instead of writing one mega-prompt:

  • Each analyst is focused. A funnel expert and a churn expert need different reasoning; keeping them separate makes each sharper.
  • Each analyst is independently versioned, evaluated, cached, and tuned. You can put a cheap model behind a simple summary and a stronger one behind cohort analysis.
  • The capability grows without a rewrite. Adding a KPI means adding one task agent and one line in a routing map — the action and its handler don’t change.
sequenceDiagram
  participant U as User
  participant A as Main Agent
  participant Act as Routing Action (execute)
  participant T as Specialist Task Agent
  U->>A: "Analyze last quarter's report"
  A->>U: Which goal or KPI do you want to optimize?
  U->>A: Retention
  A->>Act: analyze_report_insights({ report, goal, kpi })
  Act->>Act: Map kpi → taskKey
  Act->>T: runTask(retention_churn_analyzer, { report, question })
  T-->>Act: Structured insights (JSON)
  Act-->>A: { kpi, summary, findings, recommendations }
  A->>U: Reply grounded in the analyst's insights

The main agent handles the conversation and the qualifying question. The routing action is a thin dispatcher: it maps the chosen KPI to a task-agent key and calls it. The task agent does the heavy reasoning and returns a predictable JSON object the agent can relay.

Step 1 — Build the specialist task agents

Section titled “Step 1 — Build the specialist task agents”

In Agent Studio → Task Agents, create one analyst per KPI family. Configure each with a JSON response so the handler gets a predictable object back. A single reusable output schema keeps every analyst interchangeable from the handler’s point of view:

{
"type": "object",
"properties": {
"summary": { "type": "string", "description": "One-paragraph headline of what the data shows" },
"findings": {
"type": "array",
"description": "The most important observations, most significant first",
"items": {
"type": "object",
"properties": {
"metric": { "type": "string" },
"observation": { "type": "string" },
"impact": { "type": "string", "enum": ["high", "medium", "low"] }
},
"required": ["metric", "observation", "impact"],
"additionalProperties": false
}
},
"anomalies": {
"type": "array",
"description": "Values that look off and are worth a human check",
"items": {
"type": "object",
"properties": {
"metric": { "type": "string" },
"note": { "type": "string" }
},
"required": ["metric", "note"],
"additionalProperties": false
}
},
"recommendations": {
"type": "array",
"description": "Concrete next actions to move the chosen KPI",
"items": { "type": "string" }
},
"confidence": { "type": "string", "enum": ["high", "medium", "low"] }
},
"required": ["summary", "findings", "anomalies", "recommendations", "confidence"],
"additionalProperties": false
}

Give each analyst instructions scoped to its KPI. A starting set:

Task agent (api_name)Optimizes forInstructions focus
revenue_growth_analyzerRevenueRevenue drivers by segment, expansion vs. new, ARPU, refund/discount drag
conversion_funnel_analyzerConversionStage-by-stage drop-off, activation, signup→paid, where to intervene
retention_churn_analyzerRetentionCohort retention, churn concentration, refunds, at-risk segments
engagement_analyzerEngagementFeature usage, active-user trends, engagement anomalies

Example instructions for one analyst — keep them tight and tell it the input to expect and the goal to serve:

You are a retention and churn analyst. You receive report (rows of metrics, often by cohort or segment) and a question describing the user’s goal. Identify where retention is strongest and weakest, concentrate on churn drivers and at-risk segments, flag anomalies, and return concrete actions to improve retention. Be specific and quantitative; never invent numbers not in the data.

See the Task Agents guide for the editor, and Example: analyze report data for a worked single-analyst call.

In Agent Studio → Actions, create analyze_report_insights. This is the front door; its job is to collect the goal/KPI and hand off.

Description (the agent reads this to decide when to call it — say what it returns):

Analyzes a reporting or analytics report and returns structured insights — summary, key findings, anomalies, and recommended actions — tuned to the KPI the user wants to optimize.

Instructions (the qualifying-question rule — this is what makes it a router, not a guesser):

Use when the user wants to analyze a report, dashboard, or analytics export and get insights or recommendations. Before calling, make sure you know which goal or KPI to optimize for. If the user hasn’t said, ask: “What goal or KPI do you want to optimize — for example revenue, conversion, retention, or engagement?” When the goal is already clear from context, skip the question and proceed. Pass the user’s objective in goal and the matching category in kpi.

User Input parameters (see Defining inputs):

ParameterTypeRequiredPurpose
reportObject / ArrayYesThe report data (or a reference the handler can resolve)
goalStringNoThe user’s objective in their own words, e.g. “reduce churn in EU”
kpiString (enum)YesOne of revenue, conversion, retention, engagement, other

The kpi enum is what the handler routes on; goal is the free-text nuance the analyst reads.

Step 3 — Write the execute() router handler

Section titled “Step 3 — Write the execute() router handler”

The handler is small on purpose: map kpi to a task-agent key, call it, and return the structured result. All the reasoning lives in the analysts.

// KPI → the specialist task agent that handles it.
// Add a KPI by adding a task agent and one entry here — nothing else changes.
const ROUTES = {
revenue: 'revenue_growth_analyzer',
conversion: 'conversion_funnel_analyzer',
retention: 'retention_churn_analyzer',
engagement: 'engagement_analyzer',
};
foldspace('when', 'ready', () => {
foldspace.agent({ /* …common setup… */ })
.addActionHandlers({
analyze_report_insights: {
// Analysis can take longer than the 5s default — give it room.
timeout: 60000,
execute: async ({ report, goal, kpi }) => {
const taskKey = ROUTES[kpi];
// Routing couldn't decide — hand control back so the agent asks the
// qualifying question instead of guessing an analyst.
if (!taskKey) {
return {
needsGoal: true,
message: 'Which KPI should I optimize for?',
options: Object.keys(ROUTES),
};
}
try {
const insights = await foldspace
.agent('YOUR-AGENT-API-NAME')
.runTask({
taskKey,
data: {
report,
goal,
question: `Optimize for ${goal || kpi}. Surface the drivers, flag anomalies, and recommend concrete next actions.`,
},
// Dashboards refresh often; reuse an identical analysis for an hour.
cacheOptions: { ttlSeconds: 3600 },
});
// Return the KPI alongside the analyst's output so the agent can
// frame its reply ("Here's what matters for retention…").
return { kpi, goal, ...insights };
} catch (error) {
console.error('Report analysis failed:', error);
return { error: true, kpi, message: 'The analysis could not be completed. Try again shortly.' };
}
},
},
});
});

A few things this handler gets right:

  • It routes, it doesn’t analyze. Swapping a model or sharpening a prompt happens in the task agent, never here.
  • It closes the loop when routing fails. The needsGoal return nudges the agent back to the qualifying question rather than picking an analyst at random.
  • It caches. Identical data returns from cache, so a re-opened dashboard doesn’t pay twice — see cache options.

Step 4 — The qualifying-question pattern, in depth

Section titled “Step 4 — The qualifying-question pattern, in depth”

There are two ways the agent gathers the goal/KPI. Pick based on how much you want to steer:

  1. Conversationally (default, no code). The action Instructions from Step 2 tell the agent to ask “what goal or KPI do you want to optimize?” whenever it’s unclear, and to skip the question when the goal is obvious from context. This is enough for most cases and keeps the flow natural.
  2. With an in-chat UI picker. For a guided experience, render a KPI chooser in the chat from the action instead of returning plain data — see UI components in chat. Set awaitUserInput: true on the handler so the agent pauses for the user’s selection before the analysis runs.

The needsGoal fallback in the handler is the safety net for both: if the KPI still isn’t set when the action fires, control returns to the agent to ask, rather than to a wrong analyst.

  • Route correctly. Use the action’s Evals tab to confirm real phrasings (“why are we losing customers?”, “where’s revenue coming from?”) extract the right kpi and route to the right analyst.
  • Analyze correctly. Use each task agent’s Evaluation tab to assert the JSON output meets your criteria on representative reports before it ever reaches the main agent.
  • Watch cost and latency. The task agent Logs tab records inputs, output, model, latency, and cost per run — use it to move simple analysts to a cheaper model.
  • Publish in order. Publish the task agents first (the handler calls them by taskKey), then publish the routing action. A task agent must be Published before the agent can delegate to it.
  • One clear job per analyst. If an analyst’s instructions need “and” several times, it’s probably two analysts.
  • Add a KPI in two edits. Create the task agent, add one ROUTES entry. The action, its schema, and the handler are untouched.
  • Cache for dashboards, bypass on fresh data. Set cacheOptions.bypass: true when the underlying report changed and you need a fresh run.
  • Observe adoption. Track execution and routing accuracy with Action Insights and Conversational Analytics — they tell you which KPIs users actually ask about, so you know which analyst to build next.