AR ▾

Chinese LLM APIالبدء السريع

احصل على مفتاح API

تم التحديث في

بناء تطبيق بالصينية: الموجّهات، التحكم في الخطوط وUTF-8

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

ما تقوم بتوصيله

تعرض الخدمة POST /v1/chat/completions و GET /v1/models تحت https://api.chinesellmapi.com/v1. المصادقة تتم بمفتاح حامل، ومعرف النموذج الوحيد هو uncensored. إنها واجهة برمجة التطبيقات للنصوص فقط مع نموذج واحد، لذا لا يوجد شيء للاختيار بينه: عملك في التعريب يحدث بالكامل في الموجّه وفي الكود الخاص بك حوله.

حدود يجب معرفتها قبل تصميم أي شيء: نافذة سياق مشتركة بين الموجّه والإكمال بحجم 100,000 رمز، مع max_tokens التي تتراوح افتراضياً من 2,048 مع سقف 32,000، ومحتويات الطلب تصل إلى 8 ميجابايت، و300 طلب في الدقيقة لكل مفتاح. يعمل البث المتدفق (stream: true) عبر أحداث الإرسال من الخادم، ويتم قبول أدوات بتنسيق استدعاء الدوال من OpenAI.

الحسابات الجديدة تحصل على رصيد تجريبي بقيمة $0.50 صالح لمدة سبعة أيام، بدون تفاصيل الدفع؛ سجل ببريد إلكتروني وكلمة مرور ويظهر المفتاح فوراً. الأسئلة الشائعة للتجربة تغطي القواعد بالتفصيل.

اكتب الموجّهات بالصينية، وقل أي صينية

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

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

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.chinesellmapi.com/v1",
    api_key=os.environ["API_KEY"],
)

SYSTEM_SC = (
    "你是一名产品文案助手。始终使用简体中文回答,使用中国大陆常见的用词和标点,"
    "不要夹杂繁体字或英文句子,专有名词除外。"
)

resp = client.chat.completions.create(
    model="uncensored",
    messages=[
        {"role": "system", "content": SYSTEM_SC},
        {"role": "user", "content": "为一款记账应用写三条应用商店的一句话简介。"},
    ],
    max_tokens=300,
    temperature=0.7,
)
print(resp.choices[0].message.content)
print(resp.usage)

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

التحكم في المخرجات المبسطة مقابل التقليدية

اختيار الخط هو قرار منتج مرتبط بمنطقة المستخدم، وليس إعداد نموذج. المنتجات الموجهة للبر الرئيسي تتوقع الأحرف المبسطة؛ جمهور تايوان وهونغ كونغ يتوقع التقليدي، مع مفردات مختلفة أيضاً (أمثلة شائعة هي مصطلحات البرمجيات والشبكة وقواعد البيانات). النهج العملي هو ربط علامة المنطقة الخاصة بك بموجّه نظام وجعل الاختيار صريحاً في الكود.

  • zh-CN, zh-SG: مبسط، مفردات البر الرئيسي، أرقام بعرض نصف، علامات ترقيم صينية بعرض كامل.
  • zh-TW: التقليدي، مفردات تايوان، الأقواس الزاوية للاقتباسات شائعة.
  • zh-HK: تقليدي بصيغة هونغ كونغ؛ قدم قائمة مصطلحات قصيرة إذا كان لمنتجك مصطلحات ثابتة.

يبدو المتغير التقليدي لنفس الاستدعاء هكذا؛ يتغير فقط موجّه النظام:

import os
from openai import OpenAI

client = OpenAI(base_url="https://api.chinesellmapi.com/v1", api_key=os.environ["API_KEY"])

SYSTEM_TC = (
    "你是一名產品文案助手。請一律使用繁體中文回答,採用臺灣常用的詞彙與全形標點,"
    "例如「軟體」「網路」「資料庫」,不要混入簡體字。"
)

resp = client.chat.completions.create(
    model="uncensored",
    messages=[
        {"role": "system", "content": SYSTEM_TC},
        {"role": "user", "content": "請用兩句話說明什麼是雙重驗證。"},
    ],
    max_tokens=200,
)
print(resp.choices[0].message.content)

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

# A cheap guard: flag replies that contain characters that exist only in Simplified.
# The set below is a small sample, not a full list; use a converter such as OpenCC
# for production-grade checks.
SIMPLIFIED_ONLY = set("这个们说话时间书买卖东车门开关见觉")

