CodeGym /Cursos /ChatGPT Apps /Localização de tools e descriptions: impacto no GPT e exp...

Localização de tools e descriptions: impacto no GPT e experimentos de comportamento

ChatGPT Apps
Nível 9 , Lição 3
Disponível

1. Como o modelo “enxerga” seus tools

Vamos começar pelo fato de que para o modelo um tool não é “sua linda função em TypeScript”, e sim uma descrição estrutural no estilo:

  • name: nome técnico, por exemplo "search_gifts";
  • description: texto em linguagem natural que explica quando e para que usar esse instrumento;
  • inputSchema: JSON Schema com campos, cada um podendo ter também description, tipo e restrições.

De forma bem simplificada, o modelo faz algo assim (pseudocódigo na cabeça do GPT):


1. Ler a solicitação do usuário (em qualquer idioma).
2. Ler a lista de tools: name + description + descrições dos argumentos.
3. Para cada tool, estimar se ele é adequado para a tarefa.
4. Se for necessário um tool — gerar JSON com argumentos conforme o schema.
5. Caso contrário — responder em texto.

Há duas conclusões importantes.

Em primeiro lugar, o campo description do instrumento não é um comentário para desenvolvedores, mas sim a interface entre o modelo e o seu backend. Se a descrição do tool for vaga, incompleta ou em um idioma diferente do do usuário, o modelo vai errar com mais frequência: tool errado, argumentos errados, resposta sem ferramenta onde ela era necessária.

Em segundo lugar, o description dos campos no JSON Schema é tão importante quanto a descrição da própria ferramenta. O modelo realmente lê o description de cada propriedade e, com base nele, decide em qual campo colocar “idade”, em qual “orçamento” e onde deve estar o id.

Miniexemplo para o GiftGenius

Vamos pegar nosso instrumento search_gifts. Na versão original, “apenas EN”, ele poderia ser assim:

// 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 o usuário escreve: “Preciso de um presente para a minha mãe, ela tem 60 anos, orçamento até 3000 rublos”, o modelo deve:

  1. Entender que search_gifts é o instrumento adequado.
  2. Entender que “60 anos” deve ir para recipient_age, e “3000 rublos” — para budget.

Enquanto as descrições estiverem apenas em inglês, o GPT ainda assim consegue, mas isso já exige uma “tradução interna” extra. Em múltiplos idiomas e em modelos mais fracos, isso prejudica a precisão.

2. O problema das “descrições em inglês” em um App multilíngue

No módulo 9, já comentamos por alto o “mapa de localização”: widget de UI, catálogos, erros, textos de comércio. Agora vamos focar no que acontece quando as descrições das ferramentas estão apenas em inglês, mas o usuário interage, digamos, em russo ou espanhol — é aí que começa uma leve bagunça.

Cenário típico:

  1. Usuário: “Escolha um presente para um amigo de TI, orçamento até 50 euros”.
  2. O modelo olha a lista de tools e vê descrições apenas em EN.
  3. Se a solicitação também está em EN — tudo certo.
  4. Se a solicitação está em outro idioma, ele precisa:
    • entender a solicitação,
    • mapeá-la mentalmente às descrições em inglês,
    • selecionar o instrumento,
    • e depois ainda extrair os argumentos em JSON.

Em modelos fortes isso ainda funciona, mas:

  • com mais frequência aumenta a proporção de respostas sem chamar tools — o modelo “acha” que consegue resolver sozinho;
  • os erros nos argumentos ficam mais prováveis (especialmente quando importam moeda, unidades de medida e restrições regionais);
  • a lógica de roteamento entre vários tools fica menos confiável (instrumento “fora de propósito”).

Exemplo simples de erro: no campo budget espera-se “na moeda do usuário”, mas a descrição não diz nada sobre isso. O modelo decide que é USD por padrão e envia ao backend 50 dólares onde o usuário claramente quis 50 euros.

