CodeGym /Cursos /ChatGPT Apps /Das instruções ao design de tools e metadados: descoberta...

Das instruções ao design de tools e metadados: descoberta e roteamento

ChatGPT Apps
Nível 5 , Lição 4
Disponível

1. Por que instruções não bastam sem bons tools e metadados

É importante registrar uma verdade incômoda: o modelo não vê o seu código. Ele não sabe quais controladores você tem no Next.js, quais funções existem em TypeScript e que heurísticas maravilhosas você reuniu no serviço de recomendações.

Ele vê seu App por meio de algumas interfaces:

  1. System‑prompt (contrato de papel/role).
  2. Descrições das ferramentas: nome, description, inputSchema, outputSchema, anotações etc.
  3. Metadados do próprio aplicativo: nome, ícone, descrição curta e longa, categorias, conversation starters etc.

Ao processar a solicitação, o modelo olha para o contexto do diálogo e esses metadados para decidir:

  • se é preciso oferecer algum App;
  • se sim — qual exatamente entre os disponíveis;
  • e, se o App for escolhido — qual ferramenta desse App é adequada ao pedido atual.

Na parte anterior do Módulo 5, trabalhamos o que é possível “contar” ao modelo em palavras — system‑prompt e instruções de UX. Agora passamos ao que ele vê além do texto: tools e metadados.

Portanto, a tarefa do Módulo 5 é na verdade dupla. Primeiro, no system‑prompt você formula “o que este App deve fazer e como deve se comportar”, e depois, no design dos tools e dos metadados, você embala isso em uma forma que o modelo realmente sabe usar — inclusive para discovery e roteamento.

Podemos formular assim: o system‑prompt é a constituição, e os tools e metadados são as leis e toda a burocracia ao redor: formulários, esquemas de banco de dados etc. Se ficarmos só na constituição, não iremos longe.

2. Decomposição: “uma tarefa — um tool”, mas com bom senso

Vamos começar pelo mais doloroso: quantas ferramentas criar e como fatiá-las.

Princípio intuitivo: uma ferramenta — uma tarefa clara. Isso facilita muito a escolha do modelo: ele não tem uma função monstruosa do_everything, e sim várias ações bem organizadas com bons nomes.

Para o GiftGenius, podemos ter estas ferramentas básicas:

  • profile_to_segments — transformar a descrição livre do destinatário (idade, interesses, relação, contexto) em segmentos normalizados como "tech", "fitness", "gamer".
  • recommend_gifts — selecionar uma lista de ids de presentes por segmentos, orçamento, localidade e ocasião.
  • get_gift — obter a ficha completa do presente escolhido (descrição, mídia, SKU/variantes) pelo id.
  • (opcional) similar_gifts — a partir de um presente escolhido, sugerir mais 3–5 opções semelhantes.

Teoricamente, poderíamos fazer um único gift_tool com um parâmetro mode: "profile_to_segments" | "recommend" | "details" | "similar", mas aí você complica a vida para si e para o modelo: a descrição vira um textão, o inputSchema incha e, na hora de escolher a ferramenta, o modelo tem menos âncoras nítidas.

Antipadrão: God Tool

Imagine o seguinte esquema:

server.registerTool(
  "gift_tool",
  {
    description: "Operações diversas com presentes.",
    inputSchema: { /* 50 campos e flags */ },
  },
  async ({ input }) => { /* switch enorme por mode */ }
);

Na cabeça do modelo isso parece “há uma ferramenta abstrata sobre presentes, e depois eu me viro”. Isso piora a precisão da escolha, atrapalha o discovery e complica sua manutenção.

Mas cair no outro extremo — criar 50 ferramentas microscópicas para cada detalhe — também é ruim. Cada ferramenta adicional entra no contexto, sobrecarrega a atenção do modelo e aumenta o risco de erros de roteamento. A documentação alerta explicitamente: ferramentas demais e muito pequenas prejudicam a qualidade, especialmente quando suas descrições se sobrepõem.

