DE ▾

Chinese LLM APISchnellstart

API-Schlüssel erhalten

Aktualisiert am

Chinesische App entwickeln: Prompts, Schriftsteuerung und UTF-8

Das Ausliefern einer chinesischen Funktion ist meist ein Lokalisierungsproblem, kein Modellproblem. Du entscheidest, welche Schrift die Nutzer sehen, hältst die Kodierungen von der Datei bis zur Übertragung sauber und planst Token für Text, der nicht an Leerzeichen aufgeteilt wird. Diese Anleitung behandelt diese drei Ebenen mit Code, den du noch heute gegen den Chat-Completions-Endpunkt ausführen kannst.

Was du verdrahtest

Der Dienst stellt POST /v1/chat/completions und GET /v1/models unter https://api.chinesellmapi.com/v1 bereit. Die Authentifizierung erfolgt über einen Bearer-Schlüssel, und die einzige Modell-ID ist uncensored. Es handelt sich um eine Nur-Text-API mit einem Modell, sodass du nichts auswählen musst: Deine Lokalisierungsarbeit erfolgt vollständig im Prompt und in deinem eigenen Code darum herum.

Grenzen, die du vor dem Design kennen solltest: ein 100.000-Token-Kontextfenster, das von Prompt und Completion geteilt wird, max_tokens mit einem Standardwert von 2.048 und einem Maximum von 32.000, Anfragekörper bis zu 8 MB und 300 Anfragen pro Minute pro Schlüssel. Streaming (stream: true) funktioniert über Server-Sent Events, und Tools im OpenAI Function-Calling-Format werden akzeptiert.

Neue Konten erhalten ein $0,50 kostenloses Testguthaben, das sieben Tage gültig ist, ohne dass Zahlungsdaten angegeben werden müssen; registriere dich mit E-Mail und Passwort und der Schlüssel erscheint sofort. Die FAQ zum Testguthaben regelt die Bedingungen im Detail.

Schreibe Prompts auf Chinesisch, und gib an, welches Chinesisch

Gemischtsprachige Prompts sind die häufigste Ursache für Abweichungen bei lokalisierten Funktionen. Wenn die Anweisungen auf Englisch sind, der Inhalt aber auf Chinesisch, kommen Antworten manchmal auf Englisch oder in einer Mischung zurück. Ein zuverlässiges Muster ist ein System-Prompt in der Zielsprache, der drei Dinge angibt: die Rolle, die Schrift und den regionalen Wortschatz. Halte benutzergenerierten Text in einer separaten Nachricht, damit er nicht mit Anweisungen verwechselt wird.

Hier ist eine Einrichtung für vereinfachtes Chinesisch. Beachte, dass der System-Prompt das Modell anweist, nur in vereinfachten Zeichen zu antworten und fremdes Englisch zu vermeiden, wobei Eigennamen als Ausnahme gelten:

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)

Zwei Gewohnheiten lohnen sich schnell. Erstens halte Prompts kurz und konkret: eine Rolle, ein Ausgabeformat, ein oder zwei Einschränkungen. Zweitens schreibe die Sprachanforderung in die Systemnachricht, statt sie in jedem Benutzer-Durchlauf zu wiederholen, damit der Konversationsverlauf sie nicht verwässert.

Steuerung der Ausgabe: Vereinfacht vs. Traditionell

Die Schriftwahl ist eine Produktentscheidung, die an die User-Locale gebunden ist, nicht an eine Modelleinstellung. Produkte für das Festlandchina erwarten vereinfachte Zeichen; Nutzer in Taiwan und Hongkong erwarten traditionelle Zeichen, auch mit anderem Wortschatz (die üblichen Beispiele sind Begriffe aus Software, Netzwerk und Datenbanken). Der praktische Ansatz ist, deinen Locale-Tag einem System-Prompt zuzuordnen und die Wahl im Code explizit zu machen.

  • zh-CN, zh-SG: Vereinfacht, kontinentalchinesischer Wortschatz, halbbreite Ziffern, volle Breite bei chinesischer Zeichensetzung.
  • zh-TW: Traditionell, taiwanesisches Vokabular, Eckige Klammern für Zitate sind üblich.
  • zh-HK: Traditionell mit Hongkonger Ausdrucksweise; liefere ein kurzes Glossar, wenn dein Produkt feste Begriffe hat.

