Gestire responsabilmente un prodotto di chatbot per adulti: checklist per sviluppatori
Un chatbot per adulti è un prodotto reale e i prodotti reali comportano responsabilità. L'API ti offre un modello che non rifiuta contenuti adulti leciti, il che significa che la tua app, non il modello, è dove risiedono i controlli dell'età, le regole, le segnalazioni e i controlli sugli abusi. Questa checklist passa in rassegna ogni livello con codice funzionante, così puoi lanciare con sicurezza.
Aggiornato il
Punti chiave
- La piattaforma è solo per adulti; verifica l'età alla tua porta e mantieni il controllo lato server.
- Scrivi la tua policy sui contenuti e un percorso di segnalazione, perché l'apertura del modello non sostituisce le tue regole.
- I contenuti sessuali che coinvolgono minori sono sempre bloccati con un 403; progetta un'UX chiara e tranquilla per questo.
- Limita l'uso per utente e mantieni la chiave API sul tuo server; una chiave è condivisa da tutto il tuo traffico.
Chi è responsabile di cosa
Pensa allo stack in due livelli. L'API serve contenuti adulti leciti, narrativa e argomenti controversi senza rifiutarli, per utenti di età superiore ai 18 anni. Tutto ciò che circonda il modello, le persone che possono raggiungerlo, le regole che accettano e ciò che accade quando qualcosa va storto, è tuo. Questa separazione è liberante, ma solo se prendi sul serio la tua parte.
Ecco una breve tabella delle responsabilità da tenere appesa al muro.
| Preoccupazione | Piattaforma | La tua app |
|---|---|---|
| Contenuti sessuali che coinvolgono minori | Sempre bloccato (403) | Spiegalo, termina la scena, preveni le soluzioni di contorno |
| Età dei tuoi utenti | Solo adulti secondo i termini | Fai da filtro e verifica all'ingresso |
| Regole interne oltre la legge | Non applicate | Scrivi, pubblica ed applicale |
| Abusi per utente | 300 richieste al minuto per chiave | Limiti per utente e per giorno |
| Chiave segreta | La emette | Tienila sul tuo server |
Questa è una guida tecnica, non un parere legale; le regole variano a seconda del luogo, quindi verifica i requisiti dove vivono i tuoi utenti.
Verifica dell'età che funziona davvero
Un banner con un pulsante "Ho 18 anni" è il minimo, e un minorenne determinato può cliccarlo. Ha ancora importanza, perché registra una dichiarazione affermativa e mantiene onesta la tua policy. La chiave è dove la applichi. Se il controllo nasconde solo la chat nel browser, chiunque può chiamare il tuo endpoint direttamente. Fai in modo che il server rifiuti di parlare finché non esiste un marker firmato.
import crypto from "node:crypto";
// Minimal 18+ gate: the user must confirm before the chat routes work.
// Replace the confirmation with a real verification step when your market requires it.
const SECRET = process.env.GATE_SECRET; // random string kept on the server
function sign(value) {
return crypto.createHmac("sha256", SECRET).update(value).digest("hex");
}
export function issueAdultCookie(res, userId) {
const stamp = String(Date.now());
const payload = `${userId}.${stamp}`;
res.cookie("adult_ok", `${payload}.${sign(payload)}`, {
httpOnly: true, sameSite: "strict", secure: true, maxAge: 30 * 24 * 3600 * 1000,
});
}
export function requireAdult(req, res, next) {
const raw = req.cookies?.adult_ok || "";
const [userId, stamp, sig] = raw.split(".");
if (!sig || sign(`${userId}.${stamp}`) !== sig) {
return res.status(403).json({ state: "age_required" });
}
req.userId = userId;
next();
}Collega requireAdult davanti a ogni endpoint di chat. Aggiungi una verifica più forte quando il tuo mercato o il livello di rischio lo richiedono, come un controllo dell'età di terze parti, e mantieni il marker a breve durata in modo che tu possa fare re-prompt. Non rivolgerti mai a studenti o scuole nel tuo marketing, e posiziona il filtro prima che venga mostrato qualsiasi contenuto per adulti, incluse anteprime e conversazioni di esempio.
Scrivere la tua policy sui contenuti
Il modello non rifiuta materiale adulto legale, quindi decidi tu cosa permette il tuo prodotto. Una policy di una pagina è più che sufficiente. Copri cosa è benvenuto, cosa è fuori limite nella tua comunità anche se legale (ad esempio molestie a persone reali o doxxing), come gli utenti possono segnalare problemi e quali azioni intraprendi: avvertimenti, silenzi temporanei, ban.
- Pubblicala dove gli utenti si registrano, in linguaggio chiaro.
- Specchiala nel tuo system prompt. Una riga come "Tutti i personaggi sono adulti; termina qualsiasi scena che diventi non consensuale o coinvolga persone reali e nominate" mantiene il bot allineato alle tue regole.
- Rendi noiosa l'applicazione delle regole. Decidi le soglie in anticipo in modo che i moderatori non improvvisino.
- Rivedi la policy ogni trimestre mentre il tuo prodotto evolve.
Un percorso di segnalazione che gli utenti possono trovare
Assegna a ogni messaggio un piccolo pulsante di segnalazione, e fallo funzionare senza un giro di login. Quando qualcuno segnala una risposta, cattura il minimo necessario per agire: l'id utente, l'id del messaggio, una breve motivazione e un timestamp. Inoltralo in una coda che i tuoi moderatori controllano.
app.post("/api/report", requireAdult, express.json(), (req, res) => {
const { messageId, reason } = req.body;
// Store only what you need to act on: who, which message, why, when.
queueForModerator({ userId: req.userId, messageId, reason: String(reason).slice(0, 500), at: Date.now() });
res.json({ ok: true });
});Mantieni le tue promesse strette. Dichiara agli utenti esattamente cosa attiva una segnalazione e archivia solo ciò che la tua policy e le normative applicabili richiedono. Rivedi per quanto tempo conservi le segnalazioni e cancellale secondo un programma. Riconosci ogni segnalazione alla persona che l'ha inviata, anche con un ringraziamento di una riga, perché gli utenti smettono di segnalare quando sembra che non accada nulla. Tieni traccia di quanto rapidamente i tuoi moderatori chiudono gli elementi e stabilisci un obiettivo che puoi effettivamente raggiungere.
Progettare per il blocco 403 dei minori
I contenuti sessuali che coinvolgono minori sono sempre bloccati, anche nella narrativa e nel roleplay, e l'API risponde con un 403 e il codice content_blocked. Non riprovare e non cercare di riformulare per conto dell'utente. Invece, trattalo come un momento del prodotto che merita un design chiaro.
- Traducilo sul server in uno stato che la tua UI conosce, così il testo grezzo del provider non raggiunge mai lo schermo.
- Dì cosa è successo in una frase tranquilla e nomina la regola.
- Termina o resetta la scena. L'opzione "prosegui comunque" ne vanifica lo scopo.
- Registra l'evento con l'ID utente in modo che tentativi ripetuti possano attivare i tuoi meccanismi di enforcement.
- Non indovinare l'intento. Alcuni blocchi derivano da formulazioni ambigue; il messaggio neutro funziona per entrambi i casi.
// server: translate upstream outcomes into states your UI understands
if (upstream.status === 403) {
return res.status(403).json({
state: "content_blocked",
message: "That request breaks our rules, so we can't continue this scene.",
});
}
if (upstream.status === 402) return res.status(503).json({ state: "paused" });
if (upstream.status === 503) return res.status(503).json({ state: "busy" });// browser: show a calm, specific message for each state
const MESSAGES = {
content_blocked: "This scene can't continue. Sexual content involving minors is never allowed. Start a new chat any time.",
age_required: "Please confirm you are 18 or older to use the chat.",
slow_down: "You're sending messages quickly. Give it a few seconds.",
daily_limit: "You've reached today's message allowance. Come back tomorrow.",
paused: "Chat is briefly unavailable. We're on it.",
busy: "The service is busy. Try again in a moment.",
};
async function send(messages) {
const res = await fetch("/api/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ messages }),
});
if (!res.ok) {
const info = await res.json().catch(() => ({}));
showBanner(MESSAGES[info.state] || "Something went wrong.");
if (info.state === "content_blocked") endCurrentScene();
return null;
}
return res;
}
Controlli di abuso e rate limit per utente
La tua unica chiave API permette 300 richieste al minuto in totale, condivise da tutti gli utenti. Un account scriptato può affamare tutti gli altri, quindi applica limiti di fair-use tu stesso, ben al di sotto di quel tetto. L'esempio limita ogni utente a 12 messaggi al minuto e assegna a ciascuno un budget giornaliero di token misurato dalla figura usage nell'ultimo chunk di streaming.
const WINDOW_MS = 60_000;
const PER_USER_PER_MIN = 12; // your product rule, far below the key's 300
const DAILY_TOKEN_BUDGET = 60_000; // per user, tracked from the usage chunk
const hits = new Map(); // userId -> array of timestamps
const spent = new Map(); // userId -> tokens used today
export function userLimit(req, res, next) {
const now = Date.now();
const recent = (hits.get(req.userId) || []).filter((t) => now - t < WINDOW_MS);
if (recent.length >= PER_USER_PER_MIN) {
return res.status(429).json({ state: "slow_down" });
}
if ((spent.get(req.userId) || 0) >= DAILY_TOKEN_BUDGET) {
return res.status(429).json({ state: "daily_limit" });
}
recent.push(now);
hits.set(req.userId, recent);
next();
}
export function recordUsage(userId, totalTokens) {
spent.set(userId, (spent.get(userId) || 0) + totalTokens);
}Per la produzione, memorizza i contatori in un archivio condiviso invece che nella memoria del processo, in modo che i limiti sopravvivano ai riavvii e funzionino su più server. Aggiungi un max_tokens moderato a ogni richiesta per limitare il caso peggiore e monitora il 402 sul tuo saldo. Un credito di prova gratuito di $0,50 per 7 giorni è un buon modo per testare questi controlli prima che arrivi il traffico reale.
Mantieni la chiave sul server
Non spedire mai la chiave nei bundle front-end, nelle app mobili o nei repository pubblici. Memorizzala come variabile d'ambiente o in un gestore di segreti, caricala solo nel tuo backend ed escludila dai log e dai report di errore. Se sospetti una compromissione, rigenerala dal tuo account; la vecchia chiave smette di funzionare immediatamente, quindi prepara un deploy. Ricorda che c'è una chiave per account, il che rende uno strato proxy pulito ancora più prezioso. Il tutorial della chat web mostra il pattern dall'inizio alla fine, e la documentazione elenca i codici di errore che il tuo wrapper dovrebbe mappare.
Checklist pre-lancio
Scorri questa lista il giorno prima di aprire. Ogni elemento richiede minuti e previene una classe di problemi dolorosa da risolvere dopo l'arrivo degli utenti.
- Prova a rompere il filtro. Chiama il tuo endpoint di chat con curl e senza cookie. Deve rispondere 403 con
age_required, mai una risposta del modello. - Attiva ogni stato. Simula l'upstream per restituire 402, 403, 429 e 503 a turno, e conferma che ogni stato mostri il banner corretto e non perda mai testo di errore grezzo.
- Leggi ad alta voce la tua policy. Se un moderatore non riesce a decidere un caso basandosi solo su quella policy in un minuto, rivedi la formulazione.
- Testa il pulsante di segnalazione da uno schermo di telefono. Un controllo difficile da raggiungere non conta come percorso di segnalazione.
- Cerca la chiave nel repository. Cerca nelle cartelle front-end, negli output di build, nelle configurazioni di esempio e nella cronologia dei commit. Rigenera la chiave se la trovi ovunque in pubblico.
- Imposta gli alert. Notifica te stesso su un 402, su un picco di blocchi 403 da un singolo utente e su un aumento nell'uso giornaliero di token.
- Prepara l'interruttore di pausa. Un singolo flag che disattiva la chat in modo elegante è prezioso durante un incidente.
La sicurezza non è mai finita, e nemmeno l'elenco; aggiungi elementi ogni volta che un incidente ti insegna qualcosa di nuovo, e condividili con chiunque si unisca al tuo team in seguito. Rivedi l'elenco quando aggiungi funzionalità come upload di immagini nella tua UI, stanze di gruppo o condivisione pubblica dei personaggi, perché ognuno apre nuovi percorsi per gli abusi. Per aiuto nel modellare i personaggi stessi, leggi la guida al design dei personaggi, e tieni a portata di mano le basi delle note di integrazione nella documentazione mentre il tuo team cresce.
Domande e risposte
È sufficiente una casella di controllo per la verifica dell'età?
È un minimo e registra una dichiarazione, ma è facile da aggirarlo. Applicalo sul server e aggiungi una verifica più forte dove il tuo rischio o le regole locali lo richiedono.
Cosa dovrebbe fare la mia app in caso di 403 content_blocked?
Non ripetere. Traduci in un messaggio calmo nell'app, termina o resetta la scena e registra l'evento per la tua applicazione.
Posso permettere agli utenti di condividere la capacità della mia chiave API in modo equo?
Sì, aggiungendo limiti di rate e token giornalieri per utente sul tuo server. La chiave stessa è limitata a 300 richieste al minuto in totale.
Il modello applica le mie regole?
No. Non rifiuta contenuti adulti legali, quindi la tua policy, il system prompt e il flusso di moderazione devono fare questo lavoro.
La tua chiave è a un modulo di distanza
Crea un account, copia la chiave, modifica l'URL di base. È tutta qui la configurazione.