Vai alla navigazione

Procedure strutturate

Una sequenza fissa di passaggi tipizzati che il tuo agente esegue sempre nello stesso modo

Panoramica

Una procedura strutturata è una procedura che esegue una sequenza fissa di passaggi. Una procedura in formato libero è una guida in linguaggio naturale che l’agente interpreta e adatta alla situazione. Una procedura strutturata è un elenco ordinato di passaggi tipizzati che l’agente esegue in ordine ogni volta che la procedura si applica.

Usa una procedura strutturata quando passaggi specifici devono avvenire nello stesso modo a ogni chiamata: per verificare l’identità di chi chiama, effettuare l’escalation di un ticket o ricevere un pagamento. La definisci come un breve elenco di passaggi in linguaggio semplice.

Come ogni procedura, una procedura strutturata ha un trigger che descrive quando si applica. Quando una conversazione corrisponde al trigger, l’agente esegue nell’ordine i passaggi della procedura e poi torna al resto della conversazione.

Editor delle procedure strutturate

Quando usare una procedura strutturata

Usa una procedura strutturata quando passaggi specifici devono essere eseguiti sempre nello stesso modo, ma vuoi comunque crearla rapidamente con passaggi semplici. Le procedure strutturate sono più facili da scrivere rispetto a un workflow, ma meno espressive. Per un confronto con le procedure in formato libero, i workflow e il prompt di sistema, consulta Quando usare le procedure.

Anatomia di una procedura strutturata

Una procedura strutturata è composta da tre parti: un nome, un trigger e un elenco ordinato di passaggi.

Nome

Una breve etichetta che identifica la procedura nella dashboard. Il nome non viene mai inviato al LLM, quindi non influisce sul comportamento dell’agente.

Trigger

Una descrizione in linguaggio semplice di quando l’agente deve eseguire questa procedura, ad esempio Quando l’utente chiede il rimborso di un ordine. L’agente confronta l’intento dell’utente con il trigger di ogni procedura ed esegue quella corrispondente, quindi i trigger devono essere concreti e distinti. L’agente vede solo il testo del trigger, mai il nome o l’ID della procedura. Un trigger funziona allo stesso modo di qualsiasi procedura; consulta Scrivere i trigger.

Lascia vuoto il trigger per rendere la procedura una sottoprocedura che viene eseguita solo quando viene richiamata da un’altra procedura.

Passaggi

Il corpo della procedura è un elenco ordinato di passaggi tipizzati. Esistono più tipi di passaggio, che puoi combinare per descrivere l’attività.

PassaggioFunzione
ChiediChiede informazioni all’utente e attende. Continua a chiedere finché l’utente non risponde. Questo è l’unico passaggio che si interrompe per attendere l’utente.
ComunicaFa sì che l’agente comunichi qualcosa con parole proprie, quindi passa al passaggio successivo.
PronunciaFa pronunciare all’agente un messaggio esatto parola per parola, quindi passa al passaggio successivo. Un passaggio Pronuncia può avere una traduzione configurata in modo distinto per ogni lingua supportata dall’agente.
StrumentoRichiama uno strumento specifico. Puoi indicare al LLM in linguaggio semplice come richiamarlo oppure fissare esplicitamente i valori dei parametri quando è richiesto il massimo determinismo. Puoi anche definire i passaggi da eseguire se la chiamata dello strumento non riesce.
SeValuta una o più condizioni in ordine ed esegue i passaggi della prima corrispondenza. Un’opzione Altrimenti viene eseguita quando non c’è alcuna corrispondenza.
SottoproceduraEsegue un’altra procedura strutturata. Al completamento dei suoi passaggi, il controllo torna al passaggio successivo di questa procedura (chiamante).
Strumento di sistemaEsegue un’azione di sistema integrata. Al momento, è supportata solo la chiusura della chiamata.
RiprovaRiesegue il gestore degli errori di un passaggio Strumento, inclusa la chiamata dello strumento, fino a tre volte. Disponibile solo nel gestore degli errori di un passaggio Strumento.

Menu dei tipi di passaggio delle procedure strutturate

