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 text or collection + 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