HI ▾
API कुंजी पाएँ

NsfwAiApiगाइड

NSFW LLM API पायथन में: स्ट्रीमिंग, JSON और टूल्स

Python से NSFW LLM API का उपयोग करने के लिए, आपको केवल मानक openai पैकेज और दो बदलावों की आवश्यकता है: बेस URL और कुंजी। यह गाइड एक पहला अनुरोध, स्ट्रीमिंग, JSON मोड, टूल कॉलिंग और रेट लिमिट्स की स्वच्छ हैंडलिंग दिखाती है।

अपडेटेड

टोकन के चमकते हुए स्ट्रीम को प्रकाश की एक कुंडलित पट्टी से घिरा टर्मिनल विंडो

सेटअप: इंस्टॉल करें और पहला कॉल बनाएं

आपके पास वर्तमान Python 3, openai पैकेज (pip install openai) और एक API कुंजी होनी चाहिए। नए खातों में साइन-अप के बाद एक क्लिक से API कुंजी पृष्ठ पर $0.50 का मुफ़्त ट्रायल क्रेडिट क्लेम किया जा सकता है; इसके लिए भुगतान विवरण की आवश्यकता नहीं है। कुंजी को स्रोत कोड में नहीं, बल्कि एक पर्यावरण चर में संग्रहीत करें।

सर्विस OpenAI चैट पूर्णता प्रोटोकॉल का समर्थन करती है: जनरेशन के लिए POST /v1/chat/completions और मॉडल सूची के लिए GET /v1/models। प्रमाणीकरण एक bearer टोकन है, और मॉडल ID uncensored है। यह सबसे छोटा कार्यकारी स्क्रिप्ट है:

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)

यदि आप पहले शेल से कनेक्शन जांचना पसंद करते हैं, तो वही अनुरोध 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."}]}'

मॉडल को कानूनी वयस्कों के उपयोग के लिए बिना सेंसर उत्तर देने के लिए ट्यून्ड किया गया है। इससे लिखे गए पाठ के टोन पर प्रभाव पड़ता है, API के स्वरूप पर नहीं, इसलिए आपका बाकी कोड किसी अन्य OpenAI इंटीग्रेशन जैसा ही दिखता है। कथा, चैरेक्टर चैट और अन्य कानूनी वयस्क प्रोजेक्ट्स के लिए प्रॉम्प्ट रखें, और सुनिश्चित करें कि हर चरित्र वयस्क हो।

कुछ आदतें पहले दिन से मदद करती हैं। उन निर्देशों को सिस्टम संदेश में डालें जो कभी नहीं बदलते हैं, और उपयोगकर्ता संदेश को उस भाग के लिए रखें जो हर बारी में बदलता है। किसी कार्य के लिए एक तापमान चुनें और प्रॉम्प्ट की तुलना करते समय उसे अकेला छोड़ दें, क्योंकि एक साथ दो चीज़ें बदलने से आपको कुछ नहीं सिखाया जाता। प्रत्येक कॉल के बगल में resp.usage से टोकन गणना और अनुरोध ID लॉग करें, ताकि जब आपकी बिल या आउटपुट आपको हैरान करे, तो जाँच के लिए एक रिकॉर्ड मौजूद हो।

SSE के साथ स्ट्रीमिंग उत्तर

stream=True सेट करें और सर्वर टोकन को server-sent events के रूप में भेजता है। चैट ऐप्स के लिए यह बहुत मायने रखता है, क्योंकि रीडर पूरे जवाब की प्रतीक्षा करने के बजाय पहले शब्द जल्दी देखता है। उपयोग कुल स्ट्रीम के अंत में आते हैं, इसलिए एक स्ट्रीम किए गए अनुरोध को अभी भी सटीक रूप से बिल किया और लॉग किया जा सकता है।

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)

