Skip to main content
The Classify stage labels documents at query time. It supports two modes:
  • Built-in tasks (via task) — managed classifiers Mixpeek hosts for you. The first available task is nsfw, a content-safety classifier for text, image, and video. No plugin to build or deploy.
  • Custom classifiers (via feature_uri) — your own classifier model deployed as a custom extractor. The stage sends document text to your extractor’s inference endpoint and attaches predicted labels with confidence scores to each document.
Set exactly one of task or feature_uri.
Stage Category: APPLY (Enriches documents)Transformation: N documents → N documents (with classification results added). A built-in task can optionally drop documents (e.g. drop_if_unsafe), making it N → ≤N.

When to Use

Use CaseDescription
Custom classificationApply your own trained classifier to search results
Content labelingTag documents with domain-specific categories
Compliance scoringScore documents against compliance criteria
Intent detectionClassify user queries or document intent

When NOT to Use

ScenarioRecommended Alternative
Predefined taxonomy classificationtaxonomy_enrich (no custom model needed)
LLM-based classificationllm_enrich with output_schema
Simple keyword matchingattribute_filter

Available Classification Tasks

Built-in tasks are managed classifiers Mixpeek hosts — set task and skip feature_uri entirely. This list grows over time as more built-in tasks ship.
TaskWhat it doesModelModalitiesOutputs
nsfwContent-safety classification — scores how likely a document is unsafe (not safe for work)mixpeek/content-classifier-v1Text, image, videonsfw_score (0–1), label, is_nsfw
The mixpeek/content-classifier-v1 model is a CPU-only multimodal classifier: DistilBERT for text, ViT for images, and frame sampling for video — so the nsfw task runs without a GPU. By default it annotates each document with the outputs above; set drop_if_unsafe: true to filter unsafe documents out of the result set instead.
The same mixpeek/content-classifier-v1 model also powers a tenant-level upload gate: when nsfw_check_enabled is on for a shared-plane org, NSFW image, video, and text uploads are rejected at upload time. The Classify stage applies the same model at query time over search results. See Uploads.

Parameters

ParameterTypeDefaultDescription
taskstring (enum)nullBuilt-in classification task to run (e.g. "nsfw"). Mutually exclusive with feature_uri. See Available Classification Tasks.
feature_uristringRequired unless task is setFeature URI of your custom classifier plugin. Mutually exclusive with task.
document_fieldstring"content"Document field path containing text to classify
image_fieldstringnullDocument field path containing an image URL to classify instead of text (built-in tasks only)
video_fieldstringnullDocument field path containing a video URL to classify instead of text (built-in tasks only)
output_fieldstring"classification"Field path to store classification results
nsfw_thresholdfloat0.7Score at or above which a document is flagged is_nsfw (nsfw task only)
drop_if_unsafebooleanfalseDrop documents flagged unsafe instead of annotating them (nsfw task only)
max_document_charsinteger5000Maximum characters sent for classification (100–50000)
top_k_labelsintegernullKeep only the top-k labels by confidence (custom classifiers)
min_confidencefloatnullMinimum confidence threshold (0.0–1.0, custom classifiers)
batch_sizeinteger10Documents per inference call (1–100)
max_concurrencyinteger5Maximum concurrent inference requests (1–20)

Plugin Contract

Your classifier plugin must accept {text: str} and return {labels: [{label: str, confidence: float}]}.
# In your plugin's realtime.py
class ClassifierService(BaseInferenceService):
    def _process_single(self, inputs: dict, parameters: dict) -> dict:
        text = inputs["text"]
        # Your classification logic here
        return {
            "labels": [
                {"label": "technology", "confidence": 0.92},
                {"label": "business", "confidence": 0.78},
                {"label": "science", "confidence": 0.45},
            ]
        }
Set inference_type: "classify" in your plugin’s manifest to declare compatibility with the classify stage.

Configuration Examples

Built-in NSFW Task

{
  "stage_name": "nsfw_check",
  "config": {
    "stage_id": "classify",
    "parameters": {
      "task": "nsfw",
      "document_field": "content",
      "output_field": "safety",
      "nsfw_threshold": 0.7
    }
  }
}
{
  "stage_name": "nsfw_filter",
  "config": {
    "stage_id": "classify",
    "parameters": {
      "task": "nsfw",
      "document_field": "content",
      "drop_if_unsafe": true,
      "nsfw_threshold": 0.7
    }
  }
}
{
  "stage_name": "nsfw_image_check",
  "config": {
    "stage_id": "classify",
    "parameters": {
      "task": "nsfw",
      "image_field": "metadata.thumbnail_url",
      "output_field": "safety"
    }
  }
}
The annotate example writes a result like {"nsfw_score": 0.03, "label": "safe", "is_nsfw": false} to output_field on every document. The filter example drops any document whose nsfw_score meets nsfw_threshold instead of annotating it.

Custom Classifier

{
  "stage_name": "my_classifier",
  "config": {
    "stage_id": "classify",
    "parameters": {
      "feature_uri": "mixpeek://my_classifier@1.0.0/classify",
      "document_field": "content",
      "output_field": "classification"
    }
  }
}
{
  "stage_name": "my_classifier",
  "config": {
    "stage_id": "classify",
    "parameters": {
      "feature_uri": "mixpeek://my_classifier@1.0.0/classify",
      "document_field": "metadata.description",
      "output_field": "labels",
      "min_confidence": 0.5,
      "top_k_labels": 3
    }
  }
}
{
  "stage_name": "my_classifier",
  "config": {
    "stage_id": "classify",
    "parameters": {
      "feature_uri": "mixpeek://my_classifier@1.0.0/classify",
      "batch_size": 20,
      "max_concurrency": 10,
      "max_document_chars": 2000
    }
  }
}

Output

For a custom classifier, each document gets the predicted labels added at output_field:
{
  "document_id": "doc_123",
  "content": "Apple Inc. announced new AI features...",
  "classification": [
    {"label": "technology", "confidence": 0.95},
    {"label": "business", "confidence": 0.82}
  ]
}
For the built-in nsfw task, each document gets a safety result at output_field (unless drop_if_unsafe removed it):
{
  "document_id": "doc_123",
  "content": "Apple Inc. announced new AI features...",
  "safety": {
    "nsfw_score": 0.03,
    "label": "safe",
    "is_nsfw": false
  }
}

Performance

MetricValue
LatencyDepends on your plugin model
Batch size10 documents default
Concurrency5 parallel requests default
Max document chars5000 default

Common Pipeline Patterns

Search + Classify + Filter by Label

[
  {
    "stage_name": "search",
    "config": {
      "stage_id": "feature_search",
      "parameters": {
        "searches": [{
          "feature_uri": "mixpeek://text_extractor@v1/multilingual_e5_large_instruct_v1",
          "query": {"input_mode": "text", "value": "{{INPUT.query}}"},
          "top_k": 100
        }],
        "final_top_k": 25
      }
    }
  },
  {
    "stage_name": "classify",
    "config": {
      "stage_id": "classify",
      "parameters": {
        "feature_uri": "mixpeek://my_classifier@1.0.0/classify",
        "min_confidence": 0.7,
        "top_k_labels": 1
      }
    }
  },
  {
    "stage_name": "filter_by_label",
    "config": {
      "stage_id": "attribute_filter",
      "parameters": {
        "field": "classification.0.label",
        "operator": "eq",
        "value": "{{INPUT.target_category}}"
      }
    }
  }
]
  • Taxonomy Enrich - Predefined taxonomy classification (no custom model)
  • LLM Enrich - LLM-based enrichment and classification
  • Custom Extractors - Build and deploy custom inference models
  • Uploads - Tenant-level NSFW upload gate using the same mixpeek/content-classifier-v1 model