Regra prática útil:

  • tudo o que o usuário percebe como um “passo” único no fluxo (por exemplo, a primeira seleção de presentes com base no perfil) é um bom candidato a um tool separado;
  • o que sempre é executado estritamente dentro desse passo e não tem sentido isolado (por exemplo, calcular o scoring ou registrar a visualização dos cartões) é melhor ficar dentro da implementação da ferramenta.

Suponha que, por esse princípio, você já tenha dividido os fluxos em 2–4 ferramentas. A próxima questão importante é: como descrever as entradas desses tools de modo que o modelo consiga usá-las sem adivinhações. É por aí que começamos.

3. Projetando os use cases no Input Schema

Agora pegamos um use case específico e analisamos honestamente quais dados a ferramenta realmente precisa.

Vamos pegar o cenário: “Quem vai presentear está no limite do prazo: reunir 5–7 ideias para um amigo de 25 anos, que gosta de futebol e jogos de tabuleiro, com orçamento até US$ 50”.

Pelo jobs‑to‑be‑done, entendemos que a tarefa do núcleo de recomendações do GiftGenius é reduzir a escolha a uma lista pequena e diminuir a ansiedade de “e se eu escolher algo ruim”. No nível da conversa no chat, o assistente precisa de:

  • informações básicas sobre o destinatário (idade, sexo, relação com quem dá o presente);
  • interesses/hobbies;
  • orçamento e moeda;
  • ocasião (aniversário, ano-novo, bodas etc.);
  • opcional — país/cidade para filtrar por entrega.

Na arquitetura do GiftGenius isso se divide em duas etapas:

  1. profile_to_segments(input) recebe dados “crus” (idade, interesses, descrição em texto) e os transforma em segmentos normalizados, com os quais é mais fácil trabalhar adiante.
  2. recommend_gifts(segments, budget, locale, occasion) com base nos segmentos e no orçamento escolhe ids concretos de presentes do catálogo.

Do ponto de vista do contrato ChatGPT ↔ MCP, é importante descrever exatamente a segunda etapa — o esquema de recommend_gifts, porque é essa ferramenta que será usada na maioria dos cenários de seleção.

Ao mesmo tempo, não é necessário exigir tudo do usuário de cara: o modelo pode reunir parte via follow‑up (“qual é o orçamento aproximado?”). Portanto, alguns campos do perfil podem ser opcionais; mas quando chegamos a recommend_gifts, ele já deve ter um conjunto normalizado de parâmetros.

Exemplo: TypeScript + JSON Schema para recommend_gifts

No servidor MCP em TypeScript isso pode se parecer com isto:

// apps/mcp/server.ts
import { McpServer } from "@openai/mcp-server";

const server = new McpServer();

server.registerTool(
  "recommend_gifts",
  {
    title: "Recomendações de presentes",
    description:
      "Use esta ferramenta quando for necessário selecionar presentes por segmentos do destinatário, orçamento, localidade e ocasião.",
    inputSchema: {
      type: "object",
      properties: {
        segments: {
          type: "array",
          description:
            "Lista de segmentos do destinatário, por exemplo ['tech', 'football_fan']. Normalmente vem de profile_to_segments.",
          items: { type: "string" },
          minItems: 1
        },
        budget: {
          type: "object",
          description:
            "Faixa de orçamento do presente na moeda do usuário (mínimo/máximo).",
          properties: {
            min: {
              type: "number",
              minimum: 0,
              description: "Valor mínimo que o usuário está disposto a gastar."
            },
            max: {
              type: "number",
              minimum: 0,
              description: "Valor máximo que o usuário está disposto a gastar."
            },
            currency: {
              type: "string",
              minLength: 3,
              maxLength: 3,
              description: "Código de moeda com três letras (por exemplo, USD, EUR, BRL)."
            }
          },
          required: ["min", "max", "currency"]
        },
        locale: {
          type: "string",
          description:
            "Localidade do usuário no formato BCP‑47 (por exemplo, 'pt-BR' ou 'en-US')."
        },
        occasion: {
          type: "string",
          description:
            "Ocasião do presente, por exemplo 'birthday', 'new_year', 'anniversary'."
        }
      },
      required: ["segments", "budget", "locale", "occasion"]
    }
  },
  async ({ input }) => {
    // Por enquanto não vamos sofisticar, retornaremos um placeholder
    return {
      content: [
        {
          type: "text",
          text: `Selecionando presentes pelos segmentos ${input.segments?.join(
            ", "
          )} dentro do orçamento ${input.budget?.min}–${input.budget?.max} ${input.budget?.currency}...`
        }
      ],
      structuredContent: {}
    };
  }
);

