-
Notifications
You must be signed in to change notification settings - Fork 2
Prompt Categories
Every user prompt is tagged with one category (its intent) and a complexity score (1–5). The category is what drives the Prompts page breakdown and the category cross-filter; it answers "where does my interaction actually go — building, debugging, steering, ops…?"
There are two classifiers, both writing the same 13-label taxonomy:
-
Heuristic (default,
prompt-analytics categorize) — a deterministic FR+EN regex scorer. No API key, no cost, instant. This is what the Refresh data button runs. -
LLM (
prompt-analytics categorize --llm) — Anthropic / OpenRouter / Ollama. Reads meaning, so it handles open-ended prompts the regex can't, at the price of API calls. Same labels, defined by theSYSTEM_PROMPTincategorize.py.
The rules below describe the heuristic classifier (the source of truth is
prompt_analytics/categorize.py).
⚠️ This is the most work-in-progress part of the tool — and the easiest to help with. The heuristic rules were tuned on one developer's real prompt history, which is not representative: it skews toward this project's own workflow (French + English, lots of git/ops and dashboard iteration). As the community runs the tool on their own logs, the keyword lists, weights and category boundaries will need to evolve — this is exactly where contributions have the most impact. If a category mislabels your prompts, that's a useful signal: open an issue with a few (anonymized) examples, or send a PR tweaking the rules incategorize.py. The--llmmode is the escape hatch in the meantime for prompts the regex can't place.
| Category | What it represents | Example |
|---|---|---|
| plan | Planning, architecture, design decisions | "propose an architecture for the cache" |
| implementation | Writing new code or features | "add a login endpoint" |
| debug | Fixing errors, investigating failures/crashes | "fix the error, it crashes on merge" |
| refactor | Improving / restructuring existing code | "simplify this function" |
| review | Reviewing, auditing, verifying code or results | "analyze the project", "verify the file" |
| test | Writing/running tests, CI, coverage | "add tests for the parser" |
| docs | README, changelog, comments, status files | "update the changelog" |
| ops | Git (commit/push/merge/PR), deploys, running scripts | "commit and push the branch" |
| question | Explanations, understanding | "what does this function do?" |
| followup | Short conversational steering / acks / option picks | "ok", "yes go ahead", "ok for A" |
| feedback | Reacting to / correcting the assistant's work | "not bad but the order is wrong", "actually, change…" |
| notification | Harness task-notification (background task / sub-agent finished) — not a human prompt | <task-notification>…</task-notification> |
| other | Everything the rules can't place | open-ended prose with no keyword |
For each prompt, in order:
-
Strip harness chrome.
<system-reminder>…</system-reminder>and<task-notification>…</task-notification>blocks are removed first, so the classification reflects the user's actual words (a reminder prefixing a real instruction no longer masks it). - Pure notification? If the turn was nothing but a task-notification (empty after stripping), it becomes notification. Its token cost is untouched everywhere else — cost is derived from tokens, not the category.
- Pure ack/steering? A short prompt (≤ 40 chars) made entirely of acknowledgement tokens — ok, yes, go, sounds good, lgtm (and French equivalents like oui, c'est bon, je valide), an option pick (ok A, ok option 1), or a restart nudge (continue, reprends) — becomes followup before any scoring.
- Weighted keyword scoring. Every category has a list of FR+EN regex patterns (accent-tolerant — real prompts are mostly unaccented French). Each match adds the category's weight; the highest total wins.
-
Ties & fallback. Equal scores resolve by a fixed priority order (below), so
a prompt that both "fixes" and mentions a "plan" is debug. If no rule
fires, a prompt ending in
?is question, otherwise other.
The weight sets how strongly a single keyword pulls; the priority breaks exact ties. Specific intents outweigh and outrank generic discourse.
| Priority (ties) | Category | Weight | Representative triggers |
|---|---|---|---|
| 1 | debug | 1.2 |
fix, error, bug, crash, traceback, broken, not working, why does…, root cause
|
| 2 | docs | 1.1 |
readme, changelog, docstring, markdown, comments, status file, update the docs
|
| 3 | test | 1.25 |
test(s), pytest, coverage, regression, fixtures, CI passes
|
| 4 | review | 1.1 |
review, audit, analyze, verify, check, inspect, look at
|
| 5 | refactor | 1.0 |
refactor, improve, clean up, simplify, optimize, rename, restructure
|
| 6 | ops | 1.0 |
commit, push, merge, PR, branch, rebase, git, deploy, run the script, publish, install, release
|
| 7 | plan | 1.2 |
architecture, design, propose, strategy, approach, how should I…, best way
|
| 8 | implementation | 0.8 |
implement, create, write, add, develop, generate, build, integrate
|
| 9 | question | 1.0 |
what is, how do, why, explain, understand, describe, difference between
|
| 10 | followup | 1.5 | stalled-assistant nudges; restart orders at line start (continue, restart, resume) |
| 11 | feedback | 0.5 |
actually, instead, on second thought, I think, I prefer, not convinced, looks good but, still the same, not quite, no change
|
| — | notification | n/a | detected structurally (step 2), not scored |
| — | other | n/a | the remainder (step 5) |
Bilingual. The triggers above are shown in English, but the classifier is FR + EN: each has a French counterpart matched too (debug also fires on
erreur/corrige/plante, ops ondéploie/lance le script, feedback onen fait/plutôt/par contre, …), accent-tolerant since real prompts are mostly unaccented French. Seecategorize.pyfor the full lists.
Why feedback is the lowest weight (0.5). Course-correction markers
("actually", "instead", "by the way") are extremely common discourse and
appear inside real task prompts too. At weight 0.5 a feedback marker is always
out-scored by any concrete intent — "actually, fix the bug" stays debug,
"instead, add a test" stays test. feedback only wins when the prompt
is pure steering with no task keyword, i.e. exactly the prompts that would
otherwise fall through to other.
A few labels naturally dominate an agentic-coding history — that's signal, not noise:
- ops is often the largest bucket: in agent-driven work you commit, push, merge, run scripts, install and deploy constantly, and every one of those verbs is an ops prompt.
- debug and question follow for the same reason — a lot of a session is reporting breakage and asking how things work.
- feedback + followup together measure how much of your interaction is iterative steering (acks, corrections, course-changes) rather than net-new work — a genuinely useful ratio to watch.
- notification is harness plumbing (background tasks / sub-agents finishing), kept separate so it neither inflates other nor distorts the real intents, while its token cost still counts everywhere.
-
other is the floor the heuristic can't pass: open-ended prose with no
reliable keyword (and the unavoidable typos / source-corrupted accents). Run
categorize --llmto classify that long tail by meaning.
Complexity is observed, not classified. Rather than guess difficulty from the wording, it is the quintile-banded average of four real effort signals per prompt: assistant turns, tool calls, prompt length, and prompt cost. So a "3" means median effort across your own history, and the same scale recomputes on every run.
The heuristic stamps each row with a version (HEURISTIC_VERSION, currently
heuristic-v3). Bumping it makes the next categorize run re-classify every
heuristic row with the current rules — so a rules upgrade propagates without a
re-extract. LLM-classified rows are never overwritten by the heuristic.
See Dashboard for the Prompts page that renders these, and
CLI Commands for categorize / categorize --llm.