Danh sách kiểm tra trước khi bắt đầu
Hãy xem qua trước để tránh phải quay lại giữa chừng.
- Một địa chỉ email có thể nhận thư để đăng ký.
- Máy bạn có một trong các môi trường: Python 3, JDK 15+, Go hoặc PHP có curl. Ví dụ dùng khối văn bản.
- Xác nhận bạn là người trưởng thành trên 18 tuổi, dịch vụ chỉ dành cho người dùng trưởng thành.
- Bạn biết mình cần hội thoại văn bản thuần: ở đây chỉ có một mô hình, không có vector, hình ảnh, giọng nói hay tinh chỉnh.
- Chuẩn bị lưu khóa trong biến môi trường, không viết vào mã nguồn và đừng commit lên kho lưu trữ.
Quy ước endpoint rất đơn giản: https://api.wushenchaapi.com/v1, tương thích với định dạng chat completion của OpenAI, nên request body bạn đã viết trước đây hầu như có thể giữ nguyên.
Ước tính thời gian: đăng ký mất một phút, cài đặt môi trường tùy thuộc vào máy bạn, lần gọi đầu tiên không quá 30 giây. Nếu vượt quá thời gian này mà chưa có kết quả, khả năng cao là do mạng hoặc khóa, hãy nhảy ngay đến danh sách xử lý lỗi ở cuối trang. Thứ tự đúng: kiểm tra models trước, sau đó đến chat; kiểm tra đồng bộ trước, rồi mới đến streaming. Xác nhận từng bước rồi mới tiếp tục.
Đăng ký và lấy key
Mở /get-api-key/, đăng ký bằng email và mật khẩu. Khóa sẽ hiển thị ngay sau khi đăng ký, bạn chỉ cần sao chép. Một số chi tiết:
- Mỗi tài khoản chỉ có một khóa.
- Bạn có thể tạo lại khóa, nhưng khóa cũ sẽ mất hiệu lực ngay lập tức. Hãy triển khai giá trị mới trước khi thay khóa trên dịch vụ trực tuyến.
- Tài khoản mới được tặng $0.50 tín dụng dùng thử miễn phí, có hiệu lực trong 7 ngày, không cần điền thông tin thanh toán.
- Khi hết hạn hoặc hết tín dụng dùng thử miễn phí, yêu cầu sẽ trả về 402 với mã lỗi
no_credit. Bạn chỉ cần nạp tiền vào số dư tín dụng trả trước để tiếp tục sử dụng. Đây không phải gói đăng ký, số dư không bao giờ hết hạn.
Đặt khóa vào biến môi trường: macOS/Linux chạy export API_KEY=your_key, PowerShell dùng $env:API_KEY="your_key". Các ví dụ sau đọc từ API_KEY.
Bước 1: Xác minh khả năng kết nối bằng /v1/models
Đừng vội gửi hội thoại. Hãy thực hiện một lệnh GET không tốn phí để xác nhận ba yếu tố: địa chỉ, mạng và key đều hoạt động:
curl https://api.wushenchaapi.com/v1/models \
-H "Authorization: Bearer $API_KEY"Trả về 200 và danh sách mô hình (chỉ có uncensored) là thành công. 401 là khóa sai/thiếu; timeout là kiểm tra mạng/proxy. Tách lỗi kết nối và body giúp bạn tiết kiệm thời gian.
Python: requests
Không cần SDK, một lệnh requests.post là đủ. Lưu ý ba điểm: phải đặt timeout; kiểm tra r.ok trước khi lấy choices; khi lỗi, thân phản hồi là {"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"])Khi thành công, usage chứa prompt_tokens và completion_tokens. Trong giai đoạn phát triển, bạn nên in ra mọi lúc để nắm rõ chi phí.
Phân tích chi tiết từng trường trong thân yêu cầu
Bốn ngôn ngữ đều gửi cùng một JSON. Hãy hiểu nó trước, viết ngôn ngữ nào cũng chỉ là bản dịch.
| Trường | Bắt buộc | Mô tả |
|---|---|---|
| model | Có | Cố định là uncensored. |
| messages | Có | Mảng, mỗi mục chứa role và content, role nhận system, user, assistant. |
| max_tokens | Không | Mặc định 2048, giới hạn tối đa mỗi lần là 16,000. Bạn phải tự tăng lên khi viết văn bản dài. |
| temperature / top_p / stop | Không | Các tham số lấy mẫu tiêu chuẩn, truyền nguyên vẹn. |
| stream | Không | Khi là true, luồng sẽ chạy theo chuẩn SSE. |
Bạn thường chỉ đọc ba phần trong phản hồi: choices[0].message.content là nội dung chính, choices[0].finish_reason cho bạn biết là kết thúc bình thường hay bị cắt do giới hạn độ dài, usage là số token đã dùng cho yêu cầu này. Đọc cả ba phần thì bạn mới tích hợp đầy đủ.
Hai giới hạn cứng: body dưới 8 MB, mỗi khóa 300 yêu cầu/phút. Đừng gửi ồ ạt yêu cầu đồng thời, hãy đặt giới hạn song song trước.
Java: java.net.http
JDK 11 đã tích hợp sẵn HttpClient, bạn không cần thêm bất kỳ thư viện nào. Đoạn mã dưới đây dùng tính năng text block của JDK 15 để viết JSON; nếu dùng phiên bản thấp hơn, bạn có thể chuyển sang nối chuỗi hoặc dùng thư viện JSON quen thuộc để serialize.
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());
}
}Lưu ý: Khi nội dung có tiếng Trung, BodyPublishers.ofString sẽ mặc định dùng mã hóa UTF-8, bạn không cần xử lý thêm. Trong môi trường production, bạn hãy triển khai HttpClient dưới dạng singleton để tái sử dụng, đừng tạo mới mỗi lần gửi yêu cầu.
Go: net/http
Thư viện chuẩn của Go cũng đủ dùng. Điểm mấu chốt là bạn đừng dùng http.DefaultClient mặc định mà không đặt thời gian chờ (timeout), nếu không goroutine sẽ bị treo vô hạn khi phía server bị kẹt.
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))
}Bạn hãy đọc hết response body bằng io.ReadAll rồi mới tiến hành phân tích. Nếu cần xử lý cấu trúc, bạn định nghĩa struct tương ứng rồi dùng encoding/json để deserialize; các trường dữ liệu bao gồm choices, message, content, usage.
PHP: curl
PHP dùng extension curl, bạn nhớ thêm JSON_UNESCAPED_UNICODE khi gọi json_encode, nếu không nội dung tiếng Trung sẽ bị chuyển thành \uXXXX. Dù vẫn hoạt động được nhưng sẽ rất khó đọc khi debug.
<?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";Bạn cần phân biệt hai loại lỗi: curl_exec trả về false là lỗi tầng mạng; nếu trả về nội dung nhưng mã trạng thái không phải 200 là lỗi tầng API, bạn cần đọc error.code.
Những lỗi thường gặp khi gọi lần đầu
- 401: Header đã được viết là
Authorization: khóa API, thiếu tiền tốBearer; hoặc biến môi trường chưa có hiệu lực trong terminal mới được mở. - 404: Đường dẫn thiếu
/v1, hoặc bạn đã đánh saichat/completions. - 400: JSON không hợp lệ, hoặc prompt cộng max_tokens vượt quá giới hạn 100,000 token.
- 402: Hết số dư hoặc hết thời hạn dùng thử.
- Nội dung bị cắt ngắn:
max_tokensmặc định là 2048, tối đa một lần gọi là 16,000; bạn cần tăng giá trị này rõ ràng khi viết văn bản dài. - Muốn dùng streaming: Bạn thêm
"stream": truevào request body. Phản hồi sẽ trả về dạng SSE và cuối cùng sẽ tự động thêm một khối dữ liệu chứa thông tin usage.
Sau khi chạy thành công, bước tiếp theo bạn nên xem Cách viết prompt để cải thiện chất lượng đầu ra; nếu gặp lỗi, hãy tra Sổ tay xử lý lỗi và mã lỗi. Tài liệu đầy đủ về tham số có tại Tài liệu, giá cả xem tại Trang giá cả.
Sau khi chạy thành công, trước khi đưa lên production bạn cần bổ sung ba thứ sau
Các ví dụ trong hướng dẫn chỉ là phiên bản tối thiểu để chạy được; khi đưa vào dịch vụ thực tế, bạn ít nhất cần bổ sung ba mục này.
- Thời gian chờ. Ví dụ đặt 120 giây vì sinh văn bản dài chậm. Nếu chờ đồng bộ, hãy giảm thời gian chờ và dùng streaming để người dùng thấy kết quả ngay.
- Phân loại lỗi. Các mã 401, 402, 403 là lỗi mà thử lại cũng vô hiệu, bạn cần báo động hoặc thông báo cho người dùng; chỉ có 429 và 503 mới đáng để thử lại với cơ chế backoff. Cách triển khai cụ thể đã có trong sổ tay xử lý lỗi, không trình bày ở đây.
- Theo dõi lượng dùng. Mỗi lần phản hồi, bạn hãy ghi log usage, chỉ ghi số liệu, không ghi nội dung của người dùng vào log. Đây là cơ sở để đối chiếu cuối tháng và kiểm tra các mức tiêu thụ bất thường.
Nhắc lại một chút về quản lý khóa: bạn chỉ có một khóa duy nhất, nếu bị lộ thì chỉ có thể tạo lại khóa mới, và việc tạo lại sẽ khiến tất cả các dịch vụ đang sử dụng khóa cũ bị ngắt kết nối đồng thời. Vì vậy, bạn đừng rải khóa này vào nhiều script hay cấu hình trên nhiều máy; hãy tập trung nó vào một nơi quản lý khóa duy nhất để khi thay đổi sẽ không bị sót.
Cuối cùng là giới hạn nội dung: các nội dung người lớn hợp pháp, tiểu thuyết hư cấu và các chủ đề gây tranh cãi sẽ không bị từ chối, nhưng nội dung liên quan đến tình dục của trẻ em sẽ bị chặn hoàn toàn và trả về mã 403, kể cả trong bối cảnh hư cấu hay nhập vai. Nếu ứng dụng của bạn hướng đến người dùng trưởng thành, bạn nên thêm bước xác nhận độ tuổi trong quy trình đăng ký của mình.
Cuối cùng, đây là thứ tự tự kiểm tra, bạn có thể dán nó bên cạnh màn hình: khóa có trong biến môi trường chưa; models có hoạt động không; request body có phải JSON hợp lệ không; model có phải uncensored không; max_tokens có đủ lớn không; finish_reason trong phản hồi là stop hay length; usage đã được ghi log chưa. Nếu cả bảy mục đều xanh, việc tích hợp của bạn được coi là hoàn tất.