İçeriğe geç
mcpd
daemon yok
Kaynak

Çalıştırmalar

Bir çalıştırma; bir satır, bir imleç, denemelerin günlüğü, bir dizi süre sonu ve bir dizi askıya almadır. Bu sayfa, ona ne yapabileceğinizi ve onun size ne söylediğini anlatır.

Çalıştırma başlatmak

Bir çalıştırma bir tanım kimliği ve bir girdiyle başlar. Tanımın bir şeması varsa daemon girdiyi ona göre doğrular, saklanan en yüksek sürümü sabitler, çalıştırmayı ve trace'ini oluşturur ve çalıştırmayı saklandığı hâliyle döndürür. Bundan sonrası çalıştırmanın kendi işidir: daemon adımlarını worker'lara sunar, uykularını ve beklemelerini yürütür, olan biteni günlüğe yazar.

başlatma, yanıtlama, izleme

// Start a run from anywhere that holds an execute key, answer the wait from a
// webhook, then follow the journal to the end and read the run.
const run = await mcpd.runs.start({
  definitionId: 'support_ticket',
  input: { ticket: 'Q-42' },
})

await mcpd.events.publish({
  event: 'approved',
  key: 'Q-42',
  payload: { by: 'ops' },
  eventId: 'hook-1', // a repeat of this id is a duplicate, not a second event
})

for await (const event of mcpd.runs.watch(run.runId)) {
  console.log(event.seq, event.kind)
}
const detail = await mcpd.runs.get(run.runId)
console.log(detail.run.status, detail.run.output)

Yeniden denenebilecek her çağrıdan bir idempotency_key gönderin. Çalıştırma tutulduğu sürece proje içinde benzersizdir ve aynı çağrının yeniden denenmesi ikinci bir çalıştırma başlatmak yerine aynı çalıştırmayı döndürür. İki kez tetiklenen bir webhook ya da yeniden başlayan bir iş çalıştırıcısı böylece hiçbir şeye mal olmaz.

The cursor

The daemon holds the run between steps: where it is, what each step answered, what it is waiting for and until when. A worker holds one step at a time, and only while it runs. During a wait no process is alive at all.

classify task your process draft agent your process approval wait_event the daemon alone send task · at_most_once your process retry

Günlük

Bir çalıştırmadaki her değişiklik, sıfırdan başlayan ve boşluk bırakmayan bir sıra numarası taşıyan bir olaydır: çalıştırma başladı, imleç ilerledi, bir adım için lease verildi, adım başladı, bitti ya da başarısız oldu, çalıştırma bekledi ve kaldığı yerden devam etti, çalıştırma sona erdi. Her biri türüne göre biçimlenmiş bir payload taşır. Günlük, çalıştırmanın geçmişidir ve arayüzün çizdiği şeydir.

Günlüğü after ile sayfa sayfa okuyun, ya da olaylar endpoint'ini Accept: text/event-stream ile açık tutup her olayı işlendiği anda alın. Durup yeniden başlayan bir istemci gördüğü son sıra numarasını gönderir ve hiçbir şeyi kaçırmaz. Her SDK'nın watch çağrısı bunu sizin için yapar ve çalıştırma bittiğinde biter; wait ise günlüğü sonuna kadar izler ve çıktıyı döndürür; çalıştırma başarılı olmadıysa çalıştırmayı taşıyan, türü belli bir hata döndürür.

Olaylar ve beklemeler

Bir wait_event adımı, kendi adını ve işlenmiş anahtarını taşıyan bir olay gelene kadar çalıştırmayı tutar. Olay tek bir kapıdan girer:

bir beklemeyi yanıtlama

curl -X POST http://localhost:4317/v1/api/events \ -H 'content-type: application/json' \ -d '{"project":"support","event":"approved","key":"Q-42","payload":{"by":"ops"},"event_id":"hook-1"}'

