IT ▾
Ottieni la chiave API

Bot Discord open source con un LLM uncensored

Un bot Discord open source che parla tramite un LLM richiede circa ottanta righe di Python. Questa guida ti fornisce il codice, i limiti da rispettare e il costo per risposta, utilizzando un'API compatibile con OpenAI con un modello che non rifiuta richieste legali per adulti.

Illustrazione isometrica di un bot composto da cubi luminosi in una finestra di chat collegata a un albero di codice ramificato

Aggiornato

Punti chiave

  • discord.py e l'SDK OpenAI sono sufficienti; punta l'SDK a https://api.openrouternsfw.com/v1 e usa il modello uncensored.
  • Attiva l'intent Message Content nel portale sviluppatori Discord o il bot vedrà messaggi vuoti.
  • Usa un semaforo inferiore a 8 per restare entro il limite di concorrenza e mantieni i contenuti per adulti nei canali contrassegnati come per adulti.
  • Una risposta con 1.500 token di input e 300 di output costa $0,000375, quindi circa $3,75 per 10.000 risposte.

Nessuna carta necessaria. Dopo la registrazione, ottieni $0,50 di credito di prova gratuito con un clic (una volta per persona).

Ottieni la chiave API

Quello che stai costruendo

Il bot qui sotto risponde quando qualcuno lo menziona. Mantiene una breve cronologia per canale, la invia all'endpoint chat completions e pubblica la risposta. È Python puro, compatibile con licenza MIT e non ha database. Puoi leggerlo tutto in una volta, che è lo scopo di un progetto open source: qualcun altro può fare fork e capirlo.

Il modello alla base è un singolo modello testuale a pesi aperti, gestito da un provider indipendente e ottimizzato per rispondere senza rifiuti di contenuto per uso adulto legale. Questo si adatta alle comunità Discord costruite attorno a narrativa, roleplay o conversazioni per adulti. Si applicano due regole fin dall'inizio. Primo, i contenuti sessuali che coinvolgono minorenni non sono consentiti dall'API e non devono far parte del design del tuo bot. Secondo, Discord ha le sue regole e le impostazioni dei canali per adulti, e tu sei responsabile di rispettarle. Limita i contenuti per adulti ai canali contrassegnati come tali e ai server in cui i membri sono adulti.

Configura Discord e le tue chiavi

  1. Apri il portale sviluppatori Discord e crea un'applicazione, poi aggiungi un bot ad essa.
  2. Nelle impostazioni del bot, abilita l'Intent Message Content. Senza di esso, il bot riceve messaggi con testo vuoto.
  3. Copia il token del bot. Trattalo come una password.
  4. Usa il generatore URL OAuth2 per invitare il bot con il permesso di leggere e inviare messaggi nei canali che scegli.
  5. Ottieni una chiave API dalla pagina delle chiavi. I nuovi utenti possono richiedere $0,50 di credito di prova con un clic, senza bisogno di dettagli di pagamento, valido per 7 giorni.

Memorizza entrambi i segreti come variabili d'ambiente, mai nel repository. Per un progetto open source questo è più importante del solito, perché il codice è pubblico.

pip install discord.py openai python-dotenv
printf 'DISCORD_TOKEN=your-discord-token
API_KEY=your-api-key
' > .env
echo ".env" >> .gitignore

Il codice del bot

Salva questo come bot.py. I commenti spiegano le decisioni non ovvie.

import asyncio
import os
from collections import defaultdict, deque

import discord
from dotenv import load_dotenv
from openai import AsyncOpenAI

load_dotenv()

ai = AsyncOpenAI(
    base_url="https://api.openrouternsfw.com/v1",
    api_key=os.environ["API_KEY"],
    max_retries=4,          # the SDK retries 429 and honors Retry-After
)

SYSTEM = (
    "You are Vex, a sharp-tongued storyteller in a Discord server for adults. "
    "Stay in character, keep replies under 150 words, and never write "
    "anything sexual involving minors."
)

