Checklist pre-lavoro
Controlla tutto ora per evitare ritorni indietro.
- Un'email attiva per la registrazione.
- Disponi di uno qualsiasi di questi ambienti: Python 3, JDK 15 o superiore (gli esempi usano i blocchi di testo), Go o PHP con l'estensione curl.
- Conferma di essere un adulto sopra i 18 anni; il servizio è rivolto esclusivamente agli utenti adulti.
- Questo servizio offre solo chat testuale, senza embedding o immagini.
- Salva la chiave nelle variabili d'ambiente, non nel codice.
Le convenzioni dell'endpoint sono poche: l'indirizzo è https://api.wushenchaapi.com/v1. È compatibile con il completamento conversazionale di OpenAI, quindi puoi riutilizzare pressoché invariati i corpi delle tue vecchie richieste.
Stima: registrazione 1 min, setup variabile, prima richiesta <30s.
Registrati e ottieni la chiave
Vai su /get-api-key/ e registrati con email e password. La chiave API viene mostrata subito dopo la registrazione: copia il valore. Ecco alcuni dettagli:
- Un solo account, una sola chiave API.
- Puoi rigenerarla, ma la vecchia scade subito. Deploya la nuova prima di cambiare.
- Il nuovo account riceve un credito di prova gratuito di $0,50 valido per 7 giorni. Non è necessario inserire informazioni di pagamento.
- Quando il periodo di prova scade o il credito si esaurisce, le richieste restituiscono 402 con errore
no_credit. Ricarica il credito prepagato per continuare a usare il servizio: non è un abbonamento e il saldo non scade.
Imposta la chiave nelle variabili d'ambiente: su macOS/Linux esegui export API_KEY=la_tua_chiave, su Windows PowerShell usa $env:API_KEY="la_tua_chiave". Tutti gli esempi successivi leggono da API_KEY.
Passo 1: Verifica con /v1/models
Non inviare chat subito. Fai prima una GET a costo zero per verificare URL, rete e chiave.
curl https://api.wushenchaapi.com/v1/models \
-H "Authorization: Bearer $API_KEY"Un 200 con l'elenco dei modelli (solo uncensored) indica che tutto funziona. Un 401 significa chiave errata o mancante; un timeout richiede di controllare la rete e il proxy. Separare i problemi di connettività da quelli del corpo della richiesta è l'abitudine che fa risparmiare più tempo.
Python: requests
Non serve SDK, un singolo requests.post è sufficiente. Attenzione a tre cose: imposta timeout; verifica r.ok prima di leggere choices; in caso di errore il corpo è {"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"])In caso di successo, usage contiene prompt_tokens e completion_tokens. Durante lo sviluppo è consigliato stamparli sempre per avere chiara la situazione dei costi.
Analisi del corpo della richiesta
Tutte le lingue usano lo stesso JSON. Comprendilo prima di scrivere il codice.
| Campo | Obbligatorio | Descrizione |
|---|---|---|
| model | Sì | Imposta a uncensored. |
| messages | Sì | È un array dove ogni elemento contiene role e content. I valori validi per role sono system, user e assistant. |
| max_tokens | No | Il valore predefinito è 2048, con un massimo per singola richiesta di 16.000. Per generare testi lunghi devi aumentarlo esplicitamente. |
| temperature / top_p / stop | No | Parametri di campionamento standard, passati invariati. |
| stream | No | Imposta true per lo streaming via SSE. |
Nella risposta, i tre campi che leggi più spesso sono: choices[0].message.content per il contenuto, choices[0].finish_reason che indica se la generazione è terminata normalmente o è stata troncata, e usage per il consumo di token. Leggere tutti e tre è essenziale per un'integrazione completa.
Ricorda due limiti rigidi: il corpo della richiesta non deve superare 8 MB e ogni chiave ha un limite di 300 richieste al minuto. Per i task batch non fare troppe richieste parallele: imposta prima un limite di concorrenza.
Java: java.net.http
HttpClient è integrato dal JDK 11 senza dipendenze. Gli esempi usano i blocchi di testo del JDK 15 per il JSON; per le versioni precedenti, usa la concatenazione di stringhe o una libreria 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());
}
}Nota: con testo cinese, BodyPublishers.ofString usa UTF-8, senza elaborazione extra. In produzione, riutilizza HttpClient come singleton.
Go: net/http
Anche la libreria standard Go è sufficiente. Non usare http.DefaultClient senza timeout: altrimenti il goroutine rimarrebbe in attesa indefinitamente se il server si blocca.
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))
}Leggi tutto il corpo con io.ReadAll prima di analizzare. Per la struttura, definisci una struct e usa encoding/json. I campi sono choices, message, content e usage.
PHP: curl
In PHP usa l'estensione curl. Ricorda di aggiungere JSON_UNESCAPED_UNICODE a json_encode: altrimenti il cinese viene convertito in \uXXXX, rendendo il debug difficile.
<?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";Distingui due fallimenti: curl_exec restituisce false per errori di rete; se restituisce contenuto ma status non 200, è errore API: leggi error.code.
Errori comuni alla prima chiamata
- 401: Hai scritto
Authorization: chiavesenza il prefissoBearer, oppure la variabile d'ambiente non è attiva nel nuovo terminale. - 404: Manca il prefisso
/v1nel percorso o il nomechat/completionsè stato scritto male. - 400: JSON non valido, oppure prompt + max_tokens superano il limite di 100.000 token.
- 402: Il saldo è esaurito o il credito di prova è scaduto.
- Output troncato:
max_tokensè 2048 di default, massimo 16.000. Per i testi lunghi devi aumentarlo esplicitamente. - Vuoi lo streaming: aggiungi
"stream": trueal corpo. La risposta è SSE e alla fine ricevi un blocco dati con usage.
Una volta completata la configurazione, leggi Guida al prompt per migliorare la qualità. Per gli errori, consulta Manuale errori. Dettagli parametri in Documentazione, prezzi in Pagina prezzi.
Una volta che l'integrazione funziona, prima del lancio aggiungi questi tre elementi
Gli esempi del tutorial sono versioni minime funzionanti. Per portarli in produzione, devi integrare almeno questi tre elementi.
- Timeout. Gli esempi impostano 120 secondi perché la generazione di testi lunghi è lenta. Se la tua applicazione attende in modo sincrono, riduci il timeout in base alla tolleranza della pagina e usa lo streaming per mostrare il testo man mano che viene generato.
- Gestione errori. 401, 402, 403 sono errori fatali: avvisa o mostra un messaggio. 429 e 503 meritano un retry con backoff. I dettagli sono nel manuale.
- Registrazione del consumo. Ogni risposta genera un log con il campo usage. Registra solo i numeri, non il contenuto dell'utente. Questo è fondamentale per la riconciliazione mensile e l'individuazione di consumi anomali.
Un'ultima nota sulla gestione delle chiavi: hai una sola chiave API. Se viene compromessa, puoi rigenerarla, ma questo invalida tutte le istanze in uso, causando un'interruzione simultanea. Non spargerla tra script o configurazioni di server diversi; centralizzala in un unico punto di configurazione per facilitare la rotazione.
Per i limiti del contenuto: il contenuto adulto legale, la narrativa e i temi controversi non vengono bloccati. Tuttavia, i contenuti sessuali che coinvolgono minori sono sempre bloccati con codice 403, anche nei ruoli di gioco. Se il tuo pubblico è adulto, verifica l'età durante la registrazione.
Usa questa checklist di autoverifica: la chiave è nelle variabili d'ambiente; i modelli sono accessibili; il corpo della richiesta è JSON valido; il modello è senza censura; max_tokens è sufficiente; il finish_reason è stop; il consumo è registrato. Se tutti i controlli sono verdi, l'integrazione è completa.