Yanıt üç sonuçtan biridir. delivered: bir çalıştırma bekliyordu ve olayı aynı işlem içinde aldı, yani siz alındıyı okuduğunuzda çalıştırma çoktan ilerlemiştir. parked: bekleyen bir çalıştırma yoktu ve olay, sonradan açılıp park edilmiş olayları kabul ettiğini söyleyen bir bekleme için saklanır. duplicate: event_id daha önce görülmüştür ve hiçbir şey yazılmamıştır. İki kez tetiklenebilecek her şeyden kendi kimliğinizi gönderin.

Süre sonuna ulaşan bir bekleme, on_timeout ne diyorsa onu yapar: başarısız olur ve sonra on_error karar verir, ya da çıktı olmadan devam eder. Tek bir çalıştırmaya kendi açık beklemesi üzerinden doğrudan göndermek için POST /v1/api/runs/{run}/signal kullanılır; adres çalıştırmanın kendisi olduğu için aynı gövdeyi anahtarsız alır.

Çalıştırmayı iptal etmek

POST /v1/api/runs/{run}/cancel bir çalıştırmayı ve altındaki her alt çalıştırmayı sona erdirir. Yürümekte olan bir adım hat üzerinde kesilmez: worker bir sonraki heartbeat'inde çalıştırmanın bittiğini öğrenir, bağlamı gövdeye haber verir ve gövdenin bundan sonra gönderdiği her şey run_terminal ile reddedilir. Zaten sona ermiş bir çalıştırmayı iptal etmek hiçbir şeyi değiştirmez ve çalıştırmayı olduğu gibi döndürür.

Zamanlayıcılar ve sınırlar

Uykular, bekleme süre sonları, yeniden deneme beklemeleri ve lease bitişleri; hepsi daemon'un tuttuğu zamanlayıcılardır. Daemon'un saatiyle, saniyede bir tetiklenirler; bu yüzden yüz milisaniyelik bir retry_after_ms tam olarak o kadar değil, en az o kadar diye uygulanır. Daemon'un yeniden başlaması hiçbirini kaybettirmez; hepsi birer satırdır ve çalıştırma satırdan devam eder. Hiçbir süre 3650 günden uzun olamaz ve bir worker'dan gelen daha uzun bir retry_after_ms bir 400 ile reddedilir. 2262 yılından sonraki bir sleep_until, hiçbir zaman gelmeyecek bir an olarak tutulur.

Bir tanımın max_steps, run_timeout_ms ve max_cost_usd değerleri çalıştırmayı tavanda sona erdirir ve hata olarak tavanın adını verir. Maliyet, adımların bildirdiği kullanımın fiyatlanmış toplamıdır; span'leri fiyatlayan kitabın aynısı kullanılır, yani token'larını bildiren bir ajan adımı, tamamlandığı anda çalıştırmanın bütçesinden düşülür.

Çalıştırmanın trace'indeki yeri

Her çalıştırma aynı zamanda bir trace'tir. Daemon çalıştırma için bir kök span, her deneme için de adımın girdisi ve çıktısıyla birer span açar; adım bağlamı üzerinden kendi span'lerini kaydeden bir gövdenin span'leri de bunların altına girer. Böylece bir ajan adımının içindeki model çağrısı o adımın, o adım da o çalıştırmanın altında durur; herhangi bir trace üzerinde çalışan arama, maliyet muhasebesi ve puanlayıcılar bir çalıştırmanın trace'inde de değişmeden çalışır. Bu span'ler, bir SDK'nın span'lerinin geçtiği alım yolunun aynısından yazılır; bu yüzden aynı biçimde örneklenir, maskelenir, fiyatlanır ve iletilir. Token'lar onları harcayan model span'lerinde durur; adım span'i fiyatlanmış toplamı özniteliklerinde taşır, böylece bir trace toplamı her token'ı bir kez sayar. Çalıştırma kendi trace_id değerini taşır ve arayüz ikisini birbirine bağlar.

Daemon o span'leri, onları doğuran satır işlendikten sonra kendi saatiyle bir giden kutusu üzerinden yazar. Bir adım tamamlandıktan hemen sonra okunan bir trace o adımın span'ini henüz taşımıyor olabilir; çalıştırmanın kendi ayrıntısı her zaman taşır.

Çalıştırmaları geri okumak