Non tutti i passaggi possono comparire ovunque. All’interno di un ramo Se, puoi usare qualsiasi passaggio tranne un altro Se o un Riprova. Nel gestore degli errori di un passaggio Strumento, puoi usare qualsiasi passaggio tranne un Se o un altro Strumento.

Riferimento dei passaggi API

Il content di una procedura strutturata è un documento con codifica JSON che contiene un array steps. Ogni passaggio è un oggetto identificato dal relativo type. Il trigger è un campo separato di primo livello nella procedura e non fa parte di content. I payload API e SDK usano type: "deterministic" per la procedura stessa.

Ask

Un passaggio Ask indica all’agente di richiedere informazioni e attendere che l’utente fornisca una risposta appropriata.

  • Tipo API: ask
  • instruction: Stringa obbligatoria e non vuota.
{
"type": "ask",
"instruction": "Ask the user for their order ID."
}

Tell

Un passaggio Tell indica all’agente di generare un singolo messaggio con parole proprie. Non attende una risposta dell’utente prima di proseguire.

  • Tipo API: tell
  • instruction: Stringa obbligatoria e non vuota.
{
"type": "tell",
"instruction": "Explain that the refund normally takes five to ten business days."
}

Say

Un passaggio Say pronuncia il testo fornito esattamente come scritto, quindi prosegue. Fornisci message_translations per dare all’agente un messaggio esatto per ogni lingua aggiuntiva supportata, indicata tramite codice lingua.

  • Tipo API: say
  • message: Stringa obbligatoria e non vuota.
  • message_translations: Oggetto facoltativo che associa un codice lingua a { "value": "..." }.
{
"type": "say",
"message": "Your refund has been submitted.",
"message_translations": {
"es": { "value": "Su reembolso ha sido enviado." }
}
}

If, else if ed else

Un passaggio If contiene uno o più rami condizionali ordinati. Viene eseguito il primo ramo corrispondente. L’array facoltativo fallback è il ramo Else.

  • Tipo API: branch
  • branches: Elenco obbligatorio e non vuoto di rami condizionali.
  • fallback: Elenco facoltativo di passaggi Else.
  • Ogni ramo richiede un condition e un elenco steps non vuoto.
{
"type": "branch",
"branches": [
{
"condition": {
"type": "llm",
"condition": "The user is on an annual plan."
},
"steps": [
{
"type": "say",
"message": "Your annual plan is eligible for a prorated refund."
}
]
}
],
"fallback": [
{
"type": "tell",
"instruction": "Explain that the account's plan could not be determined."
}
]
}

Funziona come if/else-if/else:

  1. Le condizioni vengono valutate in ordine.
  2. Viene eseguito il primo ramo corrispondente.
  3. Se nessuna condizione corrisponde, viene eseguito fallback.
  4. Al termine di un ramo, la procedura riprende la sequenza principale.

L’esempio sopra usa una condizione testuale, valutata dal modello in linguaggio naturale. Le condizioni possono anche essere espressioni su variabili dinamiche:

{
"type": "expression",
"expression": {
"type": "eq_operator",
"left": {
"type": "dynamic_variable",
"name": "plan_tier"
},
"right": {
"type": "string_literal",
"value": "annual"
}
}
}

Una condizione di espressione verifica le variabili dinamiche, compilate dai risultati degli strumenti o impostate all’avvio della conversazione. Non può leggere la risposta più recente dell’utente. Per creare un ramo in base a ciò che ha detto l’utente, usa una condizione testuale.

Tutti i rami di un passaggio If devono usare lo stesso tipo di condizione: llm oppure expression.

Tool

Un passaggio Tool chiama uno strumento specifico.

  • Tipo API: tool_call
  • tool_id: ID dello strumento obbligatorio e non vuoto. Lo strumento deve essere collegato all’agente.
  • tool_name: Nome dello strumento obbligatorio, corrispondente allo strumento.
  • instruction: Istruzione facoltativa che descrive come chiamare lo strumento.
  • schema_overrides: Valori fissi facoltativi per i parametri dello strumento.
  • on_failure: Gestore di errori facoltativo.
{
"type": "tool_call",
"tool_id": "tool_abc123",
"tool_name": "lookup_order",
"instruction": "Look up the order using the order ID provided by the user."
}