E é aqui que entra a localização das descrições.

3. Abordagens de localização: tools separados vs descrições multilíngues

Existem duas abordagens arquiteturais básicas, e ambas fazem sentido.

Ferramentas separadas para cada idioma

Nesta opção, você cria vários tools com nomes diferentes, cada um com descrições no “seu” idioma.

Para o GiftGenius, isso pode ser assim:

export const searchGiftsEn = {
  name: "search_gifts_en",
  description: "Search for gift ideas based on user preferences.",
  // ...
};

export const searchGiftsRu = {
  name: "search_gifts_ru",
  description: "Seleção de presentes com base nas preferências do destinatário.",
  // ...
};

Para o ChatGPT App, é importante que a lista de tools disponíveis dependa de locale. Se locale = "ru-RU", então o seu servidor MCP deve retornar apenas search_gifts_ru. Se locale = "en-US", — apenas search_gifts_en.

Vantagens dessa abordagem: as descriptions ficam o mais “limpas” e monolíngues possível. Você pode pensar no App como várias versões monolíngues, cada uma com seus próprios prompts e descrições. É confortável quando há poucos idiomas e mercados bem diferentes.

Desvantagens — duplicação de lógica e dificuldades de análise. No backend, provavelmente o handler será o mesmo, mas no nível de MCP/manifests — já são dois instrumentos diferentes. É preciso lembrar de atualizar as descrições de ambos a cada mudança.

Insight (dados em 2025-12-01)

Experimentalmente, não foram observadas vantagens significativas de ter description no idioma do usuário/locale. As ferramentas eram escolhidas com praticamente a mesma frequência, independentemente do idioma da descrição. Se havia 2 ferramentas com descrições parecidas (em idiomas diferentes), elas confundiam o ChatGPT.

Além disso, seu aplicativo precisará passar por review ao se registrar na Store. Portanto, recomendo simplesmente escrever todas as tool descriptions e argument descriptions em inglês.

Porém, se no futuro houver milhares de aplicativos no ChatGPT e a concorrência pela “escolha do instrumento” aumentar, é possível que a description no locale do usuário passe a ter vantagem. Aguardemos o surgimento do Tool Search Optimization.

Um único instrumento com descriptions multilíngues

Na segunda opção, você mantém um único name (por exemplo, search_gifts), mas torna o description e as descrições dos campos do JSON Schema multilíngues.

Há estilos diferentes:

  1. Forma curta bilíngue:
    description: "Search gifts for a recipient. / Busca de presentes com base nas preferências do destinatário.",
  2. Blocos marcados por idioma:
    description: "[EN] Search for gifts based on user preferences. [PT] Seleção de presentes com base nas preferências do destinatário.",
  3. Campos separados, combinados em uma string (menos conveniente):
    description: `EN: ${enDescription} PT: ${ptDescription}`,

Vantagens — um único tool, uma única fonte da verdade (single source of truth), mais simples implantar uma arquitetura com MCP Gateway: você sempre expõe a mesma interface para o ChatGPT, independentemente do idioma do usuário.

Desvantagens: as descrições ficam mais longas. Se você “misturar” idiomas sem cuidado, o modelo pode se confundir um pouco — especialmente quando o inglês e o texto local ficam intercalados sem marcações claras [EN], [PT].

Para um projeto educacional como o GiftGenius, recomendamos um híbrido: manter as descrições principalmente em inglês, mas adicionar uma curta explicação no idioma local, e conduzir toda a “semântica” real (qual idioma usar, como se dirigir ao usuário) pelos argumentos (locale) e pelo system prompt.

4. Localização do JSON Schema: descrições dos campos

Agora vamos mais fundo: para os próprios argumentos do instrumento.

No JSON Schema, cada campo pode (e deve) ter description. O modelo lê essa string quando gera o JSON para a chamada do instrumento.

Para o GiftGenius, podemos fazer assim:

