Skip to content
All guides

Classify or tag thousands of items cheaply

Short, repetitive tasks like sentiment, routing or tagging do not need the largest models. A small, fast model that answers directly costs a fraction of a cent per item and handles thousands of items in minutes when you send requests in parallel.

Recommended models

Chosen from models whose abilities we have verified for this job. Cost is for one item (about 120 tokens in, 3 out), at current prices.

ModelInput / 1MOutput / 1MContextPer request
Our pickDeepSeek V4 Flash 0423
deepseek/deepseek-v4-flash
$0.175$0.351.05M$0.000022
Also strongMinistral 3 14B 2512
mistralai/ministral-14b-2512
$0.25$0.25262K$0.000031
Lowest costGemma 3 27B
google/gemma-3-27b-it
$0.125$0.375110K$0.000016

How it works

  1. 1Give a fixed list of labels in the system prompt and ask for exactly one.
  2. 2Set temperature to 0 and a small max_tokens so answers are short and consistent.
  3. 3Send many requests at once with a concurrency limit (about 20 in flight), and map anything unexpected to "other".

Copy, paste, run

Set AMR_API_KEY to a key from your dashboard, install the OpenAI SDK (pip install openai or npm install openai) and run it. Swap the model for any other in the table.

import asyncio
import os

from openai import AsyncOpenAI

client = AsyncOpenAI(base_url="https://api.aimodelsrouter.ai/v1", api_key=os.environ["AMR_API_KEY"])
MODEL = "deepseek/deepseek-v4-flash"
LABELS = ["bug", "feature request", "billing", "praise", "other"]
limit = asyncio.Semaphore(20)  # requests in flight at once


async def classify(text: str) -> str:
    async with limit:
        response = await client.chat.completions.create(
            model=MODEL, temperature=0, max_tokens=10,
            messages=[
                {"role": "system", "content": f"Classify the customer feedback. Reply with exactly one label: {', '.join(LABELS)}."},
                {"role": "user", "content": text},
            ],
        )
        label = (response.choices[0].message.content or "").strip().lower().rstrip(".")
        return label if label in LABELS else "other"


async def main():
    feedback = [
        "The app crashes every time I upload a PDF.",
        "Please add a dark mode!",
        "I was charged twice this month.",
        "Honestly the best tool we've bought this year.",
    ]
    labels = await asyncio.gather(*(classify(t) for t in feedback))
    for text, label in zip(feedback, labels):
        print(f"{label:16} {text}")


asyncio.run(main())

Tested 2026-10-28: both versions were run against the live API with each model recommended at the time, and their answers checked.

Tips

  • Pick a model without a default reasoning trace for this: reasoning models spend tokens thinking before the label and can run out at a small max_tokens.
  • Spot-check 50 results by hand before running the full batch.
  • For dozens of labels or nuanced rules, switch to strict structured output with an enum of labels.
All 11 models that fit this job