Oltre un certo punto, copiare la stessa sequenza di nodi in dieci pipeline diventa debito tecnico. Le sotto-pipeline permettono a una pipeline di chiamarne un'altra come una funzione: definisci un pezzo di logica una volta, riutilizzalo ovunque — anche tra organizzazioni.
Due building block simmetrici:
pipeline_callable(un receiver, dichiarato sul nodo Start) espone una pipeline dietro un URL, con un contratto tipizzato di input e output.pipeline_call(un nodo) chiama quella pipeline: mappa i suoi input dal contesto corrente e memorizza il risultato in una chiave di output.
Esporre una pipeline (pipeline_callable)
Sulla pipeline "servizio", aggiungi un receiver pipeline_callable che dichiara:
- Input — l'elenco dei parametri attesi (nome, tipo, obbligatorio o facoltativo).
- Output — le chiavi del risultato restituito.
- Chiave di risposta — quale valore di contesto costituisce la risposta (
exchange.resultper impostazione predefinita). - Modalità di risposta —
sync(il chiamante attende una risposta JSON) ostream(avanzamento in tempo reale). - Budget di tempo — tempo massimo di esecuzione (60 s per impostazione predefinita, 300 s massimo).
Un input dichiarato obbligatorio e assente dalla chiamata fa fallire quest'ultima (400).
La pipeline riceve quindi un URL pubblico (con un token) da condividere con la pipeline chiamante. Il token è ruotabile in qualsiasi momento per revocare l'accesso.
Chiamare una pipeline (pipeline_call)
Sulla pipeline "consumatrice", il nodo pipeline_call viene configurato con:
- L'URL della pipeline di destinazione (fisso, non templatable: viene analizzato al salvataggio per rilevare i loop).
- Una mappatura di input — per ogni parametro atteso, il selettore di contesto che lo fornisce.
- La chiave di output dove viene memorizzato il risultato (
exchange.subresultper impostazione predefinita). - La modalità (
sync,ack,stream) e un timeout (30 s per impostazione predefinita, 300 s massimo).
In caso di fallimento (timeout, errore, risposta malformata), la pipeline continua: la chiave di output riceve null e una chiave ._error descrive cosa è successo. È responsabilità della tua pipeline orchestrare il fallback (ramo di fallback, alert).
Chiamate cross-organizzazione: opt-in e sottoposte ad audit
Una sotto-pipeline può essere chiamata da un'organizzazione diversa — questo è il fondamento per condividere capacità tra entità. Il modello resta rigoroso:
- Rifiutato per impostazione predefinita. Le chiamate cross-organizzazione sono possibili solo se l'amministratore della pipeline esposta lo autorizza esplicitamente (
allow_cross_org). - Firma HMAC consigliata. Una volta aperta una chiamata cross-org, viene attivato un segreto condiviso su entrambi i lati: ogni richiesta viene firmata (header
X-Pipeline-Signature) e il receiver rifiuta qualsiasi firma assente o non valida (401). Una volta salvato, questo segreto non viene mai più mostrato, da entrambe le parti (vedi L'editor visuale, sezione Segreti); rimuoverlo dal lato chiamante elimina la firma, rimuoverlo dal lato esposto elimina la verifica. - Tutto viene tracciato. Ogni invocazione scrive un record di audit (organizzazione chiamante, nodo, profondità, latenza, stato) — prima dell'esecuzione, così che una traccia esista anche in caso di incidente. Entrambe le parti possono consultare i propri log (lato chiamante e lato chiamato), in conformità con i diritti di accesso GDPR.
Fatturazione: l'organizzazione chiamata paga per le risorse (LLM, voce…) consumate durante l'esecuzione. Logica dell'ospite: usi le risorse del tuo host.
Prevenzione dei loop
Una pipeline che chiamasse se stessa, direttamente o attraverso una catena, consumerebbe crediti all'infinito. Due protezioni:
- Rilevamento statico alla registrazione (all'interno di un'organizzazione): l'editor rifiuta di pubblicare un ciclo diretto (
A → A) o indiretto (A → B → C → A), citando la catena incriminata. - Guard a runtime (tra organizzazioni, dove la visibilità statica è impossibile): ogni chiamata propaga la propria profondità; oltre 10 livelli, la chiamata viene rifiutata.
Modalità di esecuzione
- Sincrona (
sync) — il nodo attende la risposta completa. Adatta a operazioni di breve durata. - Senza attesa (
ack) — la chiamata viene avviata e la pipeline chiamante prosegue subito; la chiave di output resta vuota. - Streaming (
stream) — per una sotto-pipeline di lunga durata (ragionamento LLM, elaborazione batch), il progresso viene ricevuto in tempo reale (sotto<chiave di output>._progress); il timeout riguarda allora il tempo massimo senza eventi, non la durata totale.
Quando usarle
- Fattorizzare una sequenza riutilizzata da più pipeline (riassumere un thread, qualificare un lead, verificare un documento).
- Condividere una capacità tra organizzazioni — un'entità espone "validare una fattura rispetto all'ERP", un'altra la consuma, con una traccia di audit su entrambi i lati.
- Parallelizzare un fan-out di sotto-attività indipendenti da un loop.