दो विवरण डीबगिंग का समय बचाते हैं। पहला, अंतिम चंक में एक खाली choices सूची हो सकती है, इसलिए लूप इंडेक्सिंग से पहले उसे जाँचता है। दूसरा, एक स्ट्रीम किए गए अनुरोध में उसकी समानांतरता स्लॉट स्ट्रीम समाप्त होने तक बनी रहती है, इसलिए यदि आपका कोड एक स्ट्रीम को बिना बंद किए छोड़ देता है, तो वह स्लॉट व्यस्त रहता है। with client.chat.completions.create(..., stream=True) as stream: का उपयोग करें या stream.close() कॉल करें जब आप जल्दी पढ़ना बंद कर दें।

संरचित आउटपुट के लिए JSON मोड

जब आपके प्रोग्राम को प्रॉज़ नहीं बल्कि डेटा चाहिए, जैसे कि एक कैरेक्टर शीट, कहानी के दृश्य बीट्स की सूची या टैग, तो JSON मोड का उपयोग करें response_format={"type": "json_object"} के साथ। प्रॉम्प्ट में "JSON" भी लिखें और उन कुंजियों का वर्णन करें जिन्हें आप चाहते हैं। सेटिंग एक JSON ऑब्जेक्ट मांगती है, लेकिन यह यह वादा नहीं कर सकती कि आपकी कुंजियाँ मौजूद हैं, इसलिए उन्हें जाँचें।

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

यदि लंबा उत्तर max_tokens द्वारा काट दिया जाता है, तो JSON अपूर्ण होगा और json.loads विफल हो जाएगा। max_tokens को अनसेट छोड़ दें, क्योंकि यह वैकल्पिक है और पूर्णता विंडो के शेष हिस्से का उपयोग कर सकती है, या इसे पर्याप्त रूप से सेट करें।

टूल कॉलिंग

टूल कॉलिंग मॉडल को आपके कोड से कुछ करने के लिए कहने देती है, जैसे पासा फेंकना, एक कैरेक्टर नोट खोजना या कीमत खोजना। आप tools पास करते हैं, और यदि आप चाहें, tool_choice। जवाब में tool_calls होता है; आप उन्हें चलाते हैं और role: "tool" के साथ संदेशों के रूप में परिणाम वापस भेजते हैं। स्ट्रीम किए गए प्रतिक्रियाओं में tool_calls डेल्टा में भी होते हैं।

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)

तर्कों को अविश्वसनीय इनपुट मानें। उन पर कार्य करने से पहले उन्हें वैलिडेट करें, बिल्कुल उसी तरह जैसे आप एक वेब फॉर्म के लिए करते। मॉडल कभी-कभी एक गायब फ़ील्ड या गलत प्रकार भेजते हैं, और json.loads के आसपास एक छोटा गार्ड एक खराब कॉल को आपकी सत्र समाप्त होने से रोकता है।

रेट लिमिट, रीट्राइज़ और आपका बैलेंस

सीमाएँ सेवा की रक्षा करती हैं और आपको भविष्यवाणी योग्य व्यवहार प्रदान करती हैं। एक पूर्ण कुंजी 8 समानांतर अनुरोध और प्रति मिनट 300 अनुरोधों की अनुमति देती है। एक ट्रायल कुंजी 2 और 60 की अनुमति देती है। अधिकतम बॉडी 8 MB है। सीमा त्रुटि के दो प्रकार HTTP 429 के रूप में लौटते हैं: कोड rate_limited का अर्थ है प्रति मिनट बहुत अधिक अनुरोध, और concurrency का अर्थ है एक साथ बहुत अधिक अनुरोध। एक अस्थायी ओवरलोड भी 429 लौटाता है, Retry-After: 5 हेडर के साथ।

OpenAI SDK डिफ़ॉल्ट रूप से कुछ त्रुटियों को रीट्राइ करता है। नियंत्रण के लिए, उसे बंद करें और एक छोटा लूप लिखें जो 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)