Valori fissi dei parametri

Usa schema_overrides quando un parametro deve avere sempre un valore specifico. Il modello non vede né sceglie un parametro sovrascritto. Le chiavi sono path dei parametri nello schema dello strumento; ogni valore indica una sorgente:

sourceCampiComportamento
constantconstant_valueInvia sempre il valore specificato.
dynamic_variabledynamic_variableInvia il valore corrente della variabile dinamica indicata.
llmprompt (facoltativo)Consente al modello di scegliere il valore, con una sostituzione facoltativa del prompt.
omitEsclude il parametro dalla chiamata.
{
"type": "tool_call",
"tool_id": "tool_abc123",
"tool_name": "update_ticket",
"schema_overrides": {
"request_body.status": { "source": "constant", "constant_value": "pending" },
"request_body.ticket_id": { "source": "dynamic_variable", "dynamic_variable": "ticket_id" }
}
}

Gestione degli errori

Senza on_failure, una chiamata allo strumento non riuscita termina la conversazione. Aggiungi invece on_failure per eseguire passaggi di ripristino.

  • fallback: Elenco obbligatorio e non vuoto di passaggi eseguiti quando lo strumento non riesce.
  • branches: Riservato alla gestione condizionale degli errori. Lascialo vuoto.
{
"type": "tool_call",
"tool_id": "tool_abc123",
"tool_name": "lookup_order",
"on_failure": {
"branches": [],
"fallback": [
{
"type": "tell",
"instruction": "Explain that the order could not be retrieved and offer to connect the user with support."
}
]
}
}

Un gestore di errori può contenere passaggi Ask, Tell, Say, Sub-procedure, System tool e Retry. Non può contenere passaggi Tool o If. Dopo l’esecuzione del gestore, la procedura prosegue con il passaggio successivo al passaggio Tool.

Retry

Un passaggio Retry riesegue il gestore di errori che lo contiene, inclusa la chiamata allo strumento. Ogni tentativo chiama di nuovo lo strumento e, se fallisce ancora, riesegue ogni passaggio del gestore. Quando i tentativi sono esauriti, la conversazione termina.

  • Tipo API: retry
  • max_retries: Intero facoltativo da 1 a 3. Il valore predefinito è 1.
  • Il valore conta i tentativi successivi alla chiamata originale allo strumento.
  • Retry è valido solo all’interno di on_failure.
  • Retry deve essere il passaggio finale del relativo gestore di errori, perché i passaggi successivi non sarebbero raggiungibili.
{
"type": "retry",
"max_retries": 2
}

Sub-procedure

Un passaggio Sub-procedure esegue un’altra procedura strutturata. Quando i passaggi di tale procedura sono completati, l’esecuzione torna al passaggio successivo al passaggio Sub-procedure.

  • Tipo API: sub_procedure
  • procedure_id: ID della procedura obbligatorio e non vuoto.
  • La destinazione deve esistere sullo stesso agente.
  • La destinazione deve essere una procedura strutturata.
  • Una procedura non può richiamare se stessa.
{
"type": "sub_procedure",
"procedure_id": "agtprc_6qbpwdq8n01bxhk44bgjy6f10ck3"
}

System tool

Un passaggio System tool esegue un’azione di sistema integrata.

  • Tipo API: system_tool
  • system_tool_name: Nome dello strumento di sistema obbligatorio.
  • Al momento è supportato solo end_call. In futuro potrebbero essere aggiunti altri strumenti di sistema.
  • Poiché end_call è terminale, deve essere il passaggio finale nella sequenza, nel ramo o nel gestore di errori che lo contiene.
{
"type": "system_tool",
"system_tool_name": "end_call"
}

Regole di convalida

