Pipeline-ok és automatizálás
A pipeline a Control Center determinisztikus fele. Az ügynök eldönti, mit mondjon; a pipeline eldönti, mi történjen ezután, minden alkalommal ugyanúgy. A pipeline lépésekből álló DAG, amely ügynököket indíthat, szkripteket futtathat, feltétel alapján elágazhat, egy gyűjtemény elemein szétágazhat és adatot adhat át a lépések között — tartósan mentve, folytathatóan és költségelszámolással.
Három okból léteznek: hogy összefűzzenek egy ismétlődő, több lépésből álló folyamatot, hogy több ügynököt hangoljanak össze sorban vagy párhuzamosan, és hogy reagáljanak valamire, ami ember jelenléte nélkül történt.
Sablonok és futtatások
Szekció neve “Sablonok és futtatások”A sablon (PipelineDefinition) a deklaratív DAG: lépések, deklarált
bemenetek és konfiguráció. A munkaterület saját adatbázisában él. Egy
futtatás (PipelineRun) a sablon egyetlen végrehajtása, amely egy
módosítható állapottárat, költség- és tokenösszegeket, valamint lépésenkénti
állapotot hordoz.
Egy sablonhoz sok futtatás tartozik. A futtatások túlélik az újraindítást: a motor újratölti a folyamatban lévő futtatásokat, és onnan folytatja őket, ahol abbamaradtak.
Két biztosíték szándékosan inkább megbuktatja a teljes futtatást, mintsem folytatna egy lépést, mert a folytatás rosszabb lenne a leállásnál:
- Egy lépés, amely a
suspendedStepTimeout-nál hosszabb ideig vansuspendedállapotban (alapértelmezés szerint 24 óra), olyan jegyekre vár, amelyek soha nem jutnak végállapotba, ezért a rendszer megbuktatja, hogy felszabadítsa a futtatást. A kivétel azextras['awaitApproval'] == true— ez azorchestration.awaitApprovalrészleges jóváhagyási kapuja. Ahuman.gatenem kivétel. - Egy lépés, amely
extras: {'idempotent': false}beállítással van deklarálva, és éppen futott, amikor a szerver leállt, már alkalmazhatta a mellékhatását (egy squash merge, egy worktree-takarítás). Az újrafuttatása kétszer alkalmazhatná, ezért a motor megbuktatja, és az újrapróbálkozást Önre hagyja.
A fajta ütemez, a törzs dolgozik
Szekció neve “A fajta ütemez, a törzs dolgozik”Egy lépésnek két egymástól független része van, és éppen a szétválasztásuk teszi lehetővé, hogy a motor kicsi maradjon.
A fajta (StepKind) mondja meg a motornak, hogy egy lépés mikor válik
futtathatóvá a felette lévő lépésekhez képest — az ütemezőnek csak ezt kell
tudnia. Hat van belőle: trigger, listen, join, router, forEach és
terminal. A törzs (bodyKey) az a munka, amelyet a lépés az ütemezés
után elvégez. A törzsek a szerver indításakor kulcs szerint regisztrált
closure-ök, így sok különböző fajtájú lépés osztozhat egy törzsön: például
több listen lépés is ugyanazt a conversation.promptAgent törzset futtatja.
Mivel az ütemezési szemantika hat fajtában él, a viselkedések katalógusa bővülhet anélkül, hogy bárkinek hozzá kellene nyúlnia az ütemezőhöz. A fajták, törzsek és konfigurációjuk teljes katalógusát lásd a Pipeline-lépésfajták oldalon.
A regisztrérium kialakításának két következményét érdemes ismerni, mielőtt kézzel sablont ír:
- Egy lépés, amelynek
bodyKey-je nincs regisztrálva, figyelmeztetést ad a sablon betöltésekor, majd soha nem fut le. Futásidőben semmi nem jelez hangosan hibát. Atriggerésterminallépések mentesülnek ez alól a figyelmeztetés alól: a trigger továbbra is lefuttatja a semmittevőpipeline.triggertörzset, hogy a további figyelők elinduljanak; egyterminallépésnek nincs törzse, és az ütemező őrszeme. - Egy csomópont
extrasleképezésében lévő kulcsok pontos egyezést igényelnek, és minden más esetben csendben figyelmen kívül maradnak. Csak azextras['spaceId']teszi egy ügynöklépés munkáját egy létező beszélgetésbe. Azextras['mode'](chat/plan/review) annál a csomópontnál olvasódik, amelyik megnyitja a szobát (messaging.createSpace, alapértelmezés:review) — egy későbbi ügynöklépés nem tudja újra jogosultságolni azt a beszélgetést, amelyhez csatlakozott. Mindkét kulcs bármely más írásmódja figyelmen kívül marad.
Állapot és adatáramlás
Szekció neve “Állapot és adatáramlás”A lépések nem hívják egymást. Egy közös állapottárba írnak és abból olvasnak a
futtatáson belül: egy lépés kulcs szerint olvassa be a bemeneteit, végrehajt,
majd a kimenetét a saját outputKey-je alá írja vissza. Ha párhuzamos ágak
ugyanazt a kulcsot célozzák, egy StateReducer fésüli össze az egyidejű
írásokat, egy TemplateRenderer pedig ugyanabból az állapotból helyettesíti be
a {{...}} helyőrzőket a promptokban és a szkriptekben.
Éppen ezért vizsgálható meg egy pipeline utólag — az állapottár a futtatás teljes története.
Mi indít el egy futtatást
Szekció neve “Mi indít el egy futtatást”A PipelineTrigger sorok deklarálják, mikor indul el automatikusan egy sablon.
Négy fajtájuk van:
| Eseményindító | Akkor indít futtatást, amikor |
|---|---|
| Domainesemény | Egy illeszkedő domainesemény elsül — például PullRequestPublished vagy TicketAssigned |
| Ütemezés | Egy cron-/intervallumkifejezés esedékessé válik |
| Kézi | Ön kézzel futtatja; az, hogy létezik egy engedélyezett kézi eseményindító, az teszi be a sablont a futtatásválasztóba |
| Webhook | Egy külső rendszer POST kérést küld a szerver HTTP-portján a /webhooks/<token> végpontra |
Az eseményindítók zárt halmazt alkotnak: a diszpécser 16 eseménytípust ismer, és
ennyit kínál fel a választóban (EventPayloadMapper.knownEventTypes), más nem
indíthat pipeline-t. Ebből a 16-ból tizennégyhez tartozik payload-leképezés.
Kettőhöz — a TicketCreated és a TicketStatusChanged eseményhez — nem
tartozik, így az ezekre állított eseményindító engedélyezve marad, de soha nem
sül el. A teljes listát lásd a
Domainesemények oldalon.
A webhook token egyben a HMAC titkos kulcs is: a kérés
X-Hub-Signature-256: sha256=<hex> fejlécét a rendszer a
HMAC-SHA256(body, token) értékkel ellenőrzi, az ellenőrizetlen kézbesítéseket
elutasítja, és azok nem játszhatók újra, a duplikátumokat pedig a dedupe_key
dobja el. Mivel az eseményindító-sorok egyediek (munkaterület, eseménytípus,
sablon) szerint, egy sablonhoz legfeljebb egy webhook-eseményindító és
eseménytípusonként egy eseményindító tartozhat.
A beépített sablonok kézi és eseményindítóit engedélyezve telepítik; az ütemezett eseményindítók letiltva kerülnek be, így az ismétlődő átvizsgálás mindig kifejezett bekapcsolást igényel.
A letiltva érkező sablonok
Szekció neve “A letiltva érkező sablonok”Tizenhárom pipeline-sablont telepít a rendszer minden munkaterületre, és ezek
közül nyolc letiltva érkezik: external_pr_welcome, cross_review,
ticket_to_pr, pr_triage, pre_merge_gate, release_notes, dep_audit és
pr_digest.
Ez az a rész, amely meglepi az embereket. Az eseményindítóik engedélyezve
kerülnek be, a PipelineEngine.start viszont elutasítja a letiltott sablont, és
null-t ad vissza — így az eseményindító a semmibe sül el, és nem jelenik meg
futtatás. A kapcsoló a sablon, nem az eseményindító. Kapcsolja be a
Beállítások → Munkaterület → Pipeline-sablonok alatt, mielőtt azt várná,
hogy az a nyolc bármit is tegyen.
Egy munkaterület újratelepítése megőrzi, amit Ön választott: az isEnabled
beállítása és a meglévő eseményindító-sorai megmaradnak. Pontosan egy szándékos
kivétel van — a pr_merged_cleanup napi ütemezése akkor is kényszerítetten
engedélyezett, ha korábban ki volt kapcsolva, mert ez szemétgyűjtés. Enélkül a
worktree-sorok, a kódgráf-partíciók és a copy-on-write másolatok halmozódnak
fel, és ez soha nem is volt felhasználói döntés tárgya.
Még egy aszimmetria, amit érdemes tudni: a beépített pr_review szándékosan már
nem tesz közzé semmit a GitHubon. Egy átnézés közzététele külön, felhasználói
jóváhagyáshoz kötött lépés, és egy közvetlenül posztoló pipeline kétszer tenné
közzé. A cross_review, a ticket_to_pr és a pr_triage viszont futásukkor
továbbra is egyenesen a GitHubra tesz közzé egy hozzászólást.
Mit tud a motor
Szekció neve “Mit tud a motor”A PipelineEngine létrehozza a futtatás rekordját, ütemezi a futtatás
eseménytípusához illeszkedő indítócsomópontot, majd bejárja a DAG-ot: ahogy a
lépések befejeződnek, kiértékeli a további eseményindítókat, feloldja a router
elágazásait, vár a join lépésekre, alkalmazza az újrapróbálkozási szabályokat és
a hiba utáni folytatást, valamint minden lépésnél menti az állapotot, a
költséget és a hibákat. Azokat az éleket, amelyek egy másik indítócsomópontból
indulnak, erre a futtatásra nézve figyelmen kívül hagyja, így egy ütemezett
indítás nem vár egy csak kézi feltételre.
Mit nem tud: semmit a jegyrendszerről, az ügynökindításról, a GitHubról vagy
az üzenetküldésről. Egyetlen bővítési pontja a PipelineBodyRegistry. Az ott
regisztrált törzsek azok, amelyek az AgentDispatchPort, a MessagingPort és
testvéreik hordozói — ezért nem jelenti soha az ütemező módosítását, ha új
képességet adunk a pipeline-okhoz.
Hibakezelés
Szekció neve “Hibakezelés”Egy hibát adó lépés rögzíti a hibaüzenetét, és failed állapotba kerül. Ha a
lépés continueOnFail beállítást deklarál, a további lépések folytatódnak, és a
hiba a futtatás állapotában tárolódik; különben a futtatás megbukik. Egy
StepRetryPolicy-val rendelkező lépést előbb újrapróbál a rendszer, lineáris
vagy exponenciális backoff-fal, mielőtt bármelyik fenti eset érvénybe lépne.
Lásd még
Szekció neve “Lásd még”- Domainesemények: mire figyel egy eseményindító
- Orchestráció: egy terv, amelyet jóváhagy, és amelyet ezen pipeline-ok egyikévé fordítunk le
- Jegyek és delegálás: mit hoznak létre és fejeznek be a pipeline-lépések
- Pipeline-lépésfajták: a fajták, törzsek és konfiguráció teljes katalógusa
- Az első pipeline felépítése
- Pipeline-sablon létrehozása
- Pipeline kézi futtatása
- Pipeline-futtatások figyelése
- Pipeline-eseményindítók beállítása