AIDive

Video paketi

Spotify'ın Claude Code %90 token kesintisi, ölçüldü: hook, subagent, protokol

11 dk okuma

TL;DR

  • Spotify'ın "%90" rakamı, bir Java monorepo'sunda tahmini girdi token'ı üzerinden ölçülen toplu okuma senaryolarının ortalamasıdır. Yazıda ne dolar cinsinden bir maliyet var ne de bir kalite puanı.
  • Düz Claude Code ile yeniden kurulduğunda (tek bir PreToolUse hook'u, iki ucuz subagent, üç satırlık bir yönlendirme kuralı) ve Fastify üzerinde dört senaryo ve 16 çalıştırmayla ölçüldüğünde, bu desen ana modelin bağlamını %59.6, toplam maliyeti ise %33.1 azalttı.
  • Reddeden (deny) hook'lar ölçülen çalıştırmalarda sıfır kez tetiklendi. Tasarrufu CLAUDE.md'deki yönlendirme kuralı sağladı; hook'lar, modelin kuralı görmezden geleceği gün için bir güvenlik ağı.
  • Delege etmek her seferinde daha yavaştı: ortalama +%65.3 süre. Küçük test yazma senaryosunda %2.6 daha pahalıya geldi.
  • İki tuzak: hook'lar subagent'ların içinde de tetiklenir, bu yüzden worker'larınızı muaf tutun; ve sed -n aralık okumaları, yalnızca cat, head ve tail'i izleyen bir hook'un önünden geçip gider.
  • Haiku okuyucusunun özeti, delege edilen sekiz çalıştırmanın ikisinde olgusal hatalar içeriyordu. Ana modelin doğrulama turunu koruyun.

Ölçümler ne söylüyor

Spotify'ın eklentisi Shunt, toplu işi iki "mod" üzerinden ana modelden uzaklaştırır: bir bulk-reader ve bir code-writer. Örneklerde ikisi de Gemini 2.5 Flash üzerinde çalışır ve model alanı, Portal örneğinde yapılandırılmış herhangi bir modeli kabul eder s1. Yönlendirme üç katmandan oluşur. check-file-size hook'u her Read'de tetiklenir ve yapılandırılabilir satır eşiğini (varsayılan 350) aşan dosyaları engelleyip modeli bulk-reader skill'ine yönlendirir; check-bash-read hook'u büyük dosyalardaki cat, head, tail, less ve more komutlarını yakalar, borulu (piped) komutlar ise geçer s1. Hook kaynakları ve iki skill herkese açık depoda duruyor s2; boyut kontrolü ise tek başına okunabilir s3. Modların kendisi Spotify'ın dahili platformu Portal'da yaşıyor; bu yüzden eklenti, gönderildiği haliyle şirket dışında çalıştırılamaz s4.

Kıyaslama iddiası zayıf. Spotify, bir Java monorepo'sunda dört senaryoyu test etti; "Claude'un dosyaları doğrudan okurken tüketeceği token'lar ile bulk-reader'ın özetini tüketirken harcayacağı token'lar" ölçüldü ve ortalama toplu okuma tasarrufu yaklaşık %90 olarak bildirildi s1. Yazının kendisi şunları kabul ediyor: kod yazma senaryosunu token cinsinden ölçmek daha zor, worker özetleri güvenilir satır numaraları içermediği için düzenleme delege edilemiyor, worker ince bir thread-safety hatasını kaçırdı ve bunu ana model yakaladı, her delegasyon 10 ile 30 saniye ekliyor ve Portal tek bir çağrıyı 30 saniyeyle sınırlıyor s1. Hacker News başlığında da %90'ın tam olarak neyi ölçtüğü sorusu gündeme geldi s7.

Yeniden kurulumda Portal modları, tanım dosyaları modeli sabitleyen iki Claude Code subagent'ı ile değiştirilir: Haiku üzerinde bir Explore okuyucusu ve Sonnet üzerinde bir code-writer s6. Reddetme, güncel hook JSON biçiminde deny kararı döndüren bir PreToolUse hook'udur s5. Test edilen depo fastify/fastify, commit ac28821d: 294 .js/.ts dosyası, 78270 satır, 350 satırdan uzun 63 dosya. Oturum JSON'unun bildirdiği model kimlikleri: ana konuşma claude-opus-5[1m], okuyucu claude-haiku-4-5-20251001, yazıcı claude-sonnet-5. Her senaryo yapılandırma başına iki kez çalıştı, toplam 16 ölçülen çalıştırma; iki tarafın da sistem prompt'u özdeş olsun diye yalnızca proje ayarlarıyla tek turluk claude -p oturumları kullanıldı s5.

Desenin kazandığı yer: S2, lib/route.js (691 satır), lib/reply.js (1090) ve lib/request.js (398) üzerinde üç dosyalık bir çağrı grafiği sorusu, ortalama ana bağlamı 357165.5 token'dan 73440.0'a (-%79.4) ve maliyeti 0.5810500000000001 USD'den 0.21823605000000001 USD'ye (-%62.4) indirdi. Kazanmadığı yer: S4, 19 satırlık bir referansa bakarak 45 satırlık bir kaynak için test yazmak, delegasyonsuz 0.29465575 USD, delegasyonla 0.3022213 USD tuttu (+%2.6); çünkü Sonnet ikinci bir tam bağlam (13004 ile 18729 cache-read token'ı) ve ana model yine de üretilen dosyayı yeniden okuyup testi çalıştırdı s6.

Üç bulgu yüzdelerden daha önemli. Birincisi, hook'lar 16 ölçülen çalıştırmanın hiçbirinde tetiklenmedi: CLAUDE.md'deki yönlendirme kuralıyla ana model wc -l çalıştırdı ve kendiliğinden delege etti. Gözlenen tek reddetme, CLAUDE.md'siz bir doğrulama çalıştırmasından geldi: modelin Read'i reddedildi, ardından cat -n reddedildi ve model Agent aracını hiç çağırmadan yalnızca grep -n ile cevap verdi s5. İkincisi, hook'lar subagent'ların içinde de çalışır: atılan iki çalıştırmada Haiku okuyucusunun kendisi boyut kontrolüne takıldı ve parçalı offset/limit okumalarına döndü. Çözüm, hook'un en başına bir case "$agent_type" in Explore|code-writer) exit 0 kaçışı koymak; alan adı loglanan stdin'den doğrulanır s5. Üçüncüsü, temel yapılandırmada ana model Read aracını hiç kullanmadı. Her dosyayı Bash üzerinden okudu (cat -n, sed -n '1,200p', sed -n '200,560p'); yani yalnızca Read'i izleyen bir hook hiçbir şey yakalamaz ve yalnızca borusuz cat, head ve tail'e uyan bir Bash hook'u da sed -n aralıklarını geçirir s3.

Kalite, kaynağa karşı grep ile kontrol edildi. Temel yapılandırma bir S2 çalıştırmasında yanlış satır numaraları üretti (dosyaları satır numarasız sed -n ile döküp elle saydı). Delege edilen yapılandırma diğer S2 çalıştırmasında üç, bir S3 çalıştırmasında iki olgusal hata üretti; hepsi Haiku özetinin olduğu gibi kabul edilmesine dayanıyordu: buildRequest/buildReply için yanlış çağıranlar, dışa aktarılmayan bir sabitin export olarak listelenmesi, kapsanan bir iterator'ın kapsanmamış işaretlenmesi. Ana modelin çıktı token'larını grep ile yeniden doğrulamaya harcadığı yerlerde (S3, 4534 ile 4738 çıktı token'ı) cevaplar doğru çıktı s6. Test yazma senaryosunda üretilen her dosya geçti: 12/12, 6/6, 7/7 ve 10/10 test. Bir Reddit raporu, hiçbir şey sabitlemediğinde ana modelin yanlış modelde worker başlatması şeklindeki ilgili hata modunu gösteriyor s8; require-model hook'u ve agent dosyalarındaki model: alanı buna karşı koruma sağlar.

Ölçümler

Hücre başına 2 çalıştırmanın ortalamaları. "Main context", oturum boyunca ana modele faturalanan input + cache_creation + cache_read token'larıdır; Spotify'ın "ana bağlamdaki token'lar" ifadesiyle karşılaştırılabilir değer budur. A = düz Claude Code, B = hook + subagent'lar + CLAUDE.md kuralı.

senaryo ana bağlam A ana bağlam B değişim ana çıktı A ana çıktı B değişim toplam maliyet A toplam maliyet B değişim süre A sn süre B sn değişim
S1 88693.0 51551.5 -41.9% 1424.5 1060.5 -25.6% 0.13910675 0.08653685 -37.8% 21.817500000000003 43.799499999999995 +100.8%
S2 357165.5 73440.0 -79.4% 3835.0 2555.5 -33.4% 0.5810500000000001 0.21823605000000001 -62.4% 51.637 129.036 +149.9%
S3 303807.5 114135.5 -62.4% 6192.0 4636.0 -25.1% 0.451037 0.3738534 -17.1% 93.321 124.64099999999999 +33.6%
S4 143431.5 121818.0 -15.1% 5275.5 3340.0 -36.7% 0.29465575 0.3022213 +2.6% 65.7125 86.857 +32.2%
4'ünün tümü 223274.375 90236.25 -59.6% 4181.75 2898.0 -30.7% 0.366462375 0.2452119 -33.1% 58.122 96.08337499999999 +65.3%

Protokol: fastify/fastify'ın ac28821d commit'inde, bayt bayt özdeş iki sığ klon; repo-shunt yalnızca .claude/ (ayarlar, iki agent dosyası, üç hook) ve bir CLAUDE.md yönlendirme kuralı ekler, başka hiçbir şey değil. Her oturum: claude -p "<prompt>" --output-format json --setting-sources project --strict-mcp-config, boş bir MCP yapılandırmasıyla, --model olmadan, 600 sn zaman aşımı. İki tarafta özdeş dört prompt: S1 lib/reply.js'in export'ları, S2 üç lib dosyası boyunca çağrı grafiği, S3 lib/hooks.js'in metotları ile test/hooks.test.js kapsamı karşılaştırması, S4 test/noop-set.test.js'i örnek alarak test/head-route.test.js yazmak. Değerler oturum JSON'undaki modelUsage ve total_cost_usd alanlarından, yuvarlanmadan okunur. Cevaplar kaynağa karşı grep ile kontrol edildi; üretilen testler node --test ile çalıştırıldı.

Pazartesi bunu yap

  • Deponuzda wc -l çalıştırın ve 350 satırı aşan dosyaları sayın. Sayı sıfıra yakınsa burada durun: eşik, küçük dosyalarda delegasyonun kazandırdığından fazlaya mal olması yüzünden var.
  • CLAUDE.md'nize üç satırlık bir yönlendirme kuralı ekleyin: eşiği aşan dosyalar okuyucu subagent'a, desene uyan kod yazıcı subagent'a gider; hata ayıklama ve mimari ana modelde kalır. Ölçümlerde tüm işi bu kural yaptı.
  • Frontmatter'da model: haiku ile .claude/agents/Explore.md ve model: sonnet ile .claude/agents/code-writer.md oluşturun; böylece worker modeli orkestratöre bırakılmaz, dosyada sabitlenir.
  • Read üzerinde bir güvenlik ağı olarak PreToolUse hook'unu yazın, güncel hook JSON biçiminde deny kararı döndürsün ve ilk satırları agent_type worker'larınızdan biriyse exit 0 yapsın.
  • Bash hook'unu cat, head ve tail'in ötesine genişletin: büyük dosyalardaki sed -n aralıklarını ve cat -n'yi yakalayın, borulu ve grep komutlarını geçirin.
  • Gerçek bir soruyu .claude/ klasörüyle ve onsuz, claude -p --output-format json ile çalıştırın; yalnızca girdi sütununa değil, total_cost_usd ve duration_ms değerlerine bakarak karşılaştırın.
  • Okuyucunun özetine güvenmeden önce delege edilmiş iki cevabı kaynağa karşı grep ile kontrol edin; ana modelin doğrulama turunu maliyetin bir parçası olarak hesaba katın.
  • Çok turlu bir oturumu da ölçün: tek turlu sonuçlar ana bağlamı delegasyonsuz 84k ile 414k yerine 50k ile 119k token'da bırakıyor, yani ikinci soru daha ucuz başlamalı, ama bu ölçülmedi.

Daha fazlası için

  • Bir blog yazısından hook kopyalamadan önce resmi referanstaki hook biçimini ve agent_type alanını okuyun; deny biçimi ve stdin alanları, subagent muafiyetini mümkün kılan şeydir s5.
  • Subagent dokümantasyonu model frontmatter alanını ve araç kısıtlamalarını anlatır; bir okuyucuyu salt okunur ve ucuz tutmanın yolu budur s6.
  • Spotify'ın kendi "What doesn't work" bölümü yazının en faydalı kısmı: delege edilmiş düzenleme yok (özetlerde güvenilir satır numarası yok), delege edilmiş akıl yürütme yok (kaçırılan thread-safety hatası), 10 ile 30 saniyelik gidiş dönüşler s1.
  • Shunt README'si üç katmanlı yapıyı (hook'lar, script'ler, skill'ler) ve modele ne zaman delege edeceğini söyleyen skill metinlerini gösteriyor; uyarlamaya değer olan hook değil, skill metnidir s2.
  • Portal modları, bir model ve bir sistem prompt'u üzerine konan yapılandırma katmanıdır; aynı fikir, model alanlı bir Claude Code agent dosyasına denk düşer s4.
  • Ölçüm sorularının ilk kez ortaya atıldığı yer Hacker News başlığıdır ve herhangi bir token tasarrufu iddiasına neler sorulması gerektiği için iyi bir kontrol listesidir s7.
  • Bir Reddit başlığı, bir orkestratörün kendi pahalı modelinde beş worker başlatmasını belgeliyor; modeli agent dosyasında sabitleyin ve sert bir garanti istiyorsanız model alanı olmayan Agent çağrılarını reddedin s8.

Kaynaklar

FAQ

%90 rakamı yanlış mı?

Tek bir şeyi ölçüyor: büyük Java dosyalarında toplu okuma senaryoları için ana bağlamdaki tahmini girdi token'ları. Aynı türden bir metrikte yeniden kurulum, okuma senaryolarında %41.9 ile %79.4 arasında sonuç gördü. Maliyet, süre ya da cevap kalitesi hakkında bir şey söylemiyor ve yazı da aksini iddia etmiyor.

Bunu elde etmek için Portal'a ihtiyacım var mı?

Hayır. Yönlendirme bir CLAUDE.md kuralında, modeli sabitlenmiş iki agent dosyasında ve bir PreToolUse hook'unda yaşıyor. Portal, Spotify'da worker modellerini sağlıyor; düz Claude Code'da model: haiku satırı aynı işi görür.

Delegasyon ne zaman daha pahalıya gelir?

Dosyalar küçük olduğunda. 45 satırlık test yazma senaryosu delegasyonla %2.6 daha pahalıya geldi; çünkü yazıcı ikinci bir tam bağlam ve ana model yine de sonucu yeniden okuyup test etti. Delege edilen her çalıştırma ayrıca daha yavaştı, ortalama +%65.3.

Hook neden hiç tetiklenmedi?

Çünkü CLAUDE.md'deki yönlendirme kuralı, ana modelin okumaya çalışmadan önce wc -l kontrolü yapıp delege etmesini sağladı. Hook yalnızca model kuralı görmezden geldiğinde işe yarar; bu da CLAUDE.md'siz doğrulama çalıştırmasında oldu.