export const searchGiftsTool = {
  name: "search_gifts",
  description:
    "Search gifts based on user preferences (PT: seleção de presentes com base nas preferências do destinatário).",
  inputSchema: {
    type: "object",
    properties: {
      recipient_age: {
        type: "integer",
        description:
          "Recipient age in years. PT: idade do destinatário (número inteiro).",
      },
      budget: {
        type: "number",
        description:
          "Maximum budget in user's currency. PT: orçamento máximo na moeda do usuário.",
      },
      locale: {
        type: "string",
        description:
          "User locale (e.g. 'en-US', 'ru-RU'). PT: idioma da interface e das respostas.",
      },
    },
    required: ["budget", "locale"],
  },
};

Algumas observações práticas.

Em primeiro lugar, os nomes dos campos (recipient_age, budget, locale) geralmente ficam em inglês. O que se traduz é o description. Isso é importante para que o formato JSON não mude de idioma para idioma e você não precise manter dois contratos diferentes.

Em segundo lugar, no description é útil indicar explicitamente moeda, unidades de medida e restrições importantes. Isso reduz bastante o número de argumentos “tortos”.

Em terceiro lugar, se você já usa um MCP Gateway, dá para combinar que ele encaminhe automaticamente o locale aos argumentos do instrumento, de modo que o modelo não precise preenchê-lo por conta própria. Mesmo assim, vale manter a descrição de locale: o modelo entende melhor o que é esse parâmetro e por que ele é necessário.

5. Como escolher o idioma das descrições: estratégias para um App real

Agora a pergunta prática principal: qual idioma tornar o principal para as descrições e quando vale localizá-las por completo?

Recomendações e experiência mostram que os modelos GPT ainda funcionam melhor em contexto inglês, e muitos desenvolvedores deixam as descrições apenas em EN. Mas, para um App multilíngue, isso pode ser um compromisso.

Vamos analisar algumas estratégias.

Apenas descrições em EN

O caminho mais simples — tudo em inglês.

Vantagens: uma única base de código, um idioma para manutenção, mais fácil escrever formulações boas e precisas. O modelo fica feliz quando tudo está em inglês.

Desvantagens: para usuários que escrevem em outros idiomas, a qualidade da escolha de ferramentas e de argumentos pode ser inferior. Especialmente em modelos “preguiçosos” ou em ferramentas complexas com muitos parâmetros.

EN + um bloco local curto

Abordagem de compromisso: a descrição principal em EN e, no final, um bloco curto no idioma local que ajuda o modelo a mapear as palavras do usuário aos argumentos.

Exemplo:

description:
  "Search for gifts based on user preferences. PT: o instrumento seleciona presentes com base na descrição do destinatário, idade e orçamento.",

Para o JSON Schema:

description:
  "Age of the recipient in years. PT: idade do destinatário (em anos).",

Vantagens: o modelo continua no “mundo inglês”, mas com uma dica no idioma do usuário.

Desvantagens: as descrições ficam mais longas, mas geralmente isso não é crítico.

Localização completa das descrições por locale

A abordagem mais séria: as descrições de ferramentas e campos mudam conforme o locale que você recebe do ChatGPT. Para en-US você entrega descrições puramente em inglês, para ru-RU — puramente em russo, e para de-DE — em alemão.

Já não é “um JSON Schema para sempre”, mas um conjunto de schemas que o MCP/Gateway escolhe dinamicamente.

No nível do MCP, isso fica assim:

function getSearchGiftsToolDescription(locale: string) {
  if (locale.startsWith("ru")) {
    return {
      name: "search_gifts",
      description: "Seleção de presentes com base nas preferências do destinatário.",
      // ru‑schema...
    };
  }
  return {
    name: "search_gifts",
    description: "Search for gifts based on user preferences.",
    // en‑schema...
  };
}

Vantagens: o modelo vê a interface no mesmo idioma em que o usuário escreve. É o máximo de conveniência.

