ब्लॉग पर वापस जाएं

समस्या निवारणगाइड

AI का जवाब कट गया? finish_reason "length" और max_tokens ठीक करें

आपका API जवाब वाक्य के बीच में रुक जाता है या टूटा JSON लौटाता है? finish_reason जाँचें, सीमा के भीतर max_tokens बढ़ाएँ और continue चरण जोड़ें।

CheapTokens Team द्वाराप्रकाशित 9 मिनट का पाठ

API रिस्पॉन्स में finish_reason length दिखाता टर्मिनल-शैली कवर
इस पृष्ठ पर
  1. कटा हुआ जवाब स्क्रीन पर कैसा दिखता है
  2. चरण 1: वह फ़ील्ड पढ़ें जो आपको बताती है
  3. चरण 2: max_tokens बढ़ाएँ, लेकिन सीमा से आगे नहीं
  4. चरण 3: JSON जो आधे में रुक जाता है
  5. चरण 4: मॉडल को जारी रखने दें
  6. लंबे जवाब का खर्च
  7. शिप करने से पहले: एक छोटी चेकलिस्ट

आपकी स्क्रिप्ट चली, मॉडल ने जवाब दिया, और फ़ंक्शन एक लाइन के बीच में खत्म हो गया। या JSON पार्सर एक बिल्कुल सामान्य दिखने वाले जवाब पर एरर फेंक रहा है। ज़्यादातर मामलों में मॉडल फेल नहीं हुआ: उसने आपकी सेट की हुई max_tokens सीमा (या कोई डिफ़ॉल्ट जो आपने देखा ही नहीं) पार कर ली और API ने उसे शब्द के बीच में रोक दिया।

तुरंत समाधान: रिस्पॉन्स में finish_reason पढ़ें। अगर वह "length" है (OpenAI-संगत API) या stop_reason का मान "max_tokens" है (Anthropic Messages), तो जवाब कट गया। max_tokens को मॉडल की आउटपुट सीमा तक बढ़ाएँ, या मॉडल से जारी रखने को कहें। इस पेज का बाकी हिस्सा दोनों को ऐसे कोड में दिखाता है जिसे आप सीधे पेस्ट कर सकते हैं।

अगर आप सरल भाषा में जानना चाहते हैं कि ऐसा क्यों होता है, तो AI का जवाब वाक्य के बीच में क्यों रुकता है से शुरू करें। यह पेज डिबगिंग वाला संस्करण है।

कटा हुआ जवाब स्क्रीन पर कैसा दिखता है#

लक्षण इस बात पर अलग होते हैं कि आपने क्या माँगा था, लेकिन कारण एक ही है। इन्हें अपने देखे हुए लक्षणों से मिलाने की कोशिश करें:

जोड़े मिलाएँ

लक्षण को उसके संभावित कारण से मिलाएँ

  • एक फ़ंक्शन return resu पर खत्म होता हैकोड वाला जवाब लाइन के बीच में max_tokens पर पहुँच गया
  • json.loads "Unterminated string" या "Expecting ',' delimiter" के साथ फेल होता हैJSON बीच में कट गया
  • अनुवाद टेक्स्ट के पहले आधे हिस्से के बाद रुक जाता हैआउटपुट सीमा अनुवाद से छोटी है
  • जवाब पूरा है और फ़ील्ड में stop लिखा हैमॉडल ने खुद खत्म किया; कहीं और देखें

आखिरी पंक्ति मायने रखती है। अगर finish_reason का मान stop है, तो सीमा आपकी समस्या नहीं है, और max_tokens बढ़ाने से कुछ नहीं बदलेगा।

चरण 1: वह फ़ील्ड पढ़ें जो आपको बताती है#

