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

बिना सेंसर API त्रुटि कोड और डीबगिंग गाइड

त्रुटियाँ डरावनी नहीं हैं, डरावनी यह है कि आपको पता न हो कि रिट्राई करना है या कोड बदलना है। यह गाइड स्टेटस कोड के आधार पर प्रत्येक त्रुटि को तोड़ती है: ट्रिगर, निर्णय आधार और समाधान। त्रुटि बॉडी हमेशा JSON होती है, जैसे error ऑब्जेक्ट में code और message। इसलिए डीबगिंग का पहला कदम हमेशा बॉडी पढ़ना है, न कि केवल स्टेटस कोड देखना। बाद में एक्सपोनेंशियल बैकऑफ़ रिट्राई कोड, क्लाइंट-साइड रेट लिमिटिंग कोड और एक चेकलिस्ट दी गई है।

अपडेट किया गया:

मुख्य बिंदु

  • केवल 429 और 503 को ऑटोमैटिक रिट्राई करने का मूल्य है; अन्य स्टेटस कोड पर रिट्राई करने से अनुरोध बर्बाद होंगे।
  • 402 no_credit का अर्थ है बैलेंस खत्म या ट्रायल समाप्त, 403 content_blocked का अर्थ है कंटेंट ब्लॉक। ये दोनों नेटवर्क समस्याएँ नहीं हैं।
  • रिट्राई में एक्सपोनेंशियल बैकऑफ़ और रैंडम ज़िटर होना चाहिए, और अधिकतम बार संख्या निर्धारित करें।
  • प्रति कुंजी प्रति मिनट 300 अनुरोध; बैच टास्क के लिए क्लाइंट-साइड रेट लिमिटिंग आवश्यक है।

त्रुटि बॉडी फॉर्मेट और पढ़ने का क्रम

सभी विफल प्रतिक्रियाएँ एक ही संरचना का पालन करती हैं:

{"error":{"code":"...","message":"..."}}

पढ़ने का क्रम तीन निश्चित चरणों में है:

  1. HTTP स्टेटस कोड, जो श्रेणी निर्धारित करता है;
  2. error.code विशिष्ट कारण निर्धारित करता है; प्रोग्राम में इसे शाखा (branch) के लिए उपयोग करें;
  3. error.message, इंसानों के लिए; लॉग में लिखें, लेकिन स्ट्रिंग मैचिंग के लिए उपयोग न करें।

सबसे पहले एक सीमा स्पष्ट करें: पुनः प्रयास से हल होने वाले (429, 503, और नेटवर्क टाइमआउट) और संशोधन से हल होने वाले (शेष)। दोनों को मिला देना ऑनलाइन दुर्घटनाओं का सबसे आम कारण है, जैसे 402 के लिए लगातार पुनः प्रयास करना, जिससे प्रति सेकंड कई अमान्य अनुरोध भेजे जाते हैं।

लॉग में चार फ़ील्ड्स स्थिर रूप से रिकॉर्ड करने की सलाह दी जाती है: समय, स्थिति कोड, error.code, और इस अनुरोध के लिए प्रॉम्प्ट टोकन का अनुमान। समस्या आने पर, यह तुरंत पता चलता है कि क्या किसी एक प्रकार की त्रुटि अचानक बढ़ी है या समग्र विफलता हुई है। एक अलर्ट नियम जोड़ें: 402 एक बार आते ही तुरंत सूचित करें, क्योंकि इसका मतलब है कि सेवा उपयोगकर्ताओं के लिए अनुपलब्ध है; 429 के लिए अनुपात देखें, यदि यह कभी-कभी आता है तो उसे नज़रअंदाज़ करें, यदि लगातार आता है तो इसका मतलब है कि समानांतरता डिज़ाइन में समस्या है।

स्टेटस कोड त्वरित संदर्भ

स्टेटस कोडerror.codeअर्थरिट्राई?
400—अमान्य अनुरोध, जैसे prompt + max_tokens > 100kनहीं
401—अमान्य या अनुपलब्ध कुंजीनहीं
402no_creditबैलेंस खत्म या ट्रायल समाप्तनहीं
403content_blockedकंटेंट अवरोधितनहीं
404—एंडपॉइंट मौजूद नहींनहीं
429—रेट लिमिट सक्रियहाँ, बैकऑफ़
503upstream_busyसेवा अस्थायी रूप से व्यस्तहाँ, कुछ सेकंड बाद

तालिका में '—' का अर्थ है कि कोई विशेष fixed code स्ट्रिंग नहीं है; स्टेटस कोड के आधार पर शाखा बनाएं।

4xx: अनुरोध संशोधित करें, पुनः प्रयास न करें