Observe alguns pontos.

Em primeiro lugar, usamos bastante restrições do tipo enum e descrições claras. Mesmo que, formalmente, sejam apenas strings, a description indica ao modelo quais valores são esperados, e isso aumenta significativamente a chance de ele preencher os argumentos corretamente. Em vez de uma string vaga "ocasião": "algo como aniversário", temos uma occasion: "birthday" bem definida.

Em segundo lugar, as descrições dos campos não são “para a equipe”, e sim literalmente dicas para o modelo: o que é o campo, valores típicos, se há exemplo. Os autores da documentação do Apps SDK recomendam adicionar descrições e exemplos claros para cada parâmetro.

O que não deve estar no esquema de entrada

Campos “parasitas” típicos que costumam tentar enfiar lá:

  • identificadores internos (tenantId, internalSegment), que você pode adicionar no servidor de qualquer forma;
  • coisas que o modelo não tem como saber (por exemplo, deploymentRegion) — isso é de sua responsabilidade;
  • campos duplicados do histórico do chat (por exemplo, userPrompt): o modelo já vê a mensagem original, não o faça copiar e colar.

O Input Schema é exatamente aquilo que o modelo deve decidir e preencher, e não um saco geral com tudo.

4. Output Schema: não só dados, mas também contexto

No Apps SDK, o resultado da ferramenta volta para o diálogo como uma mensagem com role: tool. Depois o modelo decide o que fazer com ele: como formatar a resposta, quais follow‑ups fazer, se deve abrir um widget etc. Por isso, o design do esquema de saída é tão importante quanto o de entrada.

Há duas abordagens.

A opção “dados brutos” é assim:

{
  "items": [
    { "id": "GIFT_1" },
    { "id": "GIFT_2" }
  ]
}

O modelo vê apenas uma lista de ids, sem entender por que essas opções apareceram, quantos candidatos havia e quais são as melhores. Ele pode inventar algo, mas a chance de estranhezas aumenta.

Opção semanticamente rica:

{
  "items": [
    {
      "id": "GIFT_1",
      "score": 0.92,
      "reason": "Forte correspondência com o segmento 'football_fan' e cabe no orçamento."
    },
    {
      "id": "GIFT_2",
      "score": 0.81,
      "reason": "Adequado para quem gosta de jogos de tabuleiro, um pouco próximo ao limite superior do orçamento."
    }
  ],
  "meta": {
    "totalCandidates": 27,
    "returned": 5,
    "segmentsUsed": ["football_fan", "board_games"],
    "budget": { "min": 20, "max": 50, "currency": "USD" },
    "advice": "É melhor começar pelas opções com maior score e explicação clara."
  }
}

Agora o modelo pode explicar honestamente por que exatamente esses presentes e construir follow‑ups: “Encontrei 27 opções, mostrando as 5 melhores, eis o porquê”.

Exemplo: descrevendo o Output Schema para recommend_gifts

Vamos adicionar ao descritivo da ferramenta o esquema do resultado (mesmo que tecnicamente não seja obrigatório, é melhor fazê-lo — faz parte do contrato com o modelo):

