AI Analytics Assistant (Ask)
The AI Analytics Assistant lets stakeholders ask natural language questions about traffic quality and lead quality. The system converts the question into a structured query plan (no SQL), runs predefined analytics queries, then uses AI to summarize the result into a clear answer with insights and recommended actions.
Flow
- Plan — Worker AI turns the question into a
QueryPlan(e.g.analysis_type: campaign_bot_rates,filters: { time_range: last_7_days }). Only allowed analysis types; no raw SQL. - Execute — The executor calls the matching predefined function (e.g.
getHighBotRateByCampaign) with params from the plan. Result is always aggregated (top N rows or summary stats). - Summarize — Worker AI receives the aggregated result and the original question and returns:
answer,insights,recommended_actions,possible_blocks.
API
POST /analytics/ask
Headers: Authorization: Bearer <analytics-api-key> or X-API-Key: <key> (same as other analytics endpoints).
Body:
{
"question": "Which campaigns produce the most bots?"
}Response (200):
{
"answer": "Short paragraph answering the question using the data...",
"insights": ["Insight 1", "Insight 2"],
"recommended_actions": ["Action 1", "Action 2"],
"possible_blocks": ["Consider blocking source X or visitor Y"],
"query_plan": { "analysis_type": "campaign_bot_rates", "time_range": "last_7_days" }
}- 400 — Missing or invalid body (e.g. no
question, or question longer than 500 characters). - 405 — Method not GET (use POST for /analytics/ask).
Allowed question types (analysis_type)
| analysis_type | Example question |
|---|---|
| campaign_quality | "How is campaign traffic quality?" |
| campaign_bot_rates | "Which campaigns are generating bot traffic?" |
| source_bot_rates | "Which sources have the highest bot share?" |
| source_suspicion | "Which sources have high suspicion scores?" |
| referer_spam | "Which referrers produce spam leads?" |
| country_risk | "Which countries generate the most suspicious leads?" |
| visitor_abuse | "Which visitors are abusing the form?" |
| block_candidates | "Who should we consider blocking?" |
| traffic_quality | "Why did lead quality drop?" / "Overall traffic quality?" |
| aggregation_by_source | "Break down quality by source" |
| aggregation_by_campaign | "Break down by campaign" |
| aggregation_by_referer | "Break down by referrer" |
| aggregation_by_country | "Break down by country" |
| repeat_submissions_by_visitor | "Visitors with repeated submissions" |
Time range is inferred from the question (e.g. "yesterday" → last_24_hours) or defaults to last_7_days.
Safety
- No raw SQL — The planner returns only a
QueryPlanwith an allowedanalysis_type. The executor uses a fixed mapping to predefined functions inleadModerationQueries.ts. No user input is ever concatenated into SQL. - No raw rows to AI — Only aggregated results (e.g. top 20–30 rows or summary metrics) are sent to the summarizer. Raw
lead_submissionsrows are never sent. - Input validation — Question length is capped at 500 characters. Invalid or unknown planner output falls back to
traffic_qualityfor last_7_days.
Requirements
- Analytics Engine —
CLOUDFLARE_ACCOUNT_IDandCLOUDFLARE_ANALYTICS_ENGINE_API_TOKEN(for execution layer). - Worker AI — The
AIbinding must be configured inwrangler.toml(shared with the AI moderation report).
Code layout
src/ai/ask/types.ts— QueryPlan, AnalysisType, TimeRange, AskResponse, validation.src/ai/ask/plannerPrompt.ts,queryPlanner.ts— planQuery(env, question).src/analytics/ask/queryExecutor.ts— executeQueryPlan(env, plan).src/ai/ask/summarizerPrompt.ts,resultSummarizer.ts— summarizeResult(env, question, result).src/worker/askAnalyticsAssistant.ts— handleAsk(body, env); used by POST /analytics/ask.
Example requests
curl -X POST "https://your-worker/analytics/ask" \
-H "Authorization: Bearer YOUR_ANALYTICS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"question": "Which campaigns produce the most bots?"}'curl -X POST "https://your-worker/analytics/ask" \
-H "Authorization: Bearer YOUR_ANALYTICS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"question": "Which countries generate the most suspicious leads?"}'Dashboard
In the PulseGate dashboard, open Leads → Moderation and switch to the Ask tab. Type a question (e.g. “Which campaigns produce the most bots?”) and click Ask. You can pick a suggested question (e.g. Campaigns with most bots, Countries with high bot rates) or type your own. The answer, insights, recommended actions, and possible blocks are shown below. The query used (e.g. campaign_bot_rates, last_7_days) is shown at the bottom.
See AI Analytics Assistant roadmap for the full phased plan.