Bloga dön

Yeni başlayanlar için AIKılavuz

Python'da bir LLM toplu işinin maliyetini sınırlayın: bir defter ve sert bir bütçe

Her API çağrısının tokenlarını ve maliyetini bir JSONL dosyasına kaydedin, toplu işi bir bütçede durdurun ve çalıştırmadan önce faturayı tahmin edin. Python kodu dahil.

Yazan: CheapTokens TeamYayınlanma tarihi: 5 dk okuma

Bütçeye ulaşıldığında duran bir toplu çalıştırmayı gösteren terminal
Bu sayfada
  1. Clocktower çalıştırmasının kopyalayabileceğiniz yanı
  2. Defter: tek dosya, çağrı başına tek satır
  3. Toplu döngü: yapılanı atla, tavanda dur
  4. Çalıştırmaya basmadan önce faturayı tahmin edin
  5. Fatura beklenenden büyükse: defteri okuyun
  6. Başlatmadan önce

Betiğiniz 200 istem üzerinde döngü yapıyor, dizüstü bilgisayarın kapağını kapatıyorsunuz ve sabah gecenin ne kadara mal olduğunu öğreniyorsunuz. İki küçük alışkanlık bunu çözer. Her API çağrısından sonra, token ve maliyeti bir defter dosyasına tek satır olarak ekleyin. Her çağrıdan önce, çalışan toplamı bir bütçeyle karşılaştırın ve bütçeye ulaşıldıysa durun. Bu, 50 satırdan az Python demek ve 5 istemlik bir deneme çalıştırması, gerçek çalıştırma başlamadan önce faturayı size söyler.

Clocktower çalıştırmasının kopyalayabileceğiniz yanı#

Dwarkesh Podcast'in sunucusu Dwarkesh Patel, Blood on the Clocktower'da 11 modeli birbirine karşı yarıştırdı, README'ye göre 386 oyun, ve kodu, günlükleri ve puanlamaları yayımladı (github.com/dwarkeshsp/clocktower, 8 Kasım 2026'da kontrol edildi). Repodaki iki ayrıntı çalınmaya değer. Her oyun dizini, token ve maliyet içeren çağrı başına bir günlük tutar ve harcama games/ledger.jsonl dosyasına yazılır. Bir --budget bayrağı toplam harcamayı sınırlar; varsayılanı 1.000 $'dır. Kıyaslama sitesi üçüncü bir koruma ekler: her model tur başına aynı 8.000 tokenlık üst sınıra sahiptir (clocktowerbench.com).

Yani: her çağrıda bir üst sınır, her çağrının bir günlüğü, toplamda bir tavan. Bir turnuva üçüne de ihtiyaç duyar, gece çalıştırmanız da öyle, sadece daha küçüğü.

Defteri bir dükkânın kasasındaki fiş rulosu gibi düşünün. Her satış bir satır basar; yönetici ruloyu her an toplayabilir ve günün kasasındaki paranın ne zaman bittiğini bilir.

Defter: tek dosya, çağrı başına tek satır#

İşte tamamı. CheapTokens'e yönlendirilmiş openai paketini kullanır (https://api.cheaptokens.dev/v1, anahtar ve model kimlikleri için dokümanlara bakın).

python
import json
import os
from pathlib import Path

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'
PRICE_IN, PRICE_OUT = 1.00, 2.00  # USD per 1M tokens: example, substitute current ones


class BudgetExceeded(Exception):
    pass


class Ledger:
    def __init__(self, path, budget_usd):
        self.path = Path(path)
        self.budget = budget_usd
        self.rows = []
        if self.path.exists():
            with self.path.open() as f:
                self.rows = [json.loads(line) for line in f if line.strip()]

    @property
    def spent(self):
        return sum(r['cost_usd'] for r in self.rows)

    def done(self):
        return {r['unit'] for r in self.rows}

    def check(self, unit):
        if self.spent >= self.budget:
            raise BudgetExceeded(
                f'stopped before {unit}: spent {self.spent:.4f} of {self.budget} USD'
            )

    def add(self, unit, usage, finish_reason):
        cost = (usage.prompt_tokens * PRICE_IN
                + usage.completion_tokens * PRICE_OUT) / 1_000_000
        row = {
            'unit': unit,
            'model': MODEL,
            'prompt_tokens': usage.prompt_tokens,
            'completion_tokens': usage.completion_tokens,
            'finish_reason': finish_reason,
            'cost_usd': round(cost, 6),
        }
        self.rows.append(row)
        with self.path.open('a') as f:
            f.write(json.dumps(row) + '\n')


