AR ▾
الحصول على مفتاح API

دليل دمج API بدون رقابة: التسجيل، التحقق، أول استدعاء

هذا الدليل يهدف إلى شيء واحد: تمكينك من إرسال أول طلب بنجاح خلال عشر دقائق. لن نستخدم SDK، بل سنرسل طلبات HTTP مباشرة باستخدام المكتبات القياسية لكل لغة، لأن الواجهة تعتمد على نقطة نهاية POST واحدة. فهم هيكل الطلب يضمن لك السهولة عند الانتقال لأي إطار عمل. الأمثلة تغطي Python requests، Java java.net.http، Go net/http وPHP curl، وكل كود جاهز للنسخ والتشغيل.

تم التحديث في

نقاط رئيسية

  • التسجيل يتطلب بريداً إلكترونياً وكلمة مرور فقط. الحساب الجديد يحصل على رصيد تجريبي مجاني بقيمة $0.50 صالح لمدة 7 أيام، دون الحاجة لربط معلومات الدفع.
  • عنوان URL الأساسي هو https://api.wushenchaapi.com/v1,模型名固定写 uncensored، ورأس المصادقة هو Authorization: Bearer.
  • تحقق من صحة المفتاح عبر GET /v1/models، ثم أرسل POST /v1/chat/completions. فصل هاتين الخطوتين يسرع عملية استكشاف الأخطاء.
  • في اللغات الأربع، اضبط مهلة الانتظار (timeout) واقرأ error.code بدلاً من الاعتماد فقط على رمز حالة HTTP.

قائمة التحقق قبل البدء

راجع القائمة مسبقاً لتجنب التراجع لاحقاً.

  • بريد إلكتروني نشط للتسجيل.
  • بيئة تشغيل محلية تدعم واحدة على الأقل: Python 3، JDK 15 أو أحدث (يستخدم كتل النص)، Go، أو PHP مع امتداد curl.
  • تأكد من أنك بالغ (18 سنة فأكثر)، فالخدمة موجهة للبالغين فقط.
  • تأكد من حاجتك لمحادثات نصية فقط: لدينا نموذج واحد فقط، لا يدعم النصوص المتجهة (Vectors)، الصور، الصوت أو التخصيص الدقيق (Fine-tuning).
  • احفظ المفتاح في متغيرات البيئة، لا تكتبه في الكود المصدري ولا ترفعه إلى المستودع.

اتفاقية الواجهة بسيطة: العنوان https://api.wushenchaapi.com/v1، والتنسيق متوافق مع مكملات الدردشة من OpenAI، لذا يمكنك استخدام أجوبة الطلبات القديمة كما هي.

التقدير الزمني: التسجيل يستغرق دقيقة، إعداد البيئة يعتمد على جهازك، وأول طلب لا يتجاوز 30 ثانية. إذا طال الوقت، تحقق من الشبكة أو المفتاح، ثم انتقل لقائمة استكشاف الأخطاء. الترتيب مهم: تحقق من models أولاً، ثم chat؛ ابدأ بالطلب المتزامن ثم البث المتدفق، وتأكد من كل خطوة قبل الانتقال للتالية.

التسجيل والحصول على المفتاح

افتح /get-api-key/، وسجّل باستخدام بريدك الإلكتروني وكلمة المرور. سيظهر المفتاح فوراً بعد التسجيل، انسخه. ملاحظات:

  1. كل حساب يحتوي على مفتاح واحد فقط.
  2. يمكن إعادة توليد المفتاح، لكن المفتاح القديم سيفقد صلاحيته فوراً. تأكد من نشر المفتاح الجديد على الخوادم قبل استبداله.
  3. الحساب الجديد يحصل على رصيد مسبق الدفع بقيمة $0.50 صالح لمدة 7 أيام، دون الحاجة لإدخال بيانات الدفع.
  4. عند انتهاء التجربة أو نفاد الرصيد، يُرجع الطلب خطأ 402 برمز no_credit. اشحن رصيدك المسبق الدفع للمتابعة. الرصيد ليس اشتراكاً ولا ينتهي.

أضف المفتاح لمتغيرات البيئة: في macOS/Linux نفذ export API_KEY=YOUR_KEY، وفي Windows PowerShell استخدم $env:API_KEY="YOUR_KEY". ستقرأ جميع الأمثلة من API_KEY.

الخطوة الأولى: التحقق من الاتصال عبر /v1/models

لا ترسل محادثات بعد. أرسل طلب GET بتكلفة صفرية للتحقق من صحة العنوان، الشبكة، والمفتاح:

curl https://api.wushenchaapi.com/v1/models \
  -H "Authorization: Bearer $API_KEY"

استجابة 200 مع قائمة النماذج (تحتوي على uncensored فقط) تعني أن الاتصال ناجح. رمز 401 يعني خطأ في المفتاح أو غيابه. مهلة الاتصال تعني مشكلة في الشبكة أو الوكيل. فصل مشاكل الاتصال عن مشاكل جسم الطلب يوفر وقتاً كبيراً.

Python: requests