Die traditionelle Variante desselben Aufrufs sieht so aus; nur der System-Prompt ändert sich:

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)

Modelle leihen gelegentlich ein paar Zeichen der anderen Schrift, besonders wenn die Benutzermeldung selbst in der anderen Schrift ist. Füge einen günstigen Post-Check hinzu und wiederhole einmal mit einer schärferen Anweisung, wenn es fehlschlägt. Für alles, was über eine Stichprobenprüfung hinausgeht, führe die Ausgabe durch eine dedizierte Konvertierungsbibliothek wie 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 von der Festplatte über die Leitung und zurück

Die meisten Fehler mit verkorksten chinesischen Zeichen sind keine Modellprobleme. Sie stammen von einer Standardkodierung irgendwo in der Pipeline: eine Windows-Konsole mit einer Legacy-Codepage, eine CSV-Datei, die ohne Kodierung geöffnet wurde, ein Proxy, der den Content-Type umschreibt. Mache jede Grenze explizit.

In Python übergibst du encoding="utf-8" an open, und wenn du JSON manuell erstellst, verwende ensure_ascii=False gefolgt von .encode("utf-8"). Das folgende Beispiel macht dies mit plain requests, was auch die rohe HTTP-Struktur des Aufrufs zeigt:

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

In Node.js gibt readFile einen Buffer zurück, es sei denn, du gibst eine Kodierung an, und Template-Strings mit chinesischem Text sind in Ordnung, solange die Quelldatei selbst als UTF-8 gespeichert ist. Das offizielle SDK serialisiert den Körper für dich:

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);

Zwei weitere Fallen. Das Abschneiden von Strings nach Bytelänge kann ein Zeichen in der Hälfte abschneiden, also schneide immer nach Zeichen ab. Und wenn du streamst, decodiere den Stream inkrementell als UTF-8, da ein mehrbyteiges Zeichen über Netzwerk-Chunks aufgeteilt sein kann; die SDKs erledigen dies, aber manuell geschriebene Parser oft nicht.

Token-Budgetierung für chinesischen Text

Chinesisch hat keine Leerzeichen, daher sind Wortzählungen für die Budgetierung nutzlos. Behandle ein chinesisches Zeichen als grobe Annahme (kein gemessener Wert) mit etwa 1 bis 2 Token und verwende 1,5, wenn du eine einzelne Zahl benötigst. Lateinische Wörter und Ziffern, die in den Text eingebettet sind, liegen näher bei 1,3 Token pro Wort. Das Verhältnis variiert je nach Wortschatz, daher ist die einzige maßgebliche Zahl das usage-Objekt, das mit jeder Antwort zurückgegeben wird.

Ein kleiner Helfer macht es einfach, einen Prompt vor dem Senden zu schätzen und die Verhältnisse im Laufe der Zeit an echte Nutzung anzupassen:

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

Durchgerechnetes Beispiel mit genannten Annahmen: Ein 2.000-Zeichen-Artikel bei 1,5 Token pro Zeichen ergibt etwa 3.000 Input-Token. Ein 400-Zeichen-Zusammenfassung ergibt etwa 600 Output-Token. Bei 0,25 $ pro Million Input-Token und 1,00 $ pro Million Output-Token kostet ein Aufruf etwa 0,00075 $ für Input plus 0,0006 $ für Output, insgesamt etwa 0,00135 $. Da das Kontextfenster auf 100.000 Token begrenzt ist, bedeutet dieselbe Annahme, dass ein Prompt von etwa 40.000 Zeichen noch Platz für eine Antwort lässt.

Wenn du lange Dokumente füttern musst, teile sie nach Absätzen oder Überschriften, niemals mitten im Satz, und halte max_tokens explizit. Preise und Grenzen sind auf der Preisseite aufgeführt.

Chinesischen Chat im Fenster halten

