Ce que l'API vous donne et ce que vous possédez encore
Le service est une API textuelle hébergée, compatible OpenAI. Vous pointez un SDK OpenAI vers https://api.chatbotnsfw.com/v1, utilisez l'ID de modèle uncensored et envoyez des messages de chat normaux. Le modèle est un modèle à poids ouverts ajusté pour répondre sans refus de contenu pour un usage adulte légal. Il est textuel uniquement : pas d'images, d'audio ou de vidéo.
C'est tout le contrat. L'API ne sait pas qui est votre utilisateur, quel âge il a, ou ce que votre plateforme autorise. Elle ne se souvient de rien non plus entre les appels. Chaque requête doit inclure l'intégralité de la conversation que vous voulez que le modèle consulte.
| Préoccupation | Qui en est responsable |
|---|---|
| Générer des réponses sans refus de contenu | L'API |
| Persona, ton et règles de l'histoire | Vous, dans le prompt système |
| Mémoire de conversation | Vous, dans votre base de données |
| Vérification de l'âge et consentement | Vous |
| Blocage du contenu impliquant des mineurs | Vous, et l'API avez la même limite stricte |
| Signalements, bannissements, conditions d'utilisation | Vous |
Si vous n'avez jamais développé contre une API de chat, la documentation de l'API couvre le format de requête. Le guide d'intégration LLM NSFW existant passe en détail le côté intégration ; cet article concerne le produit autour de celui-ci.
Architecture : gardez la clé sur le serveur
Votre frontend ne doit jamais conserver la clé API. Placez un petit backend entre le navigateur ou l'application et l'API. Le backend authentifie votre utilisateur, vérifie le contrôle d'âge, charge son historique, appelle l'API et stocke la réponse.
- Le navigateur envoie le message de l'utilisateur à votre backend avec sa session.
- Le backend vérifie que l'utilisateur est vérifié comme majeur et sous son plafond de débit.
- Le backend construit la liste des messages : prompt système, mémoire, tours récents, nouveau message.
- Les appels backend font un
POST /v1/chat/completionset diffusent les tokens en retour. - Le backend enregistre le nouveau tour une fois la fin du streaming atteinte.
Une clé complète permet 8 requêtes simultanées et 300 requêtes par minute. C'est largement suffisant pour un bot de loisir et un bon départ pour un petit produit, tant que votre backend ne laisse pas un utilisateur ouvrir plusieurs streams à la fois. Une requête en streaming occupe son slot de concurrence jusqu'à la fin du stream, donc un utilisateur qui s'éloigne d'un stream ouvert vous coûte encore un slot.
Rédigez le persona comme un contrat
Le prompt système fait la plus grande partie du travail produit. Un bon prompt se lit comme un court contrat avec le modèle, et non comme un paragraphe d'adjectifs. Couvrez quatre choses : qui est le personnage, comment il parle, quelle est l'histoire, et ce qui est hors limites.
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.chatbotnsfw.com/v1",
api_key=os.environ["NSFW_API_KEY"],
)
PERSONA = """You play Mara, a 34-year-old ship's navigator in a slow-burn
space romance. All characters are adults.
Voice: dry, warm, short paragraphs, first person.
Story rules: keep continuity with the notes below; never speak for the user;
stay in character unless the user writes OOC: in brackets.
Hard limits: no sexual content involving anyone under 18, ever. If the user
steers there, refuse in character and change the scene."""
def reply(history, user_text):
messages = [{"role": "system", "content": PERSONA}]
messages += history[-24:]
messages.append({"role": "user", "content": user_text})
r = client.chat.completions.create(
model="uncensored",
messages=messages,
temperature=0.9,
top_p=0.95,
)
return r.choices[0].message.contentDeux détails comptent plus qu'ils n'y paraissent. Indiquez que tous les personnages sont adultes, en mots clairs, dans le prompt. Et dites au modèle quoi faire à la limite, par exemple pour changer de scène, pour que l'histoire continue au lieu de finir par un message d'erreur. Augmentez temperature pour une prose plus vive et réduisez-la si le personnage dérive.
Testez le persona avant de le lancer
Exécutez les mêmes vingt messages utilisateur à travers le prompt après chaque modification, y compris les plus délicats : un utilisateur qui demande au bot de quitter son personnage, un qui change le décor en plein milieu de la scène, un qui pousse vers la règle des mineurs. Sauvegardez les sorties et lisez-les. Les modifications de prompt qui corrigent un cas en cassent souvent un autre.
Mémoire qui tient dans la fenêtre
La fenêtre de contexte est de 100 000 tokens, prompt plus completion, donc il y a de la place pour une longue histoire. Plus long n'est pas toujours mieux. Vous payez pour chaque token d'entrée à chaque tour, et un modèle avec un historique énorme peut perdre les détails du début de toute façon.
Une disposition pratique a trois couches. Le prompt système contient le persona. Un court bloc de notes contient les faits qui doivent survivre : noms, état des relations, promesses faites dans l'histoire. Les 20 à 30 derniers tours vont mot pour mot. Les tours plus anciens sont résumés dans le bloc de notes par un appel peu coûteux tous les 20 tours environ.
Le code ci-dessus découpe déjà history[-24:], ce qui conserve les 24 derniers messages. Ajoutez le bloc de notes comme un deuxième message système quand vous en avez un. Les coûts restent faibles ainsi : un tour typique envoie quelques milliers de tokens d'entrée, ce qui à $0,15 par 1M de tokens d'entrée est une fraction de centime. La page de tarification a les chiffres, et l'article sur l'intégration montre les formats de requête.
Contrôle de l'âge et consentement
Un produit de contenu adulte a besoin d'un contrôle de l'âge avant le premier appel de chat, pas après. L'API ne vérifie pas l'âge. Ce devoir vous appartient, et la bonne méthode dépend de là où vous opérez et où vivent vos utilisateurs.
- Une case à cocher qui dit J'ai plus de 18 ans est une notice, pas une vérification. Certaines juridictions exigent plus.
- Stockez le résultat côté serveur contre le compte et vérifiez-le à chaque demande de chat, pas seulement lors de l'inscription.
- Rendez clair le caractère réservé aux adultes sur la page de destination et dans les conditions, avant l'inscription.
- Gardez les personnages fictifs adultes dans chaque persona, dans le prompt et dans la carte affichée aux utilisateurs.
Demandez à un avocat qui connaît votre marché quel est le minimum. Cet article ne peut pas vous le dire, et le fournisseur d'API ne peut pas le décider pour vous.
Responsabilités de modération qui vous incombent
Un modèle sans censure change ce que le modèle refuse. Il ne change pas ce dont vous êtes responsable. Planifiez ces éléments dès le premier jour :
- Blocage strict sur les mineurs. Le contenu sexuel impliquant des mineurs est banni sans ambiguïté. Ajoutez votre propre vérification d'entrée pour les tentatives évidentes et mettez fin à la session lorsqu'elle se déclenche.
- Signalement. Donnez aux utilisateurs un moyen de signaler une conversation et décidez de ce que vous faites avec un signalement.
- Actions sur le compte. Vous devez pouvoir suspendre un utilisateur rapidement.
- Données. Décidez combien de temps vous conservez les transcriptions et indiquez-le dans votre page de confidentialité. Le fournisseur de l'API n'utilise pas les prompts pour l'entraînement, mais votre propre base de données est votre responsabilité.
- Portée. Limitez le produit à un usage adulte légal et à la fiction. Indiquez-le dans vos conditions d'utilisation.
Les requêtes échouées ou refusées ne sont pas facturées, ce qui signifie qu'une requête bloquée par votre propre contrôle ne coûte rien non plus, car elle n'atteint jamais l'API.
Plafonds par utilisateur et contrôle des coûts
Une boîte de chat ouverte sans limites est une invitation pour un utilisateur à vider votre crédit. Définissez un plafond quotidien de tokens pour chaque compte et vérifiez-le avant l'appel à l'API. La réponse indique ce qu'a utilisé chaque tour, donc le plafond coûte un compteur.
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.chatbotnsfw.com/v1",
api_key=os.environ["NSFW_API_KEY"],
)
DAILY_CAP = 400_000 # tokens per user per day
used_today = {} # user_id -> tokens, keep this in your database
def guarded_reply(user_id, messages):
if used_today.get(user_id, 0) >= DAILY_CAP:
return "You have reached today's limit. Come back tomorrow."
r = client.chat.completions.create(model="uncensored", messages=messages)
used = r.usage.prompt_tokens + r.usage.completion_tokens
used_today[user_id] = used_today.get(user_id, 0) + used
return r.choices[0].message.contentUn plafond de 400 000 tokens est un nombre à ajuster, pas une recommandation. Avec un prompt de 6 000 tokens par tour, cela permet environ 65 tours par jour. Calculez ce qu'un utilisateur vaut pour vous, tarifiez le plafond en conséquence, et regardez l'en-tête X-Balance-USD dans votre propre monitoring pour qu'un bug ne consomme pas le crédit en une nuit.
Gardez un solde de crédit séparé et petit pour le staging. Le trafic de test et le trafic réel ne doivent jamais partager une clé, car une boucle de test qui réessaie à chaque erreur peut dépenser plus en une heure qu'une semaine d'utilisateurs réels.
Streaming et gestion du 429
Le chat semble lent sans streaming. Définissez stream: true et envoyez les blocs au navigateur. Le streaming se termine également par un bloc d'utilisation, que vous pouvez enregistrer pour le suivi des coûts.
Au-delà d'une limite, l'API répond HTTP 429. Le code d'erreur est rate_limited pour les requêtes par minute et concurrency pour trop de requêtes à la fois. Une surcharge temporaire renvoie également 429 avec Retry-After: 5. Honorez cet en-tête.
import os, time
from openai import OpenAI, RateLimitError
client = OpenAI(
base_url="https://api.chatbotnsfw.com/v1",
api_key=os.environ["NSFW_API_KEY"],
max_retries=0,
)
def stream_reply(messages):
for attempt in range(4):
try:
stream = client.chat.completions.create(
model="uncensored",
messages=messages,
stream=True,
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
yield chunk.choices[0].delta.content
return
except RateLimitError:
time.sleep(5)
yield "The service is busy. Please try again in a moment."Ajoutez un verrou par utilisateur pour qu'un compte ne détienne qu'un stream à la fois. Ensuite, 8 requêtes simultanées supportent environ 8 utilisateurs de chat simultanés, et une file d'attente absorbe le reste.
Pour commencer, obtenez une clé API. Les nouveaux utilisateurs peuvent réclamer 0,50 $ de crédit d'essai en un clic sur la page de clé. La clé d'essai est limitée à 2 requêtes simultanées et 60 requêtes par minute, ce qui est suffisant pour tester le flux.