GET /v1/api/runs bir projenin çalıştırmalarını, en son güncellenen başta olacak şekilde, duruma ya da tanıma göre filtreleyip listeler. GET /v1/api/runs/{run} ise çalıştırmanın kendisi ve onunla ilgili kalıcı olan her şeydir: lease sahibi, zamanları, hatası ve kullanımıyla her deneme; hâlâ bekleyen zamanlayıcılar; hâlâ açık olan beklemeler. Arayüzün İş akışları ekranı bu endpoint'in çizilmiş hâlidir, yanında da günlük canlı akar.

İkisi de çalıştırmaya verileni geri döndürür, bu yüzden ikisi de denetim günlüğüne list_runs ve get_run olarak kaydedilir. Çalıştırmanın günlüğü (list_run_events, istek başına bir kez, bir akış da dahil), bir adımın nedenini geriye doğru izleyen çağrı (get_step_cause) ve bir iptal (cancel_run) de kaydedilir. Reddedilen bir okuma, çalıştırmanın sahibi olan projeye karşı kaydedilir. Worker çağrıları kaydedilmez; Worker'lar sayfasına bakın.

Depolama

Çalıştırmalar, trace deposunun yanında kendi SQLite dosyasında durur: --runs-data başka bir şey söylemedikçe <data>.runs.<ext>. --runs-data off çalıştırma yüzeyini tamamen kapatır, o durumda her çalıştırma endpoint'i 503 döndürür. Yedeğini trace deposuyla birlikte alın; mcpd doctor ona kendi grubu olarak not verir.

Çalıştırma deposu payload'ları gönderildikleri gibi tutar. Bir çalıştırmanın girdisi, durum verisi, çıktısı ve ilişkilendirmesi, her adımın girdisi, çıktısı ve hatası, her olay payload'ı ve trace deposuna yazılmayı hâlâ bekleyen span payload'ları maskelenmeden saklanır; bir çalıştırmanın ilişkilendirmesindeki user_id da özetlenmeden saklanır. Bu bilerek böyledir: bunlar iş akışının çalışma durumudur, sonraki bir adım onları geri okur ve maskeleyicinin yeniden yazdığı bir değer çalıştırmanın yaptığı şeyi değiştirirdi. Daemon'un trace deposuna yazdığı span'ler, bir SDK'nın gönderdiği bir span ile aynı maskelemeden ve tanımlayıcı özetlemesinden geçer, yani trace deposu maskelenmiş kopyayı tutar. Çalıştırma dosyasını, adımlarınıza verilen her şeyi tutan bir dosya olarak görün; onu buna göre koruyun ve yedeğini buna göre alın.

Saklama, çalıştırma deposunu kapsar. Trace deposunu budayan saatlik tarama, aynı proje başına pencereyle, kökü kesim noktasından önce sona ermiş her çalıştırmayı da alt çalıştırmalarıyla ve onlar için saklanan her şeyle birlikte siler: denemeler, olaylar, süre sonları, beklemeler, kuyruktaki span'ler ve o çalıştırmaların tükettiği olaylar. Sona ermemiş bir çalıştırma, ne kadar eski olursa olsun hiçbir zaman silinmez. Tanımlar tutulur.

Silme de onu kapsar. DELETE /v1/api/subjects/{user_id}, projede ilişkilendirmesi o user_id değerini, çalıştırmayı başlatırken verdiğiniz biçimde taşıyan ve sona ermiş her çalıştırmayı, alt çalıştırmalarının tüm ağacıyla ve onlar için saklanan her şeyle birlikte siler ve sayıyı runs_erased olarak bildirir. O kişinin sona ermemiş bir çalıştırması bütün olarak bırakılır, runs_in_flight içinde sayılır ve yanıtın note alanında adlandırılır: onu iptal edin ya da bitmesine izin verin ve silme isteğini yeniden gönderin. Henüz beklemesine ulaşmamış bir çalıştırma için park edilmiş bir olay bir kişiye göre değil, ilişkilendirme anahtarına göre anahtarlanır, bu yüzden silme ona erişmez; süresi dolduğunda, 24 saat sonra silinir. Yanıtın geri kalanı için Maskeleme ve saklama sayfasına bakın.

Sonraki