1. Introduzione
Immagina di scrivere un normale servizio web. Lì tutto è semplice: hai un URL /search, l’utente preme un pulsante, tu chiami il controller searchController. Nel mondo delle ChatGPT Apps nessun /search è visibile all’utente. Scrive testo naturale:
«Trova un regalo per mio fratello gamer fino a 50$»
E poi:
- il modello decide: «Oh, si parla di regali, ho GiftGenius che sa farlo»;
- GPT “preme i pulsanti” da solo — invoca gli strumenti della tua App;
- a volte propone anche all’utente: «Vuoi che apra GiftGenius e ti mostri delle opzioni?».
Il cambiamento chiave: l’utente esprime un’intenzione e i pulsanti li preme il modello. Se non si comprende questo flusso, è molto facile:
- scrivere strumenti con nomi privi di senso (run_func, doStuff),
- ottenere un’App che non viene mai proposta dal modello o viene invocata a sproposito,
- creare un widget che “spunta dal nulla” e rompe il dialogo.
Perciò in questa lezione costruiamo un modello mentale: come GPT viene a sapere della tua App e in quali punti del dialogo la “inserisce”.
Insight: l’app è un plugin per ChatGPT
A differenza delle app su telefono o delle mini‑app in WeChat, le app in ChatGPT sono organizzate diversamente.
ChatGPT decide da solo quando avviare la tua applicazione e quale sua funzione invocare. Le applicazioni in ChatGPT possono intervenire attivamente (seppur con limiti) nella logica della chat. Il loro obiettivo principale e il loro punto di forza — è estendere le capacità di ChatGPT stesso.
Se ChatGPT può risolvere perfettamente il problema dell’utente — non ha bisogno di chiamare la tua applicazione. Se ChatGPT non può affatto risolvere il problema — l’utente non ne chiederà nemmeno. La situazione ideale è quando ChatGPT può risolvere solo parzialmente la richiesta dell’utente. Questo significa che le richieste esistono, sono tante, ma il risultato è insufficiente.
Proprio allora ChatGPT chiama la tua applicazione e insieme rendete l’utente felice. L’utente diventa più felice e tu — più ricco.
2. Modi di avviare una ChatGPT App dal punto di vista dell’utente
L’utente non ha il pulsante «chiama il server MCP e call_tool», ma ha un campo di testo e (talvolta) un menu delle applicazioni. Dal suo punto di vista esistono due schemi base di avvio: esplicito e implicito.
Avvio esplicito (explicit)
È lo scenario in cui l’utente sceglie consapevolmente la tua App.
Varianti tipiche:
- trova l’App nello Store di ChatGPT e preme «Apri»;
- seleziona l’App dal launcher (per esempio tramite il pulsante + nel campo di input testo, il Composer);
- inizia il messaggio con il nome dell’applicazione: «GiftGenius, trova un regalo…» — questo si chiama named mention. Se il nome dell’App è all’inizio del prompt, ChatGPT include automaticamente la tua App nel contesto della risposta.
In modalità esplicita il modello sa fin dall’inizio: l’utente è qui per lavorare proprio con questa App. Quindi:
- GPT chiama i tuoi strumenti più spesso e in modo più attivo;
- il widget UI della tua App può apparire già nella prima risposta;
- GPT ignora meno spesso l’App rispondendo “con le proprie forze”.
Un esempio classico: l’utente apre direttamente GiftGenius perché vuole “giocarci” con la scelta dei regali. Clicca l’App nell’elenco e GPT mostra un messaggio di benvenuto del tipo:
«Ciao! Sono GiftGenius, ti aiuterò a scegliere un regalo. Raccontami per chi e con quale budget stiamo cercando?»
E poi usa attivamente i tuoi strumenti per la ricerca.
Avvio implicito (implicit / suggested)
Scenario completamente diverso: l’utente non pensa affatto alle App. Scrive semplicemente in una chat normale:
«Trova un regalo per il compleanno di mia madre, le piace il giardinaggio, budget fino a 100$»
GPT analizza la richiesta e vede che:
- nell’ecosistema c’è l’App GiftGenius, i cui strumenti sono descritti come «Use this when the user wants to get gift recommendations»;
- i compiti e i vincoli (regalo, budget, interessi) coincidono bene con quest’App.
In tal caso il modello può “inserirsi con discrezione” con una proposta:
«Posso usare l’app GiftGenius per selezionare opzioni concrete di regalo e mostrarle sotto forma di schede. La apro?»
Se l’utente accetta — GPT invoca lo strumento necessario dell’App e, possibilmente, renderizza il tuo widget.
È importante che tu non scriva da nessuna parte if (prompt.includes("regalo")) openApp(). Il modello prende la decisione da solo, basandosi su:
- testo della richiesta e cronologia del dialogo;
- metadati dei tuoi strumenti (nomi, descrizioni, schemi dei parametri);
- stato della connessione dell’utente all’App (è autenticato o no), se è utente aziendale o meno.
Tu non influenzi l’algoritmo, ma il modo in cui la tua App e i suoi strumenti sono “descritti” al modello.
Ibrido: quando GPT chiede chiarimenti e poi propone l’App
A volte l’utente scrive qualcosa di molto generico:
«Serve un’idea per un collega, non so proprio cosa»
Il modello capisce che GiftGenius può aiutare, ma l’informazione è troppo vaga. Pattern frequente:
- GPT fa 1–2 domande di chiarimento in testo.
- Dopo propone di avviare l’App: «Ho uno strumento per la scelta dei regali. Vuoi che lo apra e ti mostri le opzioni?».
È un buon UX: l’utente non sente di essere stato “forzato a passare a un’altra applicazione”.
3. Discovery: come GPT trova la tua App
Ora vediamo come appare tutto questo dal punto di vista del modello.
Nella documentazione dell’Apps SDK questo si chiama Discovery — tutti i modi in cui l’utente e il modello vengono a sapere della tua App. Sono le richieste naturali in chat, il catalogo delle applicazioni e speciali “entry points” come il launcher.
Da dove il modello sa che la tua App esiste
Durante la registrazione, ChatGPT avvia la tua App e questa (tramite MCP) fornisce informazioni su di sé: elenca gli strumenti disponibili con i loro schemi — nome, descrizione, schema JSON dei parametri di input. Le informazioni sull’applicazione dovranno essere indicate in fase di registrazione, mentre le informazioni sugli strumenti ChatGPT le estrarrà da solo tramite il metodo MCP list_tools.
Il modello non vede il tuo codice sorgente, ha accesso solo a:
- nome dello strumento (name);
- descrizione (description);
- signature dell’input (inputSchema).
Questo diventa esattamente l’«API per il modello». Se chiami lo strumento run_func con la descrizione «Executes the function», il modello non capirà quando invocarlo. Se lo chiami suggest_gifts con la descrizione «Use this when the user wants gift ideas based on recipient, occasion and budget» — tutto diventa chiaro.
Named mention e in‑conversation discovery
La specifica ufficiale dell’Apps SDK evidenzia due meccanismi chiave:
- Named mention — quando l’utente inizia il messaggio con il nome della tua App. In questo caso l’App verrà quasi sicuramente attivata e utilizzata nella risposta.
- In‑conversation discovery — quando l’utente scrive semplicemente una richiesta e il modello decide se collegare l’App. In questo si tengono in considerazione:
- il contesto della conversazione (storia dei messaggi, risultati degli strumenti precedenti, preferenze dell’utente);
- menzioni esplicite del brand nel testo;
- metadati dei tuoi strumenti — nomi, descrizioni, documentazione dei parametri;
- stato del “link” — se l’utente è collegato all’App (autenticato, con i permessi necessari concessi).
Lo sviluppatore influisce su questo processo indirettamente: tramite metadati di qualità e pattern di UX, non tramite if/else nel codice.
Catalogo e launcher
Oltre al modo dialogico, esistono anche lo Store dentro ChatGPT e il launcher, accessibile dal composer. Attraverso questi, gli utenti possono scegliere esplicitamente l’App, come una normale applicazione in un negozio.
Per noi questo è importante concettualmente: quando progettiamo il flusso di GiftGenius, dobbiamo ricordare che:
- qualcuno entrerà dal catalogo e si troverà subito “dentro” l’App;
- qualcun altro non aprirà mai il catalogo e vedrà l’App solo come proposta nel dialogo.
Tutto questo riguarda la discovery dell’App stessa: i momenti in cui il modello decide se “attivare” la tua applicazione e proporla all’utente nella conversazione corrente.
4. Anatomia del ciclo di interazione: dalla frase al widget
È ora di mettere insieme tutti i livelli della lezione precedente — dalla UI di ChatGPT e il widget fino all’Apps SDK e al server MCP — in un unico ciclo logico chiaro.
Schema ad alto livello
Dal punto di vista del processo, il ciclo appare così:
sequenceDiagram
participant U as Utente
participant G as ChatGPT (modello)
participant A as App / server MCP
U->>G: Richiesta testuale
G->>G: Analisi della richiesta + scelta degli strumenti
G->>A: Chiamata dello strumento (call_tool)
A-->>G: Risposta (dati / structuredContent)
G->>U: Risposta testuale + (opzionale) widget dell'App
In parole semplici:
- L’utente scrive un messaggio in ChatGPT.
- Il modello analizza la richiesta e il contesto corrente, decide:
- se rispondere da solo,
- oppure invocare uno o più strumenti.
- Se viene selezionato uno strumento della tua App, ChatGPT forma una richiesta strutturata (call_tool) e la invia al server MCP.
- Il tuo backend (o server MCP) esegue l’azione: interroga il database, API esterne, ACP ecc., e costruisce il risultato.
- Il risultato viene restituito come dati strutturati (e, possibilmente, JSON per il widget).
- Il modello usa questi dati per:
- generare un testo comprensibile all’utente,
- se necessario — renderizzare il widget dell’App direttamente nella risposta.
Tutta la pianificazione multi‑step — “quando chiamare cosa”, “fare una domanda di chiarimento”, “fare un’altra chiamata” — si trova lato modello di IA. L’Apps SDK e l’MCP forniscono solo un contratto unificato per gli strumenti.
Dove qui scriviamo il codice
In questo ciclo ci sono tre punti in cui scrivi davvero TypeScript/codice:
- Configurazione dell’App e degli strumenti — descrizioni dei tools (nome, descrizione, schema) e metadati dell’App (nome, icona, categorie). Nel tuo progetto è probabilmente un file come openai/app-config.ts.
- Server MCP / backend — gestione di call_tool: accesso al DB, filtraggio prodotti, chiamata di altre API, ecc.
- Widget (UI) — componente React in un’app Next.js, renderizzato nella chat e che legge i risultati degli strumenti tramite window.openai o gli hook dell’Apps SDK.
Il resto è compito del modello e della piattaforma.
5. GiftGenius in azione: due scenari del flusso utente
Passiamo a scenari più concreti, così da “vedere” questo flusso.
Scenario 1: l’utente apre GiftGenius in modo esplicito
Scenario:
- L’utente in ChatGPT apre il catalogo delle App e trova GiftGenius.
- Preme «Apri».
- ChatGPT avvia il dialogo già nel contesto di GiftGenius.
Il dialogo è più o meno questo:
Utente:
Apre GiftGenius dal catalogo.
E scrive: «Ciao! Vorrei scegliere un regalo per un amico»
GPT:
«Ottimo, ti aiuterò a scegliere un regalo. Raccontami per chi, con quale budget e per quale occasione stai cercando?»
A questo punto GPT può chiamare subito il primo strumento, ad esempio start_gift_session, per inizializzare una sessione nel tuo backend (creare un carrello temporaneo, generare un sessionId, ecc.).
Il tuo codice lato server MCP potrebbe apparire così (per ora molto a grandi linee):
// Esempio pseudo future-TS: descrizione dello strumento GiftGenius
const suggestGiftsTool = {
name: "suggest_gifts",
description: "Use this when the user wants gift ideas by recipient, occasion and budget",
inputSchema: {
type: "object",
properties: {
recipient: { type: "string" },
occasion: { type: "string" },
budgetUsd: { type: "number" },
},
required: ["recipient", "occasion", "budgetUsd"],
},
};
Vedremo in dettaglio come registrarlo in MCP/Apps SDK in un modulo separato; per ora ci interessa l’idea: da questa descrizione il modello capisce che lo strumento è adatto alle richieste “scelta dei regali”.
Dopo la risposta dell’utente, GPT chiama suggest_gifts, riceve da te un array di opzioni e poi:
- redige un riassunto testuale;
- incorpora il widget di GiftGenius, dove si possono scorrere e filtrare le schede dei regali.
Scenario 2: l’utente chiede «scegli un regalo» in una chat normale
Ora un’altra variante: l’utente non sa affatto di GiftGenius.
Scrive in una chat normale:
«Serve un regalo per mio fratello, adora i giochi da tavolo, massimo 50$»
Dentro ChatGPT succede più o meno questo:
- Il modello analizza la richiesta e l’elenco degli strumenti disponibili.
- Vede lo strumento suggest_gifts con una descrizione adatta.
- Capisce che l’App GiftGenius è pensata proprio per questi compiti.
- Controlla se l’utente abbia già installato l’applicazione, se è stato autenticato e quali permessi ha concesso.
I comportamenti successivi possono variare:
- se la richiesta è sufficientemente concreta, GPT può chiamare silenziosamente suggest_gifts e restituire una risposta con il widget;
- se manca qualcosa (per esempio non è indicata l’occasione o l’età), GPT può prima chiedere un chiarimento testuale e poi proporre l’App.
Questa flessibilità è ciò che distingue le Apps dalle UI “rigide” con form: il modello sceglie da solo quando usare gli strumenti e quando parlare.
6. Instradamento semantico: «LLM come dispatcher»
A livello di discovery il modello decide se collegare o meno la tua App alla richiesta corrente. Ma poi, quando l’App è già “attivata” e i suoi strumenti sono noti al modello nella sessione corrente, entra in gioco un secondo livello — l’instradamento semantico all’interno di questi strumenti: con quale strumento elaborare la successiva battuta.
Nel classico backend web il route è scelto dall’URL: /checkout — quindi chiamiamo il controller di checkout. Nelle ChatGPT Apps non c’è il routing via URL, ma c’è il routing semantico: il modello confronta il significato della richiesta con le descrizioni dei tuoi strumenti.
In modo semplificato, il processo è questo:
- All’avvio della sessione, ChatGPT riceve l’elenco dei tools: loro nomi, descrizioni, schemi.
- Questi dati vengono inseriti nelle istruzioni di sistema del modello.
- Quando l’utente scrive una richiesta, il modello ne confronta il senso con le descrizioni degli strumenti: dove “scelta dei regali”, dove “ricerca hotel”, dove “costruire un grafico”.
- Se trova una buona corrispondenza — forma la chiamata strutturata allo strumento necessario.
Ne consegue il principale takeaway pratico:
- la descrizione dello strumento è la tua API per il modello; rileggilo ancora. E poi ancora.
- se scrivi “does stuff”, il modello davvero non capirà quando invocarlo.
La documentazione e le best practice sulla discovery sottolineano: i metadati vanno trattati come lavoro di copywriting di prodotto. Sono proprio loro a determinare in quali conversazioni il modello ricorderà la tua App.
7. Pattern di dialogo attorno all’App
Vediamo ora i pattern UX tipici che emergono quando GPT interagisce con l’App all’interno della stessa conversazione. È importante per non costruire un’App “nel vuoto”, senza capire il ruolo della parte GPT.
Tutte le guide pratiche dell’Apps SDK evidenziano alcuni pattern caratteristici:
«Procedura guidata» (The Wizard)
GPT guida l’utente passo dopo passo, spesso appoggiandosi all’App.
Sull’esempio di GiftGenius:
- GPT: «Raccontami, per chi è il regalo?»
- Utente: «Mio fratello, 25 anni, ama i giochi da tavolo».
- GPT: «Qual è il budget?»
- Utente: «Fino a 50$».
- GPT chiama suggest_gifts, mostra i risultati nel widget e scrive: «Ho selezionato alcune opzioni, dai un’occhiata all’elenco qui sotto».
In questo pattern l’App e il suo widget sono come uno strato visivo sopra un dialogo multi‑passo. L’utente per lo più scrive testo, e il widget aiuta a visualizzare la scelta.
«Widget adattivo» (The Adaptive Widget)
Il testo rimane il canale principale e l’App si collega puntualmente per compiti specifici: disegnare un grafico, mostrare una tabella, renderizzare schede di prodotti.
Esempio:
- Utente: «Confronta tre opzioni di regalo: gioco da tavolo, libro, esperienza».
- GPT inizialmente spiega in testo pro e contro.
- Poi chiama uno strumento che restituisce un elenco strutturato di prodotti e renderizza una piccola tabella o schede.
Qui l’App è un complemento visivo, non la “modalità predefinita”.
«Agente invisibile» (Invisible Agent)
L’App può anche non mostrare alcuna UI. Lavora “sotto il cofano” come fonte dati:
- implementi un MCP‑tool che cerca regali nel tuo DB;
- GPT lo chiama, ottiene un elenco e poi riassume i risultati in testo, senza alcun widget.
È simile a un classico “plugin senza UI”: l’utente vede solo che GPT conosce prezzi e assortimento aggiornati.
Un pattern utile per le App tool‑first, dove la UI non è critica.
8. Come il flusso influisce sul design dell’App
Capire il flusso è importante non solo a livello filosofico, ma anche per decisioni molto pratiche: quali strumenti creare, come descriverli, quando mostrare il widget e quando è meglio rispondere in testo.
Principio «chat‑first»
Idea chiave dell’ecosistema: la chat è il canale principale di interazione, i componenti UI sono ausiliari.
Questo significa:
- non tentare di infilare “un intero sito” in un solo widget;
- i widget devono aiutare dove la chat è scomoda: scelta da elenco, filtri, confronto, form complesse.
Per GiftGenius questo vuol dire:
- selezionare un elenco di regali e permettere all’utente di “cliccare” sulle schede;
- visualizzare i filtri (prezzo, categoria, disponibilità);
- aiutare a completare l’ordine (checkout) in alcuni passaggi chiari.
Invece, scrivere nel widget lunghe spiegazioni su “come scegliere un regalo per una ragazza introversa” — non è una buona idea: è compito della chat.
Quando avviare l’App e quando no
Un’altra conseguenza: non trasformare l’App in un “occupante del dialogo”.
Pattern sbagliato:
- l’utente sta conducendo una discussione seria;
- l’App si avvia e apre un enorme widget fullscreen senza preavviso;
- l’utente si perde: «dov’è finita la mia chat?».
Meglio:
- iniziare discutendo tutto in testo, facendo un paio di domande di chiarimento;
- poi proporre gentilmente di aprire l’App, se migliora davvero l’UX (confronto, configurazione, checkout).
Impatto sull’insieme degli strumenti
Poiché il modello sceglie lo strumento in base alla descrizione, ogni strumento deve:
- risolvere un compito chiaro e unico;
- essere ben descritto nello stile “Use this when…”;
- avere parametri che scaturiscono naturalmente dalle domande che GPT porrà all’utente.
Per GiftGenius, invece di un gigantesco do_everything, è più logico avere:
- suggest_gifts — selezione di un elenco di opzioni;
- get_gift_details — dettagli su un ID specifico;
- create_order — creazione dell’ordine.
Progetteremo gli strumenti nel dettaglio nel modulo 4, ma l’idea generale è importante già ora: il flusso del dialogo determina quali strumenti servono davvero.
9. Mini‑esempio: come le descrizioni dei tools influiscono sul flusso (abbozzo TypeScript)
Un piccolo frammento dell’immaginario openai/app-config.ts, per collegare teoria e codice. Non prendetelo come sintassi esatta dell’SDK (lo vedremo nel modulo successivo) — ora ci interessa l’idea di nomi e descrizioni.
// Frammento ipotetico di configurazione di GiftGenius (codice futuro)
const tools = [
{
name: "suggest_gifts",
description: "Use this when the user wants gift ideas based on recipient, occasion, and budget.",
inputSchema: {/* ... */},
},
{
name: "get_gift_details",
description: "Use this when the user asks for more information about a specific gift from a previous list.",
inputSchema: {/* ... */},
},
];
Se sostituisci suggest_gifts con run_func e la descrizione con «Main function», GPT:
- capirà peggio per quali richieste conviene chiamare questo strumento;
- potrebbe proporre più raramente la tua App nell’in‑conversation discovery;
- sarà più difficile collegare i follow‑up dell’utente all’elenco dei regali già mostrato.
Al contrario, buoni nomi e descrizioni aumentano la probabilità che la tua App emerga proprio al momento giusto.
10. Errori tipici nella progettazione del flusso utente
Errore n. 1: Aspettarsi il pieno controllo — «decido io quando avviare l’App».
A volte gli sviluppatori ragionano nella logica “intercetterò tutte le richieste sui regali e collegherò la mia App”. Nel mondo delle ChatGPT Apps non è così: le decisioni le prende il modello. Tiene conto delle descrizioni degli strumenti, del contesto del dialogo, dello stato dei permessi e di quanto l’utente sia soddisfatto della chiamata proprio della tua App.
Errore n. 2: Nomi e descrizioni degli strumenti privi di senso.
Strumenti con nomi run, main, tool1 e descrizioni come «Calls the main function» creano la tempesta perfetta: il modello non capisce quando invocarli, l’in‑conversation discovery praticamente non funziona e la tua App diventa “invisibile”. Una buona descrizione nello stile “Use this when the user wants…” e un nome chiaro — sono molto più importanti di quanto sembri.
Errore n. 3: Tentare di infilare “tutto il mondo” in una sola App.
Se la tua App “sceglie regali, prenota hotel, calcola le tasse e mostra gattini” allo stesso tempo, il modello non riuscirà a instradare le richieste in modo affidabile. Le raccomandazioni ufficiali e le guide pratiche sottolineano il principio “one clear job per tool/App”: meglio più applicazioni specializzate che un mega‑monolite.
Errore n. 4: Avvio automatico aggressivo di una UI pesante.
Lo sviluppatore è felice del suo bel widget fullscreen e vuole mostrarlo “a ogni occasione”. Ne risulta che all’utente sembra che la chat si “rompa” e si trasformi in una strana applicazione web. Molto meglio quando GPT prima conversa in testo, fa domande di chiarimento e solo dopo propone di aprire l’App, spiegando perché serve.
Errore n. 5: Ignorare il ruolo di GPT come layer di UX.
Si può progettare l’App come una SPA classica: fare tutto nel widget e ChatGPT deve “stare zitto e non interferire”. Ma non funzionerà. ChatGPT può non mostrare il tuo widget o mostrare un nuovo widget a ogni chiamata dello strumento. Vuoi un prodotto di successo — adattati alla piattaforma, non aspettarti che sia la piattaforma ad adattarsi a te.
GO TO FULL VERSION