Desvantagens: a manutenção e os testes se complicam. É preciso ter um processo que garanta que todas as versões localizadas das descrições estejam sincronizadas semanticamente, e que você não esqueça de atualizar, por exemplo, o schema em alemão ao adicionar um campo novo no inglês.

6. Implementação no nosso aplicativo GiftGenius

Vamos à prática. Faremos no GiftGenius a variante híbrida: um único instrumento search_gifts, descrições predominantemente em EN, mas com explicações em português, além do argumento locale.

Suponha que você tenha um servidor MCP em TypeScript que descreve os tools no estilo do MCP SDK.

// 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. PT: idade do destinatário (número inteiro)."
    ),
  budget: z
    .number()
    .describe(
      "Maximum budget in user's currency. PT: orçamento máximo na moeda do usuário."
    ),
  locale: z
    .string()
    .describe(
      "User locale (e.g. 'en-US', 'ru-RU'). PT: idioma da interface e das respostas."
    ),
});

export const searchGiftsTool = {
  name: "search_gifts",
  description:
    "Search for gifts based on user preferences (PT: seleção de presentes com base nas preferências do destinatário).",
  inputSchema: searchGiftsInputSchema,
  // execute(...) ...
};

Importante:

  • locale é obrigatório. Se o widget souber (e nós sabemos via _meta["openai/locale"]), ele próprio colocará no callTool, ou o MCP Gateway fará isso automaticamente do lado dele;
  • as descrições já contêm palavras‑chave em português como “idade”, “orçamento”, “idioma da interface”, então fica mais fácil para o modelo entender o que extrair da solicitação do usuário e aonde colocar.

No lado do Apps SDK, você pode, por exemplo, ter uma função que chama esse tool diretamente (se widgetAccessible estiver ativado), passando o locale do 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;
}

Esse encadeamento reforça a arquitetura: o locale veio do ChatGPT → entrará no tool → ele escolherá o catálogo e os formatos de preço corretos, que você depois exibirá direitinho no frontend.

7. Experimentos de comportamento: como medir o impacto da localização

Agora o mais interessante: como saber se a localização de tools e descrições realmente melhora o comportamento do modelo e se valeu a pena o tempo gasto com traduções?

Dá para fazer um pequeno “experimento científico” diretamente no Dev Mode do GiftGenius.

Duas variantes do App: base vs localized

Prepare duas configurações do seu App:

  • base — descrições de ferramentas e JSON Schema apenas em EN;
  • localized — descrições EN+PT (ou versões totalmente em PT, se você topar).

Deixe o resto (catálogos, UI, prompts) igual, para não confundir os efeitos.

Para simplificar, você pode:

  • no Dev Mode (e ainda mais na Store) manter apenas a versão localized;
  • e rodar a base localmente em um branch separado para comparar os resultados em um conjunto de solicitações pré‑definidas.

O que medir

Há três métricas‑chave.

Primeira — frequência de escolhas corretas de ferramentas. Para um conjunto de testes em português (e/ou outro idioma), você observa quantas vezes o modelo:

  • decidiu chamar uma ferramenta quando isso era necessário;
  • escolheu especificamente search_gifts, e não outro tool.

Segunda — correção dos argumentos. Verifique com que frequência o JSON da chamada corresponde ao esperado: campos não trocados, orçamento na moeda correta, idade como inteiro explícito, locale presente.

Terceira — quantidade de chamadas estranhas ou sem sentido. Por exemplo, o modelo chama search_gifts para a pergunta “que horas são agora?” ou preenche recipient_age: 3000 no lugar do orçamento.

Você pode testar manualmente e também pelos logs do MCP/Agents — de qualquer forma, os logs serão úteis no futuro, então é bom se acostumar com essa analítica desde já.

Como organizar um conjunto de testes manual

Você pode criar um pequeno “golden prompt set” para localização:

