一键导入
adhoc-analysis
// How to conduct ad-hoc analyses: gather data from multiple sources, synthesize findings, save reusable analysis artifacts that anyone can re-run for fresh results.
// How to conduct ad-hoc analyses: gather data from multiple sources, synthesize findings, save reusable analysis artifacts that anyone can re-run for fresh results.
How to create new skills for an agent-native app. Use when adding a new skill, documenting a pattern the agent should follow, or creating reusable guidance for the agent.
How to delegate all AI work to the agent chat. Use when delegating AI work from UI or scripts to the agent, when a user asks for agent behavior or LLM-powered features, when tempted to add inline LLM calls, or when sending messages to the agent from application code.
How to write great agent instructions for an agent-native app or template: AGENTS.md, skills, and tool/action descriptions. Use when authoring or reviewing AGENTS.md, writing a SKILL.md, wording action descriptions, or deciding what belongs in instructions vs skills vs memory.
Use when an analytics question spans multiple data sources (e.g. warehouse events + CRM + support + first-party) and you must stitch identities, remove duplicates, and produce one consolidated answer with per-source provenance.
How analytics dashboards are stored, created, and modified. Covers SQL dashboard tables, legacy settings migration, valid panel sources, layout shape, and safe update patterns.
General guidance on querying data sources, using existing scripts vs ad-hoc queries, filtering patterns, and generating charts for the analytics app.
| name | adhoc-analysis |
| description | How to conduct ad-hoc analyses: gather data from multiple sources, synthesize findings, save reusable analysis artifacts that anyone can re-run for fresh results. |
Ad-hoc analyses are deep-dive investigations that cross-reference multiple data sources, produce a written report with findings, and save a reusable artifact so anyone on the team can re-run the analysis with up-to-date data at any time.
Use the ad-hoc analysis workflow when:
For simple one-off questions (e.g., "how many signups last week?"), just query the data and answer in chat — no need to save an analysis.
If the user asks for an analysis output that needs a bespoke interactive
surface, custom visualization, multi-step workflow, or UI that cannot be
faithfully represented as saved-analysis Markdown, generated chart images, and
structured resultData, create an extension instead of forcing the request into
the saved-analysis format. In production mode, call create-extension
automatically and tell the user the requested analysis needed bespoke UI/code, so
you built it as an extension.
Orient before gathering data. Consult the injected <data-dictionary> and data-source status first to see which sources are configured and which one owns each fact, then settle scope:
If the metric definition, date range, or grain is ambiguous and a wrong guess would change the numbers, use the ask-question clarifying tool (multiple-choice) before gathering data. Ask at most once per turn, and skip it when the dictionary or the user already answered.
Use the available actions to pull data. Read the relevant .agents/skills/<provider>/SKILL.md before querying each source.
Common data source combinations:
| Analysis type | Data sources |
|---|---|
| Sales pipeline analysis | HubSpot deals + Gong calls + Slack mentions |
| Customer health check | HubSpot deals + Pylon support tickets + BigQuery usage events |
| Content performance | BigQuery pageviews + GA4 + SEO keywords + HubSpot signups |
| Engineering velocity | GitHub PRs + Jira tickets + BigQuery deploy events |
| Churn investigation | Stripe billing + HubSpot deals + Pylon tickets + BigQuery usage |
Tips for data gathering:
--grep and --fields to narrow results before cross-referencingcross-source-analysis: match on BOTH a stable id AND email (ids can be reassigned), de-duplicate, and record match quality. Email/company-name/domain matches alone are low-confidence — flag them as caveats, not headline numbers.Don't just dump raw data. Synthesize findings:
When the analysis benefits from a visual — trends over time, distributions, comparisons between categories — call generate-chart before formatting the report. The action returns a url you embed directly in the markdown.
generate-chart
--title "Closed-lost deals by month"
--type bar
--labels '["Jan","Feb","Mar"]'
--data '[18, 22, 14]'
Embed the returned URL in resultMarkdown using standard markdown image syntax:

You can include multiple charts in one analysis. Reach for a chart when it communicates the finding faster than a table — don't force visuals on every analysis.
Include the re-generation step in your saved instructions so re-runs produce fresh charts.
Structure the report clearly:
## Key Findings
- **Finding 1**: Specific insight with supporting numbers
- **Finding 2**: Another insight
- **Finding 3**: Actionable recommendation
## Summary Metrics
| Metric | Value |
|---|---|
| Total deals analyzed | 54 |
| Average deal size | $42,300 |
| Win rate | 23% |
## Detailed Analysis
### Category 1
[Detailed breakdown with tables, lists, etc.]
### Category 2
[More detail...]
## Methodology
Data sources: HubSpot (deals, contacts), Gong (calls), Slack (mentions)
Time range: Jan 1 – Mar 31, 2026
Filters: S1+ pipeline, closed-lost only
Call save-analysis with all required fields:
save-analysis
--id "closed-lost-q1-2026"
--name "Q1 2026 Closed-Lost Analysis"
--description "Deep dive into 54 Fusion deals closed-lost in Q1, cross-referenced with Gong calls and Slack activity"
--question "Why are we losing deals in Q1? Cross-reference with Gong calls and Slack."
--dataSources '["hubspot", "gong", "slack"]'
--instructions "1. Fetch closed-lost S1+ deals from HubSpot (pipeline: Fusion, close date: Q1 2026)
2. For each deal, fetch associated contacts and their emails
3. Search Gong calls matching those contact emails (lookback: 6 months before close date)
4. For top 15 deals by amount, search Slack for '{company name} fusion'
5. Calculate: total deals, avg deal size, win rate, Gong coverage rate
6. Break down by: lost reason, stage reached, deal size tier
7. Highlight deals with no Gong coverage (blind spots)
8. Save results with save-analysis using id='closed-lost-q1-2026'"
--resultMarkdown "[the full markdown report]"
--resultData '{"deals": [...], "metrics": {...}}'
resultData is required. Fill it with structured evidence copied or summarized from the real data-source action results you used: raw rows, row samples, aggregate metrics, match decisions, and explicit provider errors for any gaps. If you cannot query a source, do not save a guessed analysis; report the unavailable/error result instead.
Critical: Write good instructions. The instructions field is what gets sent to the agent on re-run. Be specific:
After saving, navigate the user to see the saved analysis:
navigate --view=analyses --analysisId=closed-lost-q1-2026
When a user clicks "Re-run" on a saved analysis, the agent receives:
Follow the instructions to gather fresh data, then call save-analysis with the same id to update the results. The createdAt timestamp is preserved; updatedAt is refreshed.
| Action | Purpose |
|---|---|
save-analysis | Save or update an analysis (id, name, instructions, results) |
get-analysis | Retrieve a saved analysis by ID |
list-analyses | List all saved analyses (id, name, description, timestamps) |
delete-analysis | Delete a saved analysis |
navigate | Navigate to analyses view: --view=analyses [--analysisId=<id>] |
Analyses are stored in the SQL settings table with key prefix adhoc-analysis-{id}. They respect org/user scoping — org-scoped analyses are visible to all org members.
API endpoints (for UI consumption):
GET /api/analyses — list allGET /api/analyses/{id} — get oneDELETE /api/analyses/{id} — delete oneclosed-lost-q1-2026 not analysis-1resultData with raw metrics/rows so the UI can render richer views in the future