開放原始碼 Discord 機器人搭配無審查 LLM
透過 LLM 進行對話的開放原始碼 Discord 機器人約需八十行 Python。本指南提供程式碼、必須遵守的限制,以及使用具有不拒絕合法成人請求之模型的 OpenAI 相容 API 的每則回應成本。

重點摘要
- discord.py 加上 OpenAI SDK 即可;將 SDK 指向 https://api.openrouternsfw.com/v1 並使用模型 uncensored。
- 在 Discord 開發者入口網站開啟訊息內容意圖,否則機器人將看到空訊息。
- 使用低於 8 的信號量以保持在並行限制內,並將成人內容保留在標記為年齡限制的頻道中。
- 包含 1,500 個輸入 token 和 300 個輸出 token 的回應成本為 $0.000375,因此每 10,000 則回應約為 $3.75。
無需綁卡。註冊後,點擊一次即可領取 $0.50 免費試用額度(每人限領一次)。
取得 API 金鑰你要建置的內容
下方的機器人在有人提及它時進行回應。它為每個頻道保留簡短歷史,將其傳送至聊天完成端點,然後發布回應。它是純淨的 Python,符合 MIT 授權,且沒有資料庫。你可以一次讀完所有內容,這也是開放原始碼專案的重點:其他人可以分叉它並理解它。
其後端的模型是一個單一的開放權重文字模型,由獨立供應商運行,並針對合法成人用途調整為不會拒絕內容。這適合以小說、角色扮演或成人對話為主的 Discord 社群。從一開始就有兩項規則適用。第一,API 不允許涉及未成年人的性內容,且不得納入您的機器人設計中。第二,Discord 有自己的規則和限制年齡頻道的設定,您有責任遵守這些規則。將成人內容限制在標記為該類型的頻道中,以及成員均為成年人的伺服器中。
設定 Discord 和你的金鑰
- 開啟 Discord 開發者入口網站並建立應用程式,然後為其新增機器人。
- 在機器人設定下,啟用訊息內容意圖。沒有它,機器人收到的訊息文字為空。
- 複製機器人權杖。將其視為密碼。
- 使用 OAuth2 URL 產生器,以在你選擇的頻道中讀取和發送訊息的權限邀請機器人。
- 從金鑰頁面取得 API 金鑰。新用戶可以一鍵領取 $0.50 的免費試用額度,無需提供付款資訊,有效期為 7 天。
將兩個秘密儲存為環境變數,不要放在儲存庫中。對於開放原始碼專案來說,這比平常更重要,因為程式碼是公開的。
pip install discord.py openai python-dotenv
printf 'DISCORD_TOKEN=your-discord-token
API_KEY=your-api-key
' > .env
echo ".env" >> .gitignore
機器人程式碼
將其儲存為bot.py。註解解釋了不顯眼的決策。
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"])
使用python bot.py執行它,然後在機器人可以讀取的頻道中提及機器人。第一則回應應在幾秒內到達。
如果沒有反應,請依序檢查三件事。機器人必須在成員列表中顯示線上狀態,表示 token 有效。它必須擁有在該頻道讀取和發送訊息的權限。而且提及必須是有效的 Discord 提及,從自動完成清單中選擇,因為包含機器人名稱的純文字不會出現在 message.mentions 中。終端機會列印 API 錯誤,因此金鑰錯誤會在那裡顯示為驗證失敗。
程式碼為何這樣設計
歷史紀錄很小是故意的
上下文視窗為 100,000 個 token,所以你可以傳送很多。但每個輸入 token 在每次呼叫時都會計費,而 Discord 聊天大多是短行。十二個回合可保持回應連貫,同時不會讓每則訊息變成大帳單。對於需要連續性的故事頻道,請提高maxlen。
信號量保護你的金鑰
完整金鑰允許 8 個並行請求和每分鐘 300 個請求。試用金鑰僅允許 2 個和 60 個。如果十個人同時提及機器人,您發出十個請求,額外的請求會收到 HTTP 429 錯誤,錯誤程式碼為 concurrency。semaphore 會在您自己的程序中將它們排隊。在使用試用金鑰時,將其設定為 2。如果您開啟串流輸出,請記住串流請求會佔用其槽位,直到串流結束為止。
重試來自 SDK
OpenAI Python SDK 會在 429 時重試,並尊重 Retry-After 標頭,該服務在暫時過載時會傳送 Retry-After: 5。將 max_retries 設定為 4 可涵蓋短暫的尖峰。失敗或被拒絕的請求不會收費,因此當重試失敗時,不會花你的 token。
一個共享人格
系統提示詞位於每次呼叫的第一位。每個頻道的角色設定是一個小型擴充功能:保留一個從頻道 ID 到提示詞的字典,並在 ask 中查詢它。
使其成為良好的開放原始碼專案
程式碼可以運作,但公開儲存庫需要一些額外功能,讓陌生人可以使用它。
- 授權條款。 MIT 或 Apache 2.0 是小型機器人的常見選擇。將檔案新增至儲存庫的根目錄。
- .env.example 檔案。 列出
DISCORD_TOKEN和API_KEY並填入假值,讓使用者知道該設定什麼。 - 可配置的基礎 URL。 從環境中讀取
BASE_URL和MODEL,預設值為上述值。任何 fork 它的人都可以使用任何與 OpenAI 相容的伺服器。 - Dockerfile。 一個基於 Python slim 映像的短檔案,複製
bot.py、安裝三個套件並執行腳本,讓任何人都能在任何地方託管它。 - 包含意圖警告的 README。 缺少訊息內容意圖是每個 Discord 機器人的主要支援問題。
將你自己的權杖和金鑰保留在 Git 歷史之外。如果一個洩漏,請在 Discord 入口網站或 API 金鑰頁面撤銷它,並發行新的。
託管與成本
機器人是一個單一長時間執行的處理程序,CPU 使用量輕。小型 VPS、備用機器或容器平台即可。沒有要公開的網頁伺服器,因為機器人會連接到 Discord。
API 成本很容易計算。此處的典型回應使用 1,500 個輸入 token(系統提示詞加上十二個短回合)和 300 個輸出 token。
- 輸入:1,500 x $0.15 / 1M = $0.000225
- 輸出:300 x $0.50 / 1M = $0.00015
- 每則回覆:$0.000375
這意味著 1,000 則回覆費用為 $0.375,10,000 則回覆費用為 $3.75。$0.50 的試用額度約可回覆 1,333 則。$20 的儲值可回覆超過 53,000 則。儲值金額從 $20 到 $500 不等,$50 以上加贈 5%,$100 以上加贈 10%,$200 以上加贈 15%。額度永不過期,且無訂閱制,因此閒置伺服器的成本幾乎為零。請參見定價頁面以獲取詳細資訊。僅接受加密貨幣付款,使用 TRC20 上的 USDT 或 Base 上的 USDC。
下一步該去哪
有三項升級值得投入。在收到訊息區塊時編輯單一訊息以啟用串流輸出,但需注意 Discord 的編輯速率限制。新增一個斜線命令來重置頻道歷史記錄。新增工具呼叫功能,讓機器人可以擲骰子或查詢角色表;API 支援 tools、tool_choice,並在 OpenAI 格式中產生 role: "tool" 的結果。
API 文件列出了所有支援的參數,Hermes API 文章涵蓋了無審查模型在專案中的行為。傳送至 API 的提示詞不會用於訓練,如果你的成員詢問,這值得寫在伺服器規則中。
更多指南
問答
機器人需要訊息內容意圖嗎?
是的。請在 Discord 開發者入口網站啟用,並在程式碼中將 intents.message_content 設為 true。否則機器人將看到空訊息。
機器人能同時處理多少則回應?
完整金鑰允許 8 個並行請求和每分鐘 300 個;試用金鑰允許 2 個和 60 個。機器人中的信號量可讓你保持在限制以下。
我可以發布這個 bot 的程式碼嗎?
可以,只要 Discord token 和 API 金鑰不放入程式庫即可。請從環境變數讀取這些值,並提供 .env.example 檔案。
允許使用成人主題嗎?
僅限合法的成人用途,並符合 Discord 的規則及其年齡限制頻道設定。涉及未成年人的性內容一律禁止。
運作成本是多少?
回覆包含 1,500 個輸入 token 和 300 個輸出 token 的成本為 $0.000375,因此每 10,000 次回覆約需 $3.75,再加上執行過程的託管成本。
只差一張表單,即可取得金鑰
建立帳號、複製金鑰、更改基礎 URL。這就是整個設定過程。
取得 API 金鑰