def ask(ledger, unit, prompt, max_tokens=400):
    ledger.check(unit)
    resp = client.chat.completions.create(
        model=MODEL,
        messages=[{'role': 'user', 'content': prompt}],
        max_tokens=max_tokens,
    )
    ledger.add(unit, resp.usage, resp.choices[0].finish_reason)
    return resp.choices[0].message.content

Her çağrı aynı dört adımdan geçer:

Her API çağrısı etrafında dört adım: bütçeyi kontrol et, çağır, kullanımı oku, deftere ekle
Sarmalayıcıdaki her çağrının arkasındaki döngü

Buradaki üç seçim bilinçlidir.

  • Satır başına bir JSON nesnesi (JSONL), ekleme modunda açılır. Betik 130. çağrıda çökerse, 1'den 129'a kadar olan çağrılar zaten diskte olur.
  • Toplam, bir değişkenden değil dosyadan gelir. Betiği yeniden başlatın, tavan hâlâ geçerlidir, çünkü defter önceki çalıştırmanın ne harcadığını hatırlar.
  • finish_reason tokenların yanına kaydedilir. length diyen bir satır, yanıtın max_tokens sınırınıza çarptığı ve kesildiği anlamına gelir. Bunu sonra bilmek isteyeceksiniz.

İki PRICE_ sabiti yer tutucudur. Güncel rakamları fiyat tablosundan alın. Bunu okuduğunuz sırada DeepSeek-V4-Flash için bu, 1M giriş tokenı başına $0.015 ve 1M çıkış tokenı başına $0.10'tür. MODEL değerini zai-org/GLM-5.3-Flash veya MiniMaxAI/MiniMax-M2.7 olarak ve iki sabiti değiştirin, aynı defter onlar için de çalışır.

Toplu döngü: yapılanı atla, tavanda dur#

Döngü kısadır. İstemlerinizin, bir iş parçasının adı olan bir birim kimliğiyle anahtarlanmış bir sözlükte olduğunu varsayalım, örneğin doc-001:

python
prompts = {
    'doc-001': 'Summarize this ticket in one sentence: ...',
    'doc-002': 'Summarize this ticket in one sentence: ...',
    # ... your 200 prompts
}

ledger = Ledger('ledger.jsonl', budget_usd=0.50)
already = ledger.done()

for unit, prompt in prompts.items():
    if unit in already:
        continue
    try:
        answer = ask(ledger, unit, prompt)
    except BudgetExceeded as e:
        print(e)
        break
    Path(f'out-{unit}.txt').write_text(answer)

Çalıştırın, yarıda Ctrl+C'ye basın, tekrar çalıştırın: biten birimler atlanır, böylece defter aynı zamanda ilerleme dosyanız olur. Bütçe tükensin, sürpriz yerine tek bir satır alırsınız, stopped before doc-142: spent 0.5003 of 0.5 USD gibi bir şey.

Önce kelimesine dikkat edin. Kontrol her çağrıdan önce yapılır, bu yüzden son çağrı toplamı bütçenin biraz üzerine çıkarabilir. Ne kadar aşılacağı sınırlıdır: bir çağrı, en uzun isteminiz artı max_tokens'ten daha fazlaya mal olamaz. 1.500 tokenlık bir istem ve max_tokens=400 için bu en fazla $0.000063'tür. Bu yüzden sarmalayıcıdaki her çağrıda bir max_tokens vardır: açık uçlu bir riski, planlayabileceğiniz bir sayıya dönüştürür.

Çağrı başına token ve son bir bütçe durdurması içeren bir defter dosyasının satırları
Örnek defter satırları ve durdurma mesajı (gösterim amaçlı değerler)

Çalıştırmaya basmadan önce faturayı tahmin edin#

Şimdi diğer yarısı: başlatmadan önce maliyeti bilmek. İlk beş istemi küçük bir bütçeyle ask() üzerinden çalıştırın ve defteri okuyun. Diyelim ki beş satır ortalama 1.500 giriş tokenı ve 400 çıkış tokenı. Bunlar tüm toplu iş için rakamlarınızdır.

200 istem için bu, 200 × 1.500 = 300.000 giriş tokenı ve 200 × 400 = 80.000 çıkış tokenıdır. İşte bu iş yükünün canlı fiyatlarla hesabı:

Model İstek başına 200 istek OpenRouter, 200 istek
GLM-5.3-Flash $0.000046 $0.0092 $0.0167
DeepSeek-V4-Flash $0.000063 $0.0125 $0.0322
MiniMax-M2.7 $0.00014 $0.027 $0.324

İstek başına 1.500 giriş ve 400 çı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.

Tabloda bir OpenRouter sütunu da var. Giriş ve çıkış birlikte sayıldığında, DeepSeek-V4-Flash bu yük için OpenRouter'dan daha ucuza gelir ve toplu işin gerçekte ödediği bu toplamdır.

İstemler uzunluk bakımından farklıdır, bu yüzden beş örnek bir tahmindir, bir vaat değil. Güvenli bir üst taraf istediğinizde beşin en uzununu kullanın, gerisini bütçe tavanı yakalasın. İki modeli aynı 200 istem üzerinde karşılaştırmak mı istiyorsunuz? Her modele kendi defter dosyasını verin, örneğin Ledger(f'ledger-{MODEL.split("/")[-1]}.jsonl', 0.50), ve iki toplam sonradan yan yana durur.

Kendi toplu işinizi burada deneyin: istek başına tokenları örneğinizden ayarlayın ve kaç istek planladığınızı belirtin.

Maliyet hesaplayıcı

Toplu işiniz: 5 istemlik örneğinizden tokenlar

İstek başına giriş token'ı: 1.500 · İstek başına çıkış token'ı: 400 · Günlük istek sayısı: 200

ModelGünlükAylık
GLM-5.3-Flash$0.0092$0.276
DeepSeek-V4-Flash$0.0125$0.375
MiniMax-M2.7$0.027$0.81

Göndermeden önce token sayma hakkında daha fazlası için tiktoken ile token sayma yazısına bakın.

Fatura beklenenden büyükse: defteri okuyun#

Üçüncü okuyucu senaryosu kötü olanıdır. Bir ajan çalıştırması ters gider ve döngüye girer, ve gösterge paneli yalnızca bir toplam gösterir. Defter nereye gittiğini gösterir. Satırları maliyete göre sıralayın:

python
rows = [json.loads(line) for line in open('ledger.jsonl')]
for r in sorted(rows, key=lambda r: r['cost_usd'], reverse=True)[:5]:
    print(r['unit'], r['prompt_tokens'], r['completion_tokens'], r['finish_reason'])

Bir ajan için, birimi adıma göre adlandırın (step-17), böylece çalıştırmanın şeklini görebilirsiniz. Birkaç desen tekrar tekrar ortaya çıkar; her birini olağan nedeniyle eşleştirin:

Eşleştir

Her defter desenini olağan nedeniyle eşleştirin

  • prompt_tokens her satırda biraz büyürDöngü her adımda tüm geçmişi yeniden gönderir
  • completion_tokens max_tokens'a eşit ve finish_reason lengthYanıtlar sınırınızda kesiliyor ve kesilen metin için ödeme yapıyorsunuz
  • Aynı birim arka arkaya birçok kez görünürBir yeniden deneme döngüsü veya bir adımı tekrarlayan bir ajan
  • Bir satır diğerlerinin hepsinden çok daha pahalıdırİstem içine yapıştırılmış bütün bir dosya gibi tek bir aşırı büyük girdi

Her desen, faturadan çok önce defterde görünür. İlki bir ajanın geçmişini neden yeniden okuduğu yazısında ele alınmıştır.

Betik dışında proje başına harcama ve uyarılar da istiyorsanız, proje başına bütçe uyarıları rehberi bu tarafı kapsar. Buradaki defter, kodunuzda yaşayan ve dur diyebilen kısımdır.

Başlatmadan önce#

Kontrol listesi

İlk gerçek çalıştırmadan önce

max_tokens seçerken işinize yarayacak DeepSeek-V4-Flash'in bağlam boyutu ve yanıt sınırı, kendi sayfasında: CheapTokens'te DeepSeek-V4-Flash.