Skip to main content

Frontier · Prompt library

Copilot Adoption Dashboard Prompt

Copilot Adoption Dashboard

← Back to Prompt Library

📋 Review the schema first. Before running this prompt, confirm your column names and the Copilot/agent action taxonomy against the Schema Documentation.

🗂️DataPerson Query 📅Min data8+ weeks 💻LanguageR or Python 📦OutputStatic HTML dashboard 🎯LevelIntermediate

Last validated June 2, 2026 against vivainsights R 0.7.2 / Python 0.4.2.

Purpose

Build a static HTML dashboard of Copilot adoption trends, usage patterns and organisational breakdowns.

Audience

People analytics leads, IT deployment managers

When to use

After exporting a person query with Copilot activity metrics spanning at least 8 weeks of data.

Required inputs

  • Person query CSV with columns: PersonId, MetricDate, Copilot metrics (e.g., Copilot_Actions, Copilot_Assisted_Hours, Copilot_Chat_Queries, Copilot_Summarized_Hours), and optional HR attributes (e.g., FunctionType, Area, Country or Organization)
  • At least 8 weeks of data recommended

Assumptions

  • Data is at person-week granularity
  • PersonId is a consistent anonymized identifier
  • MetricDate is a date field representing the start of each week
  • Native licensed-only M365 Copilot nulls mean unlicensed, while zero activity means licensed but inactive. Processing nulls require separate investigation
  • The vivainsights R or Python package is available in the environment

A self-contained static HTML file with embedded charts, suitable for sharing via email or SharePoint.

Quick prompt (short version)

Use this shorter prompt for a fast first pass that adapts to your data.

Help me create a self-contained static HTML dashboard for people analytics and IT leaders that summarizes Copilot adoption trends and group differences from a Viva Insights person query export.
Start by loading the actual CSV and printing the row count, column names, data types, date range, and number of unique people, then map the real metric and HR columns from what is present.
Do not assume exact field names, and ask me to confirm the primary activity metric or any missing HR columns if the mapping is ambiguous.
Prefer Copilot Enabled User or Total Copilot enabled days for licensing. Under the documented native licensed-only M365 Copilot rules, null means unlicensed and zero activity means licensed but inactive. Without explicit licence fields, use a verified metric with those semantics. Do not apply this rule to unlicensed Copilot Chat or Consumption credits.
Confirm configured weekly grouping and metric windows. Date gaps do not establish cadence. Within a supplied complete query's configured scope, absent activity rows contribute zero. Failed joins, unavailable sources, out-of-scope periods and known coverage failures remain unresolved.
Build weekly adoption metrics using distinct people per week, then add useful group views from available HR attributes. If no suitable group field exists, skip those views and explain why.
Keep the overall dashboard even when no HR attribute is suitable for grouping.
The output must be a single self-contained static HTML file with inline assets and no server or external dependencies.
Suppress any group with fewer than 10 distinct people, or the stricter organisational minimum, and withhold breakdowns that could reveal suppressed cells. Do not publish individual rankings. Note skipped charts or missing segments.
At the end, list any assumptions you made about metric selection, licensing logic, or field mappings.

Use the detailed prompt below for a reproducible, exact-structure output. Use the quick prompt above for a faster first pass that you refine through follow-up turns.

Prompt

You are a people analytics engineer. Your task is to build a self-contained static HTML dashboard that visualizes Microsoft Copilot adoption from a Viva Insights person query export.

LANGUAGE CHOICE
Choose R or Python based on what is already installed in your environment to minimize setup.

DATA LOADING AND VALIDATION
Read the configured grouping, week start, measurement windows and query scope before aggregation. State whether each summary is person-weighted or person-week-weighted.
1. Load the person query CSV using `import_query()` from the `vivainsights` library (R or Python). This handles variable name cleaning and type parsing automatically.
2. Ensure PersonId is treated as a string and MetricDate is parsed as a date type.
3. Identify HR / organizational attribute columns with `extract_hr(df, return = "names")` in R or `vi.extract_hr(df, return_type="suggestion")` in Python. Use the returned names for all segmentation breakdowns instead of hard-coding column names.
4. Verify the panel structure: each row should represent a unique PersonId × MetricDate combination. If there are duplicates, report their count and stop for an explicit resolution rule.
5. Print the shape of the data, the date range covered, and the number of unique persons.
6. List all column names so I can verify the Copilot metric columns and HR attribute columns match what is expected. Identify Copilot metric columns by checking for columns containing the word "Copilot" in their name. Reference the taxonomy at https://github.com/microsoft/viva-insights-sample-code/blob/main/examples/example-data/copilot-metrics-taxonomy.csv to classify and validate the detected metrics. Use `Total_Copilot_actions_taken` as the primary activity proxy **if it is present**. Validate it against the taxonomy first, as it may not capture every Copilot surface or app.

IDENTIFYING LICENSED USERS
6. Classify each person-week as licensed, unlicensed or unknown using the shared eligibility policy. Prefer explicit enabled-user/days or dated licence evidence; otherwise use only a verified native licensed-only M365 Copilot metric. Preserve join-match indicators and processing failures. Withhold adoption rates when eligibility or licensed activity is unresolved.
7. Also flag "active" users: licensed users who have Total_Copilot_actions_taken > 0 (the primary activity metric) in that week. Create a boolean column `is_active`.
8. Print a summary: total person-weeks, licensed person-weeks, active person-weeks.

METRIC CALCULATIONS
9. For each week (MetricDate), compute:
   a. Total licensed users (count of distinct PersonId where is_licensed == True)
   b. Total active users (count of distinct PersonId where is_active == True)
   c. Adoption rate = active users / licensed users (as a percentage)
   d. Mean Total_Copilot_actions_taken per active user
   e. Mean Copilot_Assisted_Hours per active user
   f. Median Total_Copilot_actions_taken per active user
10. Store these weekly aggregates in a summary DataFrame called `weekly_summary`.

SEGMENTATION METRICS
11. For each selected HR attribute returned by `extract_hr()`, compute for each week:
    a. Licensed user count
    b. Active user count
    c. Adoption rate
    d. Mean Total_Copilot_actions_taken per active user
12. Store each attribute's results separately, using names derived from the available fields.

GROUP SUMMARY TABLE
13. If a suitable HR attribute is available, compute activity summaries for the selected group using distinct people and the declared time window. Apply privacy suppression to every cell and omit the breakdown if totals could reveal a suppressed value. Do not publish person rows. If no suitable field exists, omit the group table, say why, and continue with overall results.

SUMMARY STATISTICS PANEL
14. Calculate overall summary statistics for the dashboard header:
    a. Latest week adoption rate
    b. Trend direction: compare the last 4 weeks' average adoption rate to the prior 4 weeks
    c. Total unique licensed users across the entire period
    d. Total unique active users across the entire period
    e. Average Total_Copilot_actions_taken per active user per week (grand mean)
    f. Highest-adoption group for the selected HR attribute in the latest week, if available

DASHBOARD GENERATION
15. Create the dashboard as an intermediary document first, then export to HTML:
    - R: Create an RMarkdown file (.Rmd) with ggplot2 charts, then knit to a self-contained HTML file (output: html_document, self_contained: true).
    - Python: Create a Jupyter notebook (.ipynb) with matplotlib/seaborn charts, then export to a self-contained HTML file (e.g., `jupyter nbconvert --to html`). Keep the intermediary .Rmd or .ipynb file alongside the HTML output for troubleshooting and iteration. Do NOT use a web framework or server.

16. The HTML dashboard should contain these sections in order:
    a. HEADER: Title ("Copilot Adoption Dashboard"), date range, generation timestamp.
    b. SUMMARY PANEL: Cards showing the key metrics from step 14 (adoption rate, trend, total users, avg actions and top group). Use colored indicators (green for positive trend, red for negative).
    c. TREND CHARTS:
       - Line chart: Weekly adoption rate over time
       - Line chart: Mean Total_Copilot_actions_taken per active user over time
       - Line chart: Mean Copilot_Assisted_Hours per active user over time
    d. SEGMENTATION CHARTS:
       - Grouped bar chart for each selected HR attribute (latest 4-week average), such as FunctionType, Area, Country or Organization, when present; skip group charts if none are suitable
       - Heatmap: Adoption rate by a selected HR attribute × week, if that field is available and has no more than 15 groups
    e. GROUP SUMMARY TABLE (if a suitable HR attribute is available): privacy-protected aggregate table from step 13, with no identifiers.
    f. METHODOLOGY NOTE: Brief paragraph explaining how adoption rate is calculated, what "licensed" and "active" mean, and the data source.

17. Style the HTML with a clean, professional design. Use a sans-serif font, consistent color palette, and adequate whitespace. The dashboard should look presentable when opened in a browser.

18. Save the HTML file and the intermediary .Rmd or .ipynb to the working directory with descriptive filenames like "copilot_adoption_dashboard_YYYYMMDD.html".

IMPORTANT NOTES
- Do NOT create interactive plots that require a running server (no plotly, no bokeh server). Static charts embedded in the RMarkdown/Jupyter output are preferred.
- Omit metrics without verified inputs, including assisted hours or licensing-dependent summaries. Describe skipped panels rather than estimating missing values.
- If any HR attribute column is missing from the data, skip that segmentation chart and note it.
- Use the `vivainsights` package (R or Python) for data loading (`import_query()`) and HR attribute discovery (`extract_hr()`). Use ggplot2 (R) or matplotlib/seaborn (Python) for charting.
- All charts should have clear titles, axis labels, and legends.
- Use at least 10 distinct people per published group, or the stricter organisational minimum. Suppress complementary cells.
- Assisted hours and actions are not measured time saved or realised ROI.

<!-- analysis-policy:start -->
Use product-specific licence evidence. For documented native licensed-only M365 Copilot metrics, null means unlicensed and zero activity means licensed but inactive. Prefer Copilot Enabled User or Total Copilot enabled days. Do not extend these semantics to unlicensed Copilot Chat or Consumption credits.
Investigate conflicting licence evidence. Keep affected eligibility or activity unresolved, and withhold affected rates or estimates until resolved.
Within a supplied complete query's configured scope, absent activity rows contribute zero. Keep failed joins, unavailable sources, out-of-scope periods and known coverage failures unresolved with reasons.
Use configured grouping, week start and metric windows; date gaps do not establish cadence. State grain, units and estimand. Count distinct people; do not sum stocks or overlapping windows.
Use max(organisation requirement, workflow floor): 5 distinct people for general analysis and 10 for joined-query, dashboard, causal or process workflows. Protect complementary cells and embedded data; never publish individual rankings.
Use only HR attributes present in the export. If none suit a requested breakdown, omit it, explain why, and continue with supported overall results.
Treat low-activity flags as review candidates, not verified holidays, employment status or job classifications. Value scenarios require explicit conversion and realisation assumptions.
Default to association. Make causal claims only with a supported design and compatible estimators. Record unavailable checks and label synthetic data.
Check installed API versions, signatures and return types. Separate executed results from expectations and do not silently fork upstream bugs.
<!-- analysis-policy:end -->

Adaptation notes

  • Adjust HR attribute column names to match your export (e.g., Organization vs Org). Prepend a note to the prompt specifying your actual column names.
  • If grouping is configured daily, aggregate only verified additive flows to aligned weeks. Keep stocks and overlapping-window metrics separate; do not sum all Copilot columns indiscriminately.
  • Apply at least 10 distinct people per group, increase this if required by organisational policy, or omit segmentation entirely.
  • Add custom Copilot metrics by extending the list in step 5 (e.g., Copilot_Edited_Hours, Copilot_Rewritten_Hours).
  • If you prefer R over Python, add “Use R with ggplot2 and R Markdown” at the start of the prompt.

Common failure modes

  • Agent assumes all rows have Copilot data. The prompt explicitly separates licensed vs. unlicensed users, but some agents may skip this. Verify that the is_licensed flag is computed before any metric calculations.
  • Agent creates interactive plots that need a server. The prompt specifies static HTML with base64-encoded images. If the agent uses plotly or bokeh, ask it to switch to matplotlib/seaborn or export static images.
  • Agent ignores the panel structure and double-counts users. Ensure adoption rate is calculated per week using distinct PersonId counts, not row counts.
  • Metric column names differ between tenants. The prompt includes an auto-detect step (columns starting with Copilot_), but always verify column names in your export before running.
  • HTML file is not self-contained. Check that the output HTML opens correctly with no external dependencies. If charts appear broken, ensure base64 encoding was applied.

Responsible use & data privacy

  • Suppress small groups. Apply the stricter of your organisation's minimum group size and the selected workflow's privacy floor to every breakdown, segment and chart.
  • Never expose individuals. Do not print raw UPNs or email addresses. Hash, truncate or report only aggregates. Person Query PersonId is already de-identified, but Purview UserId is not.
  • Report group patterns. Use these outputs to understand cohorts and trends. Do not evaluate, rank or monitor named employees.
  • Keep data in approved environments. Follow your organisation's policies when choosing an agent and deciding which data it may access. Validate every agent output before sharing.
Last updated: Nov 10, 2026 Edit this page on GitHub