Claude Architect · Lezione

Protocolli di handoff strutturati

Esegua il passaggio includendo ID, riepilogo, azioni e raccomandazione.

Lezione 4 di 413 passaggi

Protocolli di handoff strutturati è una lezione Claude Architect gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Claude Architect, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Claude Architect include 4 lezioni in totale.

Perché i passaggi richiedono una struttura

In un sistema multi-agente hub-and-spoke, il coordinatore assegna continuamente il lavoro agli agenti secondari e ne riceve i risultati. Il fatto CRITICO è questo: gli agenti secondari NON ereditano la cronologia della conversazione del coordinatore — il modello non conserva alcuno stato, quindi la cronologia COMPLETA della richiesta viaggia in messages a ogni turno.

Questo significa che ogni passaggio deve includere esplicitamente il proprio contesto. Un "vai a correggere il bug di autenticazione" non strutturato perde l'ID del caso, ciò che è già stato tentato e la decisione che il coordinatore deve ricevere. Un protocollo di passaggio strutturato risolve il problema: ogni trasferimento include un identificatore, un riepilogo, le azioni eseguite e una raccomandazione.

Il passaggio in quattro parti

Un payload di passaggio affidabile contiene quattro campi, ognuno dei quali risolve una specifica modalità di errore:

  • ID — una chiave di correlazione stabile (case_id, custom_id) per associare i risultati alle richieste, anche tra chiamate parallele.
  • Riepilogo — i fatti transazionali riportati alla lettera di cui il destinatario ha bisogno (ID cliente verificato, numero dell'ordine, importi).
  • Azioni — ciò che è già stato tentato, con i relativi risultati, per evitare di ripetere il lavoro.
  • Raccomandazione — il passo successivo o la decisione proposta che il destinatario deve confermare o annullare.

Questo corrisponde direttamente al modo in cui i coordinatori scompongono, delegano, aggregano e instradano il lavoro.

Passare esplicitamente il contesto

Poiché l'agente secondario inizia con una cronologia vuota, non potete fare affidamento sul fatto che "lo sappia già". Inserite il passaggio direttamente nel prompt dell'agente secondario. Notate come ID, riepilogo e azioni precedenti siano esplicitati: non si dà nulla per scontato.

subagent_prompt = f"""
HANDOFF
id: {case_id}
summary: Verified customer C-4821 (id confirmed via get_customer).
  Order O-9930, refund requested: $420.
actions_taken:
  - get_customer -> identity verified
  - lookup_order(O-9930) -> status DELIVERED, eligible
recommendation: Approve refund of $420; confirm against policy before process_refund.

Proceed with the recommendation or override it with justification.
"""

response = client.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=1024,
    system="You are the refund-processing subagent.",
    messages=[{"role": "user", "content": subagent_prompt}],
    tools=refund_tools,
)

Imporre la struttura con l'output strutturato

Un passaggio in testo libero può avere facilmente una struttura non valida. Per garantire la presenza di tutti e quattro i campi, trasformate il passaggio in un tool con uno JSON Schema e usate tool_choice per forzare un output strutturato. tool_use + JSON Schema elimina gli errori di sintassi e impone i campi obbligatori.

Regola fondamentale del fact sheet: contrassegnate un campo come required SOLO se è sempre presente. id, summary, actions e recommendation sono sempre presenti in un passaggio valido, quindi è corretto renderli obbligatori. Un campo opzionale come escalation_reason NON deve essere obbligatorio, altrimenti il modello lo inventerà.

handoff_tool = {
    "name": "emit_handoff",
    "description": "Emit a structured handoff to the coordinator.",
    "input_schema": {
        "type": "object",
        "properties": {
            "id": {"type": "string"},
            "summary": {"type": "string"},
            "actions": {"type": "array", "items": {"type": "string"}},
            "recommendation": {"type": "string"},
            "escalation_reason": {"type": "string"}
        },
        "required": ["id", "summary", "actions", "recommendation"]
    }
}

Forzare il passaggio con tool_choice

Il modo in cui impostate tool_choice determina se otterrete effettivamente un passaggio strutturato:

  • "auto" — il modello può rispondere con del testo invece di un passaggio. È rischioso per i protocolli.
  • "any" — il modello DEVE chiamare un tool, garantendo un output strutturato.
  • {"type":"tool","name":"emit_handoff"} — forza esattamente questo tool. Usatelo quando il compito dell'agente secondario è restituire un unico passaggio ben formato.
