1. Ferramenta do agente: o que ela realmente é
Nos módulos anteriores você já viu ferramentas pelo lado do Apps SDK — como “funções de back-end” às quais o ChatGPT acessa por meio do seu App. Agora vamos mudar o ângulo: olhar para as ferramentas pelos olhos de um agente no Agents SDK e entender como ele escolhe o que chamar e o que fazer com erros.
Em um back-end comum, você costuma pensar em categorias como “endpoint”, “método do controlador”, “função de serviço”. No mundo de agentes, a unidade básica de ação passa a ser a ferramenta (tool). As tools do agente e as mcp-tools são diferentes, embora se sobreponham.
Falando estritamente: uma ferramenta no contexto do ChatGPT Agents SDK é a descrição de uma função que o modelo pode solicitar que seja executada. O modelo não executa código por conta própria; ele gera uma solicitação estruturada (geralmente JSON), e o runtime (seu código, o servidor MCP ou o Agents SDK) executa essa operação e retorna o resultado.
No ecossistema do ChatGPT Agents SDK, uma ferramenta é descrita por configuração: ela tem name, description e parameters (JSON Schema dos argumentos). O agente vê esse conjunto de ferramentas, mantém no próprio contexto e, no processo de raciocínio, decide qual tool chamar e com quais argumentos.
O agente (ou o ChatGPT como host) recebe essa lista, “memoriza” no próprio contexto e, no processo de raciocínio (reasoning), decide: para qual solicitação do usuário chamar qual ferramenta e com quais argumentos. É por isso que as especificações repetem o mantra “tools are a contract” — ferramentas são um contrato entre o modelo e seu código, e não apenas “uma função em Python/TS”.
Podemos fazer uma analogia com uma API clássica. A rota /api/gifts/search é puramente sintaxe: URL, método, formato do corpo. Já a tool search_gifts é semântica: “buscar presentes por perfil e orçamento”. A descrição da ferramenta é como um prompt, só que estruturado e voltado para a LLM, e não para humanos.
2. Tipos de ferramentas: o que exatamente um agente LLM pode fazer
Para não se perder no caos de “funções que fazem tudo”, é útil olhar para as ferramentas como algumas categorias típicas. Não é uma tipagem formal do SDK, mas um modo de pensar arquitetural que ajuda muito.
No nosso back-end, agentes LLM geralmente têm três fontes de ferramentas.
- Ferramentas de negócios locais. É o que vive no seu back-end: trabalho com BD, lógica de domínio (filtragem, recomendações, scoring). Por exemplo, para o GiftGenius, podemos ter ferramentas que buscam produtos na tabela própria do PostgreSQL ou calculam um scoring personalizado de “o quanto este presente agrada a essa pessoa”.
- Ferramentas MCP. Aqui o servidor MCP atua como provedor de ferramentas (tools): registra funções, recursos e prompts e os entrega ao cliente (ChatGPT, agente LLM). Ferramentas via MCP podem chamar APIs externas, trabalhar com arquivos ou fornecer modelos de prompt.
- Ferramentas de integração. Tudo que conecta você ao resto do mundo: ACP/commerce (criação de pedido e checkout), envio de e-mails, webhooks, gravação no CRM. Essas ferramentas (tools) costumam ser mais perigosas porque alteram o estado de sistemas externos, exigindo rigor extra em segurança e idempotência.
Há outra classificação útil — pelo tipo de ação. Em pesquisas sobre ferramentas LLM, geralmente destacam: ferramentas de obtenção de dados (busca, RAG, get_*), ferramentas de ações com efeitos colaterais (create_order, send_email), puramente computacionais (calculate_loan) e sistêmicas/de controle (handoff_to_human, finish_task).
Para fixar, é útil ver uma pequena tabela.
| Categoria | Exemplo no GiftGenius | Efeito colateral | Risco |
|---|---|---|---|
| Data Retrieval | |
Não | Baixo |
| Action / Mutating | |
Sim | Alto |
| Computation | |
Não | Médio |
| System / Control | |
Não | Lógico |
Do ponto de vista arquitetural, o mais importante: ferramentas read‑only devem ser numerosas e baratas, e as mutantes — raras, extremamente cuidadosas, com logs, idempotência e, muitas vezes, confirmação do usuário.
A seguir, falaremos principalmente sobre ferramentas de obtenção de dados e ferramentas de ação, porque é nelas que se baseia a lógica do GiftGenius.
3. JSON Schema como contrato entre o modelo e seu código
Agora vamos aprofundar em como a ferramenta é descrita. No ChatGPT Agents SDK (como no Apps SDK), o formato padrão para descrever os parâmetros de uma ferramenta é o JSON Schema: você descreve o tipo object, suas properties, tipos de campos, campos obrigatórios, restrições etc.
Importante entender: JSON Schema aqui não é apenas (nem principalmente) sobre validação. É parte do prompt para o modelo. Nos guias oficiais da OpenAI sobre design de ferramentas (tools), é dito explicitamente que a qualidade do trabalho do agente depende muito de quão detalhados e inequívocos são os campos, seus nomes e comentários.
Vejamos um exemplo para o GiftGenius, que já apareceu no plano do curso.
{
"name": "search_gifts",
"description": "Encontra presentes por tipo de destinatário, interesses e orçamento.",
"parameters": {
"type": "object",
"properties": {
"recipient_type": {
"type": "string",
"description": "Quem é o destinatário do presente (por exemplo, 'homem', 'mulher', 'criança')."
},
"interests": {
"type": "array",
"items": { "type": "string" },
"description": "Interesses principais (esporte, livros, tecnologia etc.)."
},
"budget": {
"type": "number",
"description": "Orçamento máximo na moeda do usuário."
}
},
"required": ["recipient_type", "budget"]
}
}
Há alguns pontos importantes aqui.
- Primeiro, name e description. Para o modelo, isto é o principal sinal de quando usar essa ferramenta. A documentação sobre roteamento semântico enfatiza que a descrição da ferramenta é, de fato, a API para o modelo: se você a nomear func1 e escrever “faz algo útil”, o modelo honestamente não entenderá quando chamá-la. Se você escrever search_gifts e adicionar uma descrição clara, a escolha fica mais trivial.
- Segundo, parameters. Os nomes dos campos e suas descrições são extremamente importantes. Para a LLM, recipient_type é muito mais claro do que type. Uma boa descrição como “Quem é o destinatário do presente…” sugere ao modelo que ali deve entrar o tipo de destinatário, e não, por exemplo, o tipo de embalagem.
- Terceiro, required. Não é apenas validação do seu lado, mas também uma dica para o modelo: ele vai tentar preencher os campos obrigatórios, e pular os opcionais se o contexto não deixar claro. Isso reduz a quantidade de chamadas de tool “vazias” ou incorretas.
Os guias oficiais do Apps SDK recomendam: crie ferramentas enxutas, com uma única responsabilidade, nomes e descrições claras, e evite ferramentas “faça tudo sobre presentes”, que tentam unificar tarefas diferentes.
4. Projetando ferramentas do GiftGenius: do esquema ao código
Vamos pegar o nosso GiftGenius e adicionar dois instrumentos-chave do agente LLM, que serão necessários em quase todos os cenários:
- suggest_gifts(profile, budget) — retorna uma lista de candidatos;
- get_gift_details(gift_id) — revela detalhes sobre um presente específico.
Nossas suggest_gifts e get_gift_details são um exemplo típico de ferramentas de negócios locais da classificação anterior, principalmente da categoria Data Retrieval.
Esquema para suggest_gifts
Comecemos com um JSON Schema puro e depois mostramos como isso pode parecer em TypeScript no back-end/runtime do agente.
{
"name": "suggest_gifts",
"description": "Seleciona uma lista de presentes com base no perfil do destinatário e no orçamento.",
"parameters": {
"type": "object",
"properties": {
"age": {
"type": "integer",
"minimum": 0,
"maximum": 120,
"description": "Idade do destinatário em anos."
},
"relationship": {
"type": "string",
"enum": ["friend", "coworker", "partner", "family"],
"description": "Relação com o destinatário: amigo, colega, parceiro, família."
},
"interests": {
"type": "array",
"items": { "type": "string" },
"description": "Interesses do destinatário (esporte, livros, tecnologia etc.)."
},
"budget": {
"type": "number",
"minimum": 1,
"description": "Orçamento máximo na moeda do usuário."
}
},
"required": ["budget"]
}
}
Aqui usamos enum para relationship, para que o modelo não invente strings arbitrárias como "mau colega" e não as envie adiante no código. Esse design cuidadoso do esquema ajuda tanto o modelo (que vê as opções permitidas) quanto o desenvolvedor (menos surpresas em runtime).
Agora vamos supor que temos um servidor MCP em Node.js com um McpServer hipotético. O registro da ferramenta pode ser assim:
// exemplo simplificado de registro de ferramenta no servidor MCP
server.registerTool(
{
name: "suggest_gifts",
description: "Seleciona presentes por perfil e orçamento.",
inputSchema: suggestGiftsSchema
},
async (input, ctx) => {
const gifts = await findGiftsInDb(input, ctx.userLocale);
return { items: gifts }; // JSON que o agente verá depois
}
);
O código está bastante simplificado, mas a lógica é clara: em um lugar — a descrição do contrato (nome, descrição, esquema), em outro — a implementação.
Esquema para get_gift_details
Segunda ferramenta, necessária em praticamente qualquer vitrine:
{
"name": "get_gift_details",
"description": "Obtém informações completas sobre um presente pelo seu identificador.",
"parameters": {
"type": "object",
"properties": {
"gift_id": {
"type": "string",
"description": "UUID do presente no banco do GiftGenius."
}
},
"required": ["gift_id"]
}
}
E um registro análogo:
server.registerTool(
{
name: "get_gift_details",
description: "Retorna informações detalhadas sobre um presente.",
inputSchema: getGiftDetailsSchema
},
async ({ gift_id }) => {
const gift = await db.gifts.findById(gift_id);
if (!gift) return { notFound: true };
return { gift };
}
);
Note que aqui já mostramos que a ferramenta pode retornar notFound: true. Estes são os embriões de erros semânticos (erros de negócio), sobre os quais falaremos a seguir. O agente poderá ver “presente não encontrado” e decidir o que fazer: por exemplo, tentar outro id ou sugerir ao usuário escolher outro item.
5. Como o agente escolhe qual ferramenta chamar
Agora vem a parte mais interessante: roteamento. Em um aplicativo web tradicional, o roteamento é rígido: URL → controlador específico. No mundo do ChatGPT Apps e de agentes, a escolha da ferramenta é semântica e probabilística.
O ciclo de alto nível pode ser ilustrado assim:
flowchart TD
U[User message] --> M["Modelo (agente)"]
M -->|análise da solicitação| C{Precisa de tool?}
C -->|não| T[Resposta em texto]
C -->|sim| S[Escolha da ferramenta]
S --> K[Formação do JSON de argumentos]
K --> R[Execução da ferramenta]
R --> M2[Modelo vê o resultado]
M2 --> T2[Resposta final ou próximo passo]
Em cada etapa, o agente vê algumas coisas:
- Primeiro, instruções de sistema (papel do agente, restrições);
- Segundo, o histórico do diálogo;
- E por fim, a lista de ferramentas (tools) com seus name, description, inputSchema.
Quando chega uma nova mensagem do usuário, o modelo compara o sentido da solicitação com as descrições das ferramentas (correspondência semântica). Se a solicitação for “selecione um presente para um amigo até 50 dólares”, a descrição de suggest_gifts soa muito mais relevante do que get_gift_details, e o agente provavelmente escolherá a primeira.
Os guias oficiais destacam dois pontos que influenciam muito a qualidade do roteamento.
- Primeiro, evite ferramentas com significado sobreposto: se você tem search_gifts e find_gifts, descritas de forma semelhante, o modelo vai se confundir.
- Segundo, tente seguir o princípio da responsabilidade única para a ferramenta: uma tool — uma tarefa clara, e não “selecionar presentes e criar pedido e enviar e-mail”.
Dentro de diferentes agentes LLM há mecanismos para controlar o modo de escolha de ferramentas: por exemplo, “auto” (o modelo decide se precisa de ferramenta), “required” (obrigatório chamar uma tool), “none” (tools desativadas). Isso ajuda em workflows complexos (cenários de vários passos), quando, digamos, em certo passo você quer forçar a chamada de suggest_gifts, em vez de permitir que o modelo apenas converse.
Exemplo de roteamento semântico no GiftGenius
Suponha que nosso agente tenha pelo menos duas ferramentas: suggest_gifts e get_gift_details.
- O usuário escreve: “Escolha um presente para um colega de até 30 dólares, ele gosta de jogos de tabuleiro”.
- O agente vê que a solicitação contém o objetivo “selecionar presente”, informação de orçamento e interesses. A descrição de suggest_gifts se encaixa perfeitamente — chamamos essa ferramenta.
- A ferramenta retorna uma lista de cinco presentes com seus ids, nomes e uma breve descrição.
- Depois o usuário escreve: “Conte mais sobre a terceira opção”. O agente associa “terceira opção” ao id do resultado anterior e, agora, por sentido, a ferramenta adequada é get_gift_details — ela é chamada.
É importante notar: em nenhum lugar do código você escreveu explicitamente “se a solicitação contiver a palavra ‘selecionar’, então chame suggest_gifts”. Quem cuida disso é o próprio modelo com base nas descrições e no histórico do diálogo. Sua responsabilidade como desenvolvedor é fazer com que a escolha seja óbvia tanto para o modelo quanto para a pessoa.
6. Erros das ferramentas: não 500, e sim um sinal para o modelo
Lembre-se, em get_gift_details já mostramos notFound: true? Este é justamente um exemplo de erro de negócio, que o agente deve ver e tratar de maneira inteligente, em vez de receber um 500 cru.
Agora vamos à parte mais dolorosa. Em um REST‑API comum, algo caiu no fundo do back-end — retornamos 500 Internal Server Error, registramos o stack trace no log — e o usuário que se vire. No caso do agente, essa abordagem funciona mal.
Guias práticos e materiais sobre o Agents SDK recomendam tratar erros de ferramentas como eventos observáveis, não apenas quedas. Isso é frequentemente chamado de padrão “Error as Observation”.
Grosseiramente, você não deve “cair” sem explicação; deve retornar ao modelo uma resposta estruturada que explique o que deu errado, para que ele possa adaptar seu comportamento: reformular a solicitação, perguntar ao usuário, tentar outra ferramenta etc.
Os tipos de erros costumam ser divididos em três grupos.
- Erros de validação de argumentos. O modelo pode gerar parâmetros incorretos: omitir um campo obrigatório, passar string em vez de número, ficar fora dos limites permitidos. Aqui, seu esquema e validação devem ser usados não apenas para lançar exceções, mas para uma resposta significativa: por exemplo, retornar qual campo está incorreto e por quê.
- Erros de negócio. Situações esperadas, como “produto não encontrado”, “região indisponível”, “orçamento pequeno demais para este tipo de presente”. Do ponto de vista da API, também são erros, mas devem ser retornados em uma resposta normal — com um código e mensagem claros, e não como um crash.
- Erros de sistema. Timeouts de serviço externo, problemas de rede, falhas de banco. Aqui, ao agente geralmente basta uma mensagem cuidadosa e genérica como “serviço temporariamente indisponível, tente mais tarde”. Nada de stack traces, nomes de tabelas e outros detalhes que não servem ao modelo e podem ser perigosos do ponto de vista de segurança.
Os materiais oficiais do Agents SDK chegam a propor um mecanismo especial failure_error_function, permitindo formar cuidadosamente o texto do erro que o modelo verá, em vez de simplesmente lançar a exceção para cima na pilha.
Estrutura de um erro “amigável”
Na ferramenta do agente (no seu back-end) você pode combinar que qualquer erro seja retornado, por exemplo, como um objeto:
type ToolError = {
code: string; // 'VALIDATION_ERROR', 'OUT_OF_STOCK', ...
message: string; // para o modelo
retryable: boolean;
};
E o resultado da ferramenta — como uma união:
type SuggestGiftsResult =
| {
ok: true;
items: GiftSummary[];
}
| {
ok: false;
error: ToolError;
};
O modelo (ou o runtime do agente) verá esse JSON e poderá decidir: se retryable: true, pode tentar novamente com pequenas mudanças; se o erro for de negócio e não retryable, melhor voltar ao usuário e explicar o que houve.
7. Exemplos: validação, erro de negócio e erro de sistema
Voltemos ao nosso back-end/ferramentas do agente e vejamos como implementar as mesmas ideias em código.
Erro de validação
Imagine que sua ferramenta suggest_gifts chegou, mas o modelo resolveu passar um orçamento negativo.
async function handleSuggestGifts(input: SuggestGiftsInput)
: Promise<SuggestGiftsResult> {
if (input.budget <= 0) {
return {
ok: false,
error: {
code: "VALIDATION_ERROR",
message: "budget deve ser um número positivo.",
retryable: false
}
};
}
const items = await findGiftsInDb(input);
return { ok: true, items };
}
Aqui deliberadamente não lançamos exceção; retornamos um erro estruturado. O agente pode repensar a solicitação: talvez ele conclua que confundiu a moeda, pergunte ao usuário ou apenas admita que não consegue selecionar um presente com esse orçamento.
Erro de negócio
Agora um exemplo com get_gift_details. Pode simplesmente não existir um presente com o id informado.
async function handleGetGiftDetails(input: { gift_id: string }) {
const gift = await db.gifts.findById(input.gift_id);
if (!gift) {
return {
ok: false,
error: {
code: "GIFT_NOT_FOUND",
message: "Presente com esse identificador não foi encontrado.",
retryable: false
}
};
}
return { ok: true, gift };
}
Na resposta do modelo, podemos esperar algo como: “Parece que o presente escolhido não está mais disponível. Posso sugerir algumas alternativas de categoria semelhante?”. Para isso, o agente não precisa ver erros SQL nem stack traces — apenas um code e message compreensíveis.
Erro de sistema
Por fim, um exemplo de erro de sistema. Suponha que sua ferramenta acesse uma API externa de entrega, que às vezes “cai”.
async function handleEstimateDelivery(input: EstimateDeliveryInput) {
try {
const eta = await callDeliveryApi(input);
return { ok: true, eta_days: eta };
} catch (e) {
return {
ok: false,
error: {
code: "DELIVERY_SERVICE_UNAVAILABLE",
message: "Serviço de entrega temporariamente indisponível.",
retryable: true
}
};
}
}
O agente pode decidir: “Parece que o serviço de entrega está indisponível agora. Vou mostrar os presentes mesmo assim, mas o tempo de entrega pode variar. Deseja continuar?”.
8. Segurança e idempotência das ferramentas (visão rápida do lado de tools)
Uma conversa completa sobre segurança e permissões virá em outro tópico, mas as ferramentas do agente estão tão ligadas a isso que vale um breve comentário.
Primeiro, é preciso separar ferramentas de leitura e de escrita. Nas descrições, esquemas e permissões, indique explicitamente quais tools apenas leem dados e são absolutamente seguras, e quais debitam dinheiro, alteram pedidos etc. Documentação e fóruns de cenários com agentes falam claramente sobre a separação entre ferramentas ReadOnly e Mutating (tools).
Segundo, para ferramentas mutantes é preciso pensar em idempotência. O agente ou o cliente MCP pode repetir a chamada (por exemplo, devido a erro de rede), e você não quer que create_order crie dois pedidos em vez de um. Padrões típicos aqui:
- idempotency‑key, passada como argumento da ferramenta;
- verificação da existência da operação antes de executá-la;
- separar passos em “criar rascunho de pedido” e “confirmar pedido”.
Tudo isso está intimamente ligado a como você projeta o contrato da ferramenta: se no JSON Schema não houver um campo para idempotency‑key, adicionar idempotência depois será bem mais doloroso.
9. Um pequeno olhar sobre o Agents SDK: como isso aparece no runtime do agente
Esta seção é um pequeno overview para quem vai trabalhar com um Agents SDK orientado a TypeScript. Embora a maior parte do curso trate de MCP, é útil entender como ferramentas semelhantes são vistas pelo Agents SDK e como é uma tool típica no runtime.
Na documentação oficial, geralmente descreve-se algo como uma “ferramenta funcional”: qualquer função, descrita via um objeto de configuração (ou helper como tool(...)) e tipada, pode ser automaticamente transformada em ferramenta, para a qual o SDK vai gerar o JSON Schema e a descrição.
Em nível conceitual é o mesmo que já discutimos: o nome da função, seus parâmetros e o comentário/description fazem o papel de nome, esquema e descrição da ferramenta. A diferença é que o SDK e/ou uma biblioteca auxiliar de esquemas (por exemplo, Zod ou JSON Schema) faz a maior parte do trabalho “mecânico” por você.
Exemplo hipotético (pseudo-TypeScript, simplificado):
type Gift = {
id: string;
title: string;
// ...
};
const suggestGifts = tool({
name: "suggest_gifts",
description: "Seleciona uma lista de presentes por tipo de destinatário e orçamento.",
parameters: {
type: "object",
properties: {
recipient_type: {
type: "string",
description: "Quem é o destinatário do presente (por exemplo, 'homem', 'mulher', 'criança')."
},
budget: {
type: "number",
description: "Orçamento máximo na moeda do usuário."
}
},
required: ["recipient_type", "budget"]
}
}, async (args: { recipient_type: string; budget: number }): Promise<Gift[]> => {
// Aqui dentro — sua lógica de domínio
return findGifts(args.recipient_type, args.budget);
});
O SDK (ou seu helper tool) vai construir o JSON Schema a partir do objeto parameters e passá-lo ao agente, e o runtime cuidará da validação e do marshaling dos argumentos de ida e volta. Conceitualmente, é exatamente o que você fazia manualmente no servidor MCP em TypeScript, só que agora a ferramenta está “plugada” diretamente no runtime do agente.
O importante aqui não é decorar a sintaxe específica do helper tool, mas captar a ideia: tipagem de qualidade + description/comentários claros = ferramenta de qualidade.
Se juntarmos tudo: uma boa ferramenta de agente é uma função enxuta, claramente descrita, com um JSON Schema bem pensado, descrição compreensível para o modelo e tratamento de erros cuidadoso. O roteamento semântico só funciona bem se as ferramentas não se sobrepõem em significado. E operações mutantes devem ser seguras e idempotentes, caso contrário o agente em produção vira rapidamente uma fonte de surpresas.
10. Erros típicos ao projetar ferramentas de agente
Erro nº 1: ferramentas “do_everything” amplas demais.
Às vezes dá muita vontade de enfiar tudo em uma só ferramenta manage_gifts, que busca presentes, mostra detalhes, cria pedidos e envia e-mails. Para o modelo isso fica difícil: a descrição se torna vaga, o roteamento semântico degrada e o agente passa a chamar essa ferramenta “por via das dúvidas” mesmo quando só é preciso uma busca simples. Melhor dividir tarefas em ferramentas separadas, com uma responsabilidade bem compreendida.
Erro nº 2: ferramentas com significado sobreposto.
Se você tem search_gifts e find_gifts, ambas “buscando presentes por interesses”, o modelo vai escolher entre elas aleatoriamente. O resultado é um comportamento instável: solicitações idênticas às vezes vão para uma tool, às vezes para outra. Procure fazer com que cada nome e descrição ocupem um “nicho” único no espaço semântico.
Erro nº 3: descrições ruins ou campos de esquema ausentes.
O nome func1, a descrição “Does something” e o parâmetro data: string — é o jeito clássico de deixar o agente “burro”. O modelo não é telepata e não lê seu código-fonte. Ele se apoia em description, properties e seus description no esquema. Se você não explicar o que é recipient_type, o modelo vai chutar e errar.
Erro nº 4: focar só no happy path, ignorando erros.
Muitas implementações assumem: “Os argumentos sempre serão corretos e o serviço estará disponível”. No mundo real, o modelo gera parâmetros errados, serviços externos caem e o banco às vezes diz “timeout”. Se você não pensar em formatos de erro e não retornar ao agente uma mensagem significativa, ele não conseguirá ajustar o comportamento e vai ou cair silenciosamente, ou alucinar.
Erro nº 5: lançar um 500 cru e stack trace para a LLM.
Em REST‑API, estamos acostumados a logar o stack trace completo para depurar mais rápido. No contexto do agente, um stack trace enviado ao modelo é, ao mesmo tempo, inútil (o modelo não sabe o que é SQLException na sua biblioteca específica) e potencialmente perigoso (detalhes de implementação desnecessários e, possivelmente, informação confidencial). É muito mais útil capturar a exceção, registrar os detalhes no log e enviar ao modelo um code e message bem formatados.
Erro nº 6: falta de idempotência em ferramentas mutantes.
A ferramenta create_order sem idempotency‑key é um convite a pedidos duplicados, especialmente em condições de falhas de rede e retries automáticos. Se seu agente opera em cenário comercial, ferramentas ligadas a dinheiro devem ser projetadas de modo que chamadas repetidas não resultem em cobranças adicionais ou duplicatas.
Erro nº 7: guardar segredos e detalhes técnicos no esquema ou descrição.
Às vezes o desenvolvedor, por hábito, escreve no description: “Internamente chama o serviço X em https://internal-api.example.com”. O modelo não precisa dessa informação, o usuário — menos ainda. Esquemas e descrições são parte do prompt, vivem no contexto do modelo, e não é adequado colocar URLs de serviços internos, nomes de tabelas privadas e muito menos segredos.
Erro nº 8: passar tudo para dentro das ferramentas, em vez de um conjunto de campos pensado.
É tentador a ideia de “vamos passar todo o prompt do usuário como string e nos viramos lá dentro”. Assim você perde o benefício da estruturação via JSON Schema: o modelo deixa de entender quais partes da solicitação são importantes para a lógica, e você perde validação e previsibilidade. É melhor extrair da solicitação os campos explícitos (budget, interests, user_location) e descrevê-los como parte do contrato da ferramenta.
GO TO FULL VERSION