def looks_simplified(text: str) -> bool:
    return any(ch in SIMPLIFIED_ONLY for ch in text)

reply = "請用繁體中文回覆的範例文字"
print(looks_simplified(reply))   # False

UTF-8 من القرص إلى الشبكة والعكس

معظم أخطاء تشويش الصينية ليست مشاكل في النموذج. تأتي من ترميز افتراضي في مكان ما في خط الأنابيب: وحدة تحكم Windows تستخدم صفحة رموز قديمة، ملف CSV مفتوح بدون ترميز، أو وسيط يعيد كتابة نوع المحتوى. اجعل كل حدود صريحة واضحة.

في Python، مرر encoding="utf-8" إلى open، وإذا قمت ببناء JSON يدوياً، استخدم ensure_ascii=False متبوعاً بـ .encode("utf-8"). المثال أدناه يفعل ذلك مع requests الخام، والذي يظهر أيضاً الهيكل الخام للاتصال:

import json
import os
import requests

# 1) Always open files as UTF-8, never rely on the platform default encoding.
with open("notes_zh.txt", "r", encoding="utf-8") as f:
    note = f.read()

payload = {
    "model": "uncensored",
    "messages": [{"role": "user", "content": "请把下面的笔记整理成三个要点:\n" + note}],
    "max_tokens": 400,
}

# 2) requests encodes json= as UTF-8 for you. If you build the body by hand,
#    keep Chinese readable and make the encoding explicit.
body = json.dumps(payload, ensure_ascii=False).encode("utf-8")

r = requests.post(
    "https://api.chinesellmapi.com/v1/chat/completions",
    headers={
        "Authorization": "Bearer " + os.environ["API_KEY"],
        "Content-Type": "application/json; charset=utf-8",
    },
    data=body,
    timeout=60,
)
r.raise_for_status()
r.encoding = "utf-8"
print(r.json()["choices"][0]["message"]["content"])

في Node، يُرجع readFile Buffer ما لم توفر ترميزاً، وسلاسل القوالب التي تحتوي على الصينية تكون على ما يرام طالما أن ملف المصدر نفسه محفوظ بتنسيق UTF-8. يقوم SDK الرسمي بتسلسل الجسم لك:

import { readFile } from "node:fs/promises";
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.chinesellmapi.com/v1",
  apiKey: process.env.API_KEY,
});

// Pass "utf8" explicitly; without it readFile returns a Buffer, not a string.
const note = await readFile("notes_zh.txt", "utf8");

const res = await client.chat.completions.create({
  model: "uncensored",
  messages: [{ role: "user", content: `请把下面的笔记整理成三个要点:\n${note}` }],
  max_tokens: 400,
});

console.log(res.choices[0].message.content);
console.log(res.usage);

فخاخ أخرى. تقطيع السلاسل بطول البايت يمكن أن يقطع حرفاً في النصف، لذا قم دائماً بالقطع حسب الأحرف. وعندما تقوم بالبث المتدفق، فك تشفير التدفق كـ UTF-8 بشكل تدريجي، لأن حرفاً متعدد البايت قد ينقسم عبر أجزاء الشبكة؛ تتعامل SDKs مع هذا، لكن المحللين المصممين يدوياً غالباً لا يفعلون.

ميزانية الرموز للنصوص الصينية

الصينية لا تحتوي على مسافات، لذا فإن عد الكلمات عديم الفائدة لحساب التكلفة. بافتراض تخطيطي، وليس ثابتاً مقاساً، تعامل مع حرف صيني واحد كحوالي 1 إلى 2 رمز، واستخدم 1.5 عندما تحتاج إلى رقم واحد. الكلمات اللاتينية والأرقام المضمنة في النص أقرب إلى 1.3 رمز لكل كلمة. النسبة تختلف حسب المفردات، لذا فإن الرقم الوحيد الموثوق هو كائن usage الذي يُعاد مع كل استجابة.

مساعد صغير يجعل من السهل تقدير موجّه قبل إرساله، وضبط النسب مقابل الاستخدام الحقيقي بمرور الوقت:

import re

CJK = re.compile(r"[㐀-鿿＀-￯ -〿]")