response = client.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=1024,
    system="Summarize your work as a single handoff.",
    messages=history,
    tools=[handoff_tool],
    tool_choice={"type": "tool", "name": "emit_handoff"},
)

handoff = response.content[0].input  # {id, summary, actions, recommendation}

Correlare con un ID stabile

L'ID consente a un coordinatore di aggregare i risultati che arrivano fuori ordine. Quando emettete più chiamate Task in un'unica risposta, queste vengono eseguite in parallelo: le risposte non arrivano nell'ordine in cui avete inviato le chiamate. Senza una chiave di correlazione, non potete associare un risultato alla relativa richiesta.

È lo stesso principio del custom_id della Batch API, che correla le richieste permettendovi di inviare nuovamente solo quelle non riuscite. In un flusso multi-agente sincrono, il vostro id del passaggio svolge questo ruolo.

results_by_id = {}
for handoff in subagent_handoffs:
    results_by_id[handoff["id"]] = handoff

# Aggregate deterministically by ID, not by arrival order
for case_id in dispatched_ids:
    h = results_by_id.get(case_id)
    if h is None:
        log.warning("missing handoff for %s", case_id)

Mantenere i fatti alla lettera nel riepilogo

È nel riepilogo che i passaggi si compromettono spesso senza essere notati. La sintesi progressiva rende vaghi numeri, percentuali e date, proprio i campi di cui il destinatario ha bisogno per agire ($420 diventa "qualche centinaio di dollari"). Inoltre, i modelli prestano più attenzione all'inizio e alla fine del contesto che alla parte centrale (lost-in-the-middle).

La soluzione consiste nel raccogliere i fatti transazionali in un blocco separato di fatti del caso, mantenuto alla lettera, al di fuori di qualsiasi riepilogo discorsivo. Il campo summary del passaggio deve contenere questi fatti esatti, mai una parafrasi che ne perda informazioni.

case_facts = {
    "customer_id": "C-4821",
    "order_id": "O-9930",
    "refund_amount_usd": 420.00,
    "delivered_on": "2026-06-02",
}

# Inject verbatim; do NOT let these pass through summarization
summary = (
    "Verified C-4821; order O-9930 delivered 2026-06-02; "
    "refund requested $420.00."
)

Azioni: distinguere un errore da un risultato vuoto

Il campo delle azioni deve registrare non solo ciò che è stato eseguito, ma anche ciò che ogni chiamata ha restituito; inoltre, deve distinguere un ERRORE di accesso (che potrebbe consentire un nuovo tentativo) da un risultato VUOTO valido (nessuna corrispondenza, non riprovare). Usate errori strutturati, non errori generici.

Un errore strutturato contiene isError, errorCategory (transient / validation / business / permission), isRetryable, la query tentata e i risultati parziali. Un generico "Operazione non riuscita" impedisce il recupero; il contesto strutturato consente al destinatario di instradare il lavoro in modo intelligente.

actions = [
    {"tool": "get_customer", "result": "verified C-4821"},
    {"tool": "lookup_order", "query": "O-9930",
     "isError": True, "errorCategory": "transient",
     "isRetryable": True,
     "message": "order service timeout",
     "partial_results": []},
]

Raccomandazione, non azione finale

Il quarto campo è una raccomandazione che il destinatario può confermare o annullare, non un'azione unilaterale. In questo modo l'autorità decisionale rimane dove deve essere e si supporta un'escalation ordinata.

Nella raccomandazione devono comparire buoni fattori di attivazione dell'escalation: una richiesta esplicita di una persona (escalation immediata), una lacuna nelle policy, l'assenza di progressi dopo vari tentativi o il superamento di una soglia. I fattori SBAGLIATI non devono mai determinarla: analisi del sentiment, un punteggio di sicurezza stimato dal modello o un classificatore non addestrato. Una raccomandazione del tipo "il cliente sembra frustrato, eseguire l'escalation" è un anti-pattern.

recommendation = (
    "Refund $420 is within policy and order is eligible. "
    "RECOMMEND approve. NOTE: refunds over $500 require a "
    "hook-enforced check; this is under threshold."
)
# escalation_reason set ONLY on a real trigger, e.g.:
# "Customer explicitly asked for a manager."

Proteggere i passaggi critici con gli hook

La raccomandazione di un passaggio è probabilistica: le indicazioni del prompt sono corrette circa il 90% delle volte. Quando agire sulla base di un passaggio comporta conseguenze finanziarie, legali o di sicurezza, la garanzia deve essere deterministica e applicata da un hook, non dal testo della raccomandazione.

Un hook per le chiamate in uscita può bloccare un'azione che viola le policy (ad esempio, un rimborso > 500 $), indipendentemente dalla raccomandazione dell'agente secondario. Una precondizione programmatica — bloccare process_refund finché get_customer non ha restituito un ID verificato — offre una garanzia che i prompt non possono offrire. Gli hook = 100% deterministici; i prompt ≈ 90% probabilistici.

# settings.json — deterministic enforcement on the action,
# independent of the handoff recommendation
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "process_refund",
      "command": "./hooks/block_refund_over_500.sh"
    }]
  }
}

Riprendere una sessione o creare un nuovo riepilogo

A volte un passaggio prosegue un lavoro precedente. --resume <name> continua una sessione denominata e fork_session crea un ramo a partire da un punto condiviso. Attenzione, però: i risultati dei tool ripresi possono essere OBSOLETI se nel frattempo il codebase o i dati sono cambiati.

Quando lo stato sottostante è cambiato, una nuova sessione inizializzata con un passaggio strutturato (ID + fatti riportati alla lettera + azioni + raccomandazione) è spesso più affidabile che riprendere una sessione piena di output obsoleto dei tool. È il passaggio strutturato a rendere economico un riavvio pulito.

# Continue named work...
claude --resume refund-C4821

# ...but if state changed, start fresh and inject the handoff:
claude -p "$(cat handoff_C4821.json)" \
  --system-prompt "Act on this structured handoff."

Verifica rapida: progettare il passaggio

Un coordinatore distribuisce tre casi di rimborso ad agenti secondari tramite chiamate Task parallele. State progettando il passaggio che ogni agente secondario deve restituire, in modo che i risultati possano essere aggregati e gestiti in sicurezza. Quale progettazione è corretta?

Riepilogo: protocolli di passaggio strutturati

Punti chiave:

  • Gli agenti secondari non ereditano alcuna cronologia: ogni passaggio include esplicitamente il proprio contesto.
  • Quattro campi: ID (correla i risultati paralleli), summary (fatti riportati alla lettera), actions (con errori strutturati), recommendation (conferma/annullamento).
  • Forzate la struttura con un tool di passaggio + JSON Schema e tool_choice; rendete obbligatori solo i campi sempre presenti.
  • Mantenete numeri e date alla lettera in un blocco di fatti del caso: la sintesi li rende vaghi.
  • Nelle azioni, distinguete un errore di accesso da un risultato vuoto valido tramite errorCategory e isRetryable.
  • Vincolate le azioni con conseguenze tramite hook deterministici, mai con la sola raccomandazione.
  • Se l'output dei tool ripreso potrebbe essere obsoleto, ricominciate da capo usando il passaggio strutturato.
Gratis per iniziare

Impara Python con un tutor IA — gratis

Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.

Corsi
26
Lezioni
104

Domande Frequenti

La lezione «Protocolli di handoff strutturati» è gratuita?

Sì — il testo completo di «Protocolli di handoff strutturati» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Claude Architect, passa a CoddyKit PRO. Il corso Claude Architect include 4 lezioni in totale.

Cosa imparerò in «Protocolli di handoff strutturati»?

Esegua il passaggio includendo ID, riepilogo, azioni e raccomandazione. Eserciti Claude Architect con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Claude Architect?

Non è richiesta alcuna esperienza precedente. Claude Architect su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «Protocolli di handoff strutturati»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Claude Architect?

Sì. Ogni lezione Claude Architect include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Hook PostToolUse e delle chiamate in uscita
  2. Applicazione deterministica vs prompt
  3. Precondizioni programmatiche
  4. Protocolli di handoff strutturati
← Torna a Claude Architect