const recommendGiftsOutputSchema = {
  type: "object",
  properties: {
    items: {
      type: "array",
      items: {
        type: "object",
        properties: {
          id: { type: "string", description: "ID do presente no catálogo." },
          score: {
            type: "number",
            description: "Pontuação de aderência ao perfil (0..1)."
          },
          reason: {
            type: "string",
            description:
              "Breve explicação de por que o presente é adequado (pode ser gerada no backend)."
          }
        },
        required: ["id", "score"]
      },
      description: "Lista de presentes recomendados com notas de relevância."
    },
    meta: {
      type: "object",
      properties: {
        totalCandidates: {
          type: "integer",
          description: "Quantos candidatos foram encontrados no catálogo."
        },
        returned: {
          type: "integer",
          description: "Quantos presentes esta chamada retornou."
        },
        advice: {
          type: "string",
          description:
            "Recomendação geral: por exemplo, por onde faz sentido começar."
        }
      }
    }
  },
  required: ["items"]
};

E usamos esse esquema dentro da implementação:

server.registerTool(
  "recommend_gifts",
  {
    title: "Recomendações de presentes",
    description:
      "Use quando precisar selecionar 3–7 presentes por segmentos e orçamento. Retorna ids de presentes e notas de aderência; obtenha as fichas detalhadas via get_gift.",
    inputSchema: /* como acima */,
    // Nem sempre o outputSchema é formalmente indicado, mas é útil para documentação:
    // outputSchema: recommendGiftsOutputSchema
  },
  async ({ input }) => {
    const recommendations = await recommendFromCatalog(input); // nossa lógica de negócio

    return {
      content: [
        {
          type: "text",
          text: `Encontrei ${recommendations.items.length} ideias adequadas. Vou mostrar as melhores agora.`
        }
      ],
      structuredContent: {
        items: recommendations.items,
        meta: {
          totalCandidates: recommendations.meta.totalCandidates,
          returned: recommendations.items.length,
          advice: recommendations.meta.advice
        }
      }
    };
  }
);

Fazemos duas coisas: damos ao modelo um texto mínimo para o usuário e, ao mesmo tempo, incluímos um JSON semântico com o qual ele pode continuar a conversa e os follow‑ups.

Enquanto isso, o get_gift buscará, pelo id, as fichas completas (nome, mídia, SKU etc.), e o widget do GiftGenius as renderizará como cartões de presentes.

5. Nomes e descrições dos tools como base para a descoberta

Agora o mais interessante: como nomes e descrições dos tools influenciam se o modelo vai chamá-los ou não.

A documentação e as boas práticas de metadados recomendam:

  • usar nomes orientados à ação: profile_to_segments, recommend_gifts, get_gift, similar_gifts, e não tool1, search, do_stuff;
  • começar a descrição no estilo “Use isto quando…”, descrevendo cenários de gatilho e limitações (“não use para…”).

Isso se relaciona diretamente ao seu golden prompt set. As formulações da descrição devem cruzar com as solicitações reais dos usuários. Se estiver escrito na descrição “Use quando o usuário pedir para selecionar um presente por orçamento e interesses do destinatário”, e no golden prompt houver “selecione um presente para um amigo gamer até US$ 50”, o modelo terá muito mais facilidade em associar o pedido ao tool.

Exemplo de boa descrição de ferramenta

Consideremos uma ferramenta adicional do GiftGenius — similar_gifts, que ajuda a expandir a seleção com ideias semelhantes com base em um presente específico:

server.registerTool(
  "similar_gifts",
  {
    title: "Presentes semelhantes",
    description:
      "Use esta ferramenta quando o usuário tiver escolhido um presente específico e quiser ver mais algumas opções parecidas. Não use para a primeira seleção do zero — para isso há o recommend_gifts.",
    inputSchema: {
      type: "object",
      properties: {
        giftId: {
          type: "string",
          description:
            "Identificador de um presente da seleção anterior para o qual devemos encontrar opções semelhantes."
        },
        limit: {
          type: "integer",
          description:
            "Quantos presentes semelhantes retornar (por padrão, 3–5).",
          minimum: 1,
          default: 5
        }
      },
      required: ["giftId"]
    }
  },
  async () => {
    /* ... */
  }
);

