Content moderation
Check user posts against your policy, many at a time. Clear violations are removed, clear passes are published, and the borderline ones go to a moderator, which is where people add the most value.
import asyncio
from simoai import AsyncClient, Choice, Noul
POLICY = """No harassment or threats against a person. No spam or scams.
No sharing of someone else's personal information. Criticism of products and companies is allowed."""
QUESTIONS = {
"violates": Noul("The post breaks the community policy"),
"reason": Choice("Which rule does the post break, if any?", {
"none": "it breaks no rule",
"harassment": "harassment or threats against a person",
"spam": "spam, scams or unsolicited advertising",
"privacy": "someone else's personal information",
}),
}
async def moderate(posts: list[str]) -> list[tuple[str, str]]:
async with AsyncClient(max_concurrency=16) as c:
results = await asyncio.gather(*(c.ask({"policy": POLICY, "post": p}, QUESTIONS) for p in posts))
out = []
for post, r in zip(posts, results):
p = r["violates"].noul
verdict = "remove" if p > 0.95 else "publish" if p < 0.05 else "moderator"
out.append((verdict, r["reason"].choice))
return out
posts = ["This blender is the worst product I've bought, avoid it.",
"Click here to claim your free crypto!!! limited time",
"I know where you live, @jake. Watch yourself."]
for verdict, reason in asyncio.run(moderate(posts)):
print(verdict, reason)
# publish none
# remove spam
# remove harassmentconst POLICY = `No harassment or threats against a person. No spam or scams.
No sharing of someone else's personal information. Criticism of products and companies is allowed.`;
const QUESTIONS = {
violates: { type: "noul", instructions: "The post breaks the community policy" },
reason: {
type: "choice",
instructions: "Which rule does the post break, if any?",
criteria: {
none: "it breaks no rule",
harassment: "harassment or threats against a person",
spam: "spam, scams or unsolicited advertising",
privacy: "someone else's personal information",
},
},
};
async function check(post) {
const res = await fetch("https://api.temprl.org/v1/ask", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.SIMO_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({ model: "simo-1-pro", state: { policy: POLICY, post }, questions: QUESTIONS }),
});
const { answers: a } = await res.json();
const p = a.violates.noul;
return { verdict: p > 0.95 ? "remove" : p < 0.05 ? "publish" : "moderator", reason: a.reason.choice };
}
// Up to 16 at a time
async function moderate(posts, limit = 16) {
const out = new Array(posts.length);
let next = 0;
await Promise.all(Array.from({ length: limit }, async () => {
while (next < posts.length) { const i = next++; out[i] = await check(posts[i]); }
}));
return out;
}Why it works
- The policy is in the state, so changing a rule is a text edit, not a retraining job.
- Two thresholds, three outcomes. Calibration makes "remove above 0.95" mean about 1 wrongful removal in 20 among the closest calls, and you can tighten it.
- Concurrency is cheap.
max_concurrencycaps requests in flight; each post is a short read.