بوت ديسكورد مفتوح المصدر مع نموذج LLM بدون رقابة
بوت ديسكورد مفتوح المصدر يتواصل عبر نموذج LLM يتكون من حوالي ثمانين سطرًا من Python. يقدم لك هذا الدليل الكود، والحدود التي يجب احترامها، والتكلفة لكل رد، باستخدام واجهة API متوافقة مع OpenAI مع نموذج لا يرفض الطلبات القانونية للبالغين.

نقاط رئيسية
- discord.py بالإضافة إلى OpenAI SDK يكفي؛ وجّه الـ SDK نحو https://api.openrouternsfw.com/v1 واستخدم النموذج uncensored.
- فعّل إذن محتوى الرسالة في بوابة مطوري Discord أو سيرى البوت رسائل فارغة.
- استخدم مفتاح التزامن أقل من 8 للبقاء ضمن حد التزامن، واحتفظ بالمحتوى البالغ في القنوات المحددة للعمر.
- رد يحتوي على 1,500 رمز إدخال و300 رمز إخراج يكلف $0.000375، أي حوالي $3.75 لكل 10,000 رد.
لا حاجة لبطاقة. بعد التسجيل، احصل على $0.50 من رصيد الاختبار المجاني بنقرة واحدة (مرة واحدة لكل شخص).
احصل على مفتاح APIما تبنيه
يُجيب البوت أدناه عند ذكره. يحتفظ بسجل قصير لكل قناة، ويرسله إلى نقطة النهاية الخاصة بإكمال المحادثات، ثم ينشر الرد. مكتوب بلغة Python بسيطة، مرخص بموجب رخصة MIT، ولا يعتمد على قاعدة بيانات. يمكنك الاطلاع على كامل الكود في جلسة واحدة، وهو الهدف من مشروع مفتوح المصدر: يمكن لأي شخص آخر استنساخه وفهمه.
النموذج الذي يعمل خلف الكواليس هو نموذج نصي واحد مفتوح الأوزان، يشغّله مزوّد مستقل ومضبوط للإجابة دون رفض المحتوى للاستخدام القانوني للبالغين. يناسب هذا مجتمعات Discord المبنية حول الخيال الأدبي، لعب الأدوار أو المحادثات للبالغين. تنطبق قاعدتان منذ البداية. أولاً، لا يسمح API بالمحتوى الجنسي الذي يتضمن القاصرين، ويجب ألا يكون جزءاً من تصميم البوت الخاص بك. ثانياً، لدى Discord قواعده الخاصة وإعدادات للقنوات المقيدة بالعمر، وأنت مسؤول عن اتباعها. اقتصر على المحتوى المخصص للبالغين في القنوات التي تُعلن عنها بذلك، وفي الخوادم التي يكون أعضاؤها من البالغين.
إعداد Discord ومفاتيحك
- افتح بوابة مطوري Discord وأنشئ تطبيقاً، ثم أضف بوتاً إليه.
- ضمن إعدادات البوت، فعّل نية محتوى الرسائل. بدونه، يتلقى البوت رسائل بنص فارغ.
- انسخ رمز البوت. عامله ككلمة مرور.
- استخدم مولّد عنوان URL الخاص بـ OAuth2 لدعوة البوت بإذن قراءة الرسائل وإرسالها في القنوات التي تختارها.
- احصل على مفتاح 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، ثم اذكر البوت في قناة يمكنه قراءتها. يجب أن يصل الرد الأول خلال بضع ثوانٍ.
إذا لم يحدث شيء، تحقق من ثلاثة أشياء بالترتيب. يجب أن يكون البوت متصلاً في قائمة الأعضاء، مما يعني أن الرمز صالح. يجب أن يكون لديه إذن لقراءة الرسائل وإرسالها في تلك القناة. ويجب أن يكون الذكر هو ذكر Discord الحقيقي، المحدد من قائمة الاكتمال التلقائي، لأن النص العادي الذي يحتوي على اسم البوت لا يظهر في message.mentions. يطبع الطرفية أخطاء API، لذا يظهر مفتاح خاطئ هناك كفشل في المصادقة.
لماذا صُمم الكود بهذه الطريقة
السجل صغير عن قصد
نافذة السياق تتسع لـ 100,000 رمز، لذا يمكنك إرسال الكثير. لكن كل رمز مدخل يُفوتر في كل استدعاء، ومحادثات Discord تتكون في الغالب من أسطر قصيرة. تحافظ اثنتا عشرة محادثة على تماسك الردود دون تحويل كل رسالة إلى فاتورة كبيرة. ارفع maxlen لقنوات القصة حيث يهم الاستمرارية.
يحمي السيمافور مفتاحك
يتيح المفتاح الكامل 8 طلبات متزامنة و300 طلب في الدقيقة. يتيح المفتاح التجريبي فقط 2 و60. إذا ذكر عشرة أشخاص البوت في وقت واحد وأرسلت عشرة طلبات، ستحصل الطلبات الزائدة على خطأ HTTP 429 برمز الخطأ concurrency. يقوم السيمافور بترتيبها في طابور داخل عملية البرمجيات الخاصة بك. اضبطه على 2 بينما تكون على المفتاح التجريبي. إذا قمت بتفعيل البث المتدفق، تذكر أن الطلب المتدفق يحتفظ بمكانه حتى ينتهي البث.
إعادة المحاولة تأتي من SDK
يعيد مكتبة Python SDK الخاصة بـ OpenAI المحاولة عند حدوث خطأ 429 ويحترم رأس HTTP Retry-After، الذي ترسله الخدمة كـ Retry-After: 5 عند الحمل الزائد المؤقت. ضبط max_retries على 4 يغطي الارتفاعات القصيرة. الطلبات الفاشلة أو المرفوضة لا تُفوتَر، لذا لا تكلفك إعادة المحاولة رموزاً عند فشلها.
شخصية مشتركة واحدة
يظهر الموجّه النظامي أولاً في كل استدعاء. الشخصيات لكل قناة هي إضافة صغيرة: احتفظ بقاموس يربط معرف القناة بالموجّه وابحث عنه في 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 رمز إدخال (موجه النظام بالإضافة إلى اثنتي عشرة محادثة قصيرة) و300 رمز إخراج.
- الإدخال: 1,500 × $0.15 / 1M = $0.000225
- الإخراج: 300 × $0.50 / 1M = $0.00015
- لكل رد: $0.000375
هذا يعني أن 1,000 رد ينتج عنها $0.375 و10,000 رد ينتج عنها $3.75. يغطي رصيد التجربة بقيمة $0.50 حوالي 1,333 رد. يغطي الشحن بقيمة $20 أكثر من 53,000. تتراوح الشحنات من $20 إلى $500، مع مكافأة 5% من $50، و10% من $100، و15% من $200. الرصيد لا ينتهي ولا يوجد اشتراك، لذا يكلف الخادم الهادئ تقريبًا لا شيء. انظر صفحة الأسعار للتفاصيل. الدفع بالعملات المشفرة فقط، باستخدام USDT على TRC20 أو USDC على Base.
إلى أين تذهب بعد ذلك
تستحق ثلاث ترقيات الجهد. أضف البث عن طريق تعديل رسالة واحدة مع وصول القطع، ولكن انتبه لحدود معدل تعديل Discord. أضف أمر slash يعيد تعيين سجل القناة. أضف استدعاء الأدوات حتى يتمكن الروبوت من رمي النرد أو البحث عن ورقة شخصية؛ تدعم الـ API tools، وtool_choice، وrole: "tool" بتنسيق OpenAI.
تسرد وثائق API كل معلمة مدعومة، وتغطي مقال Hermes API كيفية تصرف النماذج بدون رقابة داخل مشروع. لا تُستخدم الموجّهات المرسلة إلى API للتدريب، وهو أمر يستحق ذكره في قواعد الخادم الخاص بك إذا طلب أعضاء ذلك.
المزيد من الأدلة
أسئلة وأجوبة
هل يحتاج البوت إلى نية محتوى الرسالة؟
نعم. فعّله في بوابة مطوري Discord وفي الكود مع تعيين intents.message_content إلى true. وإلا سيرى الروبوت رسائل فارغة.
كم عدد الردود التي يمكن أن يتعامل معها البوت في وقت واحد؟
المفتاح الكامل يسمح بـ 8 طلبات متزامنة و300 في الدقيقة؛ المفتاح التجريبي يسمح بـ 2 و60. يضمن لك السيمافور في البوت البقاء تحت الحدّ.
هل يمكنني نشر كود البوت؟
نعم، طالما أن رمز Discord ومفتاح API خارج المستودع. اقرأها من متغيرات البيئة وأرسل ملف .env.example.
هل مسموح باستخدام مواضيع للكبار؟
فقط للاستخدام القانوني للبالغين، بما يتوافق مع قواعد Discord وإعدادات القنوات المقيدة للعمر. محتوى الجنس الذي يتضمن القاصرين غير مسموح به أبدًا.
كم يكلف التشغيل؟
رد مع 1,500 رمز إدخال و300 رمز إخراج يكلف $0.000375، لذا حوالي $3.75 لكل 10,000 رد، بالإضافة إلى تكلفة استضافة العملية.
مفتاحك على بُعد استمارة واحدة
أنشئ حساباً، وانسخ المفتاح، ثم غيّر URL الأساسي. هذه هي الإعدادات الكاملة.
احصل على مفتاح API