Pontos importantes:

  • Indicamos explicitamente quando usar a ferramenta e quando não.
  • A descrição contém palavras como “opções semelhantes”, “escolheu um presente específico” — exatamente aquelas que aparecerão com frequência nas solicitações reais do usuário.
  • Evitamos sobreposição com a área de recommend_gifts — isso reduz a competição entre ferramentas na escolha.

Exemplo de descrição ruim

description: "Trabalho com presentes."

O modelo praticamente não entende nada a partir dessa descrição. Essa ferramenta só pode funcionar se o GPT já estiver tentando desesperadamente acionar algo “no escuro”.

6. Anotações e hints: como sinalizar ao modelo a seriedade da ação

Uma ferramenta não é só nome e esquema, mas também anotações que indicam ao ChatGPT quão perigosa/importante é a ação e se é necessário pedir confirmação ao usuário. Na especificação do Apps SDK há vários hints para isso, como readOnlyHint, destructiveHint, openWorldHint e outros.

  • readOnlyHint: true indica que a ferramenta só lê dados e não muda estado. Então o assistente pode pular confirmações desnecessárias e chamá-la com mais liberdade.
  • destructiveHint: true sinaliza que a ferramenta pode apagar algo ou alterar de forma irreversível, então é preciso mostrar ao usuário um “Tem certeza?”.
  • openWorldHint: true indica que a ação afeta o mundo externo (postar em redes sociais, criar um registro fora da conta etc.), e isso também precisa de aviso.

Nível mínimo — sem confirmações

Se você tem public readonly tools, faz sentido marcá-los como readOnlyHint: true. Exemplo:

"annotations": {
  "readOnlyHint": true,
  "destructiveHint": false,
  "openWorldHint": false
}

Essas ferramentas podem ser chamadas sem confirmações dialogais extras por parte do GPT.

Uma confirmação

Se você tem tools que mudam algo no servidor, é lógico marcá-los como readOnlyHint: false:

"annotations": {
  "readOnlyHint": false,
  "destructiveHint": false,
  "openWorldHint": false
}

Ao ver uma ferramenta assim, o modelo provavelmente pedirá ao usuário uma confirmação uma vez (geralmente uma janela modal no UI do ChatGPT).

Ação perigosa

Se você tem um tool que apaga algo no servidor, marque-o como destructiveHint: true:

"annotations": {
  "readOnlyHint": false,
  "destructiveHint": true,
  "openWorldHint": false
}

O modelo chamará esse tool com bastante cautela e perguntará duas vezes:

  • primeiro pedirá a confirmação ao usuário no texto,
  • depois a plataforma exibirá a janela de diálogo padrão.

Para o nosso GiftGenius, neste módulo ainda não implementamos ferramentas de comércio, mas podemos esboçar como seria o futuro create_gift_order:

server.registerTool(
  "create_gift_order",
  {
    title: "Criação de pedido de presente",
    description:
      "Use somente após o consentimento explícito do usuário para comprar o presente escolhido. Cria um pedido no sistema e retorna o status.",
    inputSchema: {
      type: "object",
      properties: {
        giftId: {
          type: "string",
          description: "ID do presente que o usuário escolheu."
        },
        deliveryEmail: {
          type: "string",
          description: "E-mail para o qual o presente digital deve ser enviado."
        }
      },
      required: ["giftId", "deliveryEmail"]
    },
    annotations: {
      destructiveHint: true,
      openWorldHint: true
    }
  },
  async () => {
    /* ... */
  }
);

As anotações não substituem suas verificações de permissão no servidor; elas apenas ajudam o ChatGPT a organizar o UX: pedir confirmação, mostrar avisos e não executar essas ferramentas “às escondidas”.

7. Metadados do App e dois níveis de descoberta

As ferramentas são metade da história. A outra metade é: como o usuário encontra e inicia o seu App.