La pubblicazione dell’agente o il salvataggio della bozza dell’agente rifiuta una procedura strutturata che viola una qualsiasi di queste regole. L’errore indica il passaggio non valido tramite il suo path.

  • Non è possibile inserire due passaggi If uno dopo l’altro.
  • I passaggi If non possono essere annidati.
  • Un passaggio If con condizioni di espressione non può seguire direttamente un passaggio Ask.
  • Tutte le condizioni in un passaggio If devono essere dello stesso tipo, llm oppure expression.
  • Retry può comparire solo all’interno di on_failure e deve essere l’ultimo passaggio al suo interno.
  • end_call deve essere l’ultimo passaggio nell’elenco in cui compare.
  • Il fallback di un gestore di errori deve contenere almeno un passaggio.
  • Una Sub-procedure deve puntare a una procedura strutturata esistente sullo stesso agente e non a se stessa.
  • tool_id deve essere uno strumento dell’agente, tool_name deve corrispondere e schema_overrides deve corrispondere allo schema dello strumento.
  • L’elenco steps, ogni instruction e ogni message non possono essere vuoti.

Per sapere come ristrutturare una procedura che non rispetta una di queste regole, consulta le Best practice.

Esempio API completo

Questo esempio gestisce l’annullamento di un ordine in base allo stato della spedizione. Fissa un parametro dello strumento, gestisce una chiamata allo strumento non riuscita, richiama un’altra procedura strutturata, quindi termina la chiamata.

{
"steps": [
{
"type": "ask",
"instruction": "Ask the user for their order ID."
},
{
"type": "branch",
"branches": [
{
"condition": {
"type": "llm",
"condition": "The user says the order has already shipped."
},
"steps": [
{
"type": "tell",
"instruction": "Explain that shipped orders must be returned before they can be refunded."
}
]
},
{
"condition": {
"type": "llm",
"condition": "The user says the order has not shipped."
},
"steps": [
{
"type": "tool_call",
"tool_id": "tool_abc123",
"tool_name": "cancel_order",
"instruction": "Cancel the order using the order ID provided by the user.",
"schema_overrides": {
"request_body.notify_customer": { "source": "constant", "constant_value": true }
},
"on_failure": {
"branches": [],
"fallback": [
{
"type": "tell",
"instruction": "Apologize that the cancellation did not go through and say you will try once more."
},
{
"type": "retry",
"max_retries": 1
}
]
}
}
]
}
],
"fallback": [
{
"type": "ask",
"instruction": "Ask whether the order has already shipped."
}
]
},
{
"type": "sub_procedure",
"procedure_id": "agtprc_6qbpwdq8n01bxhk44bgjy6f10ck3"
},
{
"type": "say",
"message": "Thank you for contacting us. Goodbye.",
"message_translations": {
"es": { "value": "Gracias por contactarnos. Adiós." }
}
},
{
"type": "system_tool",
"system_tool_name": "end_call"
}
]
}

Come viene eseguita una procedura strutturata

La conversione dei passaggi di una procedura strutturata nel formato eseguito dall’agente è chiamata compilazione. La piattaforma compila ogni procedura strutturata quando pubblichi; non devi compilare nulla autonomamente. Il risultato compilato è attualmente visibile come nodi di sola lettura nella scheda Workflow.

Quando la richiesta dell’utente corrisponde al trigger di una procedura, l’agente accede alla procedura ed esegue i relativi passaggi in ordine. All’interno della procedura strutturata, l’agente si concentra su ciascun passaggio isolatamente. Quando raggiunge la fine, torna al resto della conversazione.

Le seguenti regole descrivono il comportamento dei passaggi in fase di runtime.

Ogni passaggio diverso da Ask viene eseguito immediatamente e il controllo passa al passaggio successivo nello stesso turno. Un passaggio Tell o Say invia il messaggio e prosegue. Non esiste alcun passaggio che metta in pausa la conversazione oltre ad Ask, né alcun passaggio che termini il turno corrente. Se ti serve l’input dell’utente, usa un passaggio Ask. Se la conversazione deve terminare, usa lo strumento di sistema end_call.

Quando l’ultimo passaggio è completato, la procedura termina e l’agente torna al resto della conversazione con il turno ancora aperto, quindi potrebbe aggiungere altro. Quando una sub-procedure viene completata, il controllo torna al passaggio successivo della procedura che l’ha chiamata.

