Usage insights
Label requests by the kind of work they ask for (coding, legal, writing, …) and see the mix by team, model and person.
What it does
A classifier reads each sampled chat request and picks a category from your taxonomy, with a subcategory when that category has any. Administration → Usage insights shows the result: categories over time, each category's share and confidence, the subcategories, models and people behind it, the category mix per team, and the classifier's own speed and failures.
Only the label, its confidence and the classifier's timing are stored. The prompt is sent to the classifier and never written anywhere by Janus. Results are deleted after the retention you set (180 days by default), and never kept longer than the request log (JANUS_USAGE_RETENTION_DAYS, 365 days by default).
Choosing a classifier
Decision model (System One API). A decision model scores every category you offer and returns calibrated probabilities without generating text, so it is fast and its confidence means something. Janus speaks the System One API used by TypeSafe Jev, Bespoke Nimble, Laya and Cloudflare Clef, wherever they are served: TypeSafe (api.typesafe.ai), OpenRouter (/api/alpha/decisions, model ~typesafe/jev-latest), Ollama 0.35 or later (/v1/systemone, model nimble), or llama.cpp. It also speaks the OpenAI Decisions API (/v1/decisions, model gpt-6-luna): Janus picks the format from the provider, and Usage insights → Performance can override it per model. Add the server as an upstream like any other, then pick it as the provider. A hosted classifier receives your prompts; a self-hosted one keeps them inside your network.
Chat model. Any chat model Janus can reach is shown the taxonomy and asked to answer in JSON. It needs no extra service, which suits small deployments, but it is slower than a decision model, costs generation tokens, and its confidence is its own estimate. A small, fast model is usually enough. An answer that is not one of your categories is recorded as an error, never guessed.
Use Classifier → Try it to classify a sample with unsaved settings and compare classifiers and their speed before switching. Nothing is stored. Try it reads the text as a single message; to see how a follow-up is read with its conversation, use Auto-routing → Classifier → Try routing, which takes an earlier conversation (it uses the routing categories).
One decision model can serve Usage insights and the Security Gateway (prompt injection and content safety) at once. See Classifiers: speed and accuracy for how Janus combines their questions and how to measure what your choices cost.
Background or inline
Background (the default) labels requests after they are sent on, from a queue on each replica, so reporting adds no latency. When the queue is full a sample is skipped and counted as dropped.
Inline labels the request before it is forwarded and returns the label in the X-Janus-Category response header (category/subcategory). The request waits at most the classifier timeout; a timeout or error never fails the request, it proceeds unlabeled and the miss is recorded. When more inline calls are in flight than the parallel limit, extra requests are labeled in the background instead, so a slow classifier cannot pile up latency. Auto-routing does not use this label; it asks its own questions (see Auto-routing).
When a Security Gateway check already calls the same decision model about the same text, and that model takes questions together, the Usage insights question is added to that call in either mode. That happens for a first message (or for any message with Latest user message only), with Include the system prompt off, and when the label is a single question (subcategories off, or category and subcategory asked together). A follow-up read with its conversation is asked on its own, because the guards judge the new turn alone. A shared label costs no extra call or wait, is recorded as inline, and an answer Janus cannot use is recorded as a classifier error without affecting the check.
Categories
Janus ships 22 general categories (Coding, Technical help, Data analysis, Extraction and formatting, Writing and editing, Creative writing, Summarization, Translation and language, Research, Learning and tutoring, Science and math, Business and strategy, Marketing and sales, Customer communication, Finance and accounting, Legal, Medical and health, HR and people, Security, Personal and lifestyle, General chat, Other). Built-ins can be renamed, re-described or disabled, not deleted. Other is always offered so a request that fits nothing is not forced into a wrong category.
Add your own top-level categories for your industry, and subcategories one level deep: languages under Coding, Reverse engineering under Security. The description is what the classifier reads, so say what belongs and, when two categories are easy to confuse, what does not. A category's subcategories are also named in its description when the classifier picks the top level, so it knows that work belongs there.
At most 26 top-level categories and 25 subcategories per category can be enabled at once. Deleting a category stops new labels; requests already labeled keep theirs.
When the classifier accepts enough choices in one question, Janus asks for the category and subcategory together, offering every category and every subcategory as its own answer ("Coding", "Coding › Rust", …). That is one call instead of two and was the most accurate way to ask on every decision model we tested. A server with a lower limit (Ollama accepts 26 choices) is asked the category first and the subcategory second. Usage insights → Performance → Decision models shows the limit Janus detected for each classifier (Most choices per question) and lets you change it.
Sampling and what is sent
Requests to classify sets the share of chat requests labeled. Text to classify chooses the latest message with the recent conversation as context (default), the latest user message only, every user message, or the whole conversation. With context, a follow-up such as “What about Ohio?” is labeled by what the conversation is about rather than read on its own; the last six earlier messages are sent (each user message cut to its first 1,000 characters and each assistant reply to its first 300, at most 4,000 characters in all, newest kept) with the latest message marked as the one to judge, and a first message is classified exactly as it is. Installs that had saved the old default (latest user message) were moved to the new one; Include the system prompt helps when applications put the task there. Only the most recent characters up to the limit are sent (Nimble reads about 8,000 tokens). Embeddings, images and audio are not classified, and neither are requests refused by quota, rate limits or the Security Gateway. Usage insights reads the caller’s own text (after any Security Gateway redaction). Instructions Janus adds — a router’s instructions and Child Safety’s instructions — are never classified, even with Include the system prompt on. Janus Chat messages are classified once; Chat’s tool rounds, research rounds, media calls and titles are not classified.
Classifier calls are reported on the Usage insights page with their tokens and cost (from the provider's reported price, or the model's rate card for chat models). They never count against the caller's quota. Prometheus: janus_classifications_total{status,mode}, janus_classification_latency_seconds{mode,protocol} and janus_classification_queue.
In the request log
Administration → Requests shows each request's label in the Classified as column and can filter by category, by category › subcategory, or by whether a request was classified at all. The request drawer says whether the label was produced inline or in the background, how confident the classifier was, and how long it took.
Every request also records how long it waited on classifiers before it was forwarded and how many classifier calls that took (the Classifier wait column, hidden by default). That covers the Security Gateway guards and an inline label. Background labeling never delays a request, so it is not in that number; its own time, queue wait and call count are shown separately in the drawer.