हर प्रतिक्रिया में X-Request-Id होता है, जिसे आप सहायता से संपर्क करते समय उद्धृत करते हैं, और X-Balance-USD, जो आपका शेष क्रेडिट दिखाता है। X-RateLimit-Limit-Requests और X-RateLimit-Limit-Concurrency हेडर आपको बताते हैं कि आपकी कुंजी के लिए कौन सी लिमिट लागू होती है। एक साथ कई जॉब चलाने के लिए, अपनी कुंजी की सीमाओं के अनुसार सेमाफोर के साथ अपने कोड में समानांतरता को कैप करें, एक पूर्ण कुंजी के लिए 8 और एक ट्रायल कुंजी के लिए 2, ताकि आप 429 बहुत कम देखें।

समानांतर अनुरोध चलाना

बैच जॉब, जैसे कि कुछ सौ कहानी टुकड़ों के लिए टैग जनरेट करना, वह जगह है जहां समानांतरता सीमाएँ मायने रखती हैं। एक पूर्ण कुंजी एक साथ 8 अनुरोध स्वीकार करती है, इसलिए काम को एक असिंक्रोनस क्लाइंट और उस आकार के एक सेमाफोर के माध्यम से चलाएं। यदि आप ट्रायल कुंजी पर हैं, तो 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)

सेमाफोर ही पूरी चाल है। इसके बिना, 200 टुकड़ों की सूची एक साथ 200 अनुरोध फायर करती है, और उनमें से अधिकांश कोड concurrency के साथ 429 त्रुटि के रूप में वापस आते हैं। इसके साथ, काम उस गति से बहता है जो आपकी कुंजी अनुमति देती है और कुछ भी बर्बाद नहीं होता। यदि आप प्रति मिनट बजट भी चलाते हैं, तो एक पूर्ण कुंजी पर प्रति मिनट 300 अनुरोध प्रति सेकंड पांच के बराबर होता है, इसलिए बहुत छोटे अनुरोध कन्करेंसी लिमिट से पहले मिनट लिमिट को हिट कर सकते हैं।

सामान्य समस्याएं और समाधान

  • 401 या प्रमाणीकरण त्रुटियाँ। कुंजी गायब है, ट्रंकेट है या गलत होस्ट पर भेजी गई है। client.base_url प्रिंट करें और पर्यावरण चर जाँचें। हेडर Authorization: Bearer के बाद आपकी कुंजी होनी चाहिए।
  • मॉडल नहीं मिला। एकमात्र मॉडल ID uncensored है। एक कॉपी किया गया उदाहरण जो एक अन्य नाम बताता है, विफल हो जाएगा, इसलिए यदि आप निश्चित नहीं हैं तो GET /v1/models कॉल करें।
  • कहानी लूप में खाली या छोटे उत्तर। सत्यापित करें कि आप अगले टर्न से पहले सहायक उत्तर को संदेश सूची में जोड़ रहे हैं। इसके बिना, मॉडल केवल आपका अंतिम संदेश देखता है।
  • जो जवाब दोहराते हैं। frequency_penalty को थोड़ा बढ़ाएँ, उदाहरण के लिए 0.3 तक, या यदि पाठ भटकता है तो temperature कम करें। पेनल्टी, top_p, stop और seed सभी पास किए जाते हैं।
  • हर रन पर अलग आउटपुट। seed और एक कम temperature सेट करें जब आपको डीबग करते समय परिणामों को जितना संभव हो उतना दोहराने योग्य चाहिए।
  • अनुरोध बहुत बड़ा है। बॉडी सीमा 8 MB है, और प्रॉम्प्ट और पूर्णता को 100,000 टोकन में फिट होना चाहिए। किसी भी सीमा से पहले पुराने कॉन्टेक्स्ट को काटें या सारांशित करें।

जब सर्वर साइड पर कुछ गलत लगता है, तो प्रतिक्रिया से X-Request-Id हेडर सेव करें और एक संक्षिप्त विवरण के साथ सहायता पृष्ठ संपर्क पर भेजें। यह ऑपरेटरों को आपका सटीक अनुरोध खोजने में मदद करता है।

इसकी लागत और इसकी सीमाएँ

