लागत अनुकूलनगाइड
LLM API के साथ प्राकृतिक भाषा से शेल कमांड: JSON और लागत
एक Python स्क्रिप्ट जो एक सस्ते मॉडल से एक शेल कमांड JSON के रूप में माँगती है, अनुरोधों को मना करती है या अनिश्चित बताती है, कुछ भी नहीं चलाती, और 1,000 अनुरोधों की कीमत निकालती है।

इस पृष्ठ पर
मॉडल से तीन फ़ील्ड (type, command, explanation) वाला एक JSON ऑब्जेक्ट माँगें, उत्तर को कुछ सौ टोकन तक सीमित रखें, और कमांड चलाने के बजाय उसे प्रिंट करें। टोकन के हिसाब से, ऐसा अनुरोध ज़्यादातर प्रॉम्प्ट होता है जिसका उत्तर छोटा और अनुमानित होता है: नीचे दी गई धारणाओं के तहत, ऐसे 1,000 टोकन की कीमत DeepSeek-V4-Flash पर $0.012 है।
मान लीजिए आप एक आंतरिक CLI में "जो चाहिए वह बताएँ" वाला बॉक्स जोड़ रहे हैं। कोई टाइप करता है मेरे होम फ़ोल्डर में 100 MB से बड़ी फ़ाइलें खोजें, और आपको एक पंक्ति वापस चाहिए जिसे वे पढ़ सकें, जाँच सकें और पेस्ट कर सकें। इससे दो सवाल उठते हैं: आप मॉडल को अनुमान लगाने या कुछ खतरनाक करने से कैसे रोकते हैं, और जब सौ लोग दिन भर इसका इस्तेमाल करें तो इसकी लागत क्या होती है?
एक संकीर्ण कार्य: उत्तर छोटा क्यों होता है#
9 नवंबर 2026 को एक Telegram चैनल ने dale-0.8b के मॉडल कार्ड को दोबारा बताया, जो एक ओपन मॉडल है और ठीक यही एक काम करता है। Hugging Face पर मॉडल कार्ड (10 नवंबर 2026 को जाँचा गया) के अनुसार, dale-0.8b, Qwen3.5-0.8B का Apache-2.0 के तहत पूर्ण फ़ाइन-ट्यून है जो स्पेनिश या अंग्रेज़ी अनुरोध को एक Linux bash कमांड में बदल देता है। लेखक, Manuel García, अपने स्वयं के टेस्ट सेट पर 79.4% (471 में से 374 मामले) बताते हैं, जबकि Qwen3.5-9B बेस और बिना फ़ाइन-ट्यूनिंग वाले Gemma 4 E4B-it के लिए 62.8% है। ये एक व्यक्ति के टेस्ट सेट पर स्वयं-रिपोर्ट किए गए आँकड़े हैं, इसलिए इन्हें एक डेटा पॉइंट मानें, रैंकिंग नहीं।
हमारे लिए उपयोगी बात मॉडल नहीं, बल्कि कार्य का स्वरूप है। कार्ड एक निश्चित सिस्टम प्रॉम्प्ट, एक कॉन्टेक्स्ट पंक्ति (OS, डिस्ट्रो, पैकेज मैनेजर, टूल) और अनुरोध, थिंकिंग बंद, तथा 200 टोकन तक सीमित उत्तर का वर्णन करता है। यह सीमा लागत पर दो लीवर में से एक है: जब उत्तर एक छोटा JSON ऑब्जेक्ट हो, तो आउटपुट पक्ष छोटा और अनुमानित होता है, क्योंकि सीमा उसे बाँधती है। दूसरा लीवर प्रॉम्प्ट है। बिल में प्रत्येक पक्ष का हिस्सा कितना है, यह नीचे तालिका दिखाती है; यह मॉडल से मॉडल में बदलता है।
इसके लिए आपको 0.8B मॉडल की ज़रूरत नहीं है। यही प्रारूप किसी भी API मॉडल पर काम करता है, और इसी पर इस लेख का बाकी हिस्सा बना है।