1. "Preciso de um presente barato de até 30 euros para uma menina de 10 anos, ela gosta de desenhar."
2. "Escolha um presente para um colega programador, 35 anos, orçamento de 100$."
3. "Preciso de um presente para a vovó no aniversário de 70 anos, orçamento até 5000 rublos."

E passar pelas duas versões do App (base e localized), observando:

  • quais tools o modelo escolhe;
  • quais argumentos ele preenche;
  • como muda o texto da resposta, caso a ferramenta não tenha sido chamada.

Dica semiprofissional: dá para fazer um script simples que envia essas solicitações via ChatGPT API, mas, no escopo do curso, o modo manual no Dev Mode é suficiente. Uma categoria de solicitações especialmente útil para incluir nesse conjunto é a de mensagens com idiomas mistos e combinações estranhas de locale. Dedicaremos um bloco a isso.

Se você estiver desenvolvendo um aplicativo comercial sério e estiver em jogo muito dinheiro, então teste obrigatoriamente esses pontos exatamente no seu aplicativo. O Módulo 20 é dedicado ao trabalho profissional com “golden prompt set” — estude esse tema.

8. Idiomas mistos e combinações estranhas de locale

Nada diverte tanto um desenvolvedor de LLM quanto um usuário que escreve em dois idiomas ao mesmo tempo. Por exemplo:

"Preciso de um presente for my friend, ele gosta de Star Wars, budget 100€"

Já sabemos que o modelo é multilíngue e, na maioria das vezes, dá conta. Mas, com idiomas mistos e descrições “em inglês”, a probabilidade de erro aumenta.

Há algumas situações típicas.

Primeira — o usuário escreve em PT, e as descrições das ferramentas estão em EN. O modelo pode entender, mas às vezes se confunde, especialmente com terminologia específica (nomes de categorias, rótulos raros de campos).

Segunda — locale = "ru-RU", mas o usuário escreve em inglês por algum motivo. O ChatGPT envia sinais de que a interface deve ser construída em russo, mas o idioma real do texto é EN. Você pode:

  • ainda assim entregar descrições em russo, considerando o locale como verdade principal;
  • ou implementar detecção do idioma da mensagem como sinal adicional e ajustar as descrições ao idioma efetivo.

Terceira — locale = "en", e o usuário às vezes insere palavras em russo. Nesse caso, em geral, as descrições em inglês se saem muito bem.

Na prática, basta escolher uma política clara. Por exemplo:

  • se o locale começa com "ru" — você adiciona trechos em russo às descrições;
  • se não — as descrições ficam puramente em inglês.

Uma regra clara é útil porque você consegue testar cada ramo intencionalmente, sem ter que adivinhar por que hoje as descrições apareceram em um idioma ou em outro.

9. Documentação, processo e idioma “canônico”

Localizar descrições não é um ato único, é um processo. Usuários gostam quando surgem recursos, e você gosta quando nada antigo quebra. Portanto, combine previamente com você mesmo:

  • qual idioma será o “canônico”, a partir do qual serão feitos os demais;
  • onde armazenar as descrições localizadas;
  • como verificar a consistência.

Geralmente, o inglês é o idioma canônico. Todas as novas ferramentas e campos são descritos primeiro em EN, passam por review e só depois são localizados para os outros idiomas. No código, isso pode ser expresso assim:

  • arquivo tools.en.json com a descrição completa de name/description/campos;
  • arquivos tools.ru.json, tools.de.json como “derivados” para idiomas específicos;
  • um pequeno gerador que monta os JSON Schemas finais para o MCP com base nesses dicionários.

Na versão simples, por ora você pode usar strings no código, mas estruturar de modo que seja fácil extrair para dicionários separados depois.

É importante lembrar que descrições também são texto de produto. Elas merecem um review tão rigoroso quanto os textos de UI: verificar clareza, ausência de ambiguidades e de “encheção de linguiça”. Especialmente na variante multilíngue, não queremos que o bloco em português contradiga a parte em inglês.

