DE ▾
API-Schlüssel erhalten

Open-Source-Discord-Bot mit einem unzensierten LLM

Ein Open-Source-Discord-Bot, der über ein LLM kommuniziert, besteht aus etwa achtzig Zeilen Python. Diese Anleitung gibt dir den Code, die Limits, die du beachten musst, und die Kosten pro Antwort, basierend auf einer OpenAI-kompatiblen API mit einem Modell, das rechtmäßige Erwachsenenanfragen nicht verweigert.

Isometrische Illustration eines Bots aus leuchtenden Würfeln in einem Chat-Fenster, verbunden mit einem verzweigten Code-Baum

Aktualisiert

Wichtige Punkte

  • discord.py plus das OpenAI SDK reichen aus; verweise das SDK auf https://api.openrouternsfw.com/v1 und verwende das Modell uncensored.
  • Aktiviere den Message Content Intent im Discord-Entwicklerportal, sonst sieht der Bot leere Nachrichten.
  • Verwende ein Semaphore unter 8, um das Concurrency-Limit einzuhalten, und halte Erwachseneninhalte in Kanälen, die als altersbeschränkt markiert sind.
  • Eine Antwort mit 1.500 Input- und 300 Output-Token kostet 0,000375 $, also etwa 3,75 $ pro 10.000 Antworten.

Keine Karte nötig. Nach der Anmeldung beanspruche mit einem Klick 0,50 $ kostenloses Testguthaben (einmal pro Person).

API-Schlüssel erhalten

Was du aufbaust

Der Bot unten antwortet, wenn jemand ihn erwähnt. Er speichert einen kurzen Verlauf pro Kanal, sendet ihn an den Chat-Completions-Endpunkt und postet die Antwort. Es ist reines Python, MIT-freundlich und hat keine Datenbank. Du kannst ihn in einem Rutsch lesen, was der Sinn eines Open-Source-Projekts ist: Jeder kann ihn forken und verstehen.

Das dahinterstehende Modell ist ein einzelnes Open-Weight-Textmodell, betrieben von einem unabhängigen Anbieter und darauf abgestimmt, ohne Inhaltsverweigerungen für die rechtmäßige Nutzung durch Erwachsene zu antworten. Das passt zu Discord-Communities rund um Fiktion, Rollenspiel oder Erwachsenendialog. Zwei Regeln gelten ab sofort: Erstens sind sexuelle Inhalte mit Minderjährigen von der API nicht erlaubt und dürfen nicht Teil des Bot-Designs sein. Zweitens hat Discord eigene Regeln und Einstellungen für altersbeschränkte Kanäle, und du bist dafür verantwortlich, sie einzuhalten. Halte Erwachseneninhalte auf Kanäle beschränkt, die entsprechend markiert sind, und auf Servern, auf denen die Mitglieder erwachsen sind.

Richte Discord und deine Schlüssel ein

  1. Öffne das Discord-Entwicklerportal und erstelle eine Anwendung, und füge ihr einen Bot hinzu.
  2. Aktiviere unter den Bot-Einstellungen den Message Content Intent. Ohne ihn erhält der Bot Nachrichten mit leerem Text.
  3. Kopiere das Bot-Token. Behandle es wie ein Passwort.
  4. Verwende den OAuth2-URL-Generator, um den Bot mit der Berechtigung zum Lesen und Senden von Nachrichten in den von dir gewählten Kanälen einzuladen.
  5. Hole einen API-Schlüssel von der Schlüsselseite. Neue Nutzer können mit einem Klick 0,50 $ Testguthaben beanspruchen, keine Zahlungsdaten erforderlich, gültig für 7 Tage.

Speichere beide Geheimnisse als Umgebungsvariablen, niemals im Repository. Für ein Open-Source-Projekt ist das wichtiger als üblich, weil der Code öffentlich ist.

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

Der Bot-Code

