NsfwAiApi/Hướng dẫn
API LLM NSFW trong Python: Truyền phát, JSON và Công cụ
Để sử dụng API LLM NSFW từ Python, bạn chỉ cần gói openai tiêu chuẩn và hai thay đổi: URL cơ sở và khóa. Hướng dẫn này hiển thị yêu cầu đầu tiên, truyền phát, chế độ JSON, gọi công cụ và xử lý giới hạn tốc độ sạch sẽ.

Cài đặt: cài đặt và thực hiện yêu cầu đầu tiên
Bạn cần Python 3 hiện tại, gói openai (pip install openai) và một khóa API. Tài khoản mới có thể nhận $0.50 dùng thử trên trang khóa API bằng một cú nhấp chuột sau khi đăng ký; nó không cần thông tin thanh toán. Lưu khóa vào biến môi trường, không phải trong mã nguồn.
Dịch vụ sử dụng giao thức hoàn thành trò chuyện OpenAI: POST /v1/chat/completions để tạo và GET /v1/models để danh sách mô hình. Xác thực là mã thông báo bearer, và model ID là uncensored. Đây là kịch bản hoạt động nhỏ nhất:
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.nsfwaiapi.com/v1",
api_key=os.environ["NSFWAIAPI_KEY"],
)
resp = client.chat.completions.create(
model="uncensored",
messages=[
{"role": "system", "content": "You are a fiction co-writer for adult readers. Write vivid, non-explicit scenes."},
{"role": "user", "content": "Open a noir story in a rainy harbor town, three sentences."},
],
temperature=0.8,
)
print(resp.choices[0].message.content)
print(resp.usage)
Nếu bạn muốn kiểm tra kết nối từ shell trước, cùng yêu cầu đó hoạt động với curl:
curl https://api.nsfwaiapi.com/v1/chat/completions \
-H "Authorization: Bearer $NSFWAIAPI_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "uncensored", "messages": [{"role": "user", "content": "Say hello in five words."}]}'
Mô hình được tinh chỉnh để trả lời mà không từ chối nội dung cho mục đích sử dụng người lớn hợp pháp. Điều đó ảnh hưởng đến giọng văn của những gì nó sẽ viết, không phải hình dạng của API, vì vậy phần còn lại trong mã của bạn trông giống như bất kỳ tích hợp OpenAI nào khác. Giữ các prompt cho truyện, trò chuyện nhân vật và các dự án người lớn hợp pháp khác, và giữ mọi nhân vật là người trưởng thành.
Một số thói quen giúp ích từ ngày đầu tiên. Đặt các hướng dẫn không bao giờ thay đổi trong thông báo hệ thống, và giữ thông báo người dùng cho phần thay đổi mỗi lượt. Chọn một temperature cho một nhiệm vụ và để nó yên trong khi bạn so sánh các prompt, vì thay đổi hai thứ cùng lúc không dạy bạn điều gì. Ghi lại ID yêu cầu và số lượng token từ resp.usage bên cạnh mỗi lệnh gọi, để khi hóa đơn hoặc đầu ra làm bạn ngạc nhiên, có hồ sơ để kiểm tra.
Phản hồi truyền phát với SSE
Đặt stream=True và máy chủ gửi các token dưới dạng SSE. Đối với các ứng dụng trò chuyện, điều này rất quan trọng, vì người đọc thấy những từ đầu tiên nhanh chóng thay vì chờ phản hồi đầy đủ. Tổng mức sử dụng đến vào cuối luồng truyền phát, vì một yêu cầu truyền phát vẫn có thể được tính phí và ghi lại chính xác.
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.nsfwaiapi.com/v1",
api_key=os.environ["NSFWAIAPI_KEY"],
)
stream = client.chat.completions.create(
model="uncensored",
messages=[{"role": "user", "content": "Write a short scene: two rival smugglers share a lantern during a storm."}],
stream=True,
)
text = ""
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
piece = chunk.choices[0].delta.content
text += piece
print(piece, end="", flush=True)
usage = getattr(chunk, "usage", None)
if usage:
print("\n[usage]", usage)
Hai chi tiết tiết kiệm thời gian gỡ lỗi. Đầu tiên, phần cuối cùng có thể có danh sách choices trống, đó là lý do tại sao vòng lặp kiểm tra nó trước khi lập chỉ mục. Thứ hai, một yêu cầu truyền phát giữ slot yêu cầu đồng thời của nó cho đến khi luồng kết thúc, vì vậy nếu mã của bạn bỏ qua một luồng mà không đóng nó, slot đó vẫn bận. Sử dụng with client.chat.completions.create(..., stream=True) as stream: hoặc gọi stream.close() khi bạn ngừng đọc sớm.
Chế độ JSON cho đầu ra có cấu trúc
Khi chương trình của bạn cần dữ liệu và không phải văn xuôi, chẳng hạn như hồ sơ nhân vật, danh sách các điểm nhấn cảnh hoặc thẻ cho một câu chuyện, hãy sử dụng chế độ JSON với response_format={"type": "json_object"}. Cũng hãy nói "JSON" trong prompt và mô tả các khóa bạn muốn. Cài đặt yêu cầu một đối tượng JSON, nhưng nó không thể đảm bảo rằng các khóa của bạn có mặt, vì vậy hãy kiểm tra chúng.
import json
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.nsfwaiapi.com/v1",
api_key=os.environ["NSFWAIAPI_KEY"],
)
resp = client.chat.completions.create(
model="uncensored",
response_format={"type": "json_object"},
messages=[
{"role": "system", "content": "Reply with a JSON object with keys: name, age, goal, secret. All characters are adults."},
{"role": "user", "content": "Create a ship's cook for a pirate adventure."},
],
temperature=0.7,
)
sheet = json.loads(resp.choices[0].message.content)
missing = [k for k in ("name", "age", "goal", "secret") if k not in sheet]
if missing:
raise ValueError(f"model skipped keys: {missing}")
print(sheet["name"], "-", sheet["goal"])
Nếu một câu trả lời dài bị cắt bởi max_tokens, JSON sẽ không đầy đủ và json.loads sẽ thất bại. Để max_tokens chưa đặt, vì nó là tùy chọn và phần hoàn thành có thể sử dụng phần còn lại của cửa sổ, hoặc đặt nó một cách hào phóng.
Gọi hàm
Gọi hàm cho phép mô hình yêu cầu mã của bạn làm điều gì đó, như tung xúc xắc, lookup ghi chú nhân vật hoặc lấy giá. Bạn truyền tools và, nếu bạn muốn, tool_choice. Phản hồi chứa tool_calls; bạn chạy chúng và gửi kết quả lại dưới dạng thông báo với role: "tool". Các phản hồi truyền phát mang tool_calls trong các delta.
import json
import os
import random
from openai import OpenAI
client = OpenAI(
base_url="https://api.nsfwaiapi.com/v1",
api_key=os.environ["NSFWAIAPI_KEY"],
)
tools = [{
"type": "function",
"function": {
"name": "roll_die",
"description": "Roll one die with the given number of sides",
"parameters": {
"type": "object",
"properties": {"sides": {"type": "integer", "minimum": 2}},
"required": ["sides"],
},
},
}]
messages = [
{"role": "system", "content": "You run a tabletop fiction game. Use roll_die for any chance-based outcome."},
{"role": "user", "content": "I try to pick the lock on the captain's cabin. Roll a d20."},
]
first = client.chat.completions.create(
model="uncensored", messages=messages, tools=tools, tool_choice="auto"
)
msg = first.choices[0].message
if msg.tool_calls:
messages.append(msg)
for call in msg.tool_calls:
args = json.loads(call.function.arguments)
result = random.randint(1, args["sides"])
messages.append({"role": "tool", "tool_call_id": call.id, "content": str(result)})
final = client.chat.completions.create(
model="uncensored", messages=messages, tools=tools
)
print(final.choices[0].message.content)
else:
print(msg.content)
Hãy coi các đối số là dữ liệu đầu vào không đáng tin cậy. Hãy xác thực chúng trước khi thực hiện hành động, giống như cách bạn làm với một biểu mẫu web. Mô hình đôi khi gửi thiếu trường hoặc sai kiểu, và một lớp bảo vệ nhỏ xung quanh json.loads giúp ngăn một lệnh gọi sai làm kết thúc phiên của bạn.
Giới hạn tốc độ, thử lại và số dư của bạn
Giới hạn bảo vệ dịch vụ và mang lại cho bạn hành vi dự đoán được. Khóa đầy đủ cho phép 8 yêu cầu đồng thời và 300 yêu cầu mỗi phút. Khóa dùng thử cho phép 2 và 60. Kích thước body tối đa là 8 MB. Hai loại lỗi giới hạn trả về dưới dạng HTTP 429: mã rate_limited có nghĩa là quá nhiều yêu cầu mỗi phút, và concurrency có nghĩa là quá nhiều cùng lúc. Quá tải tạm thời cũng trả về 429, với tiêu đề Retry-After: 5.
SDK của OpenAI tự động thử lại một số lỗi. Để kiểm soát, hãy tắt tính năng đó và viết một vòng lặp nhỏ tuân thủ Retry-After:
import os
import time
from openai import OpenAI, RateLimitError
client = OpenAI(
base_url="https://api.nsfwaiapi.com/v1",
api_key=os.environ["NSFWAIAPI_KEY"],
max_retries=0,
)
def ask(messages, tries=5):
for attempt in range(tries):
try:
raw = client.chat.completions.with_raw_response.create(
model="uncensored", messages=messages
)
print("balance:", raw.headers.get("X-Balance-USD"), "request id:", raw.headers.get("X-Request-Id"))
return raw.parse()
except RateLimitError as err:
wait = float(err.response.headers.get("Retry-After", 2 ** attempt))
time.sleep(wait)
raise RuntimeError("still rate limited after retries")
reply = ask([{"role": "user", "content": "Describe a market at dawn in two sentences."}])
print(reply.choices[0].message.content)
Mọi phản hồi đều mang X-Request-Id, đó là những gì bạn trích dẫn nếu liên hệ hỗ trợ, và X-Balance-USD, hiển thị tín dụng còn lại của bạn. Các tiêu đề X-RateLimit-Limit-Requests và X-RateLimit-Limit-Concurrency cho bạn biết giới hạn nào áp dụng cho khóa của bạn. Để chạy nhiều công việc cùng lúc, hãy giới hạn độ đồng thời trong mã của bạn bằng một semaphore có kích thước bằng khóa của bạn, 8 cho khóa đầy đủ và 2 cho khóa dùng thử, để bạn hiếm khi thấy 429.
Chạy nhiều yêu cầu song song
Các công việc theo lô, chẳng hạn như tạo thẻ cho vài trăm mảnh truyện, là nơi các giới hạn độ đồng thời quan trọng. Khóa đầy đủ chấp nhận 8 yêu cầu cùng lúc, vì vậy hãy chạy công việc thông qua máy khách không đồng bộ và semaphore có kích thước đó. Nếu bạn đang dùng khóa dùng thử, hãy sử dụng 2.
import asyncio
import os
from openai import AsyncOpenAI
client = AsyncOpenAI(
base_url="https://api.nsfwaiapi.com/v1",
api_key=os.environ["NSFWAIAPI_KEY"],
)
gate = asyncio.Semaphore(8)
async def summarize(fragment):
async with gate:
resp = await client.chat.completions.create(
model="uncensored",
messages=[
{"role": "system", "content": "Summarize the passage in one sentence."},
{"role": "user", "content": fragment},
],
temperature=0.3,
)
return resp.choices[0].message.content
async def main(fragments):
return await asyncio.gather(*(summarize(f) for f in fragments))
results = asyncio.run(main(["The tide came in early.", "Marta hid the ledger under the floor."]))
print(results)
Semaphore là toàn bộ bí quyết. Không có nó, một danh sách 200 mảnh sẽ kích hoạt 200 yêu cầu cùng lúc, và hầu hết trong số đó sẽ trả về lỗi 429 với mã concurrency. Với nó, công việc diễn ra ở tốc độ mà khóa của bạn cho phép và không có gì bị lãng phí. Nếu bạn cũng đặt ngân sách theo phút, 300 yêu cầu mỗi phút trên một khóa đầy đủ tương đương năm yêu cầu mỗi giây, vì vậy các yêu cầu rất ngắn có thể chạm giới hạn phút trước khi chạm giới hạn đồng thời.
Các vấn đề phổ biến và cách khắc phục
- Lỗi 401 hoặc xác thực. Khóa bị thiếu, bị cắt hoặc được gửi đến máy chủ sai. In
client.base_urlvà kiểm tra biến môi trường. Tiêu đề phải đọcAuthorization: Bearertheo sau là khóa của bạn. - Không tìm thấy mô hình. Model ID duy nhất là
uncensored. Một ví dụ sao chép nói tên khác sẽ thất bại, vì vậy hãy gọiGET /v1/modelsnếu bạn không chắc chắn. - Phản hồi trống hoặc ngắn trong vòng lặp truyện. Kiểm tra xem bạn có thêm phản hồi trợ lý vào danh sách thông báo trước lượt tiếp theo không. Không có nó, mô hình chỉ thấy thông báo cuối cùng của bạn.
- Phản hồi lặp lại chính mình. Tăng
frequency_penaltymột chút, ví dụ đến 0.3, hoặc giảmtemperaturenếu văn bản trôi. Các hình phạt,top_p,stopvàseedđều được chuyển qua. - Đầu ra khác nhau trên mỗi lần chạy. Đặt
seedvà mộttemperaturethấp khi bạn cần kết quả có thể lặp lại nhất có thể trong khi bạn gỡ lỗi. - Yêu cầu quá lớn. Giới hạn body là 8 MB, và prompt cộng với phần hoàn thành phải vừa trong 100.000 token. Cắt ngắn hoặc tóm tắt ngữ cảnh cũ trước khi nó đạt đến giới hạn nào.
Khi có lỗi từ phía máy chủ, hãy lưu tiêu đề X-Request-Id trong phản hồi và gửi nó cho bộ phận liên hệ trên trang hỗ trợ kèm mô tả ngắn. Điều này giúp nhân viên hỗ trợ xác định chính xác yêu cầu của bạn.
Chi phí và những gì nó không thể làm
Giá là $0.15 cho mỗi 1 triệu token đầu vào và $0.50 cho mỗi 1 triệu token đầu ra, trừ từ tín dụng trả trước, không có gói đăng ký. Các yêu cầu thất bại hoặc bị từ chối không bị tính phí, và tín dụng không bao giờ hết hạn. Ví dụ: một script gửi 3,000 token và nhận 800 token sẽ tốn $0.00045 cho đầu vào cộng $0.0004 cho đầu ra, tức $0.00085 cho mỗi lần gọi, nên 1,000 lần gọi tốn $0.85. Nạp tiền từ $20 đến $500, với các khoản thưởng +5% từ $50, +10% từ $100 và +15% từ $200. Trang web này chỉ chấp nhận tiền mã hóa, cụ thể là USDT trên mạng TRC20 hoặc USDC trên Base. Xem trang giá cả để có bảng đầy đủ, và trang tài liệu để tham khảo endpoint.
Các ranh giới rõ ràng. Đây là một mô hình trọng số mở duy nhất, được chạy bởi nhà cung cấp độc lập, và không phải là API chính thức của bất kỳ nhà cung cấp mô hình nào. Cửa sổ ngữ cảnh là 100,000 token cho prompt cộng với phần hoàn thành. Nó không tạo hình ảnh, âm thanh hoặc video, không cung cấp embedding và không hỗ trợ tinh chỉnh. Sử dụng nó chỉ cho mục đích người lớn hợp pháp, và lưu ý giới hạn cứng: không có nội dung tình dục liên quan đến người chưa thành niên. Các prompt không được sử dụng để huấn luyện.
Hướng dẫn khác
Hỏi đáp
Tôi có cần SDK đặc biệt để gọi API này từ Python không?
Không. Gói openai chính thức hoạt động. Đặt base_url thành https://api.nsfwaiapi.com/v1, truyền khóa của bạn và sử dụng model ID uncensored.
Truyền phát có hoạt động giống như với OpenAI không?
Có. Truyền stream=True và đọc các sự kiện gửi từ máy chủ từng phần một. Việc sử dụng được báo cáo ở cuối luồng truyền phát.
Tôi nên làm gì khi gặp lỗi 429?
Chờ và thử lại. Nếu phản hồi có tiêu đề Retry-After, hãy tuân thủ nó. Mã lỗi rate_limited có nghĩa là quá nhiều yêu cầu mỗi phút, và concurrency có nghĩa là quá nhiều yêu cầu cùng lúc.
Tôi có thể thử nó mà không cần trả tiền không?
Có. Sau khi đăng ký, bạn có thể nhận $0.50 tín dụng dùng thử trên trang khóa API. Nó không cần thông tin thanh toán, có hiệu lực trong 7 ngày và giới hạn một lần cho mỗi người.
Khóa của bạn chỉ cách một bước
Tạo tài khoản, sao chép khóa, thay đổi URL cơ sở. Đó là toàn bộ thiết lập.
Lấy khóa APINsfwAiApiAPI LLM không kiểm duyệt cho việc tạo văn bản NSFW