لا حاجة لـ SDK، طلب requests.post يكفي. انتبه لثلاث نقاط: يجب ضبط timeout؛ تحقق من r.ok قبل قراءة choices؛ جسم الخطأ عند الفشل يكون {"error":{"code":...,"message":...}}.

import os
import requests

url = "https://api.wushenchaapi.com/v1/chat/completions"
headers = {
    "Authorization": "Bearer " + os.environ["API_KEY"],
    "Content-Type": "application/json",
}
payload = {
    "model": "uncensored",
    "messages": [{"role": "user", "content": "用两句话描述一场雨夜里的追逐戏。"}],
    "max_tokens": 300,
}
r = requests.post(url, headers=headers, json=payload, timeout=120)
print(r.status_code)
data = r.json()
if r.ok:
    print(data["choices"][0]["message"]["content"])
    print(data["usage"])
else:
    print(data["error"]["code"], data["error"]["message"])

عند النجاح، يحتوي usage على prompt_tokens وcompletion_tokens. يُنصح بطباعة هذه القيم أثناء التطوير لمراقبة التكاليف.

تحليل جسم الطلب حرفاً بحرف

اللغات الأربع ترسل نفس كائن JSON. افهمه جيداً، فكتابة الكود بأي لغة هي مجرد ترجمة لهذا الهيكل.

الحقلمطلوبالوصف
modelنعمثابت على uncensored.
messagesنعممصفوفة، كل عنصر يحتوي على role وcontent. القيم المسموحة لـ role هي system، user، assistant.
max_tokensلاالقيمة الافتراضية 2048، والحد الأقصى للطلب الواحد 16,000. زد القيمة يدوياً للنصوص الطويلة.
temperature / top_p / stopلامعلمات عادية للعينات، تُمرر كما هي.
streamلاعندما تكون القيمة true، يتم استخدام تدفق SSE.

أهم ما تقرأه في الاستجابة: choices[0].message.content هو المحتوى، وchoices[0].finish_reason يوضح السبب، وusage يوضح استهلاك الرموز.

قيود أخرى: حجم الطلب لا يتجاوز 8 ميجابايت، و300 طلب في الدقيقة لكل مفتاح. لا ترسل الطلبات المتزامنة دفعة واحدة، بل حدد حداً للطلبات المتزامنة.

جافا: java.net.http

يأتي HttpClient مع JDK 11. استخدم كتل النص في JDK 15 لكتابة JSON، أو استخدم دوال السلسلة النصية في الإصدارات الأقدم.

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;

public class Demo {
    public static void main(String[] args) throws Exception {
        String key = System.getenv("API_KEY");
        String body = """
            {"model":"uncensored",
             "messages":[{"role":"user","content":"写一段两百字以内的悬疑小说开头。"}],
             "max_tokens":400}
            """;
        HttpRequest req = HttpRequest.newBuilder(
                URI.create("https://api.wushenchaapi.com/v1/chat/completions"))
            .timeout(Duration.ofSeconds(120))
            .header("Authorization", "Bearer " + key)
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(body))
            .build();
        HttpResponse<String> resp = HttpClient.newHttpClient()
            .send(req, HttpResponse.BodyHandlers.ofString());
        System.out.println(resp.statusCode());
        System.out.println(resp.body());
    }
}

ملاحظة: عندما يحتوي المحتوى على نص صيني، فإن BodyPublishers.ofString يستخدم افتراضياً ترميز UTF-8 ولا يحتاج معالجة إضافية. في بيئة الإنتاج، اجعل HttpClient كائنًا مفرداً (Singleton) لإعادة الاستخدام، ولا تنشئه في كل طلب.

Go: net/http

مكتبة Go القياسية كافية. تجنب استخدام http.DefaultClient بدون تحديد مهلة، وإلا ستعلق ألياف goroutine.

package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
	"os"
	"time"
)

func main() {
	body := []byte(`{"model":"uncensored","messages":[{"role":"user","content":"给一个反派角色写三句独白。"}],"max_tokens":300}`)
	req, err := http.NewRequest("POST", "https://api.wushenchaapi.com/v1/chat/completions", bytes.NewReader(body))
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("API_KEY"))
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{Timeout: 120 * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	out, _ := io.ReadAll(resp.Body)
	fmt.Println(resp.StatusCode, string(out))
}

اقرأ جسم الاستجابة كاملاً باستخدام io.ReadAll قبل التحليل. عند الحاجة إلى معالجة هيكلية، عرّف struct المقابل واستخدم encoding/json لعكس التسلسل، والحقول هي choices و message و content و usage.

PHP: curl

استخدم PHP امتداد curl، وتذكر إضافة JSON_UNESCAPED_UNICODE إلى json_encode، وإلا سيتم تحويل النص الصيني إلى \uXXXX، وهو ما يعمل لكنه صعب القراءة أثناء التصحيح.

<?php
$payload = [
    "model" => "uncensored",
    "messages" => [["role" => "user", "content" => "写一首八行的现代诗,主题是末班地铁。"]],
    "max_tokens" => 300,
];
$ch = curl_init("https://api.wushenchaapi.com/v1/chat/completions");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 120,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer " . getenv("API_KEY"),
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE),
]);
$res = curl_exec($ch);
if ($res === false) {
    die("curl 错误: " . curl_error($ch) . "\n");
}
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status, "\n";
$data = json_decode($res, true);
echo $data["choices"][0]["message"]["content"] ?? $res, "\n";