Speichere dies als bot.py. Die Kommentare erklären die nicht offensichtlichen Entscheidungen.

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"])

Führe es mit python bot.py aus und erwähne den Bot dann in einem Kanal, den er lesen kann. Die erste Antwort sollte in wenigen Sekunden eintreffen.

Wenn nichts passiert, überprüfe drei Dinge in dieser Reihenfolge. Der Bot muss in der Mitgliederliste online sein, also ist das Token gültig. Er muss die Berechtigung haben, Nachrichten in diesem Kanal zu lesen und zu senden. Und die Erwähnung muss eine echte Discord-Erwähnung sein, die aus der Autovervollständigungsliste ausgewählt wurde, denn reiner Text mit dem Bot-Namen erscheint nicht in message.mentions. Das Terminal gibt API-Fehler aus, also zeigt sich ein falscher Schlüssel dort als Authentifizierungsfehler.

Warum der Code so strukturiert ist

Der Verlauf ist absichtlich klein

Das Kontextfenster umfasst 100.000 Token, also könntest du viel senden. Aber jedes Input-Token wird bei jeder Anfrage abgerechnet, und Discord-Chats bestehen meist aus kurzen Zeilen. Zwölf Gesprächsrunden halten die Antworten zusammenhängend, ohne jede Nachricht zu einer hohen Rechnung werden zu lassen. Erhöhe maxlen für Story-Kanäle, bei denen Kontinuität wichtig ist.

Das Semaphore schützt deinen Schlüssel

Ein Voll-Key erlaubt 8 parallele Anfragen und 300 Anfragen pro Minute. Ein Test-Key erlaubt nur 2 und 60. Wenn zehn Personen den Bot gleichzeitig erwähnen und du zehn Anfragen startest, erhalten die zusätzlichen Anfragen HTTP 429 mit dem Fehlercode concurrency. Das Semaphore wartet sie in deinem eigenen Prozess ab. Stelle es auf 2, während du den Test-Key nutzt. Wenn du jemals das Streaming aktivierst, denke daran, dass eine gestreamte Anfrage ihren Platz bis zum Ende des Streams belegt.

Wiederholungen kommen vom SDK

Das OpenAI Python SDK wiederholt Anfragen bei 429 und berücksichtigt den Retry-After-Header, den der Dienst bei temporärer Überlastung als Retry-After: 5 sendet. Ein Wert von max_retries von 4 deckt kurze Spitzen ab. Fehlgeschlagene oder abgelehnte Anfragen werden nicht berechnet, daher kosten Wiederholungen bei einem Fehler keine Token.

Eine gemeinsame Persona

Der System-Prompt steht bei jedem Aufruf an erster Stelle. Pro-Kanal-Personas sind eine kleine Erweiterung: Halte ein Dictionary von Kanal-ID zu Prompt und suche es in ask nach.

Mache es zu einem guten Open-Source-Projekt

Der Code funktioniert, aber ein öffentliches Repository braucht ein paar Extras, bevor Fremde ihn nutzen können.

  • Eine Lizenz. MIT oder Apache 2.0 sind die üblichen Wahlmöglichkeiten für kleine Bots. Füge die Datei im Stammverzeichnis des Repositories hinzu.
  • Eine .env.example. Liste DISCORD_TOKEN und API_KEY mit Platzhalterwerten auf, damit andere wissen, was sie einstellen müssen.
  • Eine konfigurierbare Base URL. Lese BASE_URL und MODEL aus der Umgebung aus und setze sie auf die oben genannten Werte. Jeder, der es forkt, kann dann jeden OpenAI-kompatiblen Server nutzen.
  • Ein Dockerfile. Eine kurze Datei, die auf einem Python-Slim-Image basiert, bot.py kopiert, die drei Pakete installiert und das Skript ausführt, ermöglicht es, sie überall zu hosten.
  • Eine README-Datei mit der Warnung zu den Berechtigungen. Die fehlende Berechtigung zum Lesen des Nachrichteninhalts ist die häufigste Support-Frage für jeden Discord-Bot.

