Pano
14 Eylül 2026

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ı

graph TB
    S["Alerts and signals"] --> T["Triage agent"]
    T -->|"confirmed issue"| C["Coordinator agent"]
    C -->|"hypotheses"| H["Up to 15 hypothesis sub-agents"]
    H -->|"verdicts"| C
    C -->|"plan"| A["Coding agent"]
    A --> PR["Pull request"]
    style C fill:#fee2e2,stroke:#fca5a5,color:#7f1d1d
    style H fill:#fee2e2,stroke:#fca5a5,color:#7f1d1d

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.

graph TB
    R["Cloud resource"] -->|"telemetry"| B["Compare with its baselines"]
    A["Alert from an observability<br/>or error tracking provider"] --> I
    B -->|"breaks the baseline"| I["Issue"]
    B -->|"within the baseline"| N["No issue"]
    style I fill:#fee2e2,stroke:#fca5a5,color:#7f1d1d

Sorunları nasıl çözüyoruz?

Bir sorunu çözmek için şunları yapmamız gerekir:

  1. Triyaj: Sorunu doğrulamak veya reddetmek için veri toplamak.
  2. İnceleme: Birden fazla hipotezi değerlendirmek ve kök nedeni belirlemek.
  3. 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.

graph TB
    I["Triage the issue"] --> V["Investigate the root cause"]
    V -->|"dismiss, fold, or reopen"| E["Report and stop"]
    V -->|"confirm"| X["Open a pull request"]
    V -->|"confirm, no code change"| Z["Escalate to an engineer"]
    style V fill:#fef3c7,stroke:#fcd34d,color:#78350f
    style X fill:#d1fae5,stroke:#6ee7b7,color:#065f46

Alt ajan mimarisi

İlk mimarimiz birden fazla alt ajana dayanıyordu.

graph TB
    F["Finding"] --> T["Triage agent"]
    T -->|"confirm"| C["Orchestrator agent"]
    C -->|"hypotheses"| W["Fan-out workflow"]
    W --> H1["Hypothesis agent 1"]
    W --> H2["Hypothesis agent 2"]
    W --> H3["Hypothesis agent ..."]
    W --> H15["Hypothesis agent 15"]
    H1 --> AG["Vote and summarize"]
    H2 --> AG
    H3 --> AG
    H15 --> AG
    AG -->|"summary as a message"| C
    C -->|"confirmed hypothesis"| AF["Coding agent"]
    AF --> PR["Pull request"]
    style C fill:#fee2e2,stroke:#fca5a5,color:#7f1d1d
    style AG fill:#fee2e2,stroke:#fca5a5,color:#7f1d1d

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.

graph TB
    I["Issue"] --> O["Orchestrator<br/>splits the issue into briefs"]
    O -->|"brief A"| A["Sub-agent A<br/>investigates brief A"]
    O -->|"brief B"| B["Sub-agent B<br/>investigates brief B"]
    A -.->|"summary A"| M["Orchestrator, later<br/>writes the plan from the summaries"]
    B -.->|"summary B"| M
    M -.->|"plan"| F["Coding agent<br/>writes the fix"]
    F --> PR["Pull request"]
    style I fill:none,stroke:none
    style PR fill:none,stroke:none
    style O stroke:#4C8C57,color:#3d7046
    style A stroke:#3b7dd8,color:#2b5fa8
    style B stroke:#7c5cd6,color:#5b3fb0
    style M stroke:#a07d1c,color:#7a5f14
    style F stroke:#6b7280,color:#4b5563
    %% aside O right #4C8C57 Issue, alerts and history
    %% aside A left #3b7dd8 Brief A and its evidence
    %% aside B right #7c5cd6 Brief B and its evidence
    %% aside M right #a07d1c History and two summaries, no evidence
    %% aside F right #6b7280 The plan, nothing else

Ü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.

graph TB
    F["Issue"] --> A["Single agent"]
    A --> I["Triage"]
    I --> B["Investigate"]
    B --> V["One verdict"]
    V -->|"confirm"| X["Clone, edit, validate in the sandbox"]
    X --> PR["Open the pull request"]
    V -->|"dismiss, fold, or reopen"| E["Report and stop"]
    V -->|"confirm, no code change"| Z["Escalate to an engineer"]
    style A fill:#d1fae5,stroke:#6ee7b7,color:#065f46
    style PR fill:#d1fae5,stroke:#6ee7b7,color:#065f46

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.

15 dk 1 sa 4 sa 1 g 4 g 2 hf 14 Aug 18 Aug 22 Aug 26 Aug 30 Aug 3 Sep 7 Sep 11 Sep 3 Eylül: tek ajan 30 min
Günlük medyan Günlük medyan to p90 Axis not to scale
Şekil 1
Bir sorunu tespit etmekten pull request'ini açmaya kadar geçen saat

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.

0% 2% 4% 6% 8% 10% 14 Aug 18 Aug 22 Aug 26 Aug 30 Aug 3 Sep 7 Sep 11 Sep 3 Eylül: tek ajan 9.1%
Şekil 2
Pull request ile sonuçlanan tespit edilmiş sorunların oranı

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.

$1 $10 $100 $1,000 14 Aug 18 Aug 22 Aug 26 Aug 30 Aug 3 Sep 7 Sep 11 Sep 3 Eylül: tek ajan $2.88
Logarithmic scale
Şekil 3
Açılan pull request başına model harcaması
Üç grafiğin arkasındaki her değer, UTC gününe göre
GünPull request'i olan tespit edilmiş sorunlarMedyanp90Pull 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.

2026'da kimse on-call olmamalı. Polylane altyapını izler, inceler ve bozulanı düzeltir.

Bekleme listesine katıl