No ecossistema do ChatGPT existem dois níveis-chave de discovery.

O primeiro é o in‑conversation discovery. Quando o usuário escreve algo no chat (mesmo sem mencionar explicitamente o App), o modelo observa:

  • o texto da mensagem e o histórico do diálogo;
  • as descrições dos apps disponíveis e de suas ferramentas;
  • menções de marca, tema e palavras‑chave.

Com base nisso, ele decide se vale a pena sugerir algum App e, se sim, qual e com qual fluxo. Aqui são especialmente importantes as descrições das ferramentas e do próprio App. Se nelas houver “gatilhos” como “seleção de presentes”, “ideia de presente”, “orçamento de presente”, a chance de o modelo escolher o seu App aumenta bastante.

O segundo nível é o discovery global: catálogo e launcher. Aí entra o humano: ele escolhe o App pelo nome, ícone, descrição curta e tags. É importante que você explique de maneira honesta e clara o que o aplicativo faz, para quem é e qual seu valor principal.

Podemos resumir em uma pequena tabela:

Camada O que o modelo/usuário vê O que importa nos metadados
In‑conversation Texto do diálogo, descrições dos tools e do App Formulações de gatilho, nomes orientados à ação, restrições
Catálogo/launcher Nome, ícone, descrição curta/longa, tags Posicionamento claro, proposta de valor compreensível

Para o GiftGenius, podemos formular, por exemplo:

  • Nome: GiftGenius — seleção de presentes em 60 segundos.
  • Descrição curta: Reúne o perfil do destinatário e sugere 5–7 ideias de presentes com possibilidade de compra instantânea dentro do ChatGPT.
  • Descrição para in‑conversation: Use este aplicativo quando o usuário pedir ajuda para escolher um presente, não souber o que dar, informar orçamento, interesses do destinatário ou ocasião.

É altamente desejável sincronizar essas formulações com o que você já escreveu no system‑prompt e nas descrições da ferramenta recommend_gifts. Assim o modelo vê um quadro coeso, e não um conjunto de textos contraditórios.

8. Como o roteamento funciona “na cabeça” do ChatGPT

Vamos juntar tudo e observar um caminho típico de solicitação — sem entrar no protocolo MCP; isso virá nos próximos módulos.

Suponha que o usuário escreva:

“Ajude a pensar em um presente para meu irmão, ele adora futebol e jogos de tabuleiro, orçamento até US$ 50.”

Algoritmo grosseiramente simplificado:

  1. O modelo analisa a mensagem e o histórico. Vê palavras como “presente”, “irmão”, “futebol”, “jogos de tabuleiro”, “orçamento 50”.
  2. Compara isso com as descrições dos Apps disponíveis e suas ferramentas. Para o GiftGenius, as descrições contêm explicitamente “seleção de presentes por interesses e orçamento”, portanto a probabilidade de o App ser relevante é alta.
  3. Se o App ainda não estiver ativo nesta sessão, o modelo forma uma réplica‑anúncio: “Posso abrir o aplicativo GiftGenius, que ajuda a selecionar presentes pelos seus parâmetros. Abrir?” — isso foi previsto nas instruções de UX.
  4. Após o consentimento do usuário, o modelo escolhe dentro do App a ferramenta recommend_gifts, porque é a cuja descrição melhor corresponde à intenção atual. Aqui o nome, a description e a estrutura do inputSchema funcionam como sinais de entrada.
  5. O modelo preenche os argumentos da ferramenta com base no pedido: primeiro (se necessário) chama profile_to_segments para transformar “irmão, gosta de futebol e jogos de tabuleiro” nos segmentos ["football_fan", "board_games"]; em seguida chama recommend_gifts com segments, budget: {min: 0, max: 50, currency: "USD"}, locale, occasion: "birthday".
  6. O servidor MCP executa a ferramenta, forma um structured output com items e meta e o retorna.
  7. O modelo lê o JSON que você descreveu no outputSchema e compõe a resposta: explica o que encontrou, por que exatamente esses presentes e oferece follow‑ups (“quer restringir por categoria?”, “mostrar semelhantes a este presente?” ou “finalizar a compra deste presente?”).