Halte dein eigenes Token und deinen Schlüssel aus der Git-Historie. Wenn eines geleakt wird, widerrufe es im Discord-Portal oder auf der API-Schlüssel-Seite und erstelle ein neues.

Hosting und die Kosten

Der Bot ist ein einzelner langlaufender Prozess mit geringer CPU-Nutzung. Ein kleiner VPS, eine Ersatzmaschine oder eine Container-Plattform reicht aus. Es gibt keinen Webserver, den man exponieren muss, weil der Bot nach Discord hinausverbindet.

Die API-Kosten sind einfach zu berechnen. Eine typische Antwort hier verwendet 1.500 Input-Token (System-Prompt plus zwölf kurze Gesprächsrunden) und 300 Output-Token.

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

Das ergibt 1.000 Antworten für 0,375 $ und 10.000 Antworten für 3,75 $. Das 0,50-$-Testguthaben deckt etwa 1.333 Antworten ab. Eine Aufladung über 20 $ deckt mehr als 53.000 ab. Aufladungen starten bei 20 $ bis 500 $, mit +5 % ab 50 $, +10 % ab 100 $ und +15 % ab 200 $. Guthaben verfällt nie und es gibt kein Abonnement, daher kostet ein ruhiger Server fast nichts. Sieh dir die Preisseite für die Details an. Die Zahlung erfolgt nur per Krypto, mit USDT auf TRC20 oder USDC auf Base.

Nächste Schritte

Drei Upgrades lohnen den Aufwand. Füge Streaming hinzu, indem du eine einzelne Nachricht bearbeitest, während Chunks eintreffen, achte aber auf die Edit-Ratenlimits von Discord. Füge einen Slash-Befehl hinzu, der den Kanalverlauf zurücksetzt. Füge Tool Calling hinzu, damit der Bot Würfel werfen oder ein Charakterbogen nachschlagen kann; die API unterstützt tools, tool_choice und role: "tool" Ergebnisse im OpenAI-Format.

Die API-Dokumentation listet jeden unterstützten Parameter auf, und der Hermes API-Artikel behandelt, wie unzensierte Modelle sich in einem Projekt verhalten. Prompts, die an die API gesendet werden, werden nicht zum Training verwendet, was man in den Regeln deines Servers erwähnen sollte, wenn Mitglieder fragen.

Fragen und Antworten

Braucht der Bot die Berechtigung zum Lesen des Nachrichteninhalts?

Ja. Aktiviere sie im Discord-Entwicklerportal und im Code mit intents.message_content = true. Andernfalls sieht der Bot leere Nachrichten.

Wie viele Antworten kann der Bot gleichzeitig verarbeiten?

Ein Voll-Key erlaubt 8 parallele Anfragen und 300 pro Minute; ein Test-Key erlaubt 2 und 60. Ein Semaphore im Bot hält dich unter dem Limit.

Kann ich den Bot-Code veröffentlichen?

Ja, solange der Discord-Token und der API-Schlüssel nicht im Repository landen. Lies sie aus Umgebungsvariablen aus und liefere eine .env.example mit.

Ist die Nutzung von Adult-Themen erlaubt?

Nur für die legale Adult-Nutzung, entsprechend den Regeln von Discord und dessen Einstellungen für altersbeschränkte Kanäle. Sexuelle Inhalte mit Minderjährigen sind niemals erlaubt.

Was kostet der Betrieb?

Eine Antwort mit 1.500 Input-Token und 300 Output-Token kostet 0,000375 $, also etwa 3,75 $ pro 10.000 Antworten, zuzüglich der Kosten für das Hosting des Prozesses.

Dein Schlüssel ist nur einen Schritt entfernt

Erstelle ein Konto, kopiere den Schlüssel, ändere die Basis-URL. Das ist die gesamte Einrichtung.

API-Schlüssel erhalten