Maliyet optimizasyonuKılavuz
Bir LLM API'siyle doğal dilden kabuk komutuna: JSON ve maliyet
Ucuz bir modelden tek bir kabuk komutunu JSON olarak isteyen, istekleri reddeden veya emin değil olarak işaretleyen, hiçbir şeyi çalıştırmayan ve 1.000 isteği fiyatlandıran bir Python betiği.

Bu sayfada
Modelden üç alanlı (type, command, explanation) tek bir JSON nesnesi isteyin, yanıtı birkaç yüz token ile sınırlayın ve komutu çalıştırmak yerine yazdırın. Token açısından böyle bir istek çoğunlukla prompt'tan oluşur ve kısa, öngörülebilir bir yanıt alır: aşağıdaki varsayımlar altında bunlardan 1.000 tanesi DeepSeek-V4-Flash üzerinde $0.012 tutar.
Diyelim ki dahili bir CLI'ye "ne istediğinizi tanımlayın" kutusu ekliyorsunuz. Birisi ev klasörümde 100 MB'tan büyük dosyaları bul yazıyor ve siz onların okuyabileceği, kontrol edebileceği ve yapıştırabileceği tek bir satır geri almak istiyorsunuz. İki soru ortaya çıkıyor: modelin tahmin yürütmesini veya tehlikeli bir şey yapmasını nasıl engellersiniz ve yüz kişi bunu bütün gün kullandığında bunun maliyeti ne olur?
Dar bir görev: yanıt neden kısa#
9 Kasım 2026'da bir Telegram kanalı, tam olarak bu tek işi yapan açık bir model olan dale-0.8b'nin model kartını aktardı. Hugging Face'teki model kartına göre (10 Kasım 2026'da kontrol edildi), dale-0.8b, Apache-2.0 altında Qwen3.5-0.8B'nin tam ince ayarıdır ve İspanyolca veya İngilizce bir isteği tek bir Linux bash komutuna dönüştürür. Yazar Manuel García, kendi test setinde %79,4 (471 vakanın 374'ü) bildiriyor; bu, ince ayar yapılmamış Qwen3.5-9B temel modeli ve Gemma 4 E4B-it için %62,8'e karşı. Bunlar tek bir kişinin test setinde kendi bildirdiği sayılar, bu yüzden bunları bir sıralama değil, bir veri noktası olarak değerlendirin.
Bizim için yararlı olan model değil, görevin şekli. Kart, sabit bir sistem prompt'u, bir bağlam satırı (işletim sistemi, dağıtım, paket yöneticisi, araçlar) artı istek, düşünmenin kapatılması ve 200 token ile sınırlanan bir yanıt tanımlıyor. Bu sınır, maliyet üzerindeki iki koldan biri: yanıt tek bir kısa JSON nesnesi olduğunda, çıktı tarafı kısa ve öngörülebilirdir çünkü sınır onu kısıtlar. Diğer kol ise prompt'tur. Faturanın her iki tarafının hangi payı oluşturduğunu aşağıdaki tablo gösteriyor; bu modelden modele değişir.
Bunun için 0.8B'lik bir modele ihtiyacınız yok. Aynı format herhangi bir API modelinde çalışır ve bu makalenin geri kalanı da bunu kuruyor.

Yanıt formatı: komut, reddet veya emin değilim#
İşin püf noktası, modelin her zaman "hayır" demenin meşru bir yoluna sahip olmasıdır. Yanıt tek bir nesnedir:
{"type": "command | refuse | unsure", "command": "...", "explanation": "..."}command: tek bir bash komutu ve ne yaptığına dair tek cümlelik bir açıklama.refuse: istek yıkıcı veya kabukla hiçbir ilgisi yok. Komut yok.unsure: istek çok belirsiz ("diskimi temizle"). Açıklama, netleştirici bir soru içerir.
unsure olmadan, belirsiz bir istek tahmin yürütmeye zorlar ve tahmin edilen bir rm hatırlayacağınız şeydir. Kartın formatı da aynı üç türe sahip; fikri yeniden kullanıyoruz, modeli değil.
Eşleştir
Her yanıt türünü betiğin ne yapması gerektiğiyle eşleştirin
Soldaki bir öğeye, ardından eşine dokun
- commandKomutu ve açıklamayı gösterin; kişi kendisi kopyalayıp çalıştırır
- refuseAçıklamayı yazdırın ve çalıştırılacak bir şey sunmayın
- unsureSoruyu yazdırın ve kullanıcının yeniden ifade etmesine izin verin
Betik#
Tek dosya, openai paketi, anahtar bir ortam değişkeninde. Temel URL ve tam model kimliği CheapTokens belgelerinden gelir; kısa kimlikler kabul edilmez, bu yüzden deepseek- kullanın.
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. olarak çalıştırın. Burada üç seçim önemlidir:
- Hiçbir yerde
subprocessyok. Komut ekrandaki metindir. Çalıştırmak, okuduktan sonra sizin kararınızdır. max_tokens=200, kartın sınırıyla aynı. Tek bir JSON nesnesi kolayca sığar; uzayan bir yanıt sizin masrafınıza devam etmek yerine 200 token'da kesilir. Sınır tüm yanıta uygulanır, bu yüzden bir model akıl yürütmesini yazarsa bu, sınırı tüketebilir. Bir yanıtfinish_reasondeğerilengtholarak biterse, sınırı biraz yükseltin. Bununla ilgili daha fazlası max_tokens ile çıktı token'larını kısmak yazısında.- Format prompt'ta istenir, sonra savunmacı biçimde ayrıştırılır.
raw_decode, başıboş bir kod bloğunu veya{öncesindeki bir cümleyi atlar. Daha ileri gitmek isterseniz, OpenAI uyumlu bir API'den geçerli JSON ve bir yanıtta json.JSONDecodeError düzeltmesine bakın.
Herhangi bir şey çalıştırmadan önce adımların sırasının net olduğunu kontrol edin:
Sıraya koy
Betiğin adımlarını doğru sıraya koyun
Öğeleri sürükle veya okları kullan
- Prompt'u oluşturun: sabit sistem metni, bir bağlam satırı, istek
- API'yi küçük bir max_tokens ile çağırın
- JSON'u ayrıştırın ve type'ın üçten biri olduğunu kontrol edin
- Komutu gösterin ve kişinin çalıştırmasını bekleyin
1.000 isteğin maliyeti#
Betiğin son satırı usage yazdırır. Gerçek sayı budur ve kendi sayınızı okumalısınız. Ona sahip olana kadar bir varsayımla çalışın: prompt yaklaşık 400 giriş token'ına (betikteki çıplak prompt kaba bir sayımla yaklaşık 150 token'dır; geri kalanı, muhtemelen ekleyeceğiniz üç veya dört örnek istek-yanıt çifti için ayrılan alandır) ve JSON yanıtı yaklaşık 60 çıktı token'ına denk gelir.
1.000 istek için bu, 400 × 1.000 = 400.000 giriş token'ı ve 60 × 1.000 = 60.000 çıktı token'ıdır. Tablo, katalogdaki her model için tam olarak bunu fiyatlandırır, yanında OpenRouter sütunuyla; rakamlar canlı fiyatlardan gelir, bu yüzden güncel kalırlar.
| Model | Giriş $/1M | Çıkış $/1M | İstek başına | 1.000 istek | OpenRouter, 1.000 istek |
|---|---|---|---|---|---|
| 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 |
İstek başına 400 giriş ve 60 çıkış token'ı. 1M token başına fiyatlar günceldir ve tarifelerimizle birlikte değişir; OpenRouter sütunu aynı iş yükü için referans fiyatları gösterir.
Toplamda, giriş ve çıktı birlikte sayıldığında, bu iş yükü için DeepSeek-V4-Flash OpenRouter'dan daha ucuza gelir. Token açısından istek neredeyse tamamen giriştir ve yanıt kısadır, ancak her iki taraf da faturalandırılır, bu yüzden hem prompt'u hem de yanıtı kısaltın. Model başına fiyatlar fiyatlandırma sayfasında ve modelin kendisi DeepSeek sayfasında açıklanmıştır: 380K bağlam, 32.768'e kadar çıktı token'ı, her saatte tek fiyat.
Oranları hissetmenin hızlı bir yolu:
Hızlı kontrol
max_tokens=200 isteğin hangi kısmını sınırlar?
Cevabı göster
Cevap: Yanıtı
max_tokens yalnızca yanıtı sınırlar; prompt olduğu gibi faturalandırılır, bu yüzden onu ayrıca kısaltın.
Ayda 100.000 istek mi istiyorsunuz? 100 ile çarpın: 40.000.000 giriş ve 6.000.000 çıktı token'ı. Bu iki sayıyı aynı şekilde ::cost içine koyun ve satırı okuyun.
Kendi isteklerinizle kontrol edin#
Kartın %79,4'ü sizin prompt'unuz, işletim sisteminiz veya kullanıcılarınızın ifadeleri hakkında hiçbir şey söylemez. Kabul edeceğiniz komutlarla 20 gerçek istek yazın ve tam olarak küçük bir değerlendirme setinde bir prompt'u test etme yazısındaki gibi karşılaştırın. Betiğin reddetmesi veya emin değil olarak işaretlemesi gereken birkaçını da ekleyin, örneğin "her şeyi sil" veya "bilgisayarımı hızlandır".
Bir şeyler ters gittiğinde, belirti genellikle düzeltmeye işaret eder:
Could not read the reply as JSON: ham metni bir kez yazdırın. "Sure!" gibi bir önek ele alınır; sınırla kesilen bir yanıt ele alınmaz, bu yüzdenfinish_reasonkontrol edin.401veya404: yanlış anahtar, temel URL veya model kimliği. Liste API 401 veya 404: anahtar, temel URL, model kimliği yazısında.- Farklı bir sisteme uyan komutlar: sebep bağlam satırıdır. Onu doğru tutun (işletim sistemi, paket yöneticisi, araçlar); birkaç düzine token'a mal olur ve bir Fedora makinesinde yanlış bir
aptkurtarır.
Aynı görev, farklı model mi? MODEL yerine belgelerdeki GLM veya MiniMax kimliğini koyun, prompt'u koruyun ve betiğin yazdırdığı token sayılarını yukarıdaki tabloyla karşılaştırın.