intents = discord.Intents.default()
intents.message_content = True
bot = discord.Client(intents=intents)

slots = asyncio.Semaphore(6)                      # stay under 8 concurrent
history = defaultdict(lambda: deque(maxlen=12))   # last 12 turns per channel


async def ask(channel_id, user_text):
    turns = history[channel_id]
    turns.append({"role": "user", "content": user_text})
    messages = [{"role": "system", "content": SYSTEM}] + list(turns)
    async with slots:
        resp = await ai.chat.completions.create(
            model="uncensored",
            messages=messages,
            temperature=0.9,
            max_tokens=400,
        )
    reply = resp.choices[0].message.content or ""
    turns.append({"role": "assistant", "content": reply})
    return reply


@bot.event
async def on_ready():
    print(f"Logged in as {bot.user}")


@bot.event
async def on_message(message):
    if message.author.bot or bot.user not in message.mentions:
        return
    text = message.clean_content.replace(f"@{bot.user.display_name}", "").strip()
    if not text:
        return
    async with message.channel.typing():
        try:
            reply = await ask(message.channel.id, f"{message.author.display_name}: {text}")
        except Exception as exc:
            print("API error:", exc)
            await message.reply("The model is busy. Try again in a few seconds.")
            return
    for i in range(0, len(reply), 1900):          # Discord caps messages at 2000 chars
        await message.reply(reply[i:i + 1900])


bot.run(os.environ["DISCORD_TOKEN"])

Eseguilo con python bot.py, poi menziona il bot in un canale che può leggere. La prima risposta dovrebbe arrivare in pochi secondi.

Se non succede nulla, controlla tre cose in ordine. Il bot deve essere online nell'elenco dei membri, quindi il token è valido. Deve avere il permesso di leggere e inviare messaggi in quel canale. E la menzione deve essere una vera menzione Discord, selezionata dall'elenco di completamento automatico, perché il testo normale con il nome del bot non appare in message.mentions. Il terminale stampa gli errori API, quindi una chiave errata appare lì come errore di autenticazione.

Perché il codice è strutturato così

La cronologia è piccola apposta

La finestra di contesto è di 100.000 token, quindi potresti inviare molto. Ma ogni token di input è fatturato su ogni chiamata e la chat di Discord è per lo più composta da righe brevi. Dodici turni mantengono le risposte coerenti senza trasformare ogni messaggio in un conto elevato. Aumenta maxlen per i canali di narrazione dove la continuità è importante.

Il semaforo protegge la tua chiave

Una chiave completa permette 8 richieste concorrenti e 300 richieste al minuto. Una chiave di prova ne permette solo 2 e 60. Se dieci persone menzionano il bot contemporaneamente e invii dieci richieste, quelle extra ricevono HTTP 429 con il codice errore concurrency. Il semaforo le accoda nel tuo stesso processo. Impostalo a 2 mentre sei sulla chiave di prova. Se mai attivi lo streaming, ricorda che una richiesta in streaming mantiene il suo slot fino al termine dello stream.

I retry provengono dall'SDK

L'SDK Python di OpenAI riprova su 429 e rispetta l'intestazione Retry-After, che il servizio invia come Retry-After: 5 in caso di sovraccarico temporaneo. Impostare max_retries a 4 copre i picchi brevi. Le richieste fallite o rifiutate non vengono addebitate, quindi i tentativi non ti costano token quando falliscono.

Una personalità condivisa

Il prompt di sistema è il primo in ogni chiamata. Le personalità per canale sono una piccola estensione: mantieni un dizionario dall'ID del canale al prompt e cercalo in ask.

Rendi un buon progetto open source