Un passaggio Tool non può creare rami in base a un codice di stato o al body della risposta. Se lo strumento riesce, la procedura prosegue. Se non riesce e il passaggio non ha un gestore di errori, la conversazione termina. Se ne ha uno, vengono eseguiti i passaggi del gestore e la procedura prosegue al passaggio successivo. Un Retry nel gestore riesegue lo strumento e, se fallisce di nuovo, ogni passaggio del gestore, finché lo strumento riesce o i tentativi sono esauriti. Se sono esauriti, la conversazione termina.

Le condizioni vengono valutate in ordine e viene eseguita la prima corrispondenza. Il ramo Else viene eseguito quando non c’è alcuna corrispondenza. Se non è presente alcun Else e non c’è alcuna corrispondenza, la procedura prosegue con il passaggio successivo a If. Un caso non gestito non è un errore.

Nulla di ciò che viene deciso all’interno di un ramo If viene mantenuto dai passaggi successivi. Se un’informazione appresa in un ramo è necessaria in seguito, salvala esplicitamente con una chiamata allo strumento o una variabile dinamica.

Solo i passaggi Tool possono chiamare strumenti. Non devi indicare a un passaggio Ask, Tell o Say di non chiamare strumenti: non può farlo.

Gestire una procedura strutturata

Apri il tuo agente nel dashboard, quindi seleziona Procedures. Usa + per creare una procedura strutturata. Aggiungi un trigger, seleziona un tipo per ogni passaggio e pubblica le modifiche dell’agente.

Il dashboard convalida le procedure strutturate durante la modifica. Se una procedura viola una regola di convalida, il pulsante Publish mostra uno stato di errore, la scheda Procedures mostra un badge di errore e l’anteprima non può iniziare finché la procedura non viene corretta. Seleziona l’indicatore di errore per vedere quale procedura e passaggio sono interessati.

Editor delle procedure strutturate con il pulsante Publish nello stato di errore e un badge
1 Error

Finestra di dialogo dei dettagli di convalida che elenca la procedura non riuscita e il passaggio che richiede un
messaggio

Best practice

Ogni tipo di passaggio applica già il proprio comportamento, quindi raramente devi esplicitarlo. Scrivi l’obiettivo di ogni passaggio e lascia che sia il tipo di passaggio a fare il resto. Le indicazioni seguenti coprono i casi che è importante gestire correttamente.

Scegliere i tipi di passaggio

Un passaggio Ask attende una risposta. Se riunisci più domande in un’unica istruzione, l’agente tende a saltarne alcune o a unirle. Usa un Ask per ogni informazione.

Un passaggio Tell comunica il suo messaggio e prosegue senza attendere. Un Tell formulato come domanda non riceve mai una risposta. Se un passaggio richiede una risposta dell’utente, è un Ask.

Un passaggio Ask avanza quando riceve una risposta appropriata. Se non è ovvio dalla domanda cosa costituisca una risposta, specificalo nell’istruzione, ad esempio _Chiedi l’ID dell’ordine; un ID valido è composto da otto cifre _.

Usa un passaggio Tell quando l’agente deve comporre il messaggio autonomamente e un passaggio Say quando la formulazione deve essere letterale o tradotta. Entrambi inviano esattamente un messaggio, quindi non serve indicare a un passaggio di inviare un singolo messaggio.

I passaggi Ask, Tell e Say non possono chiamare strumenti. Scrivere non chiamare alcuno strumento al loro interno aggiunge rumore all’istruzione senza modificarne il comportamento.

Strutturare la procedura

Non è possibile inserire due passaggi If uno dopo l’altro. Inserire un Tell o Say non correlato tra di essi per rispettare la regola fa dire all’agente qualcosa che non dovrebbe. Invece, integra la seconda decisione nel primo If come ulteriori rami Else if oppure spostala in una sotto-procedura.

I passaggi If non possono essere nidificati. Quando una decisione dipende da un’altra, inserisci la decisione interna nella sua procedura strutturata e richiamala con un passaggio Sub-procedure dal ramo che ne ha bisogno.

Un passaggio If senza Else prosegue al passaggio successivo quando nulla corrisponde. Se il caso senza corrispondenza deve comportarsi diversamente, aggiungi un ramo Else.

Le decisioni prese all’interno di un ramo If non vengono ricordate in seguito. Se un passaggio successivo dipende da qualcosa appreso in un ramo, registralo con una chiamata a uno strumento o una variabile dinamica all’interno del ramo.