def rough_tokens(text: str, per_cjk: float = 1.5, per_other_word: float = 1.3) -> int:
    """Planning estimate only. The 1.5 and 1.3 ratios are assumptions, not
    measured values; compare against resp.usage and adjust them."""
    cjk = len(CJK.findall(text))
    others = len(re.findall(r"[A-Za-z0-9_]+", CJK.sub(" ", text)))
    return round(cjk * per_cjk + others * per_other_word)

sample = "订单 A-1042 已发货,预计周三送达。"
print(rough_tokens(sample))

مثال عملي، مع فرضيات مذكورة: مقال مكون من 2,000 حرف بمعدل 1.5 رمز لكل حرف هو حوالي 3,000 رمز إدخال. ملخص مكون من 400 حرف هو حوالي 600 رمز إخراج. بسعر $0.25 لكل مليون رمز إدخال و $1.00 لكل مليون رمز إخراج، يكلف الاتصال الواحد حوالي $0.00075 للإضافة بالإضافة إلى $0.0006 للإخراج، حوالي $0.00135 في المجموع. بما أن السياق محدود بـ 100,000 رمز، فإن نفس الافتراض يعني أن موجّهًا مكونًا من حوالي 40,000 حرف يترك مساحة لرد.

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

إبقاء دردشة الصينية متعددة الأدوار داخل النافذة

ميزات الدردشة تعيد إرسال السجل الكامل في كل طلب، لذا فإن التكلفة والسياق ينموان مع كل دور. لأن النافذة هي 100,000 رمز مشتركة بين الموجّه والإكمال، فإن محادثة طويلة ستطلق في النهاية 400 إذا لم تفعل شيئاً. قرر سياسة التقليم مبكراً بدلاً من التفاعل مع الأخطاء.

سياسة بسيطة هي الحفاظ على موجّه النظام، إسقاط الأدوار الأقدم حتى يناسب الموجّه المقدر ميزانية، واحتفظ بالباقي للإجابة. المخطط أدناه يعيد استخدام المقدر من القسم السابق:

MAX_PROMPT_TOKENS = 48_000   # leave headroom under the 100,000 window for the reply

def trim_history(messages, estimate):
    # messages[0] is the system prompt and is always kept
    system, rest = messages[0], messages[1:]
    while rest and sum(estimate(m["content"]) for m in [system] + rest) > MAX_PROMPT_TOKENS:
        rest.pop(0)   # drop the oldest turn first
    return [system] + rest

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

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

قائمة مراجعة ما قبل الإطلاق والخطوات التالية

  1. قم بتعيين كل منطقة إلى موجّه نظام واختبر الوحدة للربط.
  2. ضبط الترميزات صراحة في قراءة الملفات، أجسام الطلبات والسجلات.
  3. سجل usage لكل ميزة وقارنها مع المقدر أسبوعياً.
  4. عالج 402 (no_credit)، 429 و503 (upstream_busy) بشكل مختلف: شحن الرصيد، إبطاء، إعادة المحاولة بعد بضع ثوانٍ.
  5. عامل مع 403 (content_blocked) كإجابة نهائية لذلك الطلب، وليس حالة إعادة محاولة.

إذا كان تطبيقك يتضمن خطوط ترجمة، تابع مع دليل الترجمة والتوطين؛ للرواية المسلسلة ودردشة الشخصيات، انظر دليل الخيال على الويب. مرجع المعلمة الكامل في الوثائق.

أسئلة وأجوبة

كيف أجعل الردود تأتي بالصينية المبسطة فقط؟

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

هل يمكنني طلب الصينية التقليدية لمستخدمي تايوان؟

نعم. استخدم موجّه نظام مكتوب بحروف تقليدية يحدد المفردات الإقليمية التي تريدها، واربطها من منطقة zh-TW في الكود الخاص بك.

لماذا أرى أحرفاً صينية مُشوَّهة في إخراجي؟

في الغالب مشكلة ترميز من جانب العميل. اقرأ الملفات بتنسيق UTF-8، وحدد ترميز نوع المحتوى، وتأكد من أن طرفية العرض أو عارض السجلات يستخدم أيضاً UTF-8.

كم رمزًا تستخدم النص الصيني؟

خطط بحوالي 1.5 رمز لكل حرف كتقريب، ثم تحقق من حقل الاستخدام في كل استجابة وعدّل تقديرك.

مفتاحك على بُعد نموذج واحد

أنشئ حساباً، انسخ المفتاح، غيّر عنوان URL الأساسي. هذا هو الإعداد الكامل.

احصل على مفتاح API