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.

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 APIQuello 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
- Apri il portale sviluppatori Discord e crea un'applicazione, poi aggiungi un bot ad essa.
- Nelle impostazioni del bot, abilita l'Intent Message Content. Senza di esso, il bot riceve messaggi con testo vuoto.
- Copia il token del bot. Trattalo come una password.
- Usa il generatore URL OAuth2 per invitare il bot con il permesso di leggere e inviare messaggi nei canali che scegli.
- 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_TOKENeAPI_KEYcon valori finti così le persone sanno cosa impostare. - Un URL base configurabile. Leggi
BASE_URLeMODELdall'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.
Altre guide
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