Le condizioni di espressione verificano le variabili dinamiche. Inserisci un passaggio If che le usa subito dopo il passaggio Tool che imposta quelle variabili. Per creare rami in base a ciò che l’utente ha detto, usa una condizione di testo.

Quando più procedure strutturate condividono la stessa sequenza, ad esempio l’escalation a un operatore, inseriscila in un’unica procedura strutturata con un trigger vuoto e richiamala da ciascuna. Le sequenze copiate divergono nel tempo.

Lavorare con gli strumenti

Un passaggio Tool chiama sempre il suo strumento. Una condizione scritta nell’istruzione, come _salta questo passaggio se il ticket ha già un tag _, non può impedire la chiamata. Se la chiamata non deve sempre avvenire, inserisci la condizione in un passaggio If prima del passaggio Tool.

Quando un parametro deve assumere sempre un valore specifico, impostalo con un override constant in schema_overrides. Un’istruzione come imposta sempre lo stato su in attesa chiede al modello di rispettarla; un override viene applicato e non può essere ignorato.

Senza on_failure, qualsiasi errore dello strumento termina la conversazione. Aggiungi un gestore che comunichi all’utente cosa è successo e riprovi, esegua l’escalation o prosegua.

Un passaggio Tool esegue solo lo strumento; l’agente non può parlare né prendere decisioni durante la sua esecuzione. Per parlare con l’utente o creare rami in base a ciò che lo strumento ha restituito, usa un passaggio separato prima o dopo il passaggio Tool.

Scrivere le istruzioni

La procedura controlla cosa viene eseguito successivamente e l’agente non è a conoscenza dei passaggi successivi durante l’esecuzione di quello corrente. Lascia che l’ordine dei passaggi definisca la sequenza.

Frasi scritte nelle istruzioni dei passaggi, come questo è l’ultimo messaggio di questo turno, chiedono all’agente di applicare un confine che la piattaforma non prevede. Usa un passaggio Ask per attendere l’utente o lo strumento di sistema end_call per terminare la conversazione.

Il tono, la formattazione, le formule di chiusura e le politiche di rifiuto devono essere nel prompt di sistema. L’istruzione di un passaggio dovrebbe indicare solo ciò che è specifico di quel passaggio.

Comporre procedure

Le indicazioni generali per comporre procedure si applicano anche alle procedure strutturate; consulta Comporre procedure nella pagina delle procedure in formato libero.

Un modello è specifico della combinazione di tipi: una procedura in formato libero può fare riferimento a una procedura strutturata. Mantieni la gestione aperta in una procedura in formato libero e delega a una procedura strutturata le parti che devono essere eseguite sempre allo stesso modo, come la verifica dell’identità o l’escalation.

Limitazioni

  • I passaggi If non possono essere nidificati e non è possibile inserire due passaggi If uno dopo l’altro.
  • L’unico strumento di sistema supportato è end_call.
  • Le procedure strutturate non possono fare riferimento a documenti della knowledge base.
  • Non è possibile terminare il turno corrente al completamento di una procedura; l’agente mantiene il turno aperto e potrebbe continuare a parlare.
  • Non è possibile avviare una procedura strutturata da un nodo specifico del workflow nella dashboard.
  • L’avvio di una procedura aggiunge latenza: l’agente effettua una chiamata a uno strumento per accedervi e poi procede nel workflow generato.

Supporto dei provider di modelli

Le procedure strutturate forzano le chiamate agli strumenti interni quando si accede a una sotto-procedura e quando si completa una procedura. Le principali famiglie di modelli OpenAI, Anthropic, Gemini e Grok supportano la scelta forzata dello strumento. Altri modelli o provider personalizzati potrebbero non garantirla, rendendo meno affidabili le transizioni tra sotto-procedure o il completamento delle procedure. Verifica il supporto per la scelta forzata dello strumento quando utilizzi un altro provider di modelli.

Consulta Procedure per i limiti che si applicano a tutte le procedure, incluso il limite delle dimensioni dei contenuti e le differenze tra procedure strutturate e in formato libero.