Uyanıkken büyüt, uyurken sistemi dayanıklılaştır: benim agentic çalışma döngüm
WORKFLOWTekrarlanabilir çalışma akışı.VOICEKonuşma kaynaklı üretim.LINEAGEParent/child/relation soy ağacı gerekiyor.AI-DEVELOPMENTAI ile geliştirme pratiği.
Şu anda kendi çalışma şeklimi göstermek istiyorum. Soyut bir “AI ile çalışıyorum” anlatısı değil bu; tam o anda önümde duran şantiyeyi, ajanların kaç saattir çalıştığını, hangi işin neden stage’de beklediğini, hangi kuralın neden çağrıldığını ve bu içeriğin kendisinin nasıl çıktığını göstermek istiyorum.
Burada anlattığım şey sonradan oturup çıkardığım temiz bir metodoloji değil. Bu benim o anki çalışma döngüm. Konuşurken ajanlar çalışıyor, ben ekrana bakıyorum, bir şey kopyalıyorum, bir yeri işaretliyorum ve aynı anda neden öyle çalıştığımı anlatıyorum. O yüzden yalnız sonucu değil, o sonuca giderken gerçekten kullandığım sistemleri de göstereceğim.
Kapak için en dürüst görüntü bu: 1049 staged değişiklik, 308 açık değişiklik. Bu sayılar “çok kod yazdım” rozeti değil. Çok sayıda ajanın aynı şantiyede, farklı soyların içinde çalıştığı bir anda, benim önümde duran denetim yüzeyi.
1049 staged ve 308 açık değişiklikle çalışan çok-ajanlı Source Control yüzeyi.
Ben geriye yönelik gitme eylemini çok az yapıyorum. Tüm olanlar çoğunlukla forward, ileriye dönük. Ajanın yazdığı şeye bakıyorum, uygun olanı stage’e alıyorum. Commit’i kendim atmaya çalışmıyorum; commit beni yavaşlatıyor. Onun için de commit ajanları çıkarıyorum. Stage’e aldıklarımı kendi commit kurallarıma göre onlar kapatıyor. Changes tarafı ise ajanların o anki çalışmaları, benim henüz denetlemediğim veya devam eden parçalar.
Swatch’ları ve test sayılarını çok önemsemiyorum, çünkü onları zaten anlık yapıyorum. Benim için bu görüntü geçmişe dönüp tek tek ne yaptığımı saydığım bir rapor değil. Bütün hareket forward. Bir şeyi kabul ediyorum, stage’e alıyorum ve sıradaki şeye geçiyorum. Commit atmak ayrı bir dikkat istediği için onu da aynı akışta kendime iş çıkarmadan başka ajanlara veriyorum. Benim önümde kalan yüzey, neyin hazır olduğunu ve hangi ajan işinin hâlâ aktığını göstermeli.
Burada derdim, mükemmel sistem kurulsun diye bütün kaynak kodları tek tek okuyayım değil. Derdim her şeyin mümkün olduğunca görsel olması, UI katmanında görünmesi, akıp giden işin logla hesap vermesi. Bir şey kullanımda kırıldığında şunu diyebilmek istiyorum: “Bak, bir şeyler bozulmuş. Loglara bak. Kim bozmuş bunu?” Ajan oradan gerçek yolu bulsun; gerekiyorsa Git geçmişine baksın ve toplasın.
İki farklı enerji, iki farklı iş
Ghostty kullanıyorum. Şu anda refactor modundayım; yani sistemler zaten kurulmuş durumda. Kurduğum bütün sistemler sekmelerde, farklı ajanlarda çalışıyor.
Ghostty içinde farklı sorumluluk alanlarında çalışan refactor ajanları.
Enerjim varken kafamda ne varsa, kırık da olsa, mümkün olduğunca hızlı somut hale getirmeye çalışıyorum: bir yazılım, çalışan bir ürün, görülebilen bir şey. Enerjim tükendiği zaman — genelde çok çalışmaktan, burnout tarafına geldiğim zaman — zihnim daha hafif iş istiyor. Daha az çalışasım geliyor, yorgun oluyorum, evi toplayasım geliyor.
Ben o zamanı çöpe atmıyorum. O arada ajanları bağımlılık zincirlerine, benim “soy ağacı” dediğim yapıya göre dağıtıyorum. Dosyaları dibine kadar parçalıyorum, bölüyorum; en kötü küçük dosyalar oluşturuyorum. Yeni ürün üretmek yerine var olan sistemin dayanıklılığını artırıyorum.
Enerjim varken kurabildiğimi kurmaya çalışıyorum. Kırık da olsa kafamda ne varsa hepsini somut hale, bir yazılıma veya çalışan bir ürüne çevirmeye çalışıyorum; mümkün olduğunca hızlı. Tükendiğim anda ise kendimi hâlâ yeni şey üretmeye zorlamıyorum. Zihnimin hafif kaldığı o zamanı, zaten kurulmuş sistemleri dibine kadar dağıtmak, parçalamak ve sınırlarını belirginleştirmek için kullanıyorum. En kötü küçük dosyalar çıkıyor; ama hangi parçanın hangi parçayla gerçekten yaşadığını görmeye başlıyorum.
Bunu tek cümleyle şöyle özetliyorum:
Uyanıkken sürekli büyümeye çalışıyorum, uyurken dayanıklılığa odaklanıyorum. Ben dinlenirken sistem de dinlensin, korunsun.
“Uzun çalışan ajan” gerçekte ne demek?
Merak eden insanlar için tam o anda çalışan ajanların sürelerini de göstereyim. Bunların hepsi refactor işi. Biri 10 saat, biri neredeyse 12 saat, ikisi 3 saati geçmiş, biri 12 saat 53 dakikaya gelmiş durumda. Bazıları blocked kısmına düşüyor; ben uyandığımda onları topluyorum.
İkinci bilgisayarda runtime doğrulayan 10 saatlik Forge refactor oturumu.
Kendi scope’unda çalışan ve şantiye sınırında SLOT bırakan Clipboard refactor ajanı.
Yabancı build biterken bekleyen Cockpit + terminal refactor oturumu.
Fault’u gizlemeden gerçek launcher authority’si üzerinden ilerleyen COS refactor ajanı.
Optional ve environment belirsizliklerini kapalı state’lere çeviren Dictation refactor ajanı.
Uzun çalışma benim için “ajanı bırak, ne yaparsa yapsın” demek değil. Başlangıçtaki hedefi ve sorumluluk alanını baştan vermek; başka bir aktörün canlı alanına gelince durmasını, gerçek bir engelde beklemesini ve bilmediği yerde başarı sallamamasını istemek demek.
> Bu sistemdeki teknik karşılığı: scope, authority, runtime judge ve durma kapısı baştan belli. Başka bir aktörün canlı dosyasına dokunması gerekiyorsa SLOT bırakıyor; gerçek bir build kilidi varsa bekliyor.
Bu ajanların hepsi refactor yapıyor. Bazıları blocked kısmına düşüyor; ben onları sonra topluyorum. Sürenin uzun olması tek başına değer değil. Bir ajanın 10–12 saat çalışabilmesi, başlangıçtaki işi unutmadan ve başka bir ajanın alanına taşmadan devam edebildiğinde anlamlı. Yoksa aynı uzunluk, yalnızca daha uzun süre yanlış yöne gitmek olur.
Denetimi kodda değil, kullanımda kapatıyorum
Swatch’ları ve testleri anlık yaptığım için sayıları çok önemsemiyorum. Gece işlerinde çoğunlukla yeni runtime davranışı üretmiyorum; var olan davranışın belirsizliğini azaltıyorum. Denetleme sırasında da mümkün olduğunca kodlama yapmamaya çalışıyorum. Kod beni düşündürüyor ve yavaşlatıyor. Genellikle görsel katmanda kalıyorum.
Ajanlar görsel testleri ikinci bilgisayarımda yapıyor:
Ajanların görsel ve runtime denetimlerini çalıştırdığı ikinci bilgisayar.
Ben de uygulamanın kendisini zaten sürekli kullandığım için devamlı test halinde sayılırım. Normal kullanım akışına devam ediyorum. Bir şey kırıldıysa hemen karşıma çıkıyor. Ses kaydı açık olduğu için o kırık aynı anda bağlama, göreve ve sonra içeriğe dönüşebiliyor.
> Bu yaklaşımın dışarıdaki adı: dogfooding, yani kendi ürününü kullanmak. Buradaki ek fark, kullanım anındaki sürtünmenin konuşma ve görsel referansla kaybolmadan ajana taşınması.
Denetim yaparken özellikle mümkün olduğunca kodlama yapmamaya çalışıyorum. Kod kısmı beni düşündürüyor ve yavaşlatıyor. Ben görsel katmanda kalıyorum; ajanlar ikinci bilgisayarda görsel ve runtime testlerini yapıyor. Onlar loglardan kaçarsa ben normal kullanımda görüyorum ve “Bak bir şeyler bozulmuş, loglara bak. Kim bozmuş bunu?” diyorum. Gerekirse Git geçmişine bakıyorlar, gerçek değişikliği buluyorlar ve topluyorlar. Ben zaten uygulamayı kullandığım için ayrı bir test senaryosu oynamıyorum; normal kullanımın kendisi sürekli test oluyor. Ses kaydı sayesinde karşılaştığım problem de o anda çok hızlı içeriğe dönüşebiliyor.
Soy ağacı: silince hayatta kalıyor mu?
Soy ağacından kastım şu: Neyi silersem sistem kırılır? Bir şeyi sildiğimde sistem kırılıyorsa aynı soydan geliyor; o zaman gerçek bir bağımlılık olması lazım. Sildiğimde sistem kırılmıyorsa, arada bağımlılık olmaması lazım.
Bu testi çok iyi kurabilirsem ajanlar birbirleriyle çakışmaz; çünkü zaten birbirlerine değmezler. Kod merkezleri aynı proje içinde olsa bile sorumluluk soyları ayrıysa çakışma ihtimali düşer. Teoride bunu kusursuz yapmak çok zor. Sistem geliştikçe soyları tekrar ölçmek ve güncellemek gerekiyor. Ama belli bir eşiğin üstüne geldiğinde artık bunu sözlü ve mekanik bir sözleşmeye çevirebiliyorum.
Buradaki iddiam “soy ağacını bir kere çıkardım, bitti” değil. Sürekli geliştirme yaptıkça bu ağacı yeniden güncellemek gerekiyor. Mükemmel kurmak çok zor. Ama belli bir oranın üstüne çıktığında, ajanlara sözle verebildiğim gerçek sorumluluk sınırları oluşuyor. O zaman aynı projede, hatta birbirine yakın kod merkezlerinde çalışsalar bile, teoride birbirlerine değmemeleri mümkün hale geliyor.
Kaynaktan kullanıcı yüzeyine kadar tek owner altında kapanan örnek lineage ağacı.
Bir dosyanın yüzde 50’sini bir paket, yüzde 40’ını başka bir paket kullanıyor ve hiç kimse tamamını kullanmıyorsa ajan onu iki parçaya ayırıyor. Her consumer yalnız kullandığı kodu import ediyor. Runtime bağı yoksa build-time bağı da kalmıyor. Bu parçalama ilerledikçe aynı şeyin iki yerde tanımlandığı noktalar ortaya çıkıyor. Ben buna drift diyorum: aynı görevi iki farklı kişiye vermek gibi. Ajan onu tek sorumluluk ağına bağlıyor.
Bu işler genelde yeni bir özellik gibi hemen sonuç vermiyor. Sıkıcı tarafı da bu. Daha çok kaliteyi, stability’yi, bakımı ve dayanıklılığı artırıyor. Gündüz üretirken sürekli erteleyebileceğim şeyler bunlar; çünkü ekranda yeni bir şey çıkmıyor. Ben uyurken yapılmasının anlamı burada: insanın yaratıcı enerjisini harcamadan, sistemin sonradan çıkaracağı belirsizlikleri erkenden azaltıyor.
Böylece runtime’da soracağımız “Lan bu niye hareket ediyor da bu etmiyor?” sorusunun cevabı bazen daha kod yazılırken görünür hale geliyor.
Şantiye: aynı yerde çalış, aynı scope’a girme
Her ajana bir sorumluluk alanı veriyorum. Dictation, Clipboard, Cockpit gibi alanlar birbirinden tamamen kopuk değil; ortak kod çıkabiliyor. Bir problem gördüğümde kimin scope’unda olduğunu bilmiyorsam olası iki ajana da atıyorum:
> “Bu senin scope’undaysa çöz. Senin değilse işine devam et ve kime ait olduğunu bildir.”
Clipboard “Bu benim scope’um” diyebiliyor; Dictation “Bu benim değil, Clipboard’a ver” diyebiliyor. Bu konuşmayı ben koordine ediyorum, çünkü ajanlar birbirleriyle konuşurken fazla bağlam siliyor ve uzun işlerde geriden sapabiliyor. Ben bütün bağlama sahip olduğum için scope kararını taşıyorum.
“Şantiyede çalışıyorsun” ifadesi ajanlara başka aktörlerin de canlı olduğunu hatırlatıyor. Ama tek kelimenin sihirli bir etkisi yok. Arkasında dosya soyları, owner’lar, runtime sınırları, local authority’ler ve birbirleriyle nasıl çalışacaklarını anlatan kural mekanizması var.
Kural gövdesi değil, denenmiş prensip
Benim AGENTS dosyalarım ve ayrıca rules dosyalarım var. Rules, implementasyon notları değil; implementasyon zaten codebase’de ve compiler onu denetleyebiliyorsa aynı şeyi prose olarak kopyalamıyorum. Bunlar daha çok sistem kurarken keşfettiğim, denediğim ve kaldırıldığında sistemi yanlış kurduracak prensipler.
Çalışanları tutuyorum; çalışmayanı “kural” diye saklamıyorum. Kural gövdesi, codebase’de zaten duran alan adlarını veya compiler’ın zaten zorladığı implementasyonu yeniden anlatmıyor. O bilgi kodda varsa sistem onu mekanik olarak yakalayabiliyor. Benim burada biriktirdiğim şey, kod değişse bile sistemi yanlış kurmamak için ihtiyaç duyacağım prensip tarafı.
Mesela: Sistem arka planda bir iş yapıyorsa bunu kullanıcıya bir şekilde göstermesi lazım. Ama gösterme biçimi her zaman yazı olmamalı; yazı insanı düşünmeye zorluyor. İşin niteliğine göre motion, animasyon, görsel, ses veya başka bir geri bildirim kullanılmalı. Bu bir implementasyon tarifi değil; farklı yüzeylerde tekrar sınadığım bir prensip. Bir kuralı tek seferde “doğru” ilan etmiyorum; bazen beş farklı yerde deniyorum, çalıştığında doğru owner’a koyuyorum.
Kural oluşturma kuralının kendisi de prompt’un içinde. Crawl/preflight tarafı da prompt’tan başlıyor. Yani ajan yalnız kuralları okumuyor; yeni bir sürtünmeden kural çıkarmanın hangi kapıdan geçeceğini de baştan alıyor. Sistem kurdukça crawl’lar ve ilişkiler birikiyor. Bugün bunu yapabiliyor olmamın nedeni, arkada geniş bir altyapının zaten kurulmuş olması.
Bu altyapı bir gecede çıkmadı. Claude Code’la saydığımda yaklaşık bir yıllık yoğun çalışma var; bunun son yedi-sekiz ayı sürekli refactor ettiğim Mac uygulamasıyla geçmiş olabilir. Kuralları anlamak için sistemi defalarca baştan yazdım. Bugün bu kadar geniş bir kural ve crawl/preflight altyapısıyla çalışabilmemin nedeni o birikim.
Düz dosya sistemiyle kuralları yüklemeyi de denedim. Benim gözlemim şu oldu: Bazı Claude/Fable oturumları, kendi harness ve ortam promptları daha ağır olduğu için benim kural dosyalarımı daha az düzenli okuyabiliyor; Codex’in terminal yüzeyi daha hafif olduğu için aynı kurallara daha sık uyuyor. Bu bir evrensel model yasası değil, kendi çalışma ortamımdaki gözlem. Zaten bu yüzden “dosyayı koydum, ajan okur” varsayımına güvenmeyip anchor ve session telemetry’si kurdum.
Burada tek bir kelimenin veya tek bir prompt’un bütün davranışı değiştirdiğini söylemiyorum. “Şantiyedesin” dediğimde ajanın başka aktörleri hesaba katması, arkasındaki kural ve scope sistemi yüzünden mümkün oluyor. Aynı şekilde bir dosyaya kural yazmak da o kuralın okunacağını garanti etmiyor. Ben dosyayı koyup unutmak yerine, hangi kuralın hangi niyetle çağrıldığını ve başka hangi kurallarla gerçekten ilişkili olduğunu ayrıca izliyorum.
Kural oluşturma kuralım da prompt’un içinde. Kural yazmadan önce filtre şu:
> Bu kural olmadan sistem kesinlikle ama kesinlikle bozuk kurulur mu?
Cevap evetse ve mekanik olarak kodun kendisi zaten zorlamıyorsa kural olabilir. Cevap hayırsa kalıcı kural yazmıyorum.
Aşağıdaki blok, kullandığım refactor prompt’unun gizliliğe göre düzeltilmiş omurgası. Özel dosya, ürün içi rota ve proje sırrı yok; ama insanın işine yarayacak kısmını da kırpmadım:
Ana hedefi koru; yeni kapsam done-state’i gerçekten genişletiyorsa hedef sayacını yenile.
- Sistemi runtime soylarına göre yeniden tasarla; gerçek consumer ayrımını package ve owner sınırlarına taşı.
- Runtime bağı olmayan build bağlarını kes; bağımsız aktörleri aynı file/code soyunda tutma.
- Impossible state, fabrication, fallback ve environment/path/string drift’lerini gerçek runtime kodunda sil.
- Action → authority → result yolunu O(1) görünürlük, dispatch table ve structured log ile hesap verebilir yap.
- App’ler arasında tek-writer, parent/lifecycle, duplicate-process ve headless/background sınırlarını kapat.
- İzin, storage, hotkey ve user action soylarını önceden tanımlı feedback/motion/sound policy’sine bağla.
- Native sistemleri önceliklendir; custom çözüm ancak deterministic, zero-false-positive ve daha az bakım istiyorsa seçilsin.
- Şantiyede başka aktörün scope’una girme. Çakışma varsa SLOT bırak; legacy alias veya fallback ekleme.
- Eski yol ancak yeni soyda aynı davranış runtime’da yeniden ölçüldükten sonra silinsin; feature kaybını legacy’ye dönerek değil yeni authority’ye göç ederek kapat.
Kurallarda [denendi], [gerekli], [dene], [faydalı] gibi etiketler kullanıyorum. Başta kendim için koymuştum. Sonra fark ettim ki ajan da bunları okuduğunda epistemik ağırlığı anlıyor: “Bunu denemişsin ve gerekli diyorsun; o zaman bu sıradan öneri değil.” Ajan çok fazla sallayabildiği için ona özellikle denenmiş + gerekli olanları taşıyorum. Denenebilir fikirleri ise kendim denetliyorum.
Kamusal olarak kural gövdelerini vermiyorum. Ama ölçeği ve isim mantığını görünür kılmak için, tam o anda root source/md yüzeyindeki 166 başlığı yazının sonundaki katalogda yalnız ad olarak taşıyorum. Burada önce bu yapının nasıl çalıştığına devam ediyorum.
Bu listede gövde yok. Burada yalnız miktarı ve isim mantığını göstermek istiyorum; dosyaların içeriğini paylaşmıyorum. İnsanların kafasında ölçek oluşsun, ama benim gizliliğim ve projenin kendi değeri sızmasın.
> Teknik sınır: Kural gövdeleri kendi authority’sinde kalıyor. Bu Guide yalnız adları ve güvenle paylaşılabilen örnekleri gösteriyor; ikinci bir kural kaynağına dönüşmüyor.
Gösterilebilecek birkaç prensip örneği şöyle:
- [denendi] [gerekli] Görünürlük, yüzey-altı her işin lifecycle atasıdır. Kullanıcı sonuçtan etkilenecekse işin çalıştığı ve kapandığı görünür olmalı.
- [denendi] [gerekli] Tek writer kapısı. Aynı durumu iki bağımsız aktör yazmamalı; tek owner değiştirir, diğerleri olay veya istek gönderir.
- [denendi] [gerekli] Authority okuma sırası. Projeksiyon, hafıza veya not değil; sonucu kıran kaynak önce okunur.
- [denendi] [gerekli] Emit → refresh bağı. Bir olay görünür state’i değiştiriyorsa receiver projeksiyonu aynı nedensel olaydan yenilenir.
- [denendi] [gerekli] Paralel writer disiplini. Aynı şantiyede çalışmak aynı dosyayı sahiplenmek değildir.
Her başlığın içinde [#...:...] biçiminde çapalar var. Bir kural başka bir kuralı bu çapalarla çağırıyor. Dosya sistemi tek başına yetmedi; ajanların bazen gerekli dosyayı okumadığını, bazen de alakasız kuralı bağlama sızdırdığını gördüm. Bu yüzden düz dosya yüklemek yerine kural ilişkisini çağıran bir mekanizma kurdum.
COS anchor ve preflight
COS, Chat Operation System. Benim en kilit komutlarımdan biri anchor. Görselde dört şey var: komut, consumer, session ve çağrılan anchor kökleri.
COS anchor komutunda consumer, session ve kural kökleri.
consumer, hangi ajan/harness’in kuralı istediğini; session, hangi canlı konuşmanın tükettiğini gösteriyor. Anchor’lar ise kural ağacının kökleri. Bir kökü çağırınca komut onun aşağı soyunu — çocuklarını, torunlarını, ilgili context’leri — veriyor. Böylece ajan gerçekten doğru kural closure’ını aldı mı ölçebiliyorum.
Aynı telemetry mantığını ajanlara uyguluyorum: Hangi ajan hangi kuralı kullandı? Birlikte sürekli çağrılan iki kural arasında gerçek bir ilişki var mı? İlişkisiz ama sürekli taşınanları bulup temizliyoruz; eksik bağı bulup soy ağacını güncelliyoruz.
İnsan sistemlerinde “kullanıcı nereye tıkladı, neyi kullandı?” diye telemetry topluyoruz. Ben aynısını ajanlar için kurmaya çalışıyorum. Hangi consumer, hangi session içinde, hangi anchor’ı çağırdı? Sürekli birlikte çağrılan ama aralarında gerçek ilişki olmayan kurallar var mı? Bir kural aslında başka bir kökten mi gelmeliydi? Bu gözlemler kural ağacını yeniden düzenlememe yardım ediyor. Ama iki şey sık sık birlikte geldi diye otomatik olarak aynı soydan saymıyorum; ilişkiyi ayrıca denetliyorum.
Session başında hook çalışıyor ve context gate’i zorunlu kılıyor:
SessionStart anında preflight zorlayan context gate.
Ben buna preflight, uçuş öncesi diyorum. Ajan konuşmanın başında niyetimi, bağımsız kural köklerini ve hedefi topluyor. Büyük bir işte ilk context’in yüzde 20–30’u kurallara gidebiliyor. Kısa vadede daha çok token ödüyorum; uzun vadede yanlış yönde proje gezmek, tekrar test etmek ve kayıp bağlamı bulmak için token harcamıyorum. Yanlış yöne gitmek en pahalı şey.
Kuralları yolda vermeyi denedim. Ajanın kafası karıştı, hepsini yapamadı, asıl hedefi unuttu; benim yönetimim de zorlaştı. Şimdi bütün gerekli kökleri başlangıçta topluyor, yapılacak işi donduruyor ve bana bir kez gösteriyor. “Okay” dediğimde yeni ajan açmıyor; aynı ajan aynı bağlamla devam ediyor. Konuyla alakalı bağlamı, token pahalı diye sıfırlamıyorum.
Ben varsam üretim açık, ben yoksam kapalı
Ajanların başında ben varsam onları üretim için kullanıyorum. Yeni bir şeyin niyetini ben söylüyorum, görselini ben işaretliyorum, sonucu ben kontrol ediyorum. Yaratım kısmını insan olarak ben üstleniyorum.
Başlarında durmayacaksam, uyurken çalışacaklarsa üretim kısmını kapatıyorum. Ajanlar yeni ürün veya yeni niyet üretmiyor; yalnız belirsizlik çözüyor. Runtime’da karşılaşacağımız bir durumu mümkünse build-time’da belirgin hale getiriyor, soyları ayırıyor, duplicate authority’leri tekilleştiriyor, log ve judge ekliyor.
Ben başındaysam üretim yapabiliyor, çünkü ne istediğimi canlı olarak söylüyor, görselde işaretliyor ve çıkan şeyi kontrol ediyorum. Ben yokken bu yaratım kaynağı da yok. O yüzden gece işi “bana yeni bir ürün tasarla” değil; mevcut kodu anla, runtime’da belirsiz duran şeyi daha erken görünür hale getir, gerçekten kullanılmayan bağı kes ve aynı görevi iki yere vermeyi bırak. Ajan burada invention değil, translation yapıyor.
Aynı goal içinde 12 saat 30 dakika çalışan refactor ajanı.
Goal’un kendisi bunu sağlamıyor. Düz goal aynı prompt’u tekrar tekrar söylemek gibi. 12 saatlik bir ajan başlangıç işini bile unutabilir. Bu nedenle hedefin yanında karar taşıyan bağlamı dinamik olarak yeniden veriyorum.
Impossible state’i runtime’a bırakma
Ajanlar genellikle her şeye optional veya nil koyuyor. Sonra elinde elli tane nil’li obje oluyor; teoride ulaşılamaz kombinasyonlar runtime’a kadar yaşıyor. Bug’ı görmek zorlaşıyor, ajan boş alanı tahminle doldurabiliyor.
Ben bunu discriminated union / enum ile kapatıyorum. State’in gerçekten mümkün olan halleri tek kapalı küme oluyor. TypeScript örneği:
type RunState =
| { kind: "idle" }
| { kind: "running"; sessionId: string; startedAt: Date }
| { kind: "failed"; sessionId: string; error: RunError }
| { kind: "completed"; sessionId: string; result: RunResult };
function render(state: RunState): ViewModel {
switch (state.kind) {
case "idle": return idleView();
case "running": return runningView(state.sessionId, state.startedAt);
case "failed": return failedView(state.sessionId, state.error);
case "completed": return completedView(state.sessionId, state.result);
default: return assertNever(state);
}
}
Swift’te aynı ilişki:
enum RunState {
case idle
case running(sessionID: SessionID, startedAt: Date)
case failed(sessionID: SessionID, error: RunError)
case completed(sessionID: SessionID, result: RunResult)
}
switch state {
case .idle:
showIdle()
case let .running(sessionID, startedAt):
showRunning(sessionID: sessionID, startedAt: startedAt)
case let .failed(sessionID, error):
showFailure(sessionID: sessionID, error: error)
case let .completed(sessionID, result):
showResult(sessionID: sessionID, result: result)
}
Burada switch case başka problemleri ortaya çıkarıyor: olmayan bir case’te kullanılan uydurma folder, eksik owner, yanlış fallback artık compiler veya kapalı runtime judge tarafından yakalanıyor. Ben buna runtime belirsizliğini build-time kararına translation etmek diyorum. Ajan yeni bir şey üretmeden, var olan davranışı anlayıp daha dürüst bir tipe çevirebiliyor. Loglar burada çok kritik; değiştirdiği davranışı gerçek runtime’da tekrar ölçüyor.
Uzun bağlamı statik doküman gibi tutmuyorum
COS içinde kendi transcription yöntemim var. Session ID’yi veriyorum; o konuşmadan yalnız davranışı gerçekten değiştiren üç şeyi alıyor:
1. Benim söylediğim mesajlar. 2. Ajanın bana söylediği mesajlar — çünkü benim sonraki tepkimi değiştiriyor. 3. Ajanın değiştirdiği dosyaların yolları.
Dosya okumaları, tool trace’lerinin çoğu ve geçici kural okumaları atılabilir ara katman. Normalde yaklaşık 260 bin tokenlık context’in karar taşıyan gövdesi yaklaşık 40 bin tokene inebiliyor. Buna “özet” demiyorum; orijinal konuşmayı yeniden anlatmıyor, karar değiştiren transcript’i kırpıp kaynağıyla taşıyor.
Context compact olduğunda bu gövde tekrar öne geliyor. Sistem bunu katmanlar gibi ele alıyor; konuşma büyüdükçe eski iki-üç compact katmanını yavaşça düşürüyor. Kaynak kod diff’ini gövdeye kopyalamıyor, yalnız dosya yolunu taşıyor. Böylece bağlam statik duran bir doküman değil, konuşma ilerledikçe güncellenen dinamik bir form oluyor.
Otonom işte bu birikim normal bir insan–ajan konuşması kadar hızlı büyümüyor. Ben sürekli yeni mesaj yazmıyorum; ajan dosya okuyor, değişiklik yapıyor, kendi ara adımlarını konuşuyor. Onların çoğu atılabilir olduğu için taşınmıyor. Kaynak kod değişikliğini de transcript’in içine tekrar kopyalamıyorum; yalnız yeniden okunabilecek yolu kalıyor. Yine de sınır var: compact katmanları sonsuza kadar üst üste koymuyorum, eski katmanları kontrollü biçimde düşürüyorum.
Bu rehber sırasında eklediğim gerçek bir conversation kaydı, 91 bin tokenlık bir refactor oturumunda yalnız mesajları ve değiştirilmiş dosya yollarını görünür hale getiriyordu. O private oturumun ID’sini ve dosya listesini burada yayımlamıyorum; önemli olan mekanizma: kaynak söz korunuyor, yeniden ölçülebilir repo gerçeği kopyalanmak yerine yolu ile taşınıyor.
İş bitince kural çıkar mı?
Ben uyandıktan ve iş kapandıktan sonra ajana soruyorum:
> “Burada keşfedilen ve kurallarımızda olmayan bir kural var mı? Bu kuralı kaldırırsak sistemi yanlış kurar mıyız?”
Ajan adayları veriyor, ben özellikle bunları denetliyorum. Kaynak koddan daha önemli görüyorum; çünkü yanlış kural bir sonraki bütün kaynak kodu yanlış kurabilir. Denenmiş olanı doğru owner’a dağıtıyorum.
İki kural çakışırsa bunu matematik formülü gibi ele alıyorum. Bir formülün çalışmadığı senaryo geldiyse eski formülü koşullandırırsın; “bu kural yalnız şu zeminde geçerli, öbür zeminde şu kurala git” dersin. Eski kuralı sessizce öldürmüyor, sınırını daraltıp ilişkiyi görünür yapıyorum.
Böylece otonom çalışma yalnız kod biriktirmiyor; denenmiş çalışma bilgisini de biriktiriyor. Ama bu ancak insanın kural adayını kendisi denetlemesi ve kural gövdelerinin tek authority’de kalmasıyla değerli.
Bu içeriğin kendisi de bu döngüyle çıktı
Bu yazıyı yazmadım. Yaklaşık 25–30 dakika boyunca, önüme koyduğum görsellere bakarak anlattım. Aynı anda yaklaşık on ajan başka işlerde çalışıyordu; bir ajan da bu konuşmayı içeriğe çevirmek için hazır bekliyordu.
Bu konuşmayı da kendi konuşma sistemimi kullanarak yaptım. Bir sunum hazırlayıp metin okumadım. Kendi sistemlerimin çıktıları, ajanların cevapları ve ekran görüntüleri önümdeydi; ben onlara bakıp anlattım. Konuşurken başka on ajan çalışmaya devam ediyordu. Yani bu içeriği üretmek için bütün geliştirme sistemini durdurmadım; içerik, çalışan sistemin içinden çıktı.
Bu rehber anlatılırken canlı transcript, yakalama aksiyonları ve çalışan ajanlar.
Konuşurken ekran görüntüsü alıyor, kopyaladığım şeyleri sıraya koyuyor ve “şu kısım” dediğim yerde kare çiziyorum.
Canlı yüzeyde konuşmanın kendisi yukarıda, 25 dakikalık dictation metni ortada, konuşurken kopyaladığım materyaller sağda, kopyalama–GIF–ekran görüntüsü–etiketleme gibi kısayollar da onların yanında duruyor. Ben hâlâ konuşurken bunların hepsi birikiyor. Yani önce konuşmayı bitirip sonra hangi görselin nereye ait olduğunu hatırlamaya çalışmıyorum; ilişkiyi tam söylediğim anda yakalıyorum.
Konuşurken kullanılan görsel etiketleme paneli ve kare aracı.
Sonra konuşmayı, yeniden anlatılmış bir brief değil, kaynak söz ve bütün referanslarıyla hazır ajana veriyorum:
Otuz dakikalık konuşmayı alıp içeriğe dönüştürmeye hazır yeni ajan.
Otuz dakikalık bir konuşma ziyan edilmez. Ajan içeriği çıkarıyor ama içerik benim konuşmamla çıkıyor. Bu ayrım çok kritik: Ajan niyet üretmiyor; insanın anlattığını düzenliyor, ilişkilendiriyor ve yayımlanabilir yüzeye taşıyor.
Hazırda yeni açtığım bir ajan bekliyor. Konuşmayı olduğu gibi ona yapıştırıyorum; öteki ajanlarla yan yana çalışırken bu içeriğin hedefini çıkarıyor ve yazmaya başlıyor. Codex mi Claude mu daha iyi taşıyacak diye ikisini de deneyebilirim, ama asıl önemli olan şu: otuz dakikalık insan üretimini kısa bir brief’e çevirip çöpe atmıyorum. Kaynak konuşma, görseller ve çizimler birlikte gidiyor.
Fikri çıkarmak için yazmak yavaş
optionOS’un ilk ürününün konuşma ürünü olmasının nedeni bu. Bağlam en kritik unsur; en önemli bağlam da insanın zihnindeki fikir. Fikri çıkarmak için yazmak çok yavaş. Bu yüzden yazmak yerine konuşmak lazım.
Ama konuşmak tek başına da yetmiyor. İnsan bir şey görmeli ki hatırlasın. O yüzden bakarak konuşması lazım. Ben bu konuşmayı kaynak kod okuyarak değil; ajan çıktılarına, ekran görüntülerine, kendi sistemlerimin görsel sonuçlarına bakarak yaptım. Sanki sunum yapıyormuşum gibi materyal önümdeydi. Metin okumadım; görsele bakıp kafamdan söyledim.
Yazıya baktığımda düşünüyorum; düşünce üretim akışını yavaşlatıyor. O yüzden insan yüzeyini mümkün olduğunca görsel, hareketli ve sezgisel kurmaya çalışıyorum. Kullanıcı kaynak koda bulaşmasın. Görsel objeyi seçsin, “şu kırık” desin, kaynak kodla o objenin soy ilişkisini sistem bulsun.
Burada yalnız “metni azaltalım” demiyorum. Daha bedensel ve sezgisel çalışmak istiyorum. İnsan görsele baksın, bir yere dokunsun, kare çizsin, konuşsun. Yazıyı okuyup önce zihninde teknik bir tarif üretmek zorunda kalmasın. Sistemler bu yüzden resim, animasyon, motion ve gerektiğinde ses odaklı kurulmalı. İnsan düşünüp arayüzün diline çevirmek yerine, gördüğü şeyin üstünden doğrudan tepki verebilmeli.
Buna Inspector diyorum. Chrome DOM inspector gibi, ama görsel objeden kaynak ilişkisine giden bir yol: “Şu dosyayı değiştir” demek yerine “Şu obje kırık” diyebilmek. Fotoğraf, kare ve konuşma aynı anda gidince inanılmaz hızlı context çıkarılabiliyor.
Bunun browser tarafı var; Chrome DOM’una zaten erişebiliyoruz. Bir de kendi Mac uygulamalarımda, fotoğraf üzerinden aynı ilişkiyi ajana verebildiğim taraf üzerinde çalışıyorum. İstediğim şey kullanıcının kaynak kodu bilmesi değil. “Bak, şu kodu değiştir” demek yerine ekrandaki objeyi gösterip “Şu kırık, bunu değiştir” diyebilmek. Soy ağacı görsel objeden kaynak koda kadar devam ettiğinde, ajan teknik yolu kendisi bulabiliyor.
Bu çalışma biçimini önce denemek ve içselleştirmek gerekiyor. Ondan sonra neden böyle bir sisteme ihtiyaç duyduğum daha görünür oluyor. Benim için optionOS şu anda gerçekten elim ayağım; bu sistemlerin hepsini onun üzerinden kullanıyorum. Altındaki Chat Operation System yapıları ve ajanların yönettiği Cockpit benzeri görsel paneller de aynı ekosistemin parçaları. Cockpit ve Clipboard’ın geri kalanını bu yazıya sıkıştırmıyorum; onları sonraki konuşmalarda adım adım anlatacağım.
İnsan üretimi sürekli kaydolmalı
Konuşma geçmişinde söylediklerim, çizdiğim rectangle’lar, hangi uygulamadan ve hangi ajandan içerik kopyaladığım birlikte görünüyor:
Konuşma, görsel referans ve çizim olaylarını birlikte gösteren geçmiş paneli.
Canlı kayıt sürekli saklandığı için bilgisayar veya internet koptuğunda 30 dakikalık insan üretimi çöpe gitmiyor. Bu benim için çok kritik: İnsan üretimi inanılmaz değerli; sorunsuz ve hızlı toplanması lazım.
Geçmişte yalnız transcript yok. “Anchor” dediğim anda çizdiğim rectangle da, kopyaladığım şeyin hangi uygulamadan ve hangi ajandan geldiği de aynı konuşma içinde görünüyor. Konuşma zaten canlı kayıtta olduğu için, bilgisayar veya internet tarafında bir şey olduğunda yarım saatlik konuşmayı yeniden üretmek zorunda kalmıyorum. Çünkü onu yeniden anlatmak aynı veri değil; o anda çıkan insan üretiminin kendisini korumam gerekiyor.
Panel o an 39 saat 34 dakika gösteriyordu, çünkü büyük kayıtları kendim arşivliyorum. Son yaklaşık altı ayda tahminen 350–400 saat konuşma ve yaklaşık 1,5 milyon kelime var. Bunların hepsini yeniden anlatmak mümkün değil; bu yüzden insanın o anda ürettiği kaynağı çıktığı anda yakalamak gerekiyor.
Kural kataloğu: o anki 166 başlık
Bu, içerik gövdelerinin yayını değil; yalnız o anki ölçeğin ve isim mantığının kaydı:
001. action.policy.effect-preview.rules
002. adr.rules
003. agent.contract.attention-index.rules
004. agent.judge.domain-entry.rules
005. agent.policy.decision-state.rules
006. agent.registry.skill-attention-axes.rules
007. agent.registry.workflow-axes.rules
008. agent.skill.closure.rules
009. agent.skill.work.rules
010. agent.workflow.attention-coordination.rules
011. agent.workflow.task-execution.rules
012. agentcore.handoff.recovery.codex.context
013. agentsession.contract.actor-duty.rules
014. annotation-scene.contract.lesson-lineage.rules
015. annotation-scene.contract.stage-interaction.rules
016. annotationcontracts.intent.screen-selection-layergraph-handoff.context
017. annotationkit.drift
018. archive.index.projection
019. archive.rules
020. audit.policy.readonly-dispatch.rules
021. axinspect.drift
022. backup.registry.rules
023. carrier-generalization.rules
024. checklist.registry.placement-checks.rules
025. clipboard-app.rules
026. clipboard-capture-schemas.drift
027. clipboard.intent.data-action-lineage.context
028. cockpit-tree-projection.drift
029. cockpit.policy.agent-session.rules
030. cockpit.projection.agent-session-carrier-map
031. cockpit.projection.engine-ecosystem.map
032. codex.adapter.lightweight-passive-hook.context
033. codex.adapter.lightweight-passive-hook.rules
034. comment.policy.executable-truth.rules
035. commit.algorithm.single-delta-commit
036. component-lineage-graph.drift
037. compose.contract.timeline-authority.rules
038. cursorfollowerhost.policy.dictation-direct-runtime.rules
039. data.registry.axes.rules
040. deep-copy.projection.concept-proof
041. dictation.intent.flagged-target-delivery-handoff.context
042. dictation.policy.hud-surface.rules
043. dictation.policy.notch-surface.rules
044. dictation.registry.deferred-decisions.rules
045. dictation.runtime.user-journey.context
046. dictationhost.policy.runtime-boundaries.rules
047. dictationintegration.drift
048. file.contract.filename-axis-grammar.rules
049. file.projection.filename-segments.source-wide
050. file.registry.axes.rules
051. file.registry.filename-segments
052. file.registry.rename-verdicts
053. file.rules
054. fundamentals.registry.axes.rules
055. ghosttyport.policy.session-binding.rules
056. graph.contract.lineage-closed-universe.rules
057. graph.registry.axes.rules
058. hooks.contract.hook-record.rules
059. hooks.contract.signal-record.rules
060. hooks.contract.visible-output.rules
061. hooks.registry.axes.rules
062. hotkey.projection.assignments
063. hotkey.registry.problems.rules
064. hotkey.rules
065. imprintkit.drift
066. index.rules
067. information.contract.anchor-lineage.rules
068. information.rules
069. inspector.contract.provider-consumer-boundary.rules
070. inspector.runtime.user-journey.context
071. intent-requirement.registry.axes.rules
072. json.rules
073. markdown.contract.claim-status-grammar.rules
074. markdown.policy.rule-surface.rules
075. markdown.registry.problems.rules
076. markdown.registry.semantic-carriers.rules
077. markdown.rules
078. markup-inspector.runtime.user-journey.context
079. markup-runtime.drift
080. media.contract.derived-decode.rules
081. menubar-update.rules
082. motion.registry.solved-effects.rules
083. note.policy.capture-gate.rules
084. onboarding.contract.engine-boundary.rules
085. optionos-api.policy.beta-telemetry-privacy.rules
086. optionos-api.policy.instagram-community-delivery.rules
087. optionos-api.policy.instagram-growth.rules
088. optionos-site.contract.public-content-lineage.rules
089. optionos-site.contract.seo-geo-surface.rules
090. optionos.command.app-icon-family.rules
091. optionos.context.contact
092. optionos.context.development-risk
093. optionos.context.positioning
094. optionos.contract.app-identity.rules
095. optionos.contract.memory-block.rules
096. optionos.contract.storage-lifecycle.rules
097. optionos.handoff.support-pricing.context
098. optionos.policy.legal-disclosure.rules
099. optionos.policy.rollout-phase.rules
100. optionos.registry.deferred-decisions.rules
101. oz.registry.axes.rules
102. package.rules
103. pasteformatcontracts.policy.transcript-attachment.rules
104. performance.contract.live-session.rules
105. precedence.registry.axes.rules
106. preflight.contract.signal-carrier.rules
107. preflight.rules
108. problem-solving.algorithm.cause-identification.rules
109. problem-solving.algorithm.structural-analogy.rules
110. problem-solving.registry.axes.rules
111. problem.rules
112. proof.registry.evidence.rules
113. python.contract.executable-carrier.rules
114. question-ledger.registry.axes.rules
115. raw.policy.prompt-memory.rules
116. rebrand.policy.name-purpose-alignment.rules
117. runtime-proof.projection
118. runtime-proof.rules
119. runtime.contract.boundary-context.rules
120. runtime.contract.build-output.rules
121. runtime.contract.event-signal.rules
122. runtime.contract.operation-budget.rules
123. runtime.contract.user-journey.rules
124. security.macos.rules
125. security.registry.axes.rules
126. security.web.rules
127. service.contract.headless-lifecycle.rules
128. session-hook.rules
129. ship.registry.axes.rules
130. skills.contract.host-skill-projection.rules
131. source.contract.rule-preflight.rules
132. source.policy.migration.rules
133. source.rules
134. swift.contract.main-thread-dispatch.rules
135. swift.contract.type-shape.rules
136. swift.package.rules
137. system.contract.structure.rules
138. system.registry.axes.rules
139. system.registry.problems.rules
140. tabgestures.contract.menu-onboarding.rules
141. term.registry.user-alias.rules
142. terminalport.contract.focus-truth.rules
143. trackpad-gesture-boundary.drift
144. type-shape.policy.static-decision.rules
145. typescript.contract.cli-stdout-drain.rules
146. typescript.contract.type-shape.rules
147. typescript.package.rules
148. ui.contract.accessibility-projection.rules
149. ui.contract.animation-motion.rules
150. ui.contract.excalidraw-canvas-lineage.rules
151. ui.contract.feedback.rules
152. ui.contract.interaction-continuity.rules
153. ui.contract.interface-copy.rules
154. ui.contract.navigation-wayfinding.rules
155. ui.contract.scaled-content.rules
156. ui.contract.settings-route.rules
157. ui.contract.typography.rules
158. ui.contract.visual-craft.rules
159. ui.contract.web-projection.rules
160. ui.contract.window-native.rules
161. ui.registry.axes.rules
162. ui.registry.relation-first-editing.axes.rules
163. verdict.registry.axes.rules
164. vscode.projection.session-chat-tree.rules
165. vscode.registry.problems.rules
166. whisper.policy.decoder-term-prompt.rules
Hemen dene
Buradaki asıl ürün tek bir uygulama değil, çalışma mantığı. Uyanıkken niyeti ve büyümeyi insan sahipleniyor; uyurken ajan yeni niyet uydurmadan dayanıklılığı, görünürlüğü ve belirsizlik azaltmayı sürdürüyor. Soy ağacı scope’u, preflight doğru kuralları, dinamik transcript de uzun bağlamı koruyor.
Bu çalışma stilini denemek istiyorsanız beklemeyin; önce küçük bir akışta konuşarak, görsele bakarak ve sorumluluk soylarını ayırarak deneyin. optionOS sistemlerini kullanmak için bana ulaşabilir veya optionos.app üzerinden davet listesine girebilirsiniz. Bu içerikten geldiğinizi yazarsanız bekleme listesinde sizi önceliklendirmeye çalışacağım.