10. Esquema visual: como o idioma atravessa a stack

Para juntar tudo na cabeça, vejamos um diagrama simplificado do fluxo de uma solicitação considerando a localização dos tools.

flowchart TD
    U[Usuário escreve em russo] --> C[ChatGPT UI]
    C -->|"_meta.openai/locale = 'ru-RU'"| W[Widget GiftGenius]
    W -->|"locale = 'ru-RU'"| T["Tool descriptions (EN+RU)"]
    T --> M[Modelo GPT]
    M -->|callTool search_gifts| MCP[MCP / Gateway]
    MCP -->|"locale = 'ru-RU'"| B[Backend / catálogos RU]
    B --> MCP --> M2["Modelo GPT (resposta)"]
    M2 --> C2[ChatGPT UI + widget RU]

Aqui, o idioma do usuário e o locale determinam:

  • em qual idioma o widget mostra a UI;
  • quais descrições de ferramentas e campos o modelo vê;
  • quais catálogos e moedas o backend escolhe;
  • como as respostas são formatadas (pelo modelo e pelo widget).

11. Erros típicos na localização de tools e descrições

Erro nº 1: considerar o campo description “técnico” e não localizá-lo.
Isso funciona enquanto você só tem usuários em inglês. Assim que surgem outros idiomas, o modelo passa a responder com mais frequência sem tools ou a enviar argumentos tortos. Você traduziu a UI, mas o App continua se comportando “em inglês”.

Erro nº 2: mudar os nomes dos campos no JSON por idioma.
Às vezes surge a tentação de fazer agevozrast, budjet etc. Isso leva a um pesadelo no backend: schemas diferentes, formatos diferentes, análise de logs complicada. Melhor manter o name dos campos estável e localizar apenas as descrições.

Erro nº 3: misturar idiomas de forma caótica nas descrições.
Frases como “Busca por gifts com base nas preferências do user” não ajudam nem o modelo, nem a pessoa. Se você fizer descrições multilíngues, separe os blocos explicitamente: [EN] ... [PT] .... Assim, o modelo vê estrutura, e não bagunça.

Erro nº 4: não passar o locale para as ferramentas.
Mesmo que você tenha localizado as descrições, se não passar locale ao tool (ou se o MCP Gateway não encaminhar), o backend não sabe quais catálogos e formatos usar. No fim, o modelo tenta ser “multilíngue”, mas o servidor retorna dados de apenas um mercado.

Erro nº 5: traduzir descrições automaticamente sem review.
Parece que dá para passar as descrições por um tradutor automático e ser feliz. Na prática, esses textos são frequentemente imprecisos, especialmente nos termos e argumentos. Como resultado, o modelo pode interpretar de forma errada o sentido do instrumento ou do campo. Melhor ter uma versão em EN bem pensada e versões localizadas cuidadosas do que vinte idiomas “automáticos”.

Erro nº 6: ausência de testes/experimentos para diferentes locais.
Se você não verifica o comportamento do App ao menos com um conjunto básico de solicitações para cada locale, tudo pode “quebrar” por meses até chegar o primeiro usuário real daquele idioma. Um pequeno conjunto de solicitações “golden” e testes manuais no Dev Mode reduzem bastante esse risco.

Erro nº 7: dessincronização entre descrições canônicas e localizadas.
Você adicionou um novo campo occasion (“ocasião” do presente) no schema em inglês, mas esqueceu de atualizar o em russo. Como resultado, no locale RU o modelo nem sabe desse campo e não o preenche, embora o backend já espere por ele. Por exemplo, o servidor tenta filtrar presentes por ocasião, recebe null e mostra uma lista ampla demais — em EN tudo funciona, mas em RU o comportamento “quebra” silenciosamente. Portanto, quaisquer mudanças nas descrições das ferramentas devem passar por um processo simples, porém regular: atualizar EN → atualizar locais → rodar testes rápidos.

Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION