Business Intelligence logo

Business Intelligence

Community
ericrisco
business-intelligence

Use when a metric (revenue, MRR, margin) needs defining once in a governed semantic layer so every dashboard, report and agent returns the same number, or when an LLM must answer data questions in plain language without hallucinating SQL. NOT chart layout (that is `dashboard`), NOT which KPIs to track (that is `kpi-framework`), NOT a hand-written query (that is `sql`).

Overview

Publisherericrisco
Repositoryrsc-harness
Skill namebusiness-intelligence
Stars
239
Forks
24
Bundled files
4
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 4 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by ericrisco on GitHub. Read the source before you install it.

Installation

Install the Business Intelligence AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/ericrisco/rsc-harness/tree/main/skills/business-intelligence
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/ericrisco/rsc-harness.git /tmp/rsc-harness
mkdir -p .claude/skills
cp -r /tmp/rsc-harness/skills/business-intelligence .claude/skills/business-intelligence
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Business Intelligence in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Business Intelligence on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Business Intelligence is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Business intelligence

Answer business questions over the org's data through a governed semantic layer — define each metric once in versioned YAML, then route every "what was revenue last quarter by region" through that layer. Numbers come out consistent, auditable, and the same for everyone. This skill builds the layer and queries it in plain language.

The one rule

Never free-hand SQL against raw tables to answer a governed business question. Go through the layer.

Why, with numbers: in dbt's April 2026 benchmark (ACME Insurance, 11 questions × 20 runs, ~15-table schema), an LLM grounded in a semantic layer scored 98.2% (Claude Sonnet 4.6) / 100% (GPT-5.3 Codex) vs 90.0% / 84.1% for raw text-to-SQL on the same schema; on the unmodeled schema it was 72.7% vs 64.5%, and a 2023 GPT-4 baseline managed 32.7%. The layer is not bureaucracy — it is the accuracy. The model writing SQL against undecorated tables is the failure mode you are eliminating.

Your job is two motions: (1) build the metrics layer (entities, dimensions, measures, metrics) and (2) query it — translate a plain-language question into metric + dimensions + grain + filter, never into a hand-written query.

The four primitives

Every semantic layer (MetricFlow, Cube, warehouse-native) is built from the same four nouns. Learn these and the rest is syntax.

  • Entities — the join keys. order_id is the primary entity of orders; customer_id is a foreign entity that joins to customers. Entities are how the layer knows how tables relate so it writes the join, not you.
  • Dimensions — the axes you group and filter by, including time grains (order_date by day/week/month/quarter) and categoricals (region, product_category).
  • Measures — a single aggregation of a column: sum(amount), count(distinct customer_id).
  • Metrics — named, reusable expressions built over measures: gross_revenue, mrr, gross_margin_pct. This is what a human or agent actually asks for by name.
yaml
# MetricFlow-style semantic model for an orders table
semantic_models:
  - name: orders
    model: ref('fct_orders')
    entities:
      - name: order        # primary join key
        type: primary
        expr: order_id
      - name: customer     # foreign key -> customers semantic model
        type: foreign
        expr: customer_id
    dimensions:
      - name: order_date
        type: time
        type_params: { time_granularity: day }   # grain is declared, not implied
      - name: region
        type: categorical
    measures:
      - name: order_amount
        agg: sum            # explicit aggregation
        expr: amount

Decision: do you even need a layer?

Do not stand up a semantic layer for a spreadsheet. Branch on consumers and conflict, not on data size alone.

SituationBuild the layer?Route
One analyst, one table, a 200-row CSV, a one-off questionNo../sql/SKILL.md or ../duckdb/SKILL.md
One metric, queried in one place, never disputedNo../sql/SKILL.md
Many consumers (dashboards + reports + notebooks + an agent)Yesthis skill
An LLM/agent must answer data questions safelyYesthis skill
Two teams already report different numbers for the same thingYesthis skill

If the answer is "no," stop here and write the query. The layer earns its weight only when a definition has to be shared.

Pick the layer

PickWhenWhy
dbt Semantic Layer / MetricFlowYou already run dbt; want Git-native definitions colocated with models, reviewed in PR/CIMetrics live in YAML next to dbt models, version-controlled, served over JDBC + GraphQL APIs that apps query; compiles to SQL on Snowflake/BigQuery/Redshift/Databricks
CubeOne definition must feed a BI tool and a product dashboard and an AI copilotOpen-source, one definition exposed over four query APIs (SQL/REST/GraphQL/MDX) plus an AI API / MCP support so agents call governed metrics as tools
Warehouse-native (Snowflake Semantic Views / Databricks Metric Views)The org is all-in on one warehouseSemantic objects live inside the warehouse — no separate service to run

MetricFlow was open-sourced (Apache 2.0) at Coalesce 2025 and contributed as an OSI reference implementation, so its YAML is a safe default authoring format regardless of which engine you land on.

Author the model

One definition, version-controlled, reviewed in PR — colocated with the models. Definitions belong in code review, not in a BI tool's UI where they silently fork.

yaml
# A metric defined once over the measure above
metrics:
  - name: gross_revenue
    label: Gross Revenue
    type: simple
    type_params:
      measure: order_amount     # built on the measure, not raw SQL
  - name: gross_margin_pct
    label: Gross Margin %
    type: ratio                 # ratio metric: numerator / denominator
    type_params:
      numerator: gross_profit
      denominator: gross_revenue
text
# Bad -> Good
Bad:  "revenue" SUM(amount) hand-written in Tableau,
      SUM(net_amount) in the Looker view,
      SUM(amount)-refunds in a notebook  -> three different numbers
Good: one `gross_revenue` metric in YAML; Tableau, the notebook,
      and the agent all query that one metric -> one number

For multi-entity join paths, additive vs non-additive vs ratio vs cumulative/derived metrics, semi-additive measures (balances, inventory snapshots), time spines, and the fan-out double-count trap, see references/authoring-semantic-models.md.

Query in plain language

Decompose the question into the four parts before any SQL exists. Never jump to a query.

text
Question: "MRR by plan, monthly, last 2 quarters, EU customers only"
  metric      -> mrr
  group by    -> plan
  time grain  -> month
  date filter -> last 2 quarters
  filter      -> region = 'EU'

You hand the layer that spec; it generates the governed SQL. You then explain the answer back in business terms ("EU MRR grew 8% QoQ, driven by the Pro plan"), not as a table dump.

Wire the agent

Expose the layer as an MCP / metrics tool. The agent selects governed metrics + dimensions; the layer returns the SQL/results. The agent never sees raw warehouse tables.

text
# Bad -> Good
Bad:  agent gets warehouse credentials, reads the schema,
      writes SELECT ... FROM raw.orders JOIN ...  -> 84-90% accurate, unauditable
Good: agent calls query_metrics(metric="gross_revenue",
      group_by=["region"], grain="month", filters=["region='EU'"])
      -> layer returns governed SQL/result, 98-100% accurate

Guardrails: deny raw-table access, validate that requested dimensions actually exist on the metric, reject any ungoverned aggregate. Full MCP pattern plus dbt SL GraphQL/JDBC and Cube REST/SQL/MCP query shapes are in references/wiring-agents-and-apis.md.

Reconcile conflicting numbers

When sales says revenue is X and finance says Y, it is almost never a query bug — it is two definitions. Do not write a third query to "settle it." Find the two definitions, pick the correct one, encode it once in the layer, and point both teams at it. The disagreement disappears because there is now one number to disagree about.

Portability (OSI)

Author toward the Open Semantic Interchange standard so definitions survive a tool switch. OSI is the vendor-neutral, Apache-2.0, YAML-based spec for datasets/metrics/dimensions/relationships, launched 2025-09-23 by Snowflake + dbt Labs, Cube, Salesforce/Tableau and others; v1.0 spec published on GitHub 2026-01-27. Write MetricFlow/OSI-shaped YAML; never invent a proprietary metric format trapped in one BI tool.

Anti-patterns

Anti-patternWhy it bitesInstead
Free-handing the SQL "just this once" because it's faster"Once" becomes the fourth conflicting revenue figure; it's unauditableAdd/query a metric
Letting each dashboard define revenue itselfThat is exactly how you get three numbers and a fire drillOne metric, all consumers query it
Skipping the time dimension's grain because it's "obvious"Undeclared grain → silent daily-vs-monthly mismatchesDeclare time_granularity/grain
Handing the agent warehouse creds to figure out the joinsRaw text-to-SQL is 84-90% (33% in 2023) and unauditable; the dbt 2026 benchmark puts the layer +8-14pts aheadExpose metrics via MCP/API
Standing up a semantic layer for a 200-row CSVPure overhead for one analyst../sql/SKILL.md / ../duckdb/SKILL.md
Hard-coding the EU filter into the metricNow you need a second metric for every regionPass filters at query time

Verify

Run scripts/verify.sh [path] on your semantic-model directory. It is read-only, never touches a warehouse, and discovers candidate YAML, then warns (advisory) on: a metric with no underlying measure, a measure with no declared agg, a time dimension with no grain, duplicate metric names, and a .sql beside the model hand-rolling an aggregate the layer should own. It exits non-zero only on unparseable YAML; an empty or clean target passes clean.

Siblings: ../sql/SKILL.md · ../dashboard/SKILL.md · ../kpi-framework/SKILL.md · ../reporting/SKILL.md · ../analytics/SKILL.md · ../forecasting/SKILL.md

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Business Intelligence AI skill do?

Use when a metric (revenue, MRR, margin) needs defining once in a governed semantic layer so every dashboard, report and agent returns the same number, or when an LLM must answer data questions in plain language without hallucinating SQL. NOT chart layout (that is `dashboard`), NOT which KPIs to track (that is `kpi-framework`), NOT a hand-written query (that is `sql`).

Why use Business Intelligence on TypingMind?

Because you install it once and use it with any model. Business Intelligence is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Business Intelligence in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/ericrisco/rsc-harness/tree/main/skills/business-intelligence. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Business Intelligence?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Business Intelligence?

As many as you like. As long as a model supports skills, you can use Business Intelligence with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Business Intelligence AI skill free?

Yes. It is published on GitHub by ericrisco under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