اميز بين نوعين من الفشل: إذا أرجع curl_exec القيمة false، فهي مشكلة في طبقة الشبكة؛ وإذا أرجع محتوى لكن رمز الحالة ليس 200، فهي مشكلة في طبقة الواجهة، ويجب قراءة error.code.

أخطاء شائعة في أول استدعاء

  • 401: Header مكتوب Authorization: مفتاح API، مع فُقدان بادئة Bearer ؛ أو أن متغير البيئة لم يُفعّل في نافذة طرفية جديدة.
  • 404: المسار يفتقد /v1، أو أن chat/completions كُتبت بشكل خاطئ.
  • 400: JSON غير صالح، أو تجاوز الـ prompt مع max_tokens حد 100,000 رمز.
  • 402: نفاد الرصيد أو انتهاء صلاحية التجربة.
  • تم قطع المخرج: القيمة الافتراضية لـ max_tokens هي 2048، والحد الأقصى لكل طلب هو 16,000، لذا يجب زيادة هذا الحد صراحةً عند كتابة نصوص طويلة.
  • تريد البث المتدفق: أضف "stream": true إلى جسم الطلب، والاستجابة تكون عبر SSE، وسيتم إضافة كتلة بيانات تحتوي على usage تلقائياً في النهاية.

بعد نجاح التشغيل، انظر إلى طريقة كتابة الموجّه لتحسين جودة المخرج، وعند ظهور أخطاء راجع دليل استكشاف أخطاء رموز الخطأ. الوصف الكامل للمعلمات موجود في الوثائق، والأسعار في صفحة الأسعار.

بعد نجاح التشغيل، أضف ثلاث عناصر قبل النشر

أمثلة الدليل هي الحد الأدنى القابل للتطبيق. أضف هذه العناصر الثلاثة قبل النشر في الخدمة.

  1. مهلة زمنية. حدد المثال مهلة موحدة قدرها 120 ثانية لأن توليد النصوص الطويلة يستغرق وقتاً. إذا كانت خدمتك تنتظر بشكل متزامن، فقص المهلة وفقاً لتحمل الصفحة، واستخدم المخرج المتدفق ليتمكن المستخدم من رؤية النص فوراً.
  2. توجيه الأخطاء. أخطاء 401 و402 و403 لا تحل بالتكرار. أخطاء 429 و503 تستحق إعادة المحاولة بتقنية Backoff.
  3. تسجيل الاستخدام. سجّل استخدام كل استجابة في سجل واحد، فقط الأرقام.

نذكر أيضاً إدارة المفاتيح: يوجد مفتاح واحد فقط، وإذا تم تسريبه، يجب إعادة توليده، وإعادة التوليد ستؤدي إلى انقطاع جميع الخدمات التي تستخدمه في نفس الوقت. لذا لا تنثره في عدة نصوص برمجية أو ملفات تكوين على أجهزة متعددة، بل جمّعه في مكان واحد لتسهيل تغييره دون نسيان.

أخيراً، حدود المحتوى: لن يتم رفض المحتوى البالغ القانوني، والروايات الخيالية، والمواضيع المثيرة للجدل، ولكن سيتم حظر أي محتوى جنسي يتعلق بالأطفال وإرجاع رمز 403، حتى لو كان خيالياً أو تمثيلياً. إذا كان تطبيقك موجهاً للمستخدمين البالغين، نوصي بإجراء تأكيد العمر في عملية التسجيل الخاصة بك.

فحص: هل المفتاح في المتغيرات البيئية؟ هل models يعمل؟ هل الطلب JSON صحيح؟ هل النموذج uncensored؟ هل max_tokens كافية؟ هل finish_reason هو stop؟ هل usage مسجل؟

الأسئلة الشائعة

هل يجب استخدام SDK الرسمي للاستدعاء؟

لا حاجة لذلك. إنه HTTPS POST مع JSON قياسي. أي لغة تدعم HTTP تعمل، وSDK يضيف طبقة غلاف فقط.

ماذا يجب أن أكتب في حقل model؟

استخدم uncensored دائماً. هذا هو النموذج الوحيد. تأكد عبر GET /v1/models.

ماذا يحدث بعد انتهاء رصيد التجربة؟

الاستجابة 402 برمز no_credit. اشحن الرصيد المسبق للدفع حسب الاستخدام. الرصيد لا ينتهي وليس اشتراكاً.

هل سيؤثر إعادة توليد المفتاح على المفتاح القديم؟

نعم. سيفقد المفتاح القديم صلاحيته فوراً، لذا يجب استبدال المفتاح القديم بالجديد في الخدمة قبل النقر على إعادة التوليد، أو تقبل انقطاعاً قصيراً.

املأ النموذج فقط للحصول على المفتاح

أنشئ حساباً، انسخ المفتاح، عدّل Base URL. الإعداد بسيط جداً.