400 अमान्य अनुरोध

  • कारण 1: JSON फॉर्मेट त्रुटि, अक्सर स्ट्रिंग मैन्युअल लिखते समय क्वोट्स को एस्केप न करने के कारण।
  • कारण 2: प्रॉम्प्ट और max_tokens का योग 100,000 से अधिक हो जाता है। लंबी चैट में यह सबसे आम है।
  • कारण 3: अनुरोध बॉडी > 8 MB।
  • संशोधन: JSON लाइब्रेरी का उपयोग करके serialize करें; भेजने से पहले टोकन का अनुमान लगाएं, यदि सीमा पार हो जाए तो इतिहास काटें या max_tokens कम करें; लंबे कॉन्टेक्स्ट के लिए व्यावहारिक गाइड देखें।

401 कुंजी समस्या

  • हेडर गायब है, या Bearer प्रिफिक्स गायब है।
  • कुंजी (key) को पुनर्जनित किया गया है, पुरानी कुंजी तुरंत अमान्य हो जाती है, लेकिन कुछ मशीनें अभी भी पुरानी कुंजी का उपयोग कर रही हैं।
  • एनवायरनमेंट वेरिएबल्स कंटेनर या टास्क में नहीं पहुँचे।

402 no_credit

क्रैडिट खत्म या 7 दिन का ट्रायल समाप्त।खाता पृष्ठ पर जाकर प्रीपेड क्रेडिट टॉप-अप करें। बैलेंस मॉनिटर करें ताकि यूज़र से पहले पता चल जाए।

403 content_blocked

सामग्री ब्लॉक हो गई। वयस्क-अनुमत सामग्री, काल्पनिक और विवादास्पद विषयों को अस्वीकार नहीं किया जाता, लेकिन अल्पवयकों से संबंधित यौन सामग्री को पूरी तरह से ब्लॉक किया जाता है, जिसमें उपन्यास और भूमिका निभाना भी शामिल है। यदि 403 त्रुटि मिले, तो इनपुट और इतिहास में ऐसी सामग्री तो नहीं है, यह जांचें, शब्द बदलकर दोबारा प्रयास करने के बजाय।

404 एंडपॉइंट नहीं मिला

केवल दो एंडपॉइंट हैं: POST /v1/chat/completions और GET /v1/models। पाथ में /v1 छूट गया हो, अतिरिक्त स्लैश हो, या गलत वर्तनी हो, या एम्बेडिंग्स, इमेज आदि जैसे असमर्थित इंटरफ़ेस को कॉल किया गया हो, तो 404 मिलता है।

400 त्रुटि में एक और भ्रामक स्थिति है: लंबी बातचीत में टोकन की संख्या चरणों के साथ रैखिक रूप से बढ़ती है। दिन में परीक्षण सामान्य रहता है, लेकिन कई चरणों के बाद अचानक 400 त्रुटि आने लगती है। यह इंटरफ़ेस की अस्थिरता नहीं है, बल्कि कॉन्टेक्स्ट विंडो भर गई है। समाधान यह है कि इतिहास की लंबाई पर सीमा लगाएं और थ्रेशोल्ड पार होने पर सबसे पुराने चरण हटा दें, या पुरानी सामग्री को सारांश में बदल दें। त्रुटि आने का इंतज़ार न करें, अनुरोध भेजने से पहले ही अनुमान लगा लें।

401 की जाँच का एक टिप: कुंजी (key) के पहले और आखिरी चार अंक लॉग में प्रिंट करें, पूरा कंटेंट नहीं, और खाता पृष्ठ पर दिखाए गए से तुलना करें। इससे यह पुष्टि होती है कि प्रोग्राम में पढ़ी गई कुंजी वही है या नहीं, खासकर कंटेनर और टास्क एनवायरनमेंट में, जहाँ एनवायरनमेंट वेरिएबल्स की कमी या पुरानी कुंजी पढ़ना सबसे आम कारण है।

429 और 503: पुनः प्रयास करने योग्य दो स्थितियाँ

429 रेट लिमिट

प्रति कुंजी प्रति मिनट 300 अनुरोध। बैच टास्क, कई इंस्टेंस एक ही कुंजी साझा करना, या पुनः प्रयास का तूफ़ान, इसे ट्रिगर कर सकता है। संशोधन के दो स्तर हैं: पहले क्लाइंट-साइड रेट लिमिट (नीचे कोड देखें), फिर 429 के लिए बैकऑफ़ पुनः प्रयास।

503 upstream_busy