उत्तर प्रारूप: कमांड, मना करना या अनिश्चित#
चाल यह है कि मॉडल के पास हमेशा "ना" कहने का वैध तरीका हो। उत्तर एक ऑब्जेक्ट है:
{"type": "command | refuse | unsure", "command": "...", "explanation": "..."}command: एक bash कमांड, साथ में यह बताते हुए एक वाक्य कि यह क्या करता है।refuse: अनुरोध विनाशकारी है या शेल से इसका कोई लेना-देना नहीं है। कोई कमांड नहीं।unsure: अनुरोध बहुत अस्पष्ट है ("मेरी डिस्क साफ़ करो")। स्पष्टीकरण में एक स्पष्ट करने वाला प्रश्न होता है।
unsure के बिना, अस्पष्ट अनुरोध अनुमान लगाने को मजबूर करता है, और अनुमानित rm वही होता है जो आपको याद रहता है। कार्ड के प्रारूप में भी यही तीन प्रकार हैं; हम विचार का पुनः उपयोग करते हैं, मॉडल का नहीं।
जोड़े मिलाएँ
प्रत्येक उत्तर प्रकार को स्क्रिप्ट के कार्य से मिलाएँ
बाईं ओर एक आइटम पर टैप करें, फिर उसका जोड़ा
- commandकमांड और स्पष्टीकरण दिखाएँ; व्यक्ति स्वयं इसे कॉपी करके चलाता है
- refuseस्पष्टीकरण प्रिंट करें और चलाने के लिए कुछ न दें
- unsureप्रश्न प्रिंट करें और उपयोगकर्ता को पुनः शब्दों में कहने दें
स्क्रिप्ट#
एक फ़ाइल, openai पैकेज, कुंजी एक एनवायरनमेंट वेरिएबल में। बेस URL और पूरा मॉडल id CheapTokens दस्तावेज़ से आते हैं; छोटे id स्वीकार नहीं किए जाते, इसलिए deepseek- का उपयोग करें।
import json
import os
import sys
from openai import OpenAI
client = OpenAI(
base_url='https://api.cheaptokens.dev/v1',
api_key=os.environ['CHEAPTOKENS_API_KEY'],
)
MODEL = 'deepseek-ai/DeepSeek-V4-Flash-0731'
SYSTEM = '''You turn a request into ONE Linux bash command.
Reply with a single JSON object and nothing else:
{"type": "command" | "refuse" | "unsure", "command": "<one command, or empty>", "explanation": "<one short sentence>"}
Use "refuse" when the request is destructive or not about the shell.
Use "unsure" when it is too vague, and put a clarifying question in "explanation".'''
CONTEXT = 'os: Ubuntu 24.04; package manager: apt; tools: git, curl, jq'
def parse(text):
start = text.find('{')
if start == -1:
return None
try:
obj, _ = json.JSONDecoder().raw_decode(text[start:])
except json.JSONDecodeError:
return None
if not isinstance(obj, dict) or obj.get('type') not in ('command', 'refuse', 'unsure'):
return None
return obj
def ask(request):
resp = client.chat.completions.create(
model=MODEL,
max_tokens=200,
temperature=0,
messages=[
{'role': 'system', 'content': SYSTEM},
{'role': 'user', 'content': f'Context: {CONTEXT}\nRequest: {request}'},
],
)
return parse(resp.choices[0].message.content), resp.usage
if __name__ == '__main__':
result, usage = ask(' '.join(sys.argv[1:]))
if result is None:
print('Could not read the reply as JSON. Try again.')
elif result['type'] == 'command':
print(result['explanation'])
print('\n ' + result['command'] + '\n')
print('Read it, then copy it yourself. This script never runs it.')
else:
print(f"[{result['type']}] {result['explanation']}")
print(f'tokens: {usage.prompt_tokens} in, {usage.completion_tokens} out')इसे python shellhelp. के रूप में चलाएँ। यहाँ तीन चुनाव मायने रखते हैं:
- कहीं भी
subprocessनहीं। कमांड स्क्रीन पर टेक्स्ट है। इसे चलाना आपका फ़ैसला है, इसे पढ़ने के बाद। max_tokens=200, कार्ड की सीमा के समान। एक JSON ऑब्जेक्ट आसानी से फ़िट हो जाता है; बेतुका उत्तर आपके खर्च पर चलने के बजाय 200 टोकन पर कट जाता है। सीमा पूरे उत्तर पर लागू होती है, इसलिए यदि कोई मॉडल अपना तर्क लिखता है, तो वह सीमा खा सकता है। यदि कभी उत्तरfinish_reasonके साथlengthके बराबर समाप्त हो, तो सीमा थोड़ी बढ़ाएँ। इस पर अधिक जानकारी max_tokens से आउटपुट टोकन कम करना में।- प्रारूप प्रॉम्प्ट में माँगा जाता है, फिर रक्षात्मक रूप से पार्स किया जाता है।
raw_decodeकिसी भटके हुए कोड फ़ेंस या{से पहले के वाक्य को छोड़ देता है। यदि आप और आगे जाना चाहते हैं, तो OpenAI-संगत API से वैध JSON और उत्तर पर json.JSONDecodeError का समाधान देखें।
कुछ भी चलाने से पहले, जाँच लें कि चरणों का क्रम स्पष्ट है:
क्रम में लगाएँ
स्क्रिप्ट के चरणों को सही क्रम में रखें
आइटम खींचें या तीरों का उपयोग करें
- प्रॉम्प्ट बनाएँ: निश्चित सिस्टम टेक्स्ट, एक कॉन्टेक्स्ट पंक्ति, अनुरोध
- छोटे max_tokens के साथ API कॉल करें
- JSON पार्स करें और जाँचें कि type तीन में से एक है
- कमांड दिखाएँ और व्यक्ति के चलाने की प्रतीक्षा करें
1,000 अनुरोधों की लागत#
स्क्रिप्ट की अंतिम पंक्ति usage प्रिंट करती है। यही असली संख्या है, और आपको अपनी स्वयं की पढ़नी चाहिए। जब तक आपके पास यह न हो, एक धारणा के साथ काम करें: प्रॉम्प्ट लगभग 400 इनपुट टोकन का होता है (स्क्रिप्ट में नंगा प्रॉम्प्ट मोटे अनुमान से लगभग 150 टोकन है; बाकी उन तीन या चार उदाहरण अनुरोध-और-उत्तर जोड़ों के लिए जगह है जो आप संभवतः जोड़ेंगे), और JSON उत्तर लगभग 60 आउटपुट टोकन का।
1,000 अनुरोधों के लिए यह 400 × 1,000 = 400,000 इनपुट टोकन और 60 × 1,000 = 60,000 आउटपुट टोकन है। तालिका कैटलॉग के प्रत्येक मॉडल के लिए ठीक इसी की कीमत देती है, साथ में OpenRouter कॉलम; आँकड़े लाइव कीमतों से आते हैं, इसलिए वे अद्यतित रहते हैं।
| मॉडल | इनपुट $/1M | आउटपुट $/1M | प्रति अनुरोध | 1,000 अनुरोध | OpenRouter, 1,000 अनुरोध |
|---|---|---|---|---|---|
| GLM-5.3-Flash | $0.02 | $0.04 | $0.00001 | $0.0104 | $0.0184 |
| DeepSeek-V4-Flash | $0.015 | $0.10 | $0.000012 | $0.012 | $0.0364 |
| MiniMax-M2.7 | $0.05 | $0.15 | $0.000029 | $0.029 | $0.348 |
प्रति अनुरोध 400 इनपुट और 60 आउटपुट टोकन। प्रति 1M टोकन की कीमतें वर्तमान हैं और हमारे टैरिफ के साथ बदलती रहती हैं; OpenRouter कॉलम समान कार्यभार के लिए संदर्भ कीमतें दिखाता है।
कुल मिलाकर, इनपुट और आउटपुट को एक साथ गिनने पर, इस कार्यभार के लिए DeepSeek-V4-Flash OpenRouter से सस्ता पड़ता है। टोकन के हिसाब से अनुरोध लगभग पूरा इनपुट है और उत्तर छोटा है, लेकिन दोनों पक्षों का बिल आता है, इसलिए प्रॉम्प्ट और उत्तर दोनों को छोटा करें। प्रति मॉडल कीमतें मूल्य पृष्ठ पर हैं, और मॉडल का वर्णन DeepSeek पृष्ठ पर है: 380K कॉन्टेक्स्ट, 32,768 आउटपुट टोकन तक, किसी भी घंटे एक ही कीमत।
अनुपात का अंदाज़ा लगाने का एक त्वरित तरीका:
त्वरित जाँच
max_tokens=200 अनुरोध के किस हिस्से को सीमित करता है?
उत्तर दिखाएँ
उत्तर: उत्तर को
max_tokens केवल उत्तर को सीमित करता है; प्रॉम्प्ट का बिल जैसा है वैसा ही आता है, इसलिए इसे अलग से छोटा करें।
महीने में 100,000 अनुरोध चाहिए? 100 से गुणा करें: 40,000,000 इनपुट और 6,000,000 आउटपुट टोकन। उन दो संख्याओं को उसी तरह ::cost में डालें और पंक्ति पढ़ें।
इसे अपने स्वयं के अनुरोधों पर जाँचें#
कार्ड का 79.4% आपके प्रॉम्प्ट, आपके OS या आपके उपयोगकर्ताओं के शब्दों के बारे में कुछ नहीं कहता। 20 वास्तविक अनुरोध उन कमांडों के साथ लिखें जिन्हें आप स्वीकार करेंगे और तुलना करें, ठीक वैसे ही जैसे छोटे eval सेट पर प्रॉम्प्ट का परीक्षण में। कुछ ऐसे भी शामिल करें जिन्हें स्क्रिप्ट को मना करना चाहिए या अनिश्चित बताना चाहिए, जैसे "सब कुछ हटा दो" या "मेरा कंप्यूटर तेज़ करो"।
जब कुछ गलत हो, तो लक्षण आमतौर पर समाधान की ओर इशारा करता है:
Could not read the reply as JSON: कच्चा टेक्स्ट एक बार प्रिंट करें। "Sure!" जैसा उपसर्ग संभाला जाता है; सीमा से कटा उत्तर नहीं, इसलिएfinish_reasonजाँचें।401या404: गलत कुंजी, बेस URL या मॉडल id। सूची API 401 या 404: कुंजी, बेस URL, मॉडल id में है।- भिन्न सिस्टम के अनुरूप कमांड: कॉन्टेक्स्ट पंक्ति कारण है। इसे सटीक रखें (OS, पैकेज मैनेजर, टूल); इसकी लागत कुछ दर्जन टोकन है और यह Fedora बॉक्स पर गलत
aptबचाता है।
वही कार्य, भिन्न मॉडल? MODEL को दस्तावेज़ों से GLM या MiniMax id से बदलें, प्रॉम्प्ट वही रखें, और स्क्रिप्ट द्वारा प्रिंट किए गए टोकन गणनाओं की ऊपर की तालिका से तुलना करें।



