Checkliste vor Arbeitsbeginn
Gehe sie durch, um spätere Rückwege zu vermeiden.
- Eine E-Mail-Adresse, die Mails empfangen kann, zur Registrierung.
- Voraussetzung: Der lokale Rechner hat eine der Laufzeitumgebungen: Python 3, JDK 15+ (Textblöcke im Beispiel), Go oder PHP mit curl-Erweiterung.
- Du musst mindestens 18 Jahre alt sein, da der Dienst nur für Erwachsene bestimmt ist.
- Du benötigst reines Text-Chatting: Es gibt nur ein Modell, keine Vektoren, Bilder, Audio oder Fine-Tuning.
- Speichere den Key in Umgebungsvariablen, nicht im Quellcode, und committ ihn nicht ins Repository.
Die Schnittstelle ist schlicht: Adresse https://api.wushenchaapi.com/v1, kompatibel mit OpenAI Chat Completions. Alte Anfrage-Bodys können meist unverändert übernommen werden.
Zeitschätzung: Registrierung dauert eine Minute, Umgebungseinrichtung variiert, die erste Anfrage dauert maximal 30 Sekunden. Bei Verzögerung prüfe Netzwerk oder Key und springe zur Fehlerbehebung. Reihenfolge: erst models, dann chat; erst synchron, dann Streaming. Bestätige jeden Schritt, bevor du fortfährst.
Registrieren und Key erhalten
Öffne /get-api-key/ und registriere dich mit E-Mail und Passwort. Der Key wird sofort angezeigt und kann kopiert werden. Details:
- Jedes Konto hat nur einen Key.
- Du kannst ihn neu generieren, aber der alte Key wird sofort ungültig. Deploye den neuen Wert, bevor du ihn im Live-Betrieb wechselst.
- Neue Konten erhalten $0,50 Testguthaben, gültig für 7 Tage. Keine Zahlungsdaten erforderlich.
- Nach Ablauf oder Verbrauch des Guthabens erhältst du 402 mit Fehlercode
no_credit. Lade dein Prepaid-Guthaben auf, um fortzufahren. Es ist kein Abonnement; das Guthaben verfällt nicht.
Setze den Key in eine Umgebungsvariable: macOS/Linux: export API_KEY=DeinKey, Windows PowerShell: $env:API_KEY="DeinKey". Alle Beispiele lesen aus API_KEY.
Schritt 1: Verbindung mit /v1/models prüfen
Starte nicht sofort mit Chats. Sende zuerst eine kostenlose GET-Anfrage, um Adresse, Netzwerk und Key zu prüfen:
curl https://api.wushenchaapi.com/v1/models \
-H "Authorization: Bearer $API_KEY"Ein 200er mit der Modellliste (nur uncensored) bedeutet Erfolg. 401 bedeutet falscher oder fehlender Key. Timeouts deuten auf Netzwerk- oder Proxy-Probleme hin. Die Trennung von Verbindungs- und Body-Problemen spart Zeit.
Python: requests
Kein SDK nötig, ein requests.post reicht. Drei Punkte: timeout muss gesetzt sein; prüfe r.ok vor dem Zugriff auf choices; Fehler-Body ist {"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"])Bei Erfolg enthält usage prompt_tokens und completion_tokens. Gib diese in der Entwicklungsphase aus, um die Kosten im Blick zu behalten.
Anfrage-Body im Detail
Alle vier Sprachen senden denselben JSON-Body. Wenn du ihn verstehst, ist die Umsetzung in jeder Sprache nur eine Übersetzung.
| Feld | Pflicht | Beschreibung |
|---|---|---|
| model | Ja | Fest auf uncensored gesetzt. |
| messages | Ja | Array mit Objekten aus role und content. role kann system, user oder assistant sein. |
| max_tokens | Nein | Standard 2048, Maximum 16.000 pro Anfrage. Für längere Texte musst du den Wert selbst erhöhen. |
| temperature / top_p / stop | Nein | Standard-Sampling-Parameter, werden unverändert durchgereicht. |
| stream | Nein | Bei true wird der SSE-Streaming verwendet. |
In der Antwort liest du am häufigsten drei Stellen: choices[0].message.content ist der Haupttext, choices[0].finish_reason zeigt an, ob die Antwort normal endet oder durch die Längenbegrenzung abgeschnitten wurde, und usage gibt den Token-Verbrauch dieser Anfrage an. Nur wenn du alle drei liest, ist die Integration vollständig.
Zwei harte Limits: Request-Body max. 8 MB, 300 Anfragen pro Minute und Key. Batch-Aufgaben nicht blind parallel ausführen; zuerst ein einfaches Concurrency-Limit setzen.
Java: java.net.http
JDK 11+ hat HttpClient ohne Abhängigkeiten. Das Beispiel nutzt JDK 15 Textblöcke für JSON; ältere Versionen nutzen String-Konkatenation oder JSON-Serialisierung.
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());
}
}Hinweis: Bei Inhalten mit chinesischen Zeichen kodiert BodyPublishers.ofString standardmäßig UTF-8. Nutze HttpClient als Singleton.
Go: net/http
Die Standardbibliothek von Go reicht ebenfalls aus. Wichtig ist, nicht den Standard-http.DefaultClient ohne Timeout-Einstellung zu verwenden, da sonst Goroutines hängen bleiben, wenn die Gegenseite nicht antwortet.
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))
}Lies den Antwort-Body mit io.ReadAll vollständig aus, bevor du ihn analysierst. Für die strukturierte Verarbeitung definiere die entsprechenden Structs und deserialisiere sie mit encoding/json. Die Felder sind choices, message, content, usage.
PHP: curl
Verwende in PHP die curl-Erweiterung. Achte bei json_encode darauf, JSON_UNESCAPED_UNICODE zu setzen, da sonst chinesische Zeichen als \uXXXX maskiert werden. Das funktioniert zwar, ist aber bei der Fehlersuche schwer lesbar.
<?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";Unterscheide zwei Arten von Fehlern: Ein Rückgabewert von false bei curl_exec bedeutet ein Problem auf Netzwerkebene. Wenn Inhalt zurückgegeben wird, der Statuscode jedoch nicht 200 ist, liegt ein Problem auf API-Ebene vor; lies error.code.
Häufige Fallstricke beim ersten Aufruf
- 401: Der Header wurde als
Authorization: 密钥geschrieben, dasBearer-Präfix fehlt; oder die Umgebungsvariable wurde in einem neu geöffneten Terminal nicht geladen. - 404: Der Pfad enthält kein
/v1oderchat/completionswurde falsch geschrieben. - 400: Das JSON ist ungültig, oder die Summe aus Prompt und max_tokens überschreitet das Limit von 100.000 Token.
- 402: Guthaben aufgebraucht oder Testzeitraum abgelaufen.
- Ausgabe abgeschnitten:
max_tokenshat standardmäßig den Wert 2048, maximal sind 16.000 möglich. Für längere Texte musst du den Wert explizit erhöhen. - Streaming gewünscht: Füge im Request-Body
"stream": truehinzu. Die Antwort erfolgt als SSE, am Ende wird automatisch ein Datenblock mit usage angehängt.
Nachdem du die Integration erfolgreich getestet hast, sieh dir Prompt-Schreibweise an, um die Ausgabequalität zu optimieren. Bei Fehlern konsultiere das Handbuch zur Fehlerbehebung. Die vollständige Parameterreferenz findest du in Dokumentation, die Preise auf der Preisseite.
Nachdem es funktioniert, vor dem Go-Live drei Dinge ergänzen
Die Beispiele in der Anleitung sind Minimalversionen. Für den Einsatz in einem echten Service fehlen mindestens diese drei Komponenten.
- Timeout. Im Beispiel wurden einheitlich 120 Sekunden angegeben, da die Generierung langer Texte tatsächlich Zeit benötigt. Wenn deine Anwendung synchron wartet, kürze den Timeout entsprechend der Toleranz deiner Nutzer und kombiniere ihn mit Streaming, damit die Nutzer den Text schrittweise sehen können.
- Fehler-Handling. Die Statuscodes 401, 402 und 403 sind Fehler, bei denen ein Retry sinnlos ist; löse einen Alarm aus oder zeige dem Nutzer eine Meldung. Die Codes 429 und 503 rechtfertigen ein Backoff-Retry. Die konkrete Implementierung findest du im Handbuch zur Fehlerbehebung, hier wird dies nicht im Detail ausgeführt.
- Verbrauchsprotokollierung. Schreibe den usage-Wert jeder Antwort in ein Log. Speichere nur die Zahlen, nicht den Benutzertext. Dies ist notwendig für die monatliche Abrechnung und die Analyse von anomalem Verbrauch.
Ein Hinweis zur Schlüsselverwaltung: Es gibt nur einen Schlüssel. Nach dem Erneuern wird der alte Schlüssel ungültig, was dazu führt, dass alle aktiven Dienste gleichzeitig ausfallen. Verteile den Schlüssel daher nicht auf mehrere Skripte oder Serverkonfigurationen, sondern speichere ihn zentral an einer Stelle, damit du ihn bei Bedarf nicht übersehen und alles gleichzeitig umstellen kannst.
Ein Hinweis zu den Inhaltsrichtlinien: Adult-Content, fiktionale Romane und kontroverse Themen werden nicht blockiert. Sexuelle Inhalte mit Minderjährigen werden jedoch immer mit 403 blockiert, auch in Fiktion und Rollenspielen. Wenn deine Anwendung an erwachsene Nutzer gerichtet ist, empfehlen wir, im eigenen Registrierungsprozess eine Altersverifikation einzubauen.
Zum Abschluss eine Checkliste zur Selbstprüfung, die du auch direkt am Monitor platzieren kannst: Ist der Schlüssel in den Umgebungsvariablen gespeichert? Funktioniert die models-Verbindung? Ist der Request-Body gültiges JSON? Ist das Modell unzensiert? Reichen die max_tokens? Ist finish_reason in der Antwort „stop“ oder „length“? Wurde usage protokolliert? Wenn alle sieben Punkte grün sind, ist die Integration abgeschlossen.