सर्विस अस्थायी रूप से व्यस्त है। कुछ सेकंड बाद रीट्राई करें। तुरंत लगातार रिक्वेस्ट न भेजें, और एक सेकंड में दस बार रीट्राई न करें, इससे स्थिति और खराब होगी।

नेटवर्क टाइमआउट

लंबे टेक्स्ट जनरेशन में समय लगता है, इसलिए टाइमआउट बहुत कम न सेट करें, उदाहरण में 120 सेकंड का उपयोग किया गया है। टाइमआउट के बाद पुनः प्रयास करते समय ध्यान दें: पिछला अनुरोध सर्वर पर निष्पादित हो चुका हो सकता है, दोहरा कॉल करने से क्रेडिट दो बार खर्च हो सकता है, इसलिए जनरेशन अनुरोधों के लिए पुनः प्रयास की संख्या कम रखें, बेहतर होगा कि स्ट्रीमिंग आउटपुट के साथ एकल प्रतीक्षा समय कम करें।

import os
import random
import time
import requests

URL = "https://api.wushenchaapi.com/v1/chat/completions"
HEADERS = {
    "Authorization": "Bearer " + os.environ["API_KEY"],
    "Content-Type": "application/json",
}
RETRYABLE = {429, 503}          # 只重试这两类
FATAL = {400, 401, 402, 403, 404}

class ApiError(Exception):
    def __init__(self, status, code, message):
        super().__init__(f"{status} {code}: {message}")
        self.status, self.code = status, code

def call(payload, max_retries=5, base=1.0, cap=30.0):
    for attempt in range(max_retries + 1):
        try:
            r = requests.post(URL, headers=HEADERS, json=payload, timeout=120)
        except (requests.ConnectionError, requests.Timeout):
            r = None                      # 网络层失败,按可重试处理
        if r is not None and r.ok:
            return r.json()
        if r is not None:
            try:
                err = r.json().get("error", {})
            except ValueError:
                err = {}
            if r.status_code in FATAL or r.status_code not in RETRYABLE:
                raise ApiError(r.status_code, err.get("code"), err.get("message"))
        if attempt == max_retries:
            raise ApiError(r.status_code if r is not None else 0, "retry_exhausted", "重试次数用尽")
        delay = min(cap, base * (2 ** attempt)) * random.uniform(0.5, 1.0)
        time.sleep(delay)

if __name__ == "__main__":
    out = call({"model": "uncensored", "max_tokens": 100,
                "messages": [{"role": "user", "content": "回复一个字:好"}]})
    print(out["choices"][0]["message"]["content"])

मुख्य बात: रिकॉवरी सूत्र min(cap, base × 2^n) × गुणांक है; यादृच्छिक गुणांक यह सुनिश्चित करता है कि कई क्लाइंट एक साथ रिकॉवर न करें; FATAL सेट में दिए गए स्टेटस कोड के लिए एक भी बार रिकॉवर नहीं किया जाता।

क्लाइंट रेट लिमिट और डायग्नोस्टिक रिक्वेस्ट

429 आने का इंतज़ार करने के बजाय, पहले रेट लिमिट लगाएं। नीचे दिया गया टूल यह सुनिश्चित करता है कि रिक्वेस्ट की संख्या प्रति मिनट निर्धारित वैल्यू से कम रहे, और यह मल्टी-थ्रेड सेफ़ है:

import threading
import time

class RateGate:
    """简单的客户端限速:保证一分钟内请求数不超过 limit。"""
    def __init__(self, limit=240):          # 留出余量,低于 300/分钟
        self.limit, self.stamps, self.lock = limit, [], threading.Lock()

    def wait(self):
        while True:
            with self.lock:
                now = time.time()
                self.stamps = [t for t in self.stamps if now - t < 60]
                if len(self.stamps) < self.limit:
                    self.stamps.append(now)
                    return
                sleep_for = 60 - (now - self.stamps[0])
            time.sleep(max(sleep_for, 0.05))

डीबगिंग के दौरान, सबसे साफ़ तरीका यह है कि बिज़नेस कोड से बाहर निकलकर, curl से एक न्यूनतम अनुरोध भेजें, -i से स्थिति लाइन और रिस्पॉन्स हेडर दोनों दिखाई देते हैं:

curl -i https://api.wushenchaapi.com/v1/chat/completions \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"uncensored","max_tokens":20,"messages":[{"role":"user","content":"ping"}]}'

curl काम करता है लेकिन बिज़नेस कोड नहीं, इसका मतलब है समस्या आपके कोड या एनवायरनमेंट (प्रॉक्सी, एनवायरनमेंट वेरिएबल्स, एन्कोडिंग) में है; curl भी काम नहीं करता, तो कुंजी, बैलेंस और नेटवर्क देखें।

