Lo que te da la API y lo que sigues controlando
El servicio es una API de texto alojada y compatible con OpenAI. Apuntas un SDK de OpenAI a https://api.chatbotnsfw.com/v1, usas el ID del modelo uncensored y envías mensajes de chat normales. El modelo es un modelo de pesos abiertos ajustado para responder sin rechazos de contenido para uso adulto lícito. Solo texto: sin imágenes, audio ni video.
Ese es todo el contrato. La API no sabe quién es tu usuario, qué edad tiene ni qué permite tu plataforma. Tampoco recuerda nada entre llamadas. Cada petición debe contener toda la conversación que quieras que vea el modelo.
| Preocupación | Quién lo gestiona |
|---|---|
| Generación de respuestas sin rechazos de contenido | La API |
| Personalidad, tono y reglas de la historia | Tú, en el prompt del sistema |
| Memoria de la conversación | Tú, en tu base de datos |
| Verificación de edad y consentimiento | Tú |
| Bloqueo de contenido que involucre a menores | Tú tienes el mismo límite estricto que la API |
| Reportes, prohibiciones, términos de uso | Tú |
Si aún no has trabajado con una API de chat, la documentación de la API describe el formato de las peticiones. La guía de integración de LLM NSFW existente detalla el lado de la integración; este artículo trata sobre el producto que hay detrás.
Arquitectura: mantén la clave en el servidor
Tu frontend nunca debe contener la clave de API. Pon un backend pequeño entre el navegador o la aplicación y la API. El backend autentica a tu usuario, verifica el control de edad, carga su historial, llama a la API y guarda la respuesta.
- El navegador envía el mensaje del usuario a tu backend con su sesión.
- El backend verifica que el usuario esté verificado como adulto y dentro de su límite de peticiones.
- El backend construye la lista de mensajes: prompt del sistema, memoria, turnos recientes, nuevo mensaje.
- El backend llama a
POST /v1/chat/completionsy transmite los tokens de vuelta. - El backend guarda la nueva vuelta después de que termine el streaming.
Una clave completa permite 8 peticiones simultáneas y 300 peticiones por minuto. Eso es suficiente para un bot de hobby y un buen comienzo para un producto pequeño, siempre que tu backend no permita que un usuario abra muchos streams a la vez. Una petición en streaming mantiene su espacio de concurrencia hasta que termina el stream, por lo que un usuario que abandona un stream abierto sigue costándote un espacio.
Escribe el personaje como un contrato
El prompt del sistema hace la mayor parte del trabajo del producto. Uno bueno se lee como un contrato corto con el modelo, no como un párrafo de adjetivos. Cubre cuatro cosas: quién es el personaje, cómo habla, cuál es la historia y qué está fuera de límites.
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.contentDos detalles importan más de lo que parecen. Indica que todos los personajes son adultos, en palabras claras, en el prompt. Y dile al modelo qué hacer en el límite, por ejemplo para cambiar la escena, para que la historia continúe en lugar de terminar en un mensaje de error. Sube temperature para una prosa más animada y bájala si el personaje se desvía.
Prueba el personaje antes de lanzarlo
Ejecuta los mismos veinte mensajes de usuario a través del prompt después de cada edición, incluyendo los incómodos: un usuario que le pide al bot que deje el personaje, uno que cambia la escena a mitad de la misma, uno que empuja hacia la regla de menores. Guarda las salidas y léelas. Las ediciones del prompt que corrigen un caso a menudo rompen otro.
Memoria que cabe dentro de la ventana
La ventana de contexto es de 100.000 tokens, prompt más respuesta, así que hay espacio para una historia larga. Más largo no siempre es mejor. Pagas por cada token de entrada en cada turno, y un modelo con un historial enorme puede perder detalles iniciales de todos modos.
Una distribución práctica tiene tres capas. El prompt del sistema contiene el personaje. Un bloque de notas breve contiene datos que deben sobrevivir: nombres, estado de la relación, promesas hechas en la historia. Las últimas 20 a 30 vueltas van literalmente. Las vueltas anteriores se resumen en el bloque de notas mediante una llamada barata cada 20 vueltas más o menos.
El código anterior ya corta history[-24:], lo que mantiene los últimos 24 mensajes. Añade el bloque de notas como un segundo mensaje del sistema cuando tengas uno. Los costes se mantienen bajos así: un turno típico envía unos pocos miles de tokens de entrada, que a $0,15 por 1M de tokens de entrada es una fracción de centavo. La página de precios tiene los números, y el artículo sobre integración muestra las formas de las peticiones.
Control de edad y consentimiento
Un producto de contenido para adultos necesita un control de edad antes de la primera llamada de chat, no después. La API no verifica la edad. Esa responsabilidad recae en ti, y el método correcto depende de dónde operes y dónde vivan tus usuarios.
- Una casilla que dice Soy mayor de 18 es un aviso, no una verificación. Algunas jurisdicciones requieren más.
- Guarda el resultado en el servidor contra la cuenta y compruébalo en cada petición de chat, no solo en el registro.
- Deja claro el carácter exclusivo para adultos en la página de destino y en los términos, antes del registro.
- Mantén a los personajes ficticios adultos en cada personaje, en el prompt y en la tarjeta mostrada a los usuarios.
Pregunta a un abogado que conozca tu mercado cuál es el mínimo. Este artículo no puede decirte, y el proveedor de la API no puede decidirlo por ti.
Responsabilidades de moderación que te corresponden
Un modelo sin censura cambia lo que el modelo rechaza. No cambia lo que te corresponde. Planifica esto desde el primer día:
- Bloqueo estricto de menores. El contenido sexual que involucre a menores está prohibido de forma absoluta. Añade tu propia comprobación de entrada para intentos evidentes y finaliza la sesión cuando se active.
- Informes. Da a los usuarios una forma de marcar una conversación y decide qué haces con un informe.
- Acciones de cuenta. Sé capaz de suspender a un usuario rápidamente.
- Datos. Decide cuánto tiempo conservas las transcripciones y dilo en tu página de privacidad. El proveedor de la API no usa prompts para entrenamiento, pero tu propia base de datos es tu responsabilidad.
- Alcance. Mantén el producto en el uso adulto lícito y la ficción. Indícalo en tus términos.
Las peticiones fallidas o rechazadas no se cobran, lo que significa que una petición bloqueada por tu propia comprobación tampoco cuesta nada, porque nunca llega a la API.
Límites por usuario y control de costes
Una caja de chat abierta sin límites es una invitación para que un usuario agote tu crédito. Establece un límite diario de tokens para cada cuenta y compruébalo antes de la llamada a la API. La respuesta indica cuántos tokens ha usado cada turno, por lo que el límite cuesta un contador.
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 límite de 400.000 tokens es un valor para ajustar, no una recomendación. Con un prompt de 6.000 tokens por turno, permite unos 65 turnos al día. Calcula el valor de un usuario para ti, ajusta el límite en consecuencia y revisa el encabezado X-Balance-USD en tu propia monitorización para que un fallo no consuma el crédito durante la noche.
Mantén un saldo de crédito separado y pequeño para el entorno de pruebas. El tráfico de pruebas y el tráfico real nunca deben compartir una clave, porque un bucle de pruebas que reintenta en cada error puede gastar más en una hora que una semana de usuarios reales.
Streaming y manejo de 429
El chat se siente lento sin streaming. Establece stream: true y reenvía los fragmentos al navegador. El streaming también termina con un bloque de uso, que puedes registrar para el seguimiento de costes.
Por encima de un límite la API responde HTTP 429. El código de error es rate_limited para peticiones por minuto y concurrency para demasiadas peticiones a la vez. La sobrecarga temporal también devuelve 429 con Retry-After: 5. Honra ese encabezado.
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."Añade un bloqueo por usuario para que una cuenta mantenga un stream a la vez. Así 8 peticiones concurrentes soportan aproximadamente 8 usuarios chateando simultáneamente, y una cola absorbe el resto.
Para empezar, obtén una clave de API. Los nuevos usuarios pueden reclamar $0,50 de crédito de prueba con un clic en la página de claves. La clave de prueba está limitada a 2 peticiones simultáneas y 60 peticiones por minuto, lo que es suficiente para probar el flujo.
