1. Por que pensar em localização especificamente no ChatGPT App
Se você já desenvolveu aplicativos web comuns, provavelmente associa localização ao i18n clássico: strings de interface, alguns formatos de data e número, dicionários — e você traduz tudo direitinho. No ChatGPT App é mais divertido: aqui há um terceiro participante — o próprio modelo LLM. Ele lê as descrições das suas ferramentas, os prompts, os resultados, tira conclusões e toma decisões.
Ou seja, idioma não é só “como mostrar um texto bonito para o usuário”, mas também “como o modelo entende o que faz a sua ferramenta, quando chamá-la e quais argumentos passar”. O botão “Comprar” pode ser traduzido mais ou menos — o usuário se vira. Mas se você descreveu de forma vaga um tool que faz pagamento, numa mistura de russo e inglês, o modelo pode nunca chamá-lo ou chamá-lo de um jeito totalmente diferente do esperado.
Mais um ponto: o ChatGPT já envia para o seu servidor MCP dicas sobre a localidade e a localização do usuário — _meta["openai/locale"] e _meta["openai/userLocation"]. Isso acontece no nível das requisições MCP às ferramentas, para que você possa adaptar texto e dados ao idioma e à região do usuário. Ou seja, a plataforma já “entrega” o contexto, e a tarefa do desenvolvedor é usá-lo com intenção.
Por isso, neste módulo olhamos para a localização como um aspecto arquitetural do ChatGPT App, e não como “traduzimos a UI e esquecemos”.
2. Camadas que precisam ser localizadas
Vamos ver o App como um bolo em camadas. Cada camada pode (e muitas vezes deve) ser localizada. Para não se perder, começamos com um mapa.
Visão geral das camadas
Primeiro — uma tabela geral, depois destrinchamos por partes.
| Camada | O que é | Exemplos | Impacto |
|---|---|---|---|
| Widget UI | Todo o frontend visível no widget | Títulos, botões, erros, dicas | UX do usuário |
| Textos do modelo e prompts | System‑prompt e frases pré-definidas | Instruções, modelos de respostas | Comportamento do ChatGPT |
| Dados e conteúdo | Textos que o App exibe e processa | Catálogos de produtos, descrições, datas, preços | Tanto UX quanto precisão das respostas |
| Descrições de tools/esquemas | Metadados de ferramentas e campos do JSON Schema | description, dicas de tipos | Como o modelo chama seus tools |
| Commerce e parte jurídica | Tudo que envolve compras e políticas | Nomes de SKU, Terms, Privacy, e-mails | Correção jurídica, confiança |
Basicamente, esta é a primeira camada do nosso mapa de localização: depois adicionaremos profundidade (cosmética/semântica), idiomas e elementos específicos.
Agora vamos pelas camadas uma a uma.
Widget UI
A camada mais óbvia — a interface do widget. No GiftGenius isso inclui:
- títulos de blocos;
- rótulos de campos (“Destinatário”, “Orçamento”, “Interesses”);
- botões (“Encontrar presente”, “Redefinir filtros”);
- placeholders nos inputs (“por exemplo, colega, mãe…”);
- mensagens de erro e de estados vazios (“Nenhum presente encontrado”).
Num app React comum, esses são os primeiros candidatos a irem para dicionários. Aqui é o mesmo, com a ressalva de que a UI não é todo o App, apenas uma das suas faces.
Daqui a pouco, no módulo, vamos criar uma arquitetura de i18n “de verdade” para o widget, mas já agora é importante fixar: não deve haver strings dentro de JSX. Mesmo se você mantiver um único idioma por enquanto, é conveniente estruturar os textos da UI desde o início.
Mini‑exemplo com o nosso GiftGenius (ainda sem biblioteca real de i18n):
type Locale = "en" | "ru";
const uiText = {
en: {
title: "GiftGenius: find a perfect present",
recipientLabel: "Recipient",
},
ru: {
title: "GiftGenius: encontre o presente perfeito",
recipientLabel: "Destinatário",
},
};
function GiftForm({ locale }: { locale: Locale }) {
const t = uiText[locale];
return (
<div>
<h2>{t.title}</h2>
<label>{t.recipientLabel}</label>
{/* demais campos */}
</div>
);
}
Aqui ainda não estamos fazendo localização “de verdade”, mas já destacamos explicitamente a camada de textos da UI.
Textos do GPT e prompts
A próxima camada — textos sistêmicos e auxiliares que não são visíveis diretamente ao usuário, mas influenciam bastante o comportamento do modelo:
- system‑prompt do seu App (“Você é um assistente de presentes…”);
- modelos de explicações que você fornece ao modelo (“Gere um breve resumo da escolha”);
- follow‑ups pré-definidos e dicas para o modelo (“sugira ao usuário esclarecer o orçamento se…”).
Esses textos também podem (e muitas vezes devem) ser localizados. Exemplo simples: se o usuário escreve em português e o seu system‑prompt está totalmente em inglês, o modelo até dá conta, mas você perde controle fino sobre estilo e formulações para esse idioma.
Mais adiante, nas aulas sobre ferramentas de localização de prompts e descrições (prompts/descriptions), veremos como lidar cuidadosamente com system‑prompts multilíngues. Aqui o importante é marcar: prompts são uma camada tão localizável quanto a UI.
Dados e conteúdo
Depois vêm os seus dados. No GiftGenius, é o catálogo de presentes: nomes, descrições, categorias, às vezes dicas de como usar o presente. Em um App comercial, também preços, moedas, unidades de medida, formatos de datas etc. Nas especificações de product feed para o ChatGPT (o formato com que você descreve seus produtos e serviços para a plataforma), esses campos de texto (title, description) e preços são destacados explicitamente para que possam ser exibidos corretamente aos usuários dentro do ChatGPT.
Se você quer um App global, o catálogo de presentes levanta pelo menos estas questões:
- armazenamos nomes/descrições em vários idiomas;
- como escolhemos qual idioma entregar ao usuário;
- o que fazemos se a tradução ainda não existir (fallback);
- como mostramos moedas e formatos de datas/preços para diferentes regiões.
Pequeno exemplo tipado para o catálogo:
type Locale = "en" | "ru";
interface LocalizedString {
en: string;
ru: string;
}
interface Gift {
id: string;
title: LocalizedString;
description: LocalizedString;
priceCents: number;
currency: "USD" | "EUR" | "RUB";
}
function getLocalizedTitle(gift: Gift, locale: Locale) {
return gift.title[locale] ?? gift.title.en;
}
Ou seja, localização não é só frontend, mas também estrutura de dados no banco e nos recursos MCP. Voltaremos a isso quando falarmos do Gateway (o gateway entre o ChatGPT e seus serviços) e do servidor MCP.
Descrições de tools e JSON Schema
A quarta camada — descrições das ferramentas e de seus argumentos. É por meio delas que o modelo entende quando deve chamar seu tool e quais argumentos passar. No MCP isso é o title, description da ferramenta e o description nos campos do JSON Schema.
A documentação do Apps SDK enfatiza que o modelo usa nomes, descrições e a documentação dos parâmetros para escolher ferramentas e montar argumentos.
Exemplo hipotético de ferramenta do GiftGenius em um servidor MCP em TypeScript:
server.registerTool(
"suggest_gifts",
{
title: "Suggest gifts",
description: "Suggest 3–5 gift ideas based on recipient profile.",
inputSchema: {
type: "object",
properties: {
recipient: {
type: "string",
description: "Who is the gift for (e.g. mother, colleague)?",
},
},
required: ["recipient"],
},
},
async ({ input }) => { /* ... */ }
);
Agora está tudo em inglês, e o modelo entende muito bem. Mas e se o usuário escreve em português? Ele ainda conseguirá associar “mãe” a recipient, mas com campos complexos e termos de domínio a chance de erro aumenta. Na aula sobre estratégias de localização de descrições, vamos discutir separadamente: descrições em inglês único versus descrições localizadas.
Neste ponto do mapa de localização, é importante apenas marcar: as descrições dos tools e do JSON Schema também podem ser localizadas, e isso afeta o comportamento do modelo.
Commerce e parte jurídica
Por fim, a camada de que muitos lembram só no final — tudo que está relacionado a dinheiro e textos jurídicos:
- nomes de SKU e planos de assinatura;
- campos title/description nos feeds de commerce (produtos, serviços, assinaturas);
- Terms of Service, Privacy Policy, Refund Policy;
- e-mails e notificações (e-mail, push), se o App envia algo fora do ChatGPT;
- status de pedidos e erros de pagamento que você mostra ao usuário (“Pagamento recusado”, “Indisponível na sua região”).
Aqui há dois aspectos: UX e lei. O usuário deve entender, no seu idioma, ao que está aderindo e pelo que está pagando. E, ao mesmo tempo, as traduções precisam ser juridicamente corretas: às vezes, os jurídicos exigem que apenas os textos em um único idioma (por exemplo, inglês) sejam legalmente vinculantes, e os demais sejam “referência”.
No nosso mapa de localização, marcamos commerce e conteúdo jurídico como uma camada separada, pois muitas vezes ela exige um processo diferente (jurídicos, compliance, aprovação de textos com marketing).
3. Profundidade da localização: “cosmética” versus “semântica”
Quando falamos “localizar o App”, é útil distinguir dois níveis de profundidade: o cosmético e o semântico.
Localização cosmética
Cosmética é tudo o que muda a aparência e a legibilidade, mas quase não altera o comportamento do sistema. Exemplos:
- títulos e rótulos de botões traduzidos;
- placeholders traduzidos nos inputs;
- mensagens de erro “humanizadas” na UI;
- texto localizado de um banner de marketing no widget.
Em apps web clássicos, muitas vezes para-se por aqui. No ChatGPT App, é uma parte importante, mas apenas a ponta do iceberg.
Localização semântica
Semântica são coisas das quais depende o comportamento do modelo e a lógica do App. Aqui o idioma afeta:
- qual ferramenta o modelo vai escolher;
- como ele vai preencher os argumentos da ferramenta;
- quais dados ele considerará “corretos” para aquele usuário.
Exemplos de localização semântica:
- system‑prompt no idioma do usuário, definindo o estilo e as regras de conversa;
- descrições de tools e de seus campos no idioma em que o usuário se comunica;
- textos de dicas/instruções diferentes conforme o contexto cultural;
- configurações de formatos de datas/moedas que influenciam parsing e geração (31.12.2025 vs 12/31/2025).
Se você localizou apenas a cosmética, mas não a semântica, seu App pode parecer localizado, mas se comportar como “anglófono” por baixo dos panos. No mapa de localização, é útil marcar explicitamente quais elementos são críticos para o comportamento do modelo.
Para o nosso GiftGenius, por exemplo:
- a descrição do campo budget no JSON Schema (“Budget in the user’s currency”) — semântica;
- o rótulo do botão “Encontrar presente” — cosmética (importante para UX, mas o modelo não o vê).
Agora que distinguimos cosmética e semântica, faz sentido responder: em quantos idiomas você quer que o App funcione.
4. App monolíngue vs multilíngue
Antes de desenhar o mapa, defina a ambição: você faz um App estritamente monolíngue ou mira um público multilíngue.
App monolíngue
App monolíngue é o caso em que você decide manter apenas um idioma. Por exemplo, apenas inglês.
O widget de UI, os prompts, as descrições das ferramentas e os dados — tudo em um único idioma. Isso simplifica muito a vida:
- uma única base de código sem ramificações por idioma;
- um único esquema de catálogo (sem title_en, title_ru e afins);
- manutenção e testes mais simples.
Mas é claro que o alcance de público fica limitado. No caso do ChatGPT App, isso também significa: se o usuário vier com outra localidade, o ChatGPT ainda pode exibir seu App, mas terá que “traduzir” constantemente o idioma do usuário para o idioma interno do App. Em alguns nichos isso é ok, mas para um serviço de presentes de consumo em massa — dificilmente.
App multilíngue
App multilíngue já é uma decisão arquitetural. Aqui:
- a UI e os textos são exibidos corretamente com base na locale do usuário;
- os dados (catálogos, descrições de produtos) também são vinculados a idioma/região;
- descrições de tools e system‑prompts podem variar por idioma;
- cenários de commerce consideram moedas locais, impostos e restrições.
Nesse caso, um simples if (locale === "ru") espalhado pelo código já não basta. É necessária uma arquitetura: dicionários, recursos localizáveis, um lugar único onde locale e userLocation são armazenados e processados, acordos entre o widget e o servidor MCP.
A documentação do Apps SDK deixa claro que o ChatGPT envia locale e userLocation em _meta quando chama suas ferramentas justamente para que você possa, no servidor, escolher o idioma e o formato de dados corretos. Isso é o “combustível” para Apps multilíngues.
Pequena comparação
Para visualizar — uma mini comparação:
| Característica | App monolíngue | App multilíngue |
|---|---|---|
| Volume de código | Menor | Maior (dicionários, lógica de escolha) |
| Alcance de público | Limitado | Global |
| Complexidade de testes | Mais baixa | Mais alta |
| Trabalho com commerce/jurídico | Mais simples | Exige processos e jurídicos |
| Trabalho com comportamento do GPT | Prompt monolíngue | Prompts/descriptions multilíngues |
No nível do curso, partiremos do pressuposto de que o GiftGenius torna-se multilíngue (pelo menos EN/RU) para mostrar um esquema “maduro”. Mas muitas técnicas serão úteis também para um App monolíngue cuidadoso, se você quiser estar pronto para escalar.
5. Onde o idioma realmente influencia o modelo
Agora vamos destacar os pontos em que o idioma influencia diretamente o comportamento do ChatGPT.
Idioma do input do usuário vs idioma das descriptions dos tools
Imagine:
- o usuário escreve: “Escolha um presente para um colega por 50 euros”;
- seu tool suggest_gifts está descrito apenas em inglês;
- campos do esquema: recipient, budget, currency, interests.
O modelo deve:
- decidir que precisa mesmo chamar suggest_gifts;
- extrair recipient = "colleague", budget = 50, currency = "EUR";
- serializar isso corretamente em argumentos JSON.
Se as descriptions forem curtas e em outro idioma, o modelo lida com isso, mas a probabilidade de preencher campos erroneamente aumenta. Por exemplo, confundir budget e price_limit ou passar texto em interests, porque a descrição do campo tinha algo vago como “Any extra info about the gift”.
Para texto do usuário em português e descriptions em inglês, o modelo ainda fica “pulando” entre idiomas.
Variante com esquema localizado:
const locale = _meta?.["openai/locale"] ?? "en"; // vem do ChatGPT
const isRu = locale.startsWith("ru");
server.registerTool(
"suggest_gifts",
{
title: isRu ? "Seleção de presentes" : "Suggest gifts",
description: isRu
? "Sugira 3–5 ideias de presentes com base no perfil do destinatário."
: "Suggest 3–5 gift ideas based on recipient profile.",
inputSchema: { /* ... */ },
},
async ({ input }) => { /* ... */ }
);
Aqui está simplificado: na prática, é melhor gerar as descriptions uma vez na inicialização do servidor, e não a cada chamada, mas a ideia é clara. Podemos entregar ao ChatGPT descriptions diferentes conforme a locale para facilitar o entendimento do usuário pelo modelo.
Idioma dos dados vs idioma da solicitação
Se o seu catálogo de presentes estiver apenas em inglês e o usuário se comunicar em português, o modelo vai selecionar nomes e descrições em inglês. Às vezes tudo bem, às vezes não. Mas mais importante é como você formata a saída:
- você mostra ao usuário os titles/description originais do servidor;
- ou o modelo os reconta no idioma do usuário no próprio texto;
- ou seu tool já retorna texto localizado com base na locale.
No Apps SDK, structured content (dados estruturados que você retorna dos tools) e a resposta em texto podem viver separados. Você pode retornar dados estruturados (por exemplo, JSON com campos do produto) e um texto separado para o usuário; o modelo decide como renderizar ou recontar.
A localização pode acontecer no nível do servidor (dados) ou no nível do modelo (reformular no idioma desejado). Ao montar o mapa, é útil decidir onde você quer manter a “instância final”.
System‑prompt e follow‑ups
Se o seu system‑prompt estiver apenas em inglês e o usuário for lusófono, o modelo ficará equilibrando dois idiomas. Pode ser aceitável, mas às vezes você quer definir o tom com mais rigidez: por exemplo, na versão em português do App você quer um estilo mais informal, e na inglesa — mais formal.
Consequentemente, no mapa de localização você deve marcar:
- system‑prompt EN;
- system‑prompt RU;
- modelos de follow‑ups (EN/RU);
- quaisquer dicas “rígidas” no prompt para as ferramentas.
6. Mapa de localização para o GiftGenius
Agora juntamos tudo o que já discutimos sobre camadas, profundidade e idiomas em um mapa explícito de localização para o GiftGenius. Vamos fazer aquilo que você depois fará para o seu App: montar o mapa de localização. A ideia é simples: uma tabela; nas colunas — camada e tipo de entidade; nas linhas — elementos concretos.
Exemplo de mapa
Aqui vai um mapa simplificado para o GiftGenius (EN/RU):
| Categoria | Elemento | Exemplo (EN) | Exemplo (RU) | Cosmética ou semântica |
|---|---|---|---|---|
| UI | Título do widget | GiftGenius: find a perfect present | GiftGenius: encontre o presente perfeito | Cosmética |
| UI | Rótulo do destinatário | Recipient | Destinatário | Cosmética |
| UI | Erro de lista vazia | No gifts found | Nenhum presente encontrado | Cosmética |
| Prompts | System‑prompt | You are GiftGenius, a gift assistant… | Você é o GiftGenius, um assistente de presentes… | Semântica |
| Prompts | Modelo de resumo da escolha | Here’s why these gifts fit… | Veja por que estes presentes são adequados… | Semântica |
| Data | Nome do presente | Smart mug | Caneca inteligente | UX e semântica |
| Data | Descrição do presente | Self‑heating mug with app control… | Caneca autoaquecida com controle por aplicativo… | UX e semântica |
| Data | Moeda | 59.99 USD | 5 499 ₽ / 59,99 € | Semântica (formato/moeda) |
| Tools/schema | |
Suggest gift ideas based on profile… | Seleciona ideias de presentes com base no perfil… | Semântica |
| Tools/schema | |
Budget in user’s currency | Orçamento na moeda do usuário | Semântica |
| Commerce | Nome do SKU no feed | “Premium subscription – 1 year” | “Assinatura Premium – 1 ano” | UX e jurídico |
| Commerce | Página de Terms | Terms of Service (EN only) | Aviso: apenas o texto em EN é legalmente vinculante | Semântica/direito |
| Errors (backend) | Mensagem de erro de pagamento | Payment failed, please try again later | Pagamento não realizado, tente novamente mais tarde | Cosmética + UX |
À esquerda agrupamos por camadas; depois — elementos específicos. A última coluna ajuda a entender o que não pode ser alterado sem alinhamento com quem cuida de prompt design/modelo: tudo que estiver marcado como semântica afeta o comportamento do GPT.
Pequeno esboço de código
Para ligar o mapa ao código, podemos criar um tipo simples para entidades localizáveis:
type LocalizedTextKey =
| "ui.title"
| "ui.recipient_label"
| "error.no_gifts"
| "prompt.summary_intro";
type Locale = "en" | "ru";
type Messages = Record<Locale, Record<LocalizedTextKey, string>>;
const messages: Messages = {
en: {
"ui.title": "GiftGenius: find a perfect present",
"ui.recipient_label": "Recipient",
"error.no_gifts": "No gifts found",
"prompt.summary_intro": "Here’s why these gifts fit:",
},
ru: {
"ui.title": "GiftGenius: encontre o presente perfeito",
"ui.recipient_label": "Destinatário",
"error.no_gifts": "Nenhum presente encontrado",
"prompt.summary_intro": "Veja por que estes presentes são adequados:",
},
};
Depois, essas mesmas chaves podem ser usadas tanto no widget quanto ao formar prompts no servidor (desde que você propague a locale por toda a stack — tema da próxima aula). Assim, seu “mapa de localização” aos poucos vira um dicionário tipado, e não um conjunto disperso de strings.
7. Prática: faça o mapa de localização do seu App
Antes de aprofundar em técnicas de i18n e na arquitetura de Gateway/MCP, vale fazer um exercício chato, mas muito útil: descrever honestamente o que você pretende localizar.
Uma boa abordagem — abrir qualquer editor (Google Sheets, Notion, o que for) e criar uma tabela com colunas:
- categoria/camada (UI, prompts, dados, tools, commerce e parte jurídica, erros);
- elemento (botão específico, descrição de campo específica, endpoint específico com texto);
- exemplo de valor EN;
- exemplo de valor no segundo idioma (se já existir ou pelo menos um rascunho);
- marcação “cosmética/semântica/juridicamente importante”;
- owner (quem é responsável pelas alterações: frontend, servidor MCP, product, jurídico).
Depois percorra o seu App e anote honestamente tudo onde há texto ou onde o idioma influencia o formato dos dados.
Para o GiftGenius, sairia algo como uma versão expandida da tabela acima. No caminho, você quase certamente vai descobrir alguns pontos “escondidos”:
- constantes de texto no código dos servidores MCP (por exemplo, mensagens de erro);
- valores padrão em structuredContent (por exemplo, categorias que você não exibia na UI);
- rótulos antigos em tools que já não correspondem ao comportamento atual.
Esse exercício é especialmente útil fazê-lo antes de conectar a localização a processos de negócio reais (pagamentos, ativações de assinaturas, documentos jurídicos). Renomear o tool charge_user em um sistema multilíngue com ACP e textos jurídicos depois é bem mais doloroso.
Em geral, se você desenhar o mapa de localização com antecedência e marcar honestamente o que e em quais idiomas pretende dar suporte, economizará muito trabalho nos próximos módulos — quando entrarem em jogo MCP, Gateway, commerce e Store.
8. Erros típicos ao planejar a localização
Erro nº 1: achar que localização = “traduzir botões”.
Cenário muito comum: o time extrai cuidadosamente todas as strings da UI para dicionários, as traduz e comemora. Enquanto isso, o system‑prompt continua só em inglês, as descriptions dos tools também, e o catálogo de produtos contém apenas nomes em inglês. Resultado: o App parece localizado, mas o modelo por dentro continua vivendo no seu próprio mundo, e o comportamento segue anglocêntrico. Na prática, isso aparece em recomendações estranhas e erros nos argumentos dos tools.
Erro nº 2: não diferenciar cosmética e semântica.
Às vezes o product pede para “ajustar um pouco a formulação” na descrição de uma ferramenta ou no system‑prompt, e o desenvolvedor altera o texto como se fosse um simples rótulo de UI. Mas a description de um campo do JSON Schema ou uma frase no system‑prompt é parte do contrato com o modelo. Tais mudanças podem alterar radicalmente como o GPT chama seu tool. Se você não marcar previamente os elementos semânticos no mapa de localização, é fácil quebrar o comportamento do App por acidente.
Erro nº 3: começar um caos multilíngue sem arquitetura.
É tentador, no início, espalhar pelo código um if (locale === "ru") e injetar strings em português onde precisar. Em poucas semanas, o app vira um “inferno de localização”: em um componente as strings vêm do dicionário, em outro estão hardcoded no JSX, no servidor — um terceiro esquema de nomes de chaves. Depois, conectar um sistema de i18n decente e unificar tudo fica muito mais difícil.
Erro nº 4: esquecer dados e dinheiro.
Mesmo equipes experientes costumam começar traduzindo UI e prompts, mas deixam passar que catálogos de produtos, preços, moedas e textos jurídicos também devem considerar locale e userLocation. Nas especificações de product feed para o ChatGPT estão definidos com rigor quais campos de texto e preços são necessários para exibir corretamente produtos ao usuário. Se você não planejar multilíngue no nível dos dados, depois terá que duplicar o feed ou fazer migrações dolorosas.
Erro nº 5: ignorar os sinais da plataforma sobre localidade e localização.
O ChatGPT já envia nas chamadas MCP _meta["openai/locale"] e _meta["openai/userLocation"], para que você entenda em que idioma e de qual região estão falando com você. Alguns desenvolvedores ainda pedem ao usuário “Escolha o idioma da interface” no primeiro acesso e não usam esses sinais para escolher recursos e preços. O resultado é um UX pior e uma arquitetura mais complexa do que o necessário.
Erro nº 6: não definir “owners” dos elementos localizáveis.
Quando tudo entra em produção, descobre-se que as traduções se espalharam por pessoas diferentes: frontenders ajustam textos da UI, backenders — descriptions dos tools, especialista de ML — o system‑prompt, e os jurídicos mandam Terms revisados. Se o mapa de localização não indicar quem é responsável por qual camada, as mudanças começam a conflitar, e alguns textos são atualizados em um lugar e não em outro.
GO TO FULL VERSION