Il codice funziona, ma un repository pubblico ha bisogno di alcune integrazioni prima che gli estranei possano usarlo.

  • Una licenza. MIT o Apache 2.0 sono le scelte usuali per i bot piccoli. Aggiungi il file nella radice del repository.
  • Un .env.example. Elenca DISCORD_TOKEN e API_KEY con valori finti così le persone sanno cosa impostare.
  • Un URL base configurabile. Leggi BASE_URL e MODEL dall'ambiente, impostando come valori predefiniti quelli sopra. Chiunque lo forchi può poi usare qualsiasi server compatibile con OpenAI.
  • Un Dockerfile. Un file breve basato su un'immagine slim Python, che copia bot.py, installa i tre pacchetti ed esegue lo script, permette alle persone di ospitarlo ovunque.
  • Un README con l'avviso sugli intent. L'intent mancante per il contenuto dei messaggi è la domanda di supporto principale per ogni bot Discord.

Tieni il tuo token e la tua chiave fuori dalla cronologia Git. Se uno trapela, revocalo nel portale Discord o nella pagina della chiave API e emettine uno nuovo.

Hosting e costi

Il bot è un singolo processo a lunga esecuzione con uso leggero di CPU. Un piccolo VPS, una macchina in disuso o una piattaforma container è sufficiente. Non c'è server web da esporre, perché il bot si connette a Discord.

Il costo API è facile da calcolare. Una risposta tipica qui usa 1.500 token di input (prompt di sistema più dodici turni brevi) e 300 token di output.

  • Input: 1.500 x $0,15 / 1M = $0,000225
  • Output: 300 x $0,50 / 1M = $0,00015
  • Per risposta: $0.000375

Questo fa sì che 1.000 risposte costino $0,375 e 10.000 risposte $3,75. Il credito di prova da $0,50 copre circa 1.333 risposte. Una ricarica da $20 copre più di 53.000. Le ricariche vanno da $20 a $500, con +5% da $50, +10% da $100 e +15% da $200. Il credito non scade mai e non c'è abbonamento, quindi un server tranquillo costa quasi nulla. Vedi la pagina dei prezzi per i dettagli. Il pagamento è solo in cripto, usando USDT su TRC20 o USDC su Base.

Prossimi passi

Tre miglioramenti valgono lo sforzo. Aggiungi lo streaming modificando un singolo messaggio man mano che arrivano i chunk, ma bada ai limiti di modifica di Discord. Aggiungi un comando slash che resetta la cronologia del canale. Aggiungi la chiamata di funzioni così il bot può tirare dadi o cercare una scheda personaggio; l'API supporta tools, tool_choice e role: "tool" nei risultati nel formato OpenAI.

La documentazione API elenca ogni parametro supportato, e l'articolo API Hermes copre come si comportano i modelli senza censura all'interno di un progetto. I prompt inviati all'API non sono usati per l'addestramento, il che vale la pena dire nelle regole del tuo server se i membri chiedono.

Domande e risposte

Il bot ha bisogno dell'intent per il contenuto dei messaggi?

Sì. Attivalo nel portale sviluppatori Discord e nel codice impostando intents.message_content su true. Altrimenti il bot vede messaggi vuoti.

Quante risposte può gestire il bot contemporaneamente?

Una chiave standard permette 8 richieste parallele e 300 al minuto; una chiave di prova permette 2 e 60. Un semaforo nel bot ti mantiene sotto il limite.

Posso pubblicare il codice del bot?

Sì, purché il token di Discord e la chiave API non finiscano nel repository. Leggili dalle variabili d'ambiente e includi un file .env.example.

È consentito usare temi per adulti?

Solo per uso adulto legale, in linea con le regole di Discord e le impostazioni dei canali riservati agli adulti. I contenuti sessuali che coinvolgono minorenni non sono mai consentiti.

Quanto costa l'esecuzione?

Una risposta con 1.500 token di input e 300 token di output costa $0,000375, quindi circa $3,75 per 10.000 risposte, più il costo di hosting del processo.

La tua chiave è a un modulo di distanza

Crea un account, copia la chiave, cambia l'URL di base. Questa è tutta la configurazione.

Ottieni la chiave API