Aqui está um fluxograma simples desse processo:

flowchart TD
  A[User: pedido sobre presente] --> B[ChatGPT analisa o contexto]
  B --> C[Comparação com metadados do App e tools]
  C -->|relevante| D[Anúncio do GiftGenius]
  D -->|usuário concorda| E["Chamada recommend_gifts (+ profile_to_segments)"]
  E --> F[Servidor MCP do GiftGenius]
  F --> G[Resultado JSON com items/meta]
  G --> H[O modelo formula a resposta e o follow-up]

Quanto melhor você descreveu as ferramentas e os use cases, menor a aleatoriedade aqui e mais estável o roteamento.

Insight: Tool Call SEO

No ecossistema de Apps, em breve você terá não só competição pela atenção das pessoas no catálogo, mas também competição pela atenção do próprio modelo. Para um mesmo pedido de usuário, o ChatGPT pode chamar uma dezena de aplicativos diferentes, e a escolha ocorrerá não em quem tem o melhor design de apresentação, mas na “página de resultados de busca” dentro da cabeça do modelo. Essa camada invisível parece cada vez mais com SEO, só que em vez de páginas você tem tools e servidores MCP.

O modelo basicamente ranqueia candidatos: primeiro no nível do App, depois no nível das ferramentas. Ele observa nome, descriptions, esquemas, anotações e os confronta com as formulações do pedido. Se na descrição de recommend_gifts consta “seleção de presentes por orçamento e interesses do destinatário”, e no pedido aparece “selecione um presente para um amigo gamer por US$ 50”, essa ferramenta tem mais chances de “ficar no topo” do que um search genérico com a descrição “trabalho com presentes”.

Daí surge a ideia prática de Tool Call SEO: tratar nomes, descriptions, valores de enum e metadados como palavras‑chave e snippets. Você não está apenas descrevendo um contrato para desenvolvedores — está otimizando para o tráfego real de pedidos do seu golden prompt set. Formulações genéricas demais, áreas sobrepostas entre vários tools, God tools sem um nicho claro — tudo isso reduz o “CTR” do seu App na cabeça do modelo.

9. Um pequeno exercício prático

Tente mentalmente (ou no seu repositório) fazer o seguinte.

Primeiro, escolha um dos fluxos principais do GiftGenius — por exemplo, “Selecionar um presente para um colega de trabalho com orçamento limitado”.

Formule para ele:

  1. Qual ferramenta separada é necessária para esse fluxo: é o recommend_gifts puro, ou você precisa de uma ferramenta especializada para o caso B2B, ou, por exemplo, basta usar o similar_gifts após o recommend_gifts para variações?
  2. Quais campos são realmente necessários no esquema de entrada do recommend_gifts. Quais campos podem ser perguntados ao usuário em separado (via follow‑up), em vez de fazer o modelo adivinhar.
  3. Como deve ser o outputSchema, para que o modelo possa explicar honestamente a escolha e sugerir próximos passos (por exemplo, mudar para modo B2B, mostrar apenas presentes digitais, restringir por faixa de preço).

Depois, olhe para o seu golden prompt set da aula anterior e verifique:

  • se para cada solicitação de referência há uma ferramenta óbvia (recommend_gifts, get_gift, similar_gifts etc.);
  • se não aconteceu de duas ferramentas “servirem” igualmente a um mesmo pedido (overlapping tools);
  • se é preciso reforçar as descrições ou renomear algum tool para o modelo confundir menos.

Esse é exatamente o processo que você repetirá antes de cada mudança séria de prompt, esquemas ou lógica — basicamente, um mini‑eval da qualidade de discovery.

Resumindo tudo acima em um checklist, nesta etapa você precisa:

  • dividir honestamente os fluxos em 2–4 ferramentas com sentido;
  • descrever cuidadosamente inputSchema/outputSchema com exemplos e enums;
  • organizar os nomes, descriptions e anotações;
  • sincronizar isso com o system‑prompt e os metadados do App.

