İçeriğe geç
ivralo
Bölümler

Dokümantasyon / İşletim

Kayıt ve tekrar oynatma

Prompt'u, bir skill'i ya da modeli mi değiştirdiniz? Replay, dünkü çalıştırmanın bugün de aynı yoldan gidip gitmediğini gösterir: çalıştırmanın prompt'u bugünkü takıma verilir, her araç çağrısına da aracın geçen sefer verdiği cevap döndürülür.

Neden replay

Bir çalıştırmanın sonucu iki şeye bağlıdır: modele ve modelin okuduğu dünyaya. Replay dünyayı sabit tutar. Ağa, veritabanlarınıza ya da bir alt sürece hiçbir istek gitmez, workspace'e hiçbir şey yazılmaz. Böylece gördüğünüz her fark ya sizin değişikliğinizden ya da modelden kaynaklanır.

Bunun için iki komut var: ivralo record saklanmış bir çalıştırmayı bir kaset (cassette) olarak dışarı yazar, ivralo replay de çalıştırmanın prompt'unu bu kasete karşı yeniden çalıştırır.

Kaset: ivralo record

Saklanmış bir çalıştırma, yaptığı her araç çağrısını argümanları ve modelin gördüğü çıktıyla birlikte zaten tutar; ivralo trace'in gösterdiği de budur. ivralo record bunu dosyaya yazar:

ivralo record last
/srv/repo/.ivralo/cassettes/1a2b3c4d-.../cassette.json

Çalıştırmayı ivralo trace'teki gibi belirtirsiniz: last (varsayılan) ya da id'sinin en az ilk sekiz karakteri; başka bir konuşmadaki çalıştırma için --session. Kaset, açıp okuyabileceğiniz bir JSON dosyasıdır. İçinde bir başlık (çalıştırma, oturumu, katılanlar, kayıt zamanı, ivralo sürümü), prompt, cevap ve hem çalıştırmanın hem de iş devrettiği her uzmanın yaptığı her araç çağrısı için bir kayıt bulunur.

4 KB'tan uzun çıktılar SHA-256'larıyla .ivralo/cassettes/blobs/ altında tek bir kez saklanır. Aynı sayfayı okuyan elli çalıştırma için yalnızca bir kopya tutulur.

Kaset .ivralo/ dışına hiç çıkmaz

Kaset sizin verilerinizi içerir. Yalnızca workspace'in .ivralo/ klasörüne yazılır; ivralo'nun dosya araçları bu klasörü hiçbir zaman açmaz, repo'nun .git/info/exclude dosyası da onu diff'inizin dışında tutar. ivralo'nun elindeki bütün kimlik bilgileri, herhangi bir şey yazılmadan önce maskelenir:

  • değere göre: kimlik bilgisi adı taşıyan her ortam değişkeninin (_KEY, _TOKEN, _SECRET, PASSWORD, ...), databases.json içindeki bir bağlantının adını verdiği her değişkenin ve ivralo'nun kendi veritabanı URL'sinin değeri, nerede geçerse geçsin <NAME> ile değiştirilir: argümanda, çıktıda, prompt'ta ya da cevapta;
  • ada göre: adı kimlik bilgisini andıran bir argümanın (api_key, token) tamamı maskelenir;
  • URL'lerde: URL nerede geçerse geçsin içindeki parola user:***@ olur.

Kasetler hiçbir zaman otomatik temizlenmez. İşiniz bittiğinde .ivralo/cassettes/ klasörünü silin.

Replay: ivralo replay

ivralo replay last --tools mocked

Çalıştırmanın prompt'u bugünkü takıma (bugünkü kadro, modeller, skill'ler ve prompt'lar) yeni bir oturumda gönderilir; uzun süreli bellek ne okunur ne yazılır, böylece konuşmanız etkilenmez. Uzmanlara iş devri gerçekten yapılır, yani her uzman kendi işini yeniden yapar. Kod, shell komutu, sayfa, sorgu, dosya okuma ya da düzenleme gibi diğer bütün çağrılar kasetten cevaplanır ve hiçbiri gerçekten çalışmaz. Çalıştırmanın henüz kaseti yoksa önce bir kaset kaydedilir. Tek mod --tools mocked'tır ve varsayılan da odur.

Bir çağrıya kasetten cevap verilmesi için aynı uzmanın aynı aracına yapılmış ve argümanları birebir aynı, kodu karakteri karakterine aynı olan kayıtlı bir çağrı bulunması gerekir. Aynı çağrı iki kez yapılırsa kaydedilmiş iki cevap sırayla döner; çağrıların farklı sırada yapılması sorun değildir.

Sapmalar

Bunun dışında kalan her şey bir sapmadır (divergence). Modele bunun bir replay olduğu ve bu çağrının kaydı bulunmadığı söylenir; rapor da çağrıyı en yakın kayıtlı çağrıyla diff olarak gösterir. Çağrı hiçbir zaman o en yakın çağrının çıktısıyla cevaplanmaz: modelin farklı bir şey yapması, replay'in tam da göstermek istediği şeydir.

replay of 1a2b3c4d: diverged - 1 call(s) without a recording, 1 recorded call(s) never made
new run 9f8e7d6c in session 4b3a2918
3 call(s) answered from the cassette, 1 delegation(s) run
divergence: Data Analyst run_python
  --- recorded
  +++ replayed
  @@ -1,3 +1,3 @@
   {
  -  "code": "df = pd.read_excel('sales.xlsx')\nprint(df.revenue.sum())"
  +  "code": "df = pd.read_excel('sales.xlsx', sheet_name='Q3')\nprint(df.revenue.sum())"
   }
never made: Chart Designer run_python {"code":"save_chart(df)"}

Kayıtta olup replay sırasında hiç yapılmayan bir çağrı da sapma sayılır. Yeni çalıştırma diğerleri gibi saklanır ve hangi çalıştırmayı tekrar oynattığı etiketlenir; böylece ivralo trace ve ivralo why onun üzerinde de çalışır.

Çıkış kodları

ÇıkışAnlamı
0Replay kayda sadık kaldı
1Saptı: kaydı olmayan bir çağrı yapıldı ya da kayıtlı bir çağrı hiç yapılmadı
2Çalıştırma ya da kaseti okunamadı, ya da replay çalışamadı

--json raporu tek bir JSON nesnesi olarak basar. Rapor stdout'a, hatalar stderr'e yazılır. Böylece bu komutları, bir prompt ya da skill değişikliğini birçok saklanmış çalıştırma üzerinde deneyen bir script'te kullanabilirsiniz.

Replay neyi garanti etmez

  • Modeli deterministik yapmaz. Model yerel de olsa hosted da olsa farklı örnekleme yapabileceği için replay sapabilir; rapor bunu da aynı ifadelerle bildirir.
  • MCP sunucularını başlatmaz. Kayıtlı bir MCP çağrısı hiç yapılmamış olarak görünür.
  • Plan adımları, adımın prompt'uyla düz bir istek olarak tekrar oynatılır.