Alt ajanlar basitçe yanlış
Explore with AI
Polylane’in otomatik düzeltme ajanı başlangıçta, her biri tek bir görevden sorumlu birden fazla alt ajandan oluşan bir iş akışı olarak tasarlanmıştı:
- binlerce uyarı ve sinyali ayıklayan bir triyaj
- alt ajanları yöneten bir koordinatör
- sorun için olası tüm hipotezleri inceleyen, sayısı on beşe kadar çıkan alt ajanlar
- ve sonunda bir pull request gönderen bir kodlama ajanı
Doğrulanmış bir sorun, inceleme ve düzeltme için 18’e kadar ajan ve alt ajanın devreye girmesine yol açabiliyordu. Bugün aynı iş tek bir ajan tarafından yapılıyor.
Bu iş akışı, o zaman bildiklerimize dayanan mantıklı bir tasarımdı: küçük promptlar, küçük araç setleri, uzmanlar arasında sonuçları taşıyan bir orkestratör. Ancak işletmesi ve üzerine akıl yürütmesi son derece pahalı ve zordu.
Sorun nedir?
Polylane, bağlı her sağlayıcıdaki her bulut kaynağının (Lambda fonksiyonu, Cloudflare Worker, Vercel projesi vb.) günlüklerini, metriklerini ve izlerini tarar. Her kaynak için, verideki mevsimselliği yakalayabilmek amacıyla birden fazla zaman ufkunda taban çizgileri tutarız. Ardından bulut kaynağının mevcut durumunu değerlendirir ve geçmiş verilerle karşılaştırırız. Taban çizgisini bozan değerler sorun olarak kaydedilir.
Sorunlar, gözlemlenebilirlik ve hata izleme çözümlerinden aldığımız uyarılarla da oluşturulabilir.
Sorunları nasıl çözüyoruz?
Bir sorunu çözmek için şunları yapmamız gerekir:
- Triyaj: Sorunu doğrulamak veya reddetmek için veri toplamak.
- İnceleme: Birden fazla hipotezi değerlendirmek ve kök nedeni belirlemek.
- Pull request açmak veya yükseltmek. Sorunu çözmek için bir pull request yazmak, düzeltme bir kod değişikliği değilse bir mühendise yükseltmek ya da bulguları öne çıkaran bir rapor yazıp durmak.
Çalıştırmaların büyük çoğunluğu, Polylane sorunun ya yanlış pozitif ya da zararsız olduğu sonucuna vardığında, bir pull request veya yükseltmeden önce sona erer.
Alt ajan mimarisi
İlk mimarimiz birden fazla alt ajana dayanıyordu.
Birden fazla alt ajan arasındaki işi koordine etmek için bir orkestratör ajan kullanıyorduk. Alt ajanlar, her hipotezi farklı başlangıç noktalarından (örneğin önce günlüklere bakarak ya da önce kod tabanından başlayarak) kanıtlamaya veya çürütmeye çalışarak hipotezleri incelemek üzere oluşturuluyordu.
Alt ajanların bulguları basit aritmetikle oylanıyor ve koordinatör ajana aktarılmadan önce başka bir ajan tarafından özetleniyordu.
Her hipotezin kararı, geçişleri boyunca güvene göre ağırlıklandırılmış bir oylamaydı.
const CONFIDENCE_RANK = { definitive: 4, strong: 3, moderate: 2, weak: 1, speculative: 0 };
function aggregatePassVerdicts(passes: PassResult[]): Verdict {
const weights: Record<string, number> = {};
const counts: Record<string, number> = {};
for (const p of passes) {
weights[p.verdict] = (weights[p.verdict] ?? 0) + CONFIDENCE_RANK[p.confidence];
counts[p.verdict] = (counts[p.verdict] ?? 0) + 1;
}
const totalWeight = Object.values(weights).reduce((a, b) => a + b, 0);
const [winner, winnerWeight] = Object.entries(weights).sort((a, b) => b[1] - a[1])[0];
const countMajority = counts[winner] > passes.length / 2;
const weightMajority = winnerWeight > totalWeight / 2;
if (!countMajority && !weightMajority) {
return { verdict: "inconclusive", confidence: "weak", summary: `No consensus across ${passes.length} passes.` };
}
const majority = passes.filter((p) => p.verdict === winner);
const confidence = majority.reduce((min, p) => (CONFIDENCE_RANK[p.confidence] < CONFIDENCE_RANK[min] ? p.confidence : min), majority[0].confidence);
const lead = majority.reduce((best, p) => (CONFIDENCE_RANK[p.confidence] > CONFIDENCE_RANK[best.confidence] ? p : best));
return { verdict: winner, confidence, summary: lead.summary };
}
Tüm hipotezler incelendikten sonra bir kök neden belirlenmişse koordinatör, ya bir mühendise yükseltir ya da düzeltme için bir plan yazardı. Bu plan, düzeltmeyi uygulaması ve pull request’i göndermesi için bir kodlama alt ajanına devredilirdi.
Bu mimarideki temel sorun, alt ajanlar arasındaki bağlam kaybıydı. Her ajan, özetleme yoluyla bağlamının yalnızca bir kısmını yukarı veya aşağı aktarıyordu ve hem yukarı akıştaki hem de aşağı akıştaki ajanlar düzenli olarak aynı işi tekrarlamak zorunda kalıyordu.
Üstelik düzeltmeyi yazan ajanın elinde yalnızca plan vardı; orijinal sorun ya da inceleme sırasında toplanan kanıtlar hakkında bağlamı yoktu. Bu da genellikle kök neden yerine belirtilere odaklanan, yetersiz pull request’lere yol açıyordu.
Bu mimariyi seçmemizin başlıca nedeni, Mart 2026’da ilk tasarladığımızda öncü modellerin, düzeltmeyi yazmak da dahil olmak üzere bir incelemeyi uçtan uca yürütmede her zaman yeterli olmamasıydı; açıkçası harness’ımız da o kadar iyi değildi.
Bu temel üzerine inşa etmek giderek zorlaştı, çünkü:
- Hata ayıklama çok sayıda iz gerektiriyordu. Uçtan uca bir inceleme üzerine akıl yürütmek, bazen düzinelerce ize bakmayı gerektiriyordu
- Değerlendirme aşama bazındaydı. Her alt ajan tek başına değerlendirilip geçebiliyordu, ama nihai sonuç zayıftı çünkü hatalar devir noktalarında yaşanıyordu.
Bu mimari üzerinde aylarca yineleme yaptık; her ajanı ayrı ayrı geliştirdik, promptları ve devirleri ince ayarladık, ama sonuçlar hiçbir zaman harcanan emeğe denk gelmedi. Pahalıydı, hata ayıklaması zordu ve pull request’ler yeterince iyi değildi.
Tek ajan
3 Eylül’de alt ajan iş akışını, triyajdan pull request’e kadar her şeyi yapan tek bir ajanla değiştirdik. Aynı ajan kanıtları topluyor, tüm hipotezleri inceliyor ve pull request’i gönderiyor.
Triyaj ajanını, koordinatörü, hipotez ajanlarını ve otomatik düzeltme ajanını, aralarında sonuç taşıyan iş akışlarıyla ve pull request’in önünde duran kapılarla birlikte kaldırdık. Operasyonel faydalar hemen ortaya çıktı: değerlendirilecek tek bir iz ve alt ajanlar arasında özet yok.
Daha da önemlisi, pull request’lerin kalitesi arttı ve bir sorunu tespit etmekle onu düzelten pull request’i açmak arasındaki süre kısaldı. Geçiş civarındaki ay boyunca medyan 2.2 saatten 35 dakikaya, p90 ise dokuz günden iki saatin altına indi. Pipeline altında bir bulgu, her biri bir öncekini bekleyen bir iş akışları zincirinde tipik olarak saatlerce bekliyordu. Tek ajan altında ise pull request, sorun tespit edildikten sadece birkaç dakika sonra açılıyor.
Artık çok daha fazla pull request de açıyoruz. Alt ajanları kullanırken tespit edilen sorunların %0.6’sı bir pull request ile sonuçlanıyordu. Tek ajan altında bu oran %4.2 ve yükseliyor. Fark, hata modlarında yatıyor. Birden fazla alt ajanlı bir pipeline’ın her devri atlatması gerekir: triyajın bulguyu ilerletmesi, koordinatörün hipotezler üretmesi, fan-out’un bir karara varması vb. Her devir, olası bir hata modudur.
Pull request başına maliyet de düştü. Artık her çalıştırma daha güçlü modelle başlıyor, bu yüzden reddedilen bir bulgu pipeline altındakinden daha pahalıya mal oluyor. Ancak pull request başına ortalama maliyet, tek ajanın ilk dokuz gününde $111’den yaklaşık $18’e düştü. Bu düşüş yalnızca mimari değişikliğin sonucu değil, çünkü Polylane’in her yönü üzerinde aktif olarak yineleme yapıyoruz. Bunun bir kısmı, sürekli yinelenen bir sistemin olağan sürüklenmesidir.
Üç grafiğin arkasındaki her değer, UTC gününe göre
| Gün | Pull request'i olan tespit edilmiş sorunlar | Medyan | p90 | Pull request başına harcama |
|---|---|---|---|---|
| 14 Aug | 1.9% | 2.3 h | 2.7 h | $144 |
| 15 Aug | 1.1% | 5.6 h | 5.9 h | $270 |
| 16 Aug | 2.3% | 1.2 h | 4.2 d | $121 |
| 17 Aug | 1.5% | 38 min | 4.5 d | $120 |
| 18 Aug | 0.9% | 20 min | 27 min | $57 |
| 19 Aug | 0.7% | 49 min | 12.2 h | $157 |
| 20 Aug | 0.7% | 1 h | 35.9 h | $202 |
| 21 Aug | 0.8% | 44.2 h | 4.2 d | $211 |
| 22 Aug | 0.8% | 7.7 d | 10.4 d | $563 |
| 23 Aug | 1.3% | 32 min | 35.3 h | $205 |
| 24 Aug | 0.6% | 2.5 d | 5.6 d | $90 |
| 25 Aug | 1.4% | 1.5 h | 13.4 h | $43 |
| 26 Aug | 0.3% | 1.5 h | 2.1 h | $45 |
| 27 Aug | 0.7% | 1.9 h | 2.5 h | $58 |
| 28 Aug | 1% | 11.7 d | 14.1 d | $49 |
| 29 Aug | 1.5% | 26.1 h | 10.4 d | $32 |
| 30 Aug | 0.5% | 2 d | 2.8 d | $51 |
| 31 Aug | 0.2% | 9 d | 10.4 d | $77 |
| 1 Sep | 0.1% | 4.2 d | 4.2 d | $169 |
| 2 Sep | 0.1% | 6.7 d | 6.7 d | $93 |
| 3 Sep · tek ajan | 0.4% | 29 min | 2.6 d | $69 |
| 4 Sep | 2.4% | 23 min | 5.4 h | $25 |
| 5 Sep | 2.9% | 34 min | 3.4 d | $15 |
| 6 Sep | 1.4% | 34 min | 43.7 h | $23 |
| 7 Sep | 1.8% | 32 min | 4.5 h | $16 |
| 8 Sep | 4% | 41 min | 19.4 h | $26 |
| 9 Sep | 7.6% | 34 min | 1.2 h | $15 |
| 10 Sep | 5% | 34 min | 1.3 h | $17 |
| 11 Sep | 5.4% | 56 min | 2.1 h | $12 |
| 12 Sep | 9.1% | 35 min | 1.3 h | $3.46 |
| 13 Sep · 16:00'a kadar | 8.2% | 30 min | 55 min | $2.88 |
Alt ajan inşa etme
- Devirler, kazandırdığından fazlasını kaybettirir. Ajanlar arasında geçen her özet, bir sonraki ajanın asla sahip olamayacağı bağlamdır. Kanıtları toplayan ajan, onlara göre hareket eden ajan olmalıdır.
- Ajanları değil, çalıştırmayı değerlendir. Ajan bazlı değerlendirmeler geçer ama sistem başarısız olur, çünkü hatalar ajanlar arasında yaşanır.
- Çalıştırma başına tek bir iz tut. Bir düzine ize yayılmış yanlış bir karar, açıklamak için bir öğleden sonra alır. Tek bir izde ise bir kaydırma yeter.