Nos próximos módulos veremos como tudo isso funciona via MCP e como diagnosticar comportamentos estranhos de discovery/roteamento.

10. Erros comuns ao projetar tools e metadados

Erro №1: “Descrevemos tudo no system‑prompt, as ferramentas vão se virar”.
Se você descreveu muito bem o papel do App, os limites de responsabilidade e o comportamento de UX, mas deixou ferramentas com nomes tool1, search, do_stuff e esquemas sem descrições, o modelo simplesmente não conseguirá ligar seu texto bonito a chamadas reais. Para o ChatGPT, as ferramentas são a interface principal; sem metadados bem feitos, nenhum system‑prompt salva.

Erro №2: God Tool, que faz tudo.
A vontade de “otimizar” e criar uma única função com parâmetro mode é compreensível, mas leva a JSON Schemas monstruosos, confusão nas descrições e piora no roteamento. O modelo começa a adivinhar qual modo usar, e você a manter um enorme switch no servidor. Melhor algumas ferramentas claras para passos específicos do fluxo do que uma “faz tudo”.

Erro №3: Esquema de entrada lotado de campos “por via das dúvidas”.
Com frequência, desenvolvedores tentam passar pelo inputSchema todos os parâmetros que talvez sejam úteis, além de alguns campos internos. No fim, o modelo tenta adivinhar o que não tem como saber (por exemplo, tenantId), e você se surpreende com valores estranhos. O Input Schema deve conter apenas o que o modelo realmente pode inferir do diálogo ou esclarecer com uma pergunta. Detalhes internos, adicione no servidor.

Erro №4: Dados de saída “mudos”, sem metainformação.
Retornar apenas um array de objetos é tentador. Mas assim você priva o modelo de entender por que esses resultados apareceram. Sem campos como score, reason, searchCriteria, totalCandidates, fica mais difícil construir explicações honestas e follow‑ups. Adicionar um pequeno invólucro meta com critérios de busca e conselhos frequentemente melhora drasticamente a qualidade da resposta.

Erro №5: Vago nas descrições: “Trabalho com presentes”, “Busca de cursos”, “Processamento de dados”.
Essas descrições são ruins porque não dão ao modelo nem gatilhos, nem restrições. Ele não sabe quando exatamente chamar a ferramenta e em que área ela se aplica. Uma boa descrição começa com “Use esta ferramenta quando…” e contém cenários concretos e proibições do tipo “Não use para…”. Ideal se essas formulações coincidirem com os pedidos do seu golden prompt set.

Erro №6: Ignorar anotações e misturar ações read‑only e ações que mudam estado.
Se você não marca as ferramentas que apenas leem dados (readOnlyHint) e aquelas que realizam ações (destructiveHint, openWorldHint), o modelo não consegue organizar o UX correto de confirmações. O resultado é ou “Tem certeza?” em cada passo, ou, ao contrário, compras e alterações silenciosas sem consentimento. As anotações são uma forma barata e eficaz de sinalizar a importância da operação ao modelo.

Erro №7: Metadados do App para o catálogo e metadados para in‑conversation vivem em universos diferentes.
Acontece de a descrição curta no catálogo ser escrita por um marketeiro (“Revolucionário assistente de IA que muda sua vida”), enquanto as descriptions dos tools e o system‑prompt — por um desenvolvedor (“seleção de presentes por orçamento”). Como resultado, no catálogo não fica claro sobre o que é o App, e o modelo no chat não consegue relacionar pedidos do tipo “o que é este serviço?” com as capacidades reais do App. Escreva os metadados como uma especificação única, e não como dois textos de marketing independentes.

1
Pesquisa/teste
Comportamento do ChatGPT App, nível 5, lição 4
Indisponível
Comportamento do ChatGPT App
Instruções para o modelo e comportamento do ChatGPT App
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION