Content moderation
Rate harm on a scale, flag the hard cases with yes-no, and send the uncertain middle to a person.
Moderation asks two different questions. How bad is this? is a scale. Does this break a named rule? is a yes or no. Ask them separately and you get two numbers you can act on.
This recipe runs rate for severity and one batched yes-no call for the hard flags.
Every response below comes from a live call against https://api.milliseconds.ai.
Rate the severity
Write the scale as level descriptions, ordered low to high. A scale takes 2 to 10 levels. Numbers (“1”, “2”, “3”) carry no meaning for the model — describe each level.
Read all three numbers. level 1 is the argmax, but levels 1 and 2 split almost evenly
(0.501 against 0.488). score 1.509 sits between them, and confidence 0.463 reports the
ambiguity. This post belongs in a review queue, not in an automatic action.
score is the probability-weighted position, Σ p_i · i. It ranges from 0 to
scale.length − 1. level is the single most likely index. They disagree when the
distribution spreads across levels, and that disagreement is your review signal.
Flag the hard cases
A scale smears a rule violation across levels. Name each rule as its own statement and send
all of them in one yes-no call. The statements go into a single inference call, so the
batch costs about the same as one statement.
Each probability stands on its own. The five numbers do not sum to 1, so read every flag against its own threshold. Here the doxxing flag reaches 0.243 on “I know where you live” and still stays below any action band.
The same post scored {"score":2,"level":3,"confidence":0.208,"scores":[0,0.333,0.333,0.333]}
on the severity scale — a three-way tie. The scale was unsure; the threat statement was not.
This is why you run both calls.
The rude article comment returns the opposite picture. Its highest flag is spam at probability 0.141, and the threat flag drops to 0.008.
Write each statement as a case, never as a verdict. Hint text such as when_true: "yes" and
when_false: "no" carries no meaning to the model. A measured probe flipped a correct
answer: true (probability 1) to answer: false (probability 0.004) with that wording.
Route the item
Set one threshold per action, not one for the system. Removal needs more evidence than a warning label does. Raise the bar with the blast radius.
Build the flags dict from the yes-no response, then route on both calls.
Tune these numbers against your own labelled examples. The bands above are a starting shape, not a measured policy.
Batch a queue
Swap text for texts and keep the same scale. Send up to 32 posts. The results come
back in input order, one entry per post — a compliment, the rude comment, and the threat:
The clean post returns confidence 1 and score 0. Publish it without a human.
Operational notes
- Each capability takes at most 32
texts, andyes-noat most 32statements. - Batching
textscosts one inference call per text. Batchingstatementsdoes not. - Measured latency:
ratewith 4 levels 1.02 s,yes-nowith 2 statements 1.12 s. - A
textholds up to 20,000 characters. The API chunks text over 2,000 characters, and each level keeps its highest score over the chunks. A long thread scores on its worst part. - Write scale and statement text in English, even for non-English posts.
- Handle
overloaded(529) with backoff. Decide in advance whether a failed check holds the post or publishes it.
No API key is required during the launch period.
Next
- Thresholds and confidence routing turns these bands into policy.
- Rate documents
score,levelandscoresin full. - LLM guardrails applies the same flags to model input and output.