रेट लिमिट 300 की जगह 240 क्यों सेट करें: मल्टी-इंस्टेंस डिप्लॉयमेंट में, प्रत्येक इंस्टेंस अपना रेट लिमिट सेट करता है, लेकिन उनका योग कुल सीमा से अधिक हो सकता है; इसके अलावा रिकॉवररी से अतिरिक्त क्वोटा खर्च होता है। 20% सुरक्षा मार्जिन छोड़ना अधिक सुरक्षित है। यदि आपके पास कई इंस्टेंस हैं, तो प्रत्येक इंस्टेंस के लिए क्वोटा को कुल संख्या से समान रूप से बांटें, या एक साझा काउंटर से समानांतर अनुरोधों को एकत्रित रूप से प्रबंधित करें।

डिबगिंग चेकलिस्ट

  1. बॉडी में error.code पढ़ें, केवल स्टेटस कोड पर भरोसा न करें।
  2. 401: key प्रिफ़िक्स, एनवायरनमेंट वेरिएबल्स, और क्या key रीजेनरेट की गई है।
  3. 400: क्या JSON वैध है, prompt + max_tokens 100,000 टोकन से अधिक तो नहीं, और रिक्वेस्ट बॉडी 8 MB से अधिक तो नहीं।
  4. 402: बैलेंस और ट्रायल वैलिडिटी।
  5. 403: इनपुट और हिस्ट्री में ब्लॉक्ड कंटेंट तो नहीं है।
  6. 404: क्या पथ /v1/chat/completions या /v1/models है।
  7. 429: क्या मल्टी-इंस्टेंस एक key शेयर कर रहे हैं, और क्लाइंट साइड रेट लिमिट लगाया गया है या नहीं।
  8. 503: क्या बैकऑफ़ पुनः प्रयास किया गया है, और अंतराल कम से कम कुछ सेकंड है या नहीं।
  9. टाइमआउट: क्या टाइमआउट पर्याप्त है, और क्या स्ट्रीमिंग पर स्विच किया जा सकता है।
  10. यदि ऊपर सब ठीक है: curl से न्यूनतम रिक्वेस्ट भेजकर समस्या को रीप्रोड्यूस करें।

नई एकीकरण के लिएइंटीग्रेशन ट्यूटोरियल देखें। अन्य पैरामीटरदस्तावेज़ में हैं।

चेकलिस्ट का उपयोग: समस्या आने पर ऊपर से नीचे तक क्रम से जांचें, बीच में न छलांग लगाएं। अधिकांश 'अजीब' समस्याएं पहले चार बिंदुओं में ही मिल जाती हैं।

एक अतिरिक्त अनुभव: हर डिबगिंग निष्कर्ष को टीम डॉक्यूमेंटेशन में लिखें। अगली बार उसी एरर के लिए तुरंत समाधान मिल जाएगा।

अक्सर पूछे जाने वाले प्रश्न

503 मिलने के बाद रीट्राई के लिए कितना इंतज़ार करें?

कुछ सेकंड ही। पहली बार 1-2 सेकंड इंतज़ार करें, फिर एक्सपोनेंशियल बढ़ाएं और रैंडम ज़िटर जोड़ें। अधिकतम रीट्राई काउंट सेट करें।

मेरी रिक्वेस्ट्स लगातार 402 क्यों दे रही हैं?

बैलेंस समाप्त हो गया है, या 7 दिनों का ट्रायल समाप्त हो गया है। प्रीपेड क्रेडिट टॉप-अप करने पर सेवा फिर से शुरू हो जाएगी, और बैलेंस कभी एक्सपायर नहीं होता।

क्या 403 content_blocked को रिवाइटर करके ओवरराइड किया जा सकता है?

प्रयास न करें। अल्पवयकों से संबंधित यौन सामग्री किसी भी स्थिति में ब्लॉक हो जाएगी, जिसमें उपन्यास और भूमिका निभाना भी शामिल है। सामान्य वयस्क-अनुमत सामग्री इस त्रुटि को ट्रिगर नहीं करेगी।

क्या 429 अकाउंट के हिसाब से लगाया जाता है या key के हिसाब से?

लिमिट प्रति key प्रति मिनट 300 अनुरोध है। हर अकाउंट की केवल एक key होती है, इसलिए यदि कई सर्विसेज एक key शेयर कर रही हैं, तो उन्हें मिलकर रेट लिमिट का पालन करना होगा।

केवल फॉर्म भरें और API कुंजी प्राप्त करें

अकाउंट बनाएं, key कॉपी करें, Base URL बदलें। कॉन्फ़िगरेशन इतना ही आसान है।