Component'ler
Özet
- Bir component, platformun yetenek birimidir: tek bir iş yapan tipli, version'lanmış, container'lanmış bir kod parçası — bir görüntü oku, bir detektör çalıştır, bir ses frame'ini normalleştir, bir kuyruğa yaz. Birçok backend'de yeniden kullanılabilir ve tek bir takıma aittir.
- Bir component ne tükettiğini, ne ürettiğini ve nasıl yapılandırılabileceğini bildirir — tipli input akışları, tipli output akışları, tipli parametreler, isteğe bağlı dosya yuvaları. Bu bildirim, platformun her diğer katmanının okuduğu sözleşmedir.
- Component'lerin değişmez release'leri vardır. Her publish bir prerelease oluşturur; promotion, bir prerelease'i yayınlanmış bir version'a dönüştürür. Backend'ler belirli release'leri sabitler, böylece promotion herhangi bir çalışan deployment'ı değiştirmez.
- Bir component davranışa sahiptir. Bir backend kompozisyona sahiptir. Bir deployment runtime'a sahiptir. Üç ilkeli ayrı tutmak, tek bir yeteneğin kodu çatallamadan birçok ürünü güçlendirmesini sağlayan şeydir.
- Çoğu component durumsuz fonksiyondur: input girer, output çıkar. Durum, virtual akışlar ve özel pull politikaları, onlara ihtiyaç duyan durumlar için gelişmiş konulardır; temel şekil çoğu gerçek component'i kapsar.
Bir component gerçekte nedir
Bir component, platformun modellediği en küçük yeniden kullanılabilir yetenek birimidir. Somut olarak, ne tükettiğini, ne ürettiğini ve nasıl yapılandırılabileceğini bildiren bir manifestle, container'lanmış bir worker olarak paketlenmiş tipli bir fonksiyondur. O bildirim — component.yml — her diğer katmanın okuduğu sözleşmedir: backend'ler onu deploy'dan önce graf kablolamasını tip-kontrol etmek için kullanır, katalog onu keşif için kullanır, runtime onu worker'ın container'ının ne beklediğini belirlemek için kullanır.
Granülerlik bilinçlidir. Çıplak bir fonksiyon bağımsız çalışmak için fazla küçüktür: manifest yok, container yok, version'lama yok. Tüm bir pipeline ürünler arasında yeniden kullanmak için fazla büyüktür. Bir component, bir işin sabitlenebilen, doğrulanabilen, yeniden kullanılabilen, değiştirilebilen ve tek başına işlem yapılabilen bir birime eşlendiği düzeyde durur. Tipli sözleşme ve değişmez release modeli, o birimi yalnızca izole değil, birleştirilebilir kılan şeydir.
Varsayılan sözleşme, component'lerin graf sınırında durumsuz olmasıdır. Fonksiyon tipli input'ları tüketir ve tipli output'lar üretir; diğer her şey — model ağırlıkları, yapılandırma, isteğe bağlı durum, yan kanal olayları — component'in ihtiyaç duyduğunda bildirdiği mekanizmadır. O varsayılan, çoğu component'i küçük tutar ve zamanlayıcının onları serbestçe paralelleştirmesini sağlar. Opt-in'ler, onlara ihtiyaç duyan durumlar için vardır ve her biri runtime'ın vertex'i nasıl zamanlayabileceğini kısıtlar ki bu, component'leri basit tutmak için doğru baskıdır.
Zihinsel model
┌──── component release (immutable) ─────┐
│ │
│ component.yml src/ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ language │ │ Python or │ │
│ │ inputs[] │ │ C++ code │ │
│ │ outputs[] │ │ │ │
│ │ config │ │ implements │ │
│ │ files │ │ the typed │ │
│ │ tags │ │ function │ │
│ └─────────────┘ └─────────────┘ │
│ │
└────────────────────┬───────────────────┘
│ pinned by
▼
backend vertex
Release değişmez yapıttır. Bir backend onu bir vertex olarak sabitler, parametrelerini ve dosyalarını bağlar ve akışlarını kablolar. Aynı release birçok backend'de bir vertex olarak oturabilir; her backend kendi bağlamalarını ve kendi graf bağlamını taşır. Promotion yeni bir yayınlanmış satır kaydeder; sabitleme, bir backend'i bundan izole eden şeydir — release_v3'ü sabitlemiş bir backend, v4 varsayılan olduktan sonra v3 çalıştırmaya devam eder.
Release'in takıldığı graf için Backend'ler ve input'larının ve output'larının karşıladığı tipli akış sözleşmesi için Tipler sayfalarına bakın.
"Tipli fonksiyon" size gerçekte ne kazandırır
"Component sözleşmesi neyi garanti eder" diye sorduğunuz ilk seferde bu çerçeveyi kullanın.
Bildirilen tipli sözleşme manifestte küçüktür — akış başına birkaç satır — ve diğer her yerde yük taşır. Backend'in tip çıkarımı, bir Image çıktısını bir [BoundingBox] input'una kablolamayı reddetmek için onu kullanır. CLI, bir parametre eksik olduğunda anlamlı hata mesajları render etmek için onu kullanır. Katalog, component'leri işledikleri modalitelere göre filtrelemek için onu kullanır. Runtime, component'in başlangıçta hangi container kaynaklarına ihtiyaç duyduğunu belirlemek için onu kullanır.
Component yazarı sözleşmeyi bir kez yazar; her diğer taraf — graf yazarları, sonraki tüketiciler, ops takımları, daha sonraki bakımcılar — onu okur. Sözleşmeyi bildirmek, kablolama ve parametre hatalarını, başarısız bir deploy'a ertelemek yerine, backend'in tip çıkarımının onları yakaladığı düzenleme zamanına taşır. Bu, manifestin isteğe bağlı yerine zorunlu olmasının pratik nedenidir.
Tipli değerlerin kendileri üç yerden birinden gelir: pipelang atomik tipleri (Double, String, Int64), onlardan inşa edilen bileşik tipler ([BoundingBox], Maybe<String>, (Image, [Double])) veya platformun tip kayıt defterinden adlandırılmış tipler (Image, Tensor, AudioFrame, BoundingBox). Adlandırılmış tipler alan adı anlamları taşır: bir Image yalnızca bir bayt tensörü değildir, görüntü işleyen her component'in üzerinde anlaştığı tipli değerdir, sonraki tüketicilerin yeniden türetmek yerine doğrudan okuduğu şekil, kanal sırası ve meta veriyle.
Image, Tensor ve geri kalanını destekleyen kayıt defteri için Adlandırılmış tipler sayfasına bakın.
Varsayılan olarak durumsuz, davranış geçmiş gerektirdiğinde durumlu
Varsayılanı kullanın; duruma yalnızca sonraki çıktı gerçekten önceki çıktılara bağlı olduğunda başvurun.
Varsayılan component, durumsuz bir fonksiyondur: runtime onu aynı vertex için birçok kez eşzamanlı olarak çağırabilir, çünkü hiçbir çağrı bir diğerine bağlı değildir. Bu, zamanlayıcının tek bir vertex'i yük altında CPU çekirdeklerine yaymasını veya sıralamayı koordine etmeden bağımsız çağrıları paralel çalıştırmasını sağlar.
Durum bildirmek o sözleşmeyi değiştirir. Component, platformdan çağrılar arasında bellek kalıcılaştırmasını ve fonksiyonu vertex başına teker teker çağırmasını ister, böylece önceki çağrının next state'i sonrakine görünür. Vertex geçmişe bağımlı hale gelir: tracker'lar, kayan pencereler, oturum haritaları, konuşma belleği, debouncing ve "yalnızca N saniyelik buffer'lanmış sesten sonra yay"ın hepsi doğru davranmak için duruma ihtiyaç duyar. Durumlu bir vertex replika başına serisaldır ki bu, duruma ihtiyaç duymayan component'lerden durumu uzak tutmak için doğru baskıdır.
Kalıcı durumun dışında kalan şey, process başına mekanizmadır: model tutamaçları, veritabanı istemcileri, derlenmiş regex'ler, başlangıçta yeniden üretilebilen önbellekler. Bunlar modül global'lerine veya kurulum hook'larına aittir, platformun kalıcı durumuna değil. Kalıcı durum, davranışsal bellek içindir — çağrılar arasında kaybı sonraki çağrının yaydığı şeyi değiştirecek değerler. Diğer her şey process-yereldir ve buna göre yaşar.
Yan etkiler virtual akışların arkasında yaşar
Bunu component'in grafın dışındaki dünyayla konuşması gerektiğinde kullanın: HTTP, WebSocket, cihazlar, SDK callback'leri, yeniden deneme anlamlarıyla dosya yazımları.
Çoğu component graf input'larından tüketir, deterministik bir fonksiyon çalıştırır ve graf output'larına yayar. Bazı component'lerin daha zor bir işi vardır: trafiği eşzamansız alan bir HTTP listener'ına, graf zamanlamasından bağımsız frame'ler üreten bir kamera thread'ine, token'ları bir callback aracılığıyla geri akıtan bir LLM SDK'sına, yeniden deneme işleme gerektiren bir dosya yazıcısına sahiptirler. Bu yan etkileri doğrudan grafa bakan fonksiyona iplemek, zamanlayıcının fonksiyonu ne zaman çağırmanın güvenli olduğunu belirlemesini imkansız kılar.
Virtual akışlar o işi izole eder. Virtual input, normal grafa bakan tick'in dışındaki kodla doldurulan component'e yerel bir kuyruktur: bir HTTP listener, bir cihaz thread'i, bir akış SDK callback'i. Component, virtual input'u pull request'ine dahil edebilir, böylece bu harici olaylar yine de normal akış mesajlarıyla aynı zamanlayıcıya görünür fonksiyon aracılığıyla akar. Virtual output bunun tersidir: component'in bir tick'ten döndürdüğü yan etki iş öğelerinin bir kuyruğu, bir bridge thread'inin eşzamansız yürüttüğü ve sonuçları virtual input aracılığıyla geri besleyebileceği.
Virtual akışları işlevsel kılan disiplin şudur: grafa bakan fonksiyon zamanlayıcıya görünür kalır. Yan etkiler kuyrukların arkasında yaşar; fonksiyon onları okur ve yazar; bridge IO'yu gerçekleştirir. O ayrım, bir component'in dış dünyayla konuşmasını sağlarken zamanlayıcının fonksiyonun ne zaman çalıştığına dair modelini korumasını sağlayan şeydir.
Release'ler değişmezdir; promotion bilinçlidir
Bu zihinsel modeli "backend'im neden yeni kodu almadı" diye akıl yürüttüğünüzde kullanın.
Her publish bir prerelease oluşturur: çağıranın test backend'lerinde deploy edebileceği özel doğrulanmış bir build. Promotion, bir prerelease'i bir yayınlanmış version'a dönüştüren ayrı, bilinçli adımdır: image kayıt defterine gider, component.yml'de bildirilen etiketler hareket eder (latest, default) ve version, workspace'in kitlesindeki herkes tarafından deploy edilebilir hale gelir. Version ID'si değişmez; yalnızca durumu değişir.
Backend'ler belirli release ID'lerini sabitler. Bir prerelease'i promote etmek, deploy edilmiş herhangi bir backend'in sabitlenmiş version'ını değiştirmez — backend, son deploy zamanında sabitlediği şeyi çalıştırmaya devam eder. Bir backend'i daha yeni bir release'e ileri yuvarlamak, açık bir vertex mutasyonu ve ardından bir yeniden deploy'dur. O ayrım, bozuk bir version'ı promote etmenin tek başına çalışan bir backend'i çökertememesinin nedenidir. Çalışan backend sabitlenmiştir; yeni release, katalogda yeni bir adreslenebilir yapıttır.
Tam publish + promote döngüsü için Publish anlamları sayfasına bakın.
Bir component neye sahiptir ve neye sahip değildir
Bir component kimliğine (görüntü adı artı workspace kapsamlı slug), diline (Python veya C++), bildirilen input ve output akış tiplerine, tipli config_schema'sına, modeller ve veri yuvaları için isteğe bağlı file_schema'sına, workspace dosyaları olarak geri yazdığı çıktılar için isteğe bağlı generated_file_schema'sına ve src/ altındaki implementasyon kaynağına sahiptir. Ayrıca keşif meta verisine de sahiptir — katalog kategorisi ve modalite etiketleri, release'le seyahat eden README ve AGENT.yml.
Graf-şekilli hiçbir şeye sahip değildir. İçinde göründüğü backend, o backend'deki parametrelerinin vertex bağlamaları, yuvalarına bağlanan dosya ID'leri, output'larının açığa çıkarıldığı endpoint alias'ları, onu çalıştıran deployment, deployment'ı barındıran runtime — bunların hepsi backend-ve-deployment kaygılarıdır. Component yetenektir; diğer her şey kompozisyon ve runtime'dır.
O ayrım, tek bir component'in birçok ürünü güçlendirebilmesinin tüm nedenidir. Bir detektör component'i, bir depo-güvenliği backend'inde, bir perakende-trafik backend'inde ve bir klinik-görüntüleme backend'inde aynıdır; her backend onu farklı kablolar, farklı parametreler bağlar, farklı hesaplama üzerinde deploy eder. Component'in bunların hiçbirini bilmesi gerekmez.
Kalite çıtası
Geçerli bir component tip denetiminden geçer; iyi bir component yalnızca manifest'inden güvenilirdir. Çıta, sıkıştırılmış hâliyle: sözleşme koddan önce tasarlanmış ve açıklamalar birebir doğru; her geçerli input için her port'ta tek output, yokluk her zaman açık; kayıt defteri carrier tipleri SDK üzerinden kurulmuş, asla elle paketlenmemiş; oneof output'ları tek bir kanonik sonucun projeksiyonları olarak uygulanmış ve kol başlangıçta bir kez çözülmüş; parametreler tipin içine daraltılmış (String<"fast" | "accurate">, maybe tipli secret'lar, gerçek dosya düzenleri); bağımlılıklar birebir sabitlenmiş; değişmezler catch-and-continue'ya sarılmak yerine sınırda assert edilmiş; her input şeklini ve her output kolunu gerçek doğrulamalarla kapsayan testler; ve hem insanlar hem agent'lar için yazılmış, kaynakla eşleşen dokümantasyon. Bu çıtayı karşılayan component'ler, implementasyonu hiç okumamış insanlar — ve agent'lar — tarafından kablolanabilir, değiştirilebilir ve işletilebilir.
Bunun yeri
Component'ler, kodun ne yaptığı için platformun yük taşıyan ilkelidir. Backend'ler onları birleştirir; deployment'lar onları çalıştırır; katalog onları keşfeder; tip sistemi nasıl birbirine kablolanacaklarını kısıtlar; release modeli davranışlarını zaman içinde yeniden üretilebilir tutar. Platformdaki diğer her kavram, component'leri yeniden kullanılabilir, birleştirilebilir, işletilebilir veya keşfedilebilir kılmak için vardır, böylece tek bir yetenek, her biri için özel yapışkan olarak yeniden uygulanmak yerine birçok ürüne hizmet eder.
Platformun component yazarlarından istediği disiplin küçüktür: tipli sözleşmeyi doğru bildir, varsayılan olarak durumsuz ol, duruma ve virtual akışlara yalnızca temel şekil sözleşmeyi ifade edemediğinde başvur ve release'leri değişmez olarak ele al. Karşılığında, platform graf tip-kontrolü, katalog keşfi, runtime zamanlaması, deployment, gözlemlenebilirlik ve kanıt döngüleri sağlar. Yazar fonksiyonu yazar; etrafındaki her şey platformun sorumluluğudur.
İlgili
- Backend'ler — yayınlanmış component'leri tipli bir grafa kabloluyor.
- Tipler — kötü kablolamayı runtime'dan önce yakalayan sözleşme.
- Adlandırılmış tipler —
Image,Tensor,AudioFramearkasındaki kayıt defteri. - Publish anlamları — publish ve promote döngüsü ayrıntılı olarak.
- File schema — bir component'in tükettiği ve ürettiği dosyaları bildir.
- Build sistemleri — platform kaynağı doğrulanmış bir image'a nasıl dönüştürür.
- Solution'lar — component + backend + deployment + yüzey, uçtan uca.
- Quickstart — ilk göreviniz için rota seçici.