Chat-Funktionen senden den gesamten Verlauf bei jeder Anfrage erneut, daher steigen Kosten und Kontext mit jedem Durchlauf. Da das Fenster 100.000 Token für Prompt und Completion teilt, löst ein langes Gespräch irgendwann einen 400-Fehler aus, wenn du nichts unternimmst. Entscheide dich früh für eine Beschneidungsstrategie, anstatt auf Fehler zu reagieren.

Eine einfache Strategie ist, den System-Prompt beizubehalten, die ältesten Nachrichten so lange zu entfernen, bis der geschätzte Prompt in ein Budget passt, und den Rest für die Antwort zu reservieren. Das folgende Beispiel verwendet den Schätzer aus dem vorherigen Abschnitt:

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

Für Produkte, bei denen früher Kontext wichtig ist, wie ein Tutor-Bot oder ein Support-Assistent, ersetze gelöschte Durchläufe durch eine kurze Zusammenfassungsnachricht, anstatt sie einfach zu verwerfen. Bitte das Modell, die alten Durchläufe in ein paar Sätze in derselben Schrift wie die Konversation zu komprimieren, und füge diese Zusammenfassung direkt nach dem System-Prompt ein. Es kostet gelegentlich einen zusätzlichen Aufruf und hält die Persona und Fakten stabil.

Denke auch daran, max_tokens für Chat sinnvoll zu begrenzen. Antworten in einer Messaging-Benutzeroberfläche benötigen selten mehr als ein paar hundert Token, und eine engere Begrenzung macht Latenz und Kosten vorhersehbarer. Das Streaming der Antwort Token für Token verbessert das Geschwindigkeitsempfinden, insbesondere bei chinesischem Text, bei dem Nutzer in kurzen Abschnitten lesen.

Checkliste vor dem Launch und nächste Schritte

  1. Ordne jeder Locale einen System-Prompt zu und teste die Zuordnung mit Unit-Tests.
  2. Setze Kodierungen explizit bei Datei-Lesevorgängen, Anfragekörpern und Logs.
  3. Logge usage pro Feature und vergleiche es wöchentlich mit deinem Schätzer.
  4. Behandle 402 (no_credit), 429 und 503 (upstream_busy) unterschiedlich: lade auf, verlangsame, warte ein paar Sekunden und wiederhole.
  5. Behandle 403 (content_blocked) als endgültige Antwort für diese Anfrage, nicht als Wiederholungsfall.

Wenn deine App Übersetzungspipelines beinhaltet, fahre mit dem Übersetzungs- und Lokalisierungsleitfaden fort; für serialisierte fiktionale Texte und Character-Chat sieh dir den Leitfaden für Web-Fiktion an. Die vollständige Parameterreferenz findest du in den Dokumenten.

Fragen und Antworten

Wie stelle ich sicher, dass die Antworten nur in vereinfachtem Chinesisch zurückkommen?

Gib das in einem System-Prompt an, zum Beispiel „antworte immer auf vereinfachtes Chinesisch mit der Vokabularauswahl des chinesischen Festlandes“. Behalte diese Anweisung in der Systemnachricht und füge einen Post-Check hinzu, falls die Ausgabe strikt sein muss.

Kann ich traditionelles Chinesisch für Nutzer in Taiwan anfordern?

Ja. Verwende einen System-Prompt, der in traditionellen Zeichen verfasst ist und die gewünschte regionale Vokabularauswahl benennt, und mappe dies in deinem Code von der Locale zh-TW.

Warum sehe ich kryptische chinesische Zeichen in meiner Ausgabe?

Fast immer ein Codierungsproblem auf Client-Seite. Lese Dateien als UTF-8, setze den Content-Type-Charset und stelle sicher, dass auch dein Terminal oder Log-Viewer UTF-8 verwendet.

Wie viele Token verbraucht chinesischer Text?

Plane mit etwa 1,5 Token pro Zeichen als Näherung, prüfe dann das Nutzungsfeld in jeder Antwort und passe deine Schätzung an.

Dein Schlüssel ist nur ein Formular entfernt

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

API-Schlüssel erhalten