मूल्य $0.15 प्रति 1M इनपुट टोकन और $0.50 प्रति 1M आउटपुट टोकन है, प्रीपेड क्रेडिट से, कोई सब्सक्रिप्शन नहीं। विफल या अस्वीकृत अनुरोधों के लिए चार्ज नहीं किया जाता, और क्रेडिट कभी एक्सपायर नहीं होता। एक उदाहरण के रूप में, एक स्क्रिप्ट जो 3,000 टोकन भेजती है और 800 प्राप्त करती है, उसे इनपुट के लिए $0.00045 और आउटपुट के लिए $0.0004 भुगतान करना पड़ता है, जो प्रति कॉल $0.00085 है, इसलिए 1,000 कॉल्स की लागत $0.85 है। टॉप-अप $20 से $500 तक होते हैं, $50 से +5% बोनस, $100 से +10% और $200 से +15% बोनस मिलता है। यह साइट केवल क्रिप्टो स्वीकार करती है, TRC20 पर USDT या Base पर USDC। पूरे टैबल के लिए मूल्य निर्धारण पृष्ठ देखें, और एंडपॉइंट रेफरेंस के लिए दस्तावेज़ीकरण देखें।

सीमाएँ स्पष्ट हैं। यह एक अकेला ओपन-वेट मॉडल है, जो एक स्वतंत्र प्रदाता द्वारा चलाया जाता है, और किसी मॉडल विक्रेता की आधिकारिक API नहीं है। कॉन्टेक्स्ट विंडो प्रॉम्प्ट और पूर्णता के लिए 100,000 टोकन है। यह छवियाँ, ऑडियो या वीडियो उत्पन्न नहीं करता है, एम्बेडिंग्स प्रदान नहीं करता है और फाइन-ट्यूनिंग का समर्थन नहीं करता है। इसे केवल कानूनी वयस्क उपयोग के लिए उपयोग करें, और कठोर सीमा पर ध्यान दें: नाबालिगों से संबंधित यौन सामग्री नहीं है। प्रॉम्प्ट को प्रशिक्षण के लिए उपयोग नहीं किया जाता है।

प्रश्न और उत्तर

क्या मुझे Python से इस API को कॉल करने के लिए एक विशेष SDK की आवश्यकता है?

नहीं। आधिकारिक openai पैकेज काम करता है। base_url को https://api.nsfwaiapi.com/v1 पर सेट करें, अपनी कुंजी पास करें और मॉडल ID uncensored का उपयोग करें।

क्या स्ट्रीमिंग, OpenAI की तरह ही काम करता है?

हाँ। stream=True पास करें और सर्वर-सेंट इवेंट्स को चंक-दर-चंक पढ़ें। उपयोग स्ट्रीम के अंत में रिपोर्ट किया जाता है।

जब मुझे 429 त्रुटि मिलती है तो मुझे क्या करना चाहिए?

प्रतीक्षा करें और पुनः प्रयास करें। यदि प्रतिक्रिया में Retry-After हेडर है, तो उसे मानें। rate_limited त्रुटि कोड का मतलब प्रति मिनट बहुत सारे अनुरोध हैं, और concurrency का मतलब एक साथ बहुत सारे अनुरोध हैं।

क्या मैं बिना भुगतान किए इसका परीक्षण कर सकता हूँ?

हाँ। साइन-अप के बाद आप API कुंजी पृष्ठ पर $0.50 का मुफ़्त ट्रायल क्रेडिट दावा कर सकते हैं। इसके लिए भुगतान विवरण की आवश्यकता नहीं है, यह 7 दिनों के लिए मान्य है और एक व्यक्ति के लिए एक बार ही है।

आपकी कुंजी बस एक फ़ॉर्म दूर है

एक खाता बनाएँ, कुंजी कॉपी करें, बेस URL बदलें। सेटअप यही है।

API कुंजी प्राप्त करें

NsfwAiApiNSFW टेक्स्ट जनरेशन के लिए बिना सेंसर LLM API