Zero-Shot Classification
What Is It?
Zero-shot classification is a technique that categorizes text into predefined labels without any training data. Instead of training a model on labeled examples, it uses embedding similarity to determine which label best describes a document.
MDDB implements this using the same embedding infrastructure as vector search. Given a document (or raw text) and a list of candidate labels, it:
- Converts the document into a vector (embedding)
- Converts each candidate label into a vector
- Computes cosine similarity between the document vector and each label vector
- Returns labels ranked by similarity score
This means you can classify any document into any set of categories on the fly โ no model training, no labeled datasets, no ML pipeline.
When to Use It
- Content tagging โ Automatically tag blog posts, articles, or docs with topics
- Routing โ Route incoming documents to the right team/queue based on content
- Filtering โ Determine if content matches a category before further processing
- Quality gates โ Check if a document is "tutorial" vs "reference" vs "changelog"
- RAG pipelines โ Pre-classify retrieved documents before sending to LLM
- Moderation โ Flag content as "appropriate" / "inappropriate" / "needs review"
How It Works Internally
Document/Text Labels โ โโโโ "programming" โ โโโโ "cooking" โผ โโโโ "sports"
โโโโโโโโโโโโ โโโโ "music"
โ Embedding โ โ
โ Provider โโโโโโโโโโโโโโโโโโโโโโโโ
โ (OpenAI, โ EmbedBatch()
โ Ollama) โ
โโโโโโโโโโโโ โ โโโโ [0.87] "programming" โ cosine โโโโ [0.21] "music" โ similarity โโโโ [0.18] "sports" โผ โโโโ [0.12] "cooking" Ranked Results
Key optimization: If classifying a stored document that already has an embedding in the vector store (from vector search indexing), MDDB reuses the existing embedding instead of re-computing it.
Prerequisites
An embedding provider must be configured. Set at minimum:
MDDB_EMBEDDING_PROVIDER=openai # or: ollama, voyage, cohere
MDDB_EMBEDDING_API_KEY=sk-... # required for openai, voyage, cohere
See Embedding Providers for full configuration.
API Reference
POST /v1/classify
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
collection | string | No* | Collection name (for document reference) |
key | string | No* | Document key (for document reference) |
lang | string | No | Language code (default: "en") |
text | string | No* | Raw text to classify |
labels | string[] | Yes | Candidate labels to rank (max 100) |
topK | int | No | Return only top K labels (0 = all) |
multi | bool | No | If true, return all labels above threshold |
threshold | float | No | Minimum similarity score (default: 0.0) |
* Provide either textorcollection + key (with optional lang).
Response:
{ "results": [ { "label": "programming", "score": 0.87 }, { "label": "music", "score": 0.21 }, { "label": "sports", "score": 0.18 }, { "label": "cooking", "score": 0.12 } ], "model": "text-embedding-3-small", "dimensions": 1536
}
Usage Examples
Classify raw text
curl -X POST http://localhost:11023/v1/classify \ -H "Content-Type: application/json" \ -d '{ "text": "Go is a statically typed, compiled language designed at Google for systems programming", "labels": ["programming", "cooking", "sports", "music", "science"] }'
Classify an existing document
If the document is already stored and has been embedded (via vector reindex or auto-embedding), the existing embedding is reused โ no extra API call to the embedding provider.
curl -X POST http://localhost:11023/v1/classify \ -d '{ "collection": "blog", "key": "intro-to-go", "lang": "en", "labels": ["tutorial", "news", "opinion", "review", "changelog"] }'
Get only the top label
curl -X POST http://localhost:11023/v1/classify \ -d '{ "text": "Recipe for chocolate cake with ganache frosting", "labels": ["food", "technology", "finance", "health"], "topK": 1 }'
Response:
{ "results": [{ "label": "food", "score": 0.91 }], "model": "text-embedding-3-small", "dimensions": 1536
}
Filter by threshold
Return only labels with similarity above 0.5:
curl -X POST http://localhost:11023/v1/classify \ -d '{ "text": "Introduction to machine learning with Python and TensorFlow", "labels": ["programming", "machine learning", "data science", "cooking", "music"], "multi": true, "threshold": 0.5 }'
Sentiment-style classification
Zero-shot classification works for any label scheme โ including sentiment:
curl -X POST http://localhost:11023/v1/classify \ -d '{ "text": "This product is absolutely terrible, waste of money", "labels": ["positive", "negative", "neutral"] }'
Language detection
curl -X POST http://localhost:11023/v1/classify \ -d '{ "text": "Bonjour, comment allez-vous aujourd'\''hui?", "labels": ["english", "french", "german", "spanish", "polish"] }'
gRPC
The Classify RPC is available in the MDDB service:
rpc Classify(ClassifyRequest) returns (ClassifyResponse);
resp, err := client.Classify(ctx, &proto.ClassifyRequest{ Text: "Go is a compiled programming language", Labels: []string{"programming", "cooking", "sports"},
})
for _, r := range resp.Results { fmt.Printf("%s: %.2f\n", r.Label, r.Score)
}
MCP Tool
The classify_document tool is available to LLM agents via MCP:
{ "name": "classify_document", "arguments": { "text": "How to deploy Kubernetes on AWS with Terraform", "labels": ["devops", "frontend", "database", "security", "networking"] }
}
Or classify a stored document:
{ "name": "classify_document", "arguments": { "collection": "docs", "key": "k8s-deploy", "lang": "en", "labels": ["devops", "frontend", "database", "security"] }
}
Panel Client (JavaScript)
const result = await mddb.classify({ text: "Introduction to React hooks and state management", labels: ["frontend", "backend", "devops", "database"],
}); console.log(result.results[0].label); // "frontend"
console.log(result.results[0].score); // 0.89
Tips
- Label quality matters โ Use descriptive labels. "machine learning" works better than "ML" because embeddings capture more meaning from longer phrases.
- Number of labels โ Works well with 2-100 labels. Beyond 100 labels, consider splitting into hierarchical classification (first broad category, then subcategory).
- Threshold tuning โ Cosine similarity scores are relative. A score of 0.3 may be the "best" match if all labels are loosely related. Use
topK: 1to always get the best match regardless of absolute score. - Reuse embeddings โ If documents are already indexed for vector search, classification is nearly free since it reuses stored embeddings.
- Provider choice โ Larger embedding models (e.g.,
text-embedding-3-large) tend to produce better classification results than smaller ones.
Related Documentation
- Embedding Providers โ Configure OpenAI, Ollama, Voyage AI, Cohere
- Search Algorithms โ Vector search, FTS, hybrid search
- API Documentation โ Full endpoint reference
- LLM Connections โ MCP tool integration