हर रिस्पॉन्स बताता है कि जनरेशन क्यों खत्म हुआ। OpenAI-संगत रिस्पॉन्स में यह choices[0].finish_reason है: "stop" जब मॉडल खत्म करता है, "length" जब टोकन खत्म हो जाते हैं। Anthropic Messages API में फ़ील्ड stop_reason है, और कट-ऑफ़ मान "max_tokens" है। Anthropic की stop-reason गाइड (28 अक्टूबर 2026 को जाँची गई) ठीक नीचे दिए गए दो समाधान सुझाती है: max_tokens बढ़ाएँ या रिस्पॉन्स जारी रखें।

यहाँ वही जाँच तीन रूपों में है। OpenAI SDK के लिए बेस URL https://api.cheaptokens.dev/v1 है और Anthropic SDK के लिए https://api.cheaptokens.dev (बिना /v1)। max_tokens=200 जानबूझकर छोटा रखा गया है, ताकि आप खुद कटाव देख सकें।

एक जाँच, तीन तरीके

Python (OpenAI SDK)

python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.cheaptokens.dev/v1",
    api_key=os.environ["CHEAPTOKENS_API_KEY"],
)

resp = client.chat.completions.create(
    model="deepseek-ai/DeepSeek-V4-Flash-0731",
    max_tokens=200,
    messages=[{"role": "user", "content": "Write a Python class for a todo list with tests."}],
)

choice = resp.choices[0]
if choice.finish_reason == "length":
    print("Cut off at the token limit")
print(choice.message.content)
print(resp.usage.completion_tokens)

Python (Anthropic SDK)

python
import os
import anthropic

client = anthropic.Anthropic(
    base_url="https://api.cheaptokens.dev",
    api_key=os.environ["CHEAPTOKENS_API_KEY"],
)

msg = client.messages.create(
    model="deepseek-ai/DeepSeek-V4-Flash-0731",
    max_tokens=200,
    messages=[{"role": "user", "content": "Write a Python class for a todo list with tests."}],
)

if msg.stop_reason == "max_tokens":
    print("Cut off at the token limit")
print(msg.content[0].text)

curl

bash
curl https://api.cheaptokens.dev/v1/chat/completions \
  -H "Authorization: Bearer $CHEAPTOKENS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek-ai/DeepSeek-V4-Flash-0731",
    "max_tokens": 200,
    "messages": [{"role": "user", "content": "Write a Python class for a todo list with tests."}]
  }'

वापस आने वाले JSON में "finish_reason": "length" देखें।

जब यह निदान के रूप में काम करता है, तो आपको यह जोड़ी दिखेगी: कम सीमा length देती है, खुली सीमा stop देती है।

कम और ज़्यादा max_tokens के साथ वही अनुरोध: finish_reason length से stop में बदलता है
finish_reason के वे दो मान जो आपको सबसे अधिक मिलेंगे

चरण 2: max_tokens बढ़ाएँ, लेकिन सीमा से आगे नहीं#

स्पष्ट समाधान है बड़ी संख्या। दिक्कत: हर मॉडल की जवाब पर अपनी सीमा होती है। उससे ऊपर मान न सेट करें: सीमा प्रति मॉडल है, इसलिए पहले नीचे दी गई तालिका देखें। ये CheapTokens पर प्रति-जवाब सीमाएँ हैं (तथ्य 28 अक्टूबर 2026 को जाँचे गए):

मॉडल प्रति जवाब अधिकतम आउटपुट कॉन्टेक्स्ट
DeepSeek-V4-Flash 32,768 टोकन 380K
GLM-5.3-Flash 8,192 टोकन 390K
MiniMax-M2.7 8,192 टोकन 180K

9,000-टोकन वाले अनुवाद के लिए बड़ी प्रति-जवाब सीमा वाला मॉडल चाहिए — DeepSeek-V4-Flash प्रति जवाब 32,768 टोकन तक लेता है। लंबे कोड, लंबे JSON या पूरे दस्तावेज़ के लिए deepseek-ai/DeepSeek-V4-Flash-0731 में सबसे ज़्यादा जगह है: प्रति जवाब 32,768 टोकन तक, दिन के किसी भी घंटे एक ही कीमत। सटीक मॉडल आईडी CheapTokens डॉक्स और मॉडल पेज से लें, क्योंकि प्रोवाइडर उन्हें अलग नामों से बुलाते हैं।

एक व्यावहारिक नियम: max_tokens को उस सबसे लंबे जवाब पर सेट करें जिसे आप स्वीकार करेंगे, अधिकतम पर नहीं। आप उन्हीं टोकन के लिए भुगतान करते हैं जो मॉडल वास्तव में लिखता है, इसलिए जवाब छोटे हों तो ऊँची सीमा का कोई खर्च नहीं।

चरण 3: JSON जो आधे में रुक जाता है#

कटा हुआ JSON जवाब सबसे मुश्किल मामला है, क्योंकि टेक्स्ट तब तक सही दिखता है जब तक पार्सर अंत तक नहीं पहुँचता। मान लें आप एक कॉल में 40 इनवॉइस से फ़ील्ड निकालते हैं और एक ऐरे माँगते हैं। मॉडल 31 ऑब्जेक्ट लिखता है, सीमा तक पहुँचता है, और ऐरे कभी बंद नहीं होता।

टोकन सीमा पर कटे ऐरे पर json.loads एरर
पार्सर में कटा हुआ JSON ऐरे कैसा दिखता है

]} जोड़कर स्ट्रिंग को ठीक करने की कोशिश न करें। आपको गायब रिकॉर्ड वाला वैध JSON मिलेगा, जो एरर से भी बुरा है। पहले finish_reason जाँचें; अगर वह length है, तो या तो सीमा बढ़ाकर कॉल दोबारा चलाएँ, या इनपुट को छोटे बैचों में बाँटें। फ़ॉर्मेट को बाध्य करने के लिए, LLM API से वैध JSON देखें।

चरण 4: मॉडल को जारी रखने दें#

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

python
def complete(base_messages, model, max_tokens=4096, rounds=4):
    text = ""
    for _ in range(rounds):
        messages = list(base_messages)
        if text:
            messages += [
                {"role": "assistant", "content": text},
                {"role": "user", "content": "Continue exactly where you stopped. Do not repeat anything."},
            ]
        r = client.chat.completions.create(model=model, max_tokens=max_tokens, messages=messages)
        choice = r.choices[0]
        text += choice.message.content or ""
        if choice.finish_reason != "length":
            return text, True   # finished on its own
    return text, False          # still cut after all rounds

दो आदतें इसे ईमानदार रखती हैं। True/False फ़्लैग लौटाएँ और False पर उपयोगकर्ता को चेतावनी दिखाएँ, बजाय आधे दस्तावेज़ को पूरा बताने के। और याद रखें कि हर राउंड पिछला टेक्स्ट इनपुट के रूप में दोबारा भेजता है, इसलिए जारी किया गया जवाब एक बड़े जवाब से ज़्यादा महँगा पड़ता है। संरचित डेटा के लिए, जारी रखने के बजाय बड़ी सीमा या छोटे बैच पसंद करें।

लंबे जवाब का खर्च#

मान लें एक लंबा जवाब 2,000 टोकन इन और 8,000 टोकन आउट है। DeepSeek-V4-Flash पर वह अनुरोध आज की कीमत पर $0.00083 का पड़ता है, और कुल मिलाकर, इनपुट और आउटपुट को साथ गिनते हुए, यह OpenRouter से सस्ता है। संख्याओं को अपने लोड में बदलें:

लागत कैलकुलेटर

50 लंबे जवाबों का एक दिन

प्रति अनुरोध इनपुट टोकन: 2,000 · प्रति अनुरोध आउटपुट टोकन: 8,000 · प्रति दिन अनुरोध: 50

मॉडलप्रति दिनप्रति माह
GLM-5.3-Flash$0.018$0.54
DeepSeek-V4-Flash$0.0415$1.25
MiniMax-M2.7$0.065$1.95

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

शिप करने से पहले: एक छोटी चेकलिस्ट#

चेकलिस्ट

आपके कोड के लिए ट्रंकेशन चेकलिस्ट