1. Come il modello “vede” i vostri strumenti
Cominciamo dal fatto che per il modello un tool non è affatto «la vostra bella funzione in TypeScript», ma una descrizione strutturale nello stile:
- name: nome tecnico, ad esempio "search_gifts";
- description: testo in linguaggio naturale che spiega quando e perché usare quello strumento;
- inputSchema: JSON Schema con campi, ciascuno dei quali può avere a sua volta description, tipo, vincoli.
Molto semplificando, il modello fa pressappoco così (pseudocodice nella “testa” di GPT):
1. Prochitat' pol'zovatelskiy zapros (na lyubom yazyke).
2. Prochitat' spisok tools: name + description + opisaniya argumentov.
3. Dlya kazhdogo tool prikinut', podkhodit li on k zadache.
4. Esli nuzhen tool — sgenerirovat' JSON s argumentami po skheme.
5. Inache — otvetit' tekstom.
Qui ci sono due conclusioni importanti.
In primo luogo, il campo description di uno strumento non è un commento per sviluppatori, ma l’interfaccia tra il modello e il vostro backend. Se la descrizione dello strumento è vaga, incompleta o in una lingua diversa da quella dell’utente, il modello sbaglierà più spesso: strumento sbagliato, argomenti sbagliati, risposta senza strumenti dove invece servivano.
In secondo luogo, il description dei campi nella JSON Schema è altrettanto importante quanto la descrizione dello strumento. Il modello legge davvero il description di ogni proprietà e in base a quello decide dove mettere “età”, dove “budget” e dove dovrebbe esserci l’id.
Mini‑esempio per GiftGenius
Prendiamo il nostro strumento search_gifts. Nella versione originale “solo EN” poteva apparire così:
// server/tools/searchGifts.ts
export const searchGiftsTool = {
name: "search_gifts",
description: "Search for gift ideas based on user preferences.",
inputSchema: {
type: "object",
properties: {
recipient_age: {
type: "integer",
description: "Age of the recipient in years.",
},
budget: {
type: "number",
description: "Maximum budget in user's currency.",
},
},
required: ["budget"],
},
};
Se l’utente scrive: «Mi serve un regalo per mamma, ha 60 anni, budget fino a 3000 rubli», il modello dovrebbe:
- Capire che search_gifts è lo strumento adatto.
- Capire che “60 anni” va in recipient_age, e “3000 rubli” in budget.
Finché le descrizioni sono solo in inglese, GPT se la cava comunque, ma questo le richiede un “travaso” mentale extra. Su più lingue e modelli più deboli ne risente l’accuratezza.
2. Il problema delle “descrizioni in inglese” in un’app multilingue
Nel modulo 9 abbiamo già accennato alla “mappa della localizzazione”: widget UI, cataloghi, errori, testi di commerce. Ora restringiamo il focus e vediamo cosa succede quando le descrizioni degli strumenti sono solo in inglese e l’utente, per esempio, parla russo o spagnolo — ed è lì che inizia un leggero caos.
Scenario tipico:
- Utente: «Trova un regalo per un amico informatico, budget fino a 50 €».
- Il modello guarda l’elenco dei tools e vede descrizioni solo in EN.
- Se anche la richiesta è in EN — tutto bene.
- Se la richiesta è in un’altra lingua, deve:
- capire prima la richiesta,
- associare mentalmente il testo alle descrizioni in inglese,
- scegliere lo strumento,
- poi estrarre gli argomenti in JSON.
Nei modelli più forti questo si regge ancora, ma:
- aumenta la quota di risposte senza chiamata ai tools — il modello “pensa” di potercela fare da solo;
- cresce la probabilità di errori negli argomenti (soprattutto quando contano valuta, unità di misura, vincoli regionali);
- la logica di instradamento tra più tools diventa meno affidabile (strumento “sbagliato”).
Esempio semplice di errore: nel campo budget ci si aspetta “nella valuta dell’utente”, ma la descrizione non lo dice affatto. Il modello decide che è USD di default e invia al backend 50 dollari dove l’utente voleva chiaramente 50 €.
Ed è qui che entra in gioco la localizzazione delle descrizioni.
3. Approcci alla localizzazione: tools separati vs descrizioni multilingue
Esistono due approcci architetturali di base, entrambi legittimi.
Strumenti separati per ogni lingua
In questa variante si creano più tools con nomi diversi, ciascuno con la “propria” lingua di descrizioni.
Per GiftGenius può essere così:
export const searchGiftsEn = {
name: "search_gifts_en",
description: "Search for gift ideas based on user preferences.",
// ...
};
export const searchGiftsRu = {
name: "search_gifts_ru",
description: "Selezione di regali in base alle preferenze dell'utente.",
// ...
};
Per ChatGPT App è importante che l’elenco dei tools disponibili dipenda da locale. Se locale = "ru-RU", il vostro server MCP deve restituire solo search_gifts_ru. Se locale = "en-US", — solo search_gifts_en.
Vantaggi di questo approccio: le descriptions risultano massimamente “pulite” e monolingui. Potete pensare all’app come a più versioni monolingue, ognuna con propri prompt e descrizioni. È comodo quando le lingue sono poche e i mercati molto diversi.
Svantaggi — duplicazione di logica e analitiche più complesse. Nel backend probabilmente avrete lo stesso handler, ma a livello di MCP/manifest ci sono due strumenti diversi. Bisogna ricordarsi di aggiornare entrambe le descrizioni a ogni modifica.
Insight (dati al 2025-12-01)
Sperimentalmente non sono emersi vantaggi significativi per il description nella lingua dell’utente/locale. Gli strumenti venivano scelti con frequenza praticamente uguale, indipendentemente dalla lingua della descrizione. Se c’erano 2 strumenti con descrizioni simili (in lingue diverse), confondevano ChatGPT.
Inoltre, la vostra app dovrà passare la review durante la registrazione nello Store. Quindi consiglio di scrivere semplicemente tutte le tool description e le argument description in inglese.
Tuttavia, se in futuro su ChatGPT ci saranno migliaia di applicazioni e la concorrenza per la “scelta dello strumento” aumenterà, è possibile che le description nella lingua dell’utente ottengano un vantaggio. Attendiamo la nascita della Tool Search Optimization.
Un solo strumento con descrizioni multilingue
Nella seconda variante si mantiene un unico name (per esempio, search_gifts), ma il suo description e le descrizioni dei campi della JSON Schema diventano multilingue.
Esistono vari stili:
- Forma breve bilingue:
description: "Search gifts for a recipient. / Ricerca di regali in base alle preferenze del destinatario.", - Blocchi marcati per lingua:
description: "[EN] Search for gifts based on user preferences. [RU] Selezione di regali in base alle preferenze del destinatario.", - Campi separati uniti in una stringa (meno comodo):
description: `EN: ${enDescription} RU: ${ruDescription}` ,
Vantaggi — un solo tool, single source of truth, più semplice distribuire un’architettura con MCP Gateway: esponete sempre la stessa interfaccia a ChatGPT, indipendentemente dalla lingua dell’utente.
Svantaggi: le descrizioni si allungano. Se “mescolate” le lingue senza cura, il modello può confondersi un po’ — soprattutto quando l’inglese e il testo locale sono mescolati senza marcatori espliciti [EN], [RU].
Per un progetto didattico come GiftGenius consigliamo una variante ibrida: lasciare le descrizioni principalmente in inglese, ma aggiungere con cura una breve spiegazione nella lingua locale, mentre tutta la vera “semantica” (che lingua usare, come rivolgersi all’utente) passa negli argomenti (locale) e nel system‑prompt.
4. Localizzazione della JSON Schema: descrizioni dei campi
Andiamo più a fondo: agli argomenti dello strumento.
Nella JSON Schema per ogni campo si può (e si deve) impostare description. Il modello legge questa stringa quando genera il JSON per chiamare lo strumento.
Per GiftGenius si può fare così:
export const searchGiftsTool = {
name: "search_gifts",
description:
"Search gifts based on user preferences (RU: selezione di regali in base alle preferenze del destinatario).",
inputSchema: {
type: "object",
properties: {
recipient_age: {
type: "integer",
description:
"Recipient age in years. RU: età del destinatario (numero intero).",
},
budget: {
type: "number",
description:
"Maximum budget in user's currency. RU: budget massimo nella valuta dell'utente.",
},
locale: {
type: "string",
description:
"User locale (e.g. 'en-US', 'ru-RU'). RU: lingua dell'interfaccia e delle risposte.",
},
},
required: ["budget", "locale"],
},
};
Alcune osservazioni pratiche.
Primo: i nomi dei campi (recipient_age, budget, locale) di solito si lasciano in inglese. Si traduce il description. È importante per mantenere il JSON identico tra le lingue e non dover supportare due contratti diversi.
Secondo: nel description conviene indicare esplicitamente valuta, unità di misura e vincoli importanti. Riduce molto il numero di argomenti “storti”.
Terzo: se già usate un MCP Gateway, potete accordarvi perché inoltri automaticamente il locale tra gli argomenti dello strumento, così il modello non deve inserirlo da sé. Ma anche in questo caso è utile ricordare la descrizione di locale: il modello capisce meglio cos’è e perché serve.
5. Come scegliere la lingua delle descrizioni: strategie per un’app reale
La domanda pratica principale: quale lingua usare come base per le descrizioni e quando conviene localizzarle completamente?
Raccomandazioni ed esperienza reale mostrano che i modelli GPT lavorano ancora meglio in un contesto inglese, e molti sviluppatori lasciano le descrizioni solo in EN. Ma per un’app multilingue può essere un compromesso.
Vediamo alcune strategie.
Solo descrizioni EN
La variante più semplice — tutto in inglese.
Vantaggi: una sola base di codice, una sola lingua da mantenere, più facile scrivere formulazioni precise. Il modello è felice quando tutto è in inglese.
Svantaggi: per utenti che scrivono in altre lingue, la qualità della scelta degli strumenti e degli argomenti può essere inferiore. Soprattutto per modelli “pigri” o strumenti complessi con molti parametri.
EN + breve coda locale
Approccio di compromesso: descrizione principale in EN e in fondo un breve blocco nella lingua locale che aiuta il modello a mappare le parole dell’utente agli argomenti.
Esempio:
description:
"Search for gifts based on user preferences. RU: lo strumento seleziona regali in base alla descrizione del destinatario, alla sua età e al budget.",
Per la JSON Schema:
description:
"Age of the recipient in years. RU: età del destinatario (in anni).",
Vantaggi: il modello resta nel “mondo inglese”, ma ha un indizio nella lingua dell’utente.
Svantaggi: le descrizioni diventano più lunghe, ma di solito non è critico.
Localizzazione completa delle descrizioni per locale
L’approccio più spinto: le descrizioni degli strumenti e dei campi cambiano in base al locale che ricevete da ChatGPT. Per en-US restituite descrizioni solo in inglese, per ru-RU solo in russo, per de-DE in tedesco.
Non è più “una JSON Schema per sempre”, ma un insieme di schemi che MCP/Gateway seleziona al volo.
A livello MCP può apparire così:
function getSearchGiftsToolDescription(locale: string) {
if (locale.startsWith("ru")) {
return {
name: "search_gifts",
description: "Selezione di regali in base alle preferenze del destinatario.",
// ru‑schema...
};
}
return {
name: "search_gifts",
description: "Search for gifts based on user preferences.",
// en‑schema...
};
}
Vantaggi: il modello vede un’interfaccia nella stessa lingua dell’utente. Massimo comfort.
Svantaggi: manutenzione e test più complessi. Serve un processo che garantisca che tutte le varianti localizzate restino allineate nel significato e che non vi dimentichiate, per esempio, di aggiornare lo schema tedesco quando aggiungete un nuovo campo nell’inglese.
6. Implementazione nella nostra app GiftGenius
Passiamo alla concretezza. In GiftGenius adottiamo una variante ibrida: un solo strumento search_gifts, descrizioni prevalentemente in EN ma con note esplicative in russo, più l’argomento locale.
Supponiamo di avere un server MCP in TypeScript che descrive i tools nello stile dell’SDK MCP.
// mcp/tools/searchGifts.ts
import { z } from "zod";
export const searchGiftsInputSchema = z.object({
recipient_age: z
.number()
.int()
.describe(
"Age of the recipient in years. RU: età del destinatario (numero intero)."
),
budget: z
.number()
.describe(
"Maximum budget in user's currency. RU: budget massimo nella valuta dell'utente."
),
locale: z
.string()
.describe(
"User locale (e.g. 'en-US', 'ru-RU'). RU: lingua dell'interfaccia e delle risposte."
),
});
export const searchGiftsTool = {
name: "search_gifts",
description:
"Search for gifts based on user preferences (RU: selezione di regali in base alle preferenze del destinatario).",
inputSchema: searchGiftsInputSchema,
// execute(...) ...
};
È importante che:
- locale sia obbligatorio. Se il widget lo conosce (e lo sappiamo da _meta["openai/locale"]), o lo inserisce direttamente nella chiamata callTool, oppure MCP Gateway lo aggiunge automaticamente dalla sua parte;
- le descrizioni contengono già parole chiave in russo “età”, “budget”, “lingua dell’interfaccia”, quindi al modello è più semplice capire cosa estrarre dalla richiesta dell’utente e dove metterlo.
Dal lato dell’Apps SDK potete, per esempio, avere una funzione che invoca direttamente questo tool (se è abilitato widgetAccessible), passando il locale dal widget.
// widget/hooks/useSearchGifts.ts
export async function searchGiftsFromWidget(params: {
recipientAge: number;
budget: number;
locale: string;
}) {
const openai = (window as any).openai;
const result = await openai.callTool("search_gifts", {
recipient_age: params.recipientAge,
budget: params.budget,
locale: params.locale,
});
return result;
}
Questo collegamento rafforza l’architettura: il locale arriva da ChatGPT → finisce nel tool → il tool sceglie i cataloghi e i formati dei prezzi corretti, che poi mostrerete in modo gradevole nel frontend.
7. Esperimenti di comportamento: come misurare l’impatto della localizzazione
La parte più interessante: come capire se la localizzazione di tools e descrizioni migliora davvero il comportamento del modello, e che non avete sprecato tempo in traduzioni?
Potete fare un piccolo “esperimento scientifico” direttamente in Dev Mode su GiftGenius.
Due varianti di App: base vs localized
Preparate due configurazioni della vostra App:
- base — descrizioni di strumenti e JSON Schema solo in EN;
- localized — descrizioni con EN+RU (o versioni ru complete, se siete pronti).
Il resto (cataloghi, UI, prompt) lasciatelo uguale, per non confondere gli effetti.
Per semplificare potete:
- in Dev Mode (e ancor più nello Store) mantenere solo la versione localized;
- e lanciare la base in locale su un branch separato confrontando i risultati su un set di richieste predefinito.
Cosa misurare
Tre metriche chiave.
La prima — frequenza di scelte corrette dello strumento. Per un set di richieste di test in russo (e/o altra lingua) osservate quante volte il modello:
- ha deciso di chiamare uno strumento quando serviva;
- ha scelto proprio search_gifts e non un altro tool.
La seconda — correttezza degli argomenti. Verificate quanto spesso il JSON della chiamata corrisponde alle aspettative: campi non scambiati, budget nella valuta corretta, età come intero, locale presente.
La terza — numero di chiamate strane o senza senso. Per esempio, il modello chiama search_gifts per la domanda “che ore sono?” o inserisce in recipient_age il valore 3000 al posto del budget.
Potete testare sia manualmente sia tramite i log MCP/Agents — i log vi torneranno comunque utili in futuro, quindi meglio abituarsi a questa analitica fin d’ora.
Come organizzare un piccolo set di test manuali
Potete creare un piccolo “golden prompt set” per la localizzazione:
1. "Mne nuzhen nedorogoy podarok do 30 evro dlya devochki 10 let, ona lyubit risovat'."
2. "Podberi podarok dlya kollegi‑programmista, 35 let, byudzhet 100$."
3. "Nuzhen podarok babushke na yubiley, 70 let, byudzhet do 5000 rubley."
E farli passare in entrambe le versioni dell’App (base e localized), osservando:
- quali tools sceglie il modello;
- quali argomenti inserisce;
- come cambia il testo della risposta se lo strumento non è stato chiamato.
Trucchetto semi‑professionale: potete creare una semplice cornice script che faccia girare queste richieste attraverso le API di ChatGPT, ma per il corso è sufficiente il manuale in Dev Mode. Una categoria a parte, molto utile da includere in questo set, sono i messaggi misti per lingua e le combinazioni “strane” di locale. Dedichiamo loro un blocco separato.
Se sviluppate un’app commerciale seria e si parla di milioni di dollari, testate assolutamente questi aspetti proprio per la vostra applicazione. Il Modulo 20 è dedicato al lavoro professionale con il “golden prompt set” — assicuratevi di padroneggiare l’argomento.
8. Lingue miste e combinazioni insolite di locale
Nulla diverte tanto un developer LLM quanto un utente che scrive in due lingue contemporaneamente. Per esempio:
"Nuzhen podarok for my friend, on lyubit Star Wars, budget 100€"
Sappiamo già che il modello è multilingue e di solito se la cava. Ma con lingue miste e descrizioni “inglesi” la probabilità di errore cresce.
Ci sono alcune situazioni tipiche.
Prima — l’utente scrive in RU e le descrizioni degli strumenti sono in EN. Il modello può capire, ma a volte si confonde, specie con la terminologia specifica (nomi di categorie, etichette di campo rare).
Seconda — locale = "ru-RU", ma l’utente scrive in inglese. ChatGPT vi segnala che è meglio costruire l’interfaccia in russo, ma la lingua effettiva del testo è EN. Potete:
- comunque restituire descrizioni in russo, considerando locale la verità primaria;
- oppure implementare il rilevamento della lingua del messaggio come segnale aggiuntivo e adattare le descrizioni alla lingua effettiva.
Terza — locale = "en", ma l’utente inserisce a volte parole russe. In questo caso, in genere, le descrizioni in inglese funzionano benissimo.
In pratica basta scegliere una politica chiara. Per esempio:
- se locale inizia con "ru" — aggiungete segmenti in russo nelle descrizioni;
- altrimenti — descrizioni solo in inglese.
Una regola netta è utile perché potrete testare intenzionalmente ogni ramo, senza chiedervi perché oggi le descrizioni siano finite in una lingua o nell’altra.
9. Documentazione, processo e lingua “canonica”
La localizzazione delle descrizioni non è un atto una tantum, ma un processo. Agli utenti piace vedere nuove feature; a voi piace che nulla di vecchio si rompa. Quindi è bene chiarirsi in anticipo:
- quale lingua considerare “canonica”, rispetto alla quale fare tutte le traduzioni;
- dove conservare le descrizioni localizzate;
- come verificarne la consistenza.
Di solito la lingua canonica è l’inglese. Tutti i nuovi strumenti e campi vengono descritti prima in EN, passano la review e solo dopo vengono localizzati nelle altre lingue. In base di codice si può esprimere così:
- file tools.en.json con descrizione completa di name/description/campi;
- file tools.ru.json, tools.de.json come “derivati” per lingue specifiche;
- un piccolo generatore che compone le JSON Schema finali per MCP a partire da questi dizionari.
Nella variante semplice potete per ora cavarvela con stringhe nel codice, ma strutturatele in modo da poterle estrarre facilmente in dizionari separati in futuro.
Ricordate che le descrizioni sono testo di prodotto. Meritano una review rigorosa come i testi UI: verificare chiarezza, assenza di ambiguità e “acqua” inutile. Soprattutto nella variante multilingue non vogliamo che la coda russa contraddica la parte inglese.
10. Schema visivo: come la lingua attraversa lo stack
Per mettere ordine in testa, guardiamo uno schema semplificato del flusso della richiesta considerando la localizzazione dei tools.
flowchart TD
U[Utente scrive in RU] --> C[ChatGPT UI]
C -->|"_meta.openai/locale = 'ru-RU'"| W[Widget GiftGenius]
W -->|"locale = 'ru-RU'"| T["Tool descriptions (EN+RU)"]
T --> M[Modello GPT]
M -->|callTool search_gifts| MCP[MCP / Gateway]
MCP -->|"locale = 'ru-RU'"| B[Backend / cataloghi RU]
B --> MCP --> M2["Modello GPT (risposta)"]
M2 --> C2[ChatGPT UI + widget RU]
Qui la lingua dell’utente e il locale determinano:
- in che lingua il widget mostra la UI;
- quali descrizioni di strumenti e campi vede il modello;
- quali cataloghi e valute sceglie il backend;
- come vengono formattate le risposte (dal modello e dal widget).
11. Errori tipici nella localizzazione di tools e descrizioni
Errore n. 1: considerare il campo description “tecnico” e non localizzarlo affatto.
Funziona finché avete solo utenti anglofoni. Appena arrivano altre lingue, il modello risponde più spesso senza tools o passa argomenti errati agli schemi. Avete tradotto la UI, ma l’app si comporta “all’inglese”.
Errore n. 2: cambiare i nomi dei campi nella JSON in base alla lingua.
A volte viene la tentazione di fare age → vozrast, budjet ecc. Questo porta a un incubo nel backend: schemi diversi, formati diversi, analisi dei log complicata. Meglio lasciare stabili i name dei campi e localizzare solo le descrizioni.
Errore n. 3: mescolare le lingue in modo caotico nelle descrizioni.
Frasi tipo “Ricerca gifts in base alle preferenze user” non aiutano né il modello né l’umano. Se fate descrizioni multilingue, separate i blocchi in modo esplicito: [EN] ... [RU] .... Così il modello vede una struttura, non un minestrone.
Errore n. 4: non passare il locale agli strumenti.
Anche se avete localizzato le descrizioni, ma non passate il locale al tool (o MCP Gateway non lo inoltra), il backend non sa quali cataloghi e formati usare. Risultato: il modello cerca di essere “multilingue”, ma il server restituisce dati di un solo mercato.
Errore n. 5: tradurre automaticamente le descrizioni con un motore di traduzione senza review.
Sembra che basti passare le descrizioni in un traduttore automatico e vivere felici. In pratica tali traduzioni sono spesso imprecise, soprattutto su termini e argomenti. Il modello può interpretare in modo errato lo strumento o il campo. Meglio una buona variante EN ben studiata e versioni localizzate con cura che venti lingue “automatiche”.
Errore n. 6: assenza di test/esperimenti per i vari locale.
Se non verificate il comportamento dell’app almeno su un set base di richieste per ciascun locale, qualcosa può “rompersi” per mesi, finché non arriva il primo utente reale con quella lingua. Un piccolo set “golden” e test manuali in Dev Mode riducono molto questo rischio.
Errore n. 7: disallineamento tra descrizioni canoniche e localizzate.
Avete aggiunto un nuovo campo occasion (“occasione” del regalo) nello schema inglese, ma vi siete dimenticati di aggiornare quello russo. Risultato: sul locale RU il modello non conosce affatto questo campo e non lo compila, mentre il backend lo aspetta già. Per esempio, il server tenta di filtrare i regali per occasione, riceve null e mostra un elenco troppo generico — in EN funziona, in RU il comportamento “si rompe” in modo poco evidente. Quindi ogni modifica alle descrizioni degli strumenti deve passare per un processo semplice ma regolare: aggiornare EN → aggiornare le localizzazioni → eseguire brevi test.
GO TO FULL VERSION