Seleção do modelo de código Claude: valores padrão, alternância e custo

Seleção do modelo de código Claude: valores padrão, alternância e custo

Para a seleção do modelo de código Claude, utilize o Haiku para alterações pequenas e testáveis, o Sonnet para implementações de rotina e o Opus para trabalhos que envolvam maior ambiguidade ou exijam mais raciocínio. Atualmente, a Anthropic recomenda o Opus 5.5 como um ponto de partida geral; sua tarefa, carga de revisão e orçamento determinam se um modelo menor é a melhor opção.

Para alterar os modelos, abra /modelo. Imprensa Entrar para salvar uma configuração padrão, ou s para alterar apenas a sessão atual. Para uma única execução, use claude --modelo opus. Essas opções têm diferentes graus de persistência; portanto, decidir por quanto tempo a mudança deve durar é tão importante quanto escolher o modelo.

O trabalho de programação também envolve pesquisa, explicações, documentação e recursos criativos. O GlobalGPT reúne os principais modelos de IA e diversas ferramentas de IA em um único painel acessível, enquanto sua interface de linha de comando (CLI) conecta essas ferramentas ao terminal e aos fluxos de trabalho de desenvolvimento. Crie seu fluxo de trabalho com o GlobalGPT para manter essas tarefas relacionadas juntas à medida que você passa de uma ideia para um código funcional.

Qual modelo você deve usar no código Claude?

Comece pela natureza do trabalho. Uma função curta com resultados esperados bem definidos requer uma avaliação diferente daquela necessária para um bug intermitente que afeta vários serviços. A questão relevante é se o modelo pode produzir uma mudança aceitável por meio de revisões e iterações razoáveis.

Modelo atualPara que se destinaUma tarefa prática para começar
Claude Haiku 4.5Trabalho rápido e eficiente com um contrato restritoUma pequena refatoração, uma transformação repetitiva ou um caso de teste simples
Claude Soneto 5Um equilíbrio entre inteligência e rapidez para a programação no dia a diaUm recurso com padrões estabelecidos, uma correção de bug de rotina ou uma explicação do código
Claude Opus 5,5Raciocínio complexo e trabalho de codificação agênica mais demoradoUma falha ambígua, um compromisso arquitetônico ou uma mudança com restrições que se interagem
Claude Fable 5.1As investigações mais difíceis e mais longasUma escalada em que um trabalho difícil ainda supera um nível de esforço maior do Opus
Famílias de modelos atuais e adequação às tarefas, com base na documentação do Anthropic; as sugestões de tarefas são pontos de partida práticos.

Vale a pena avaliar o Haiku quando os erros são fáceis de detectar e a alteração é pequena. O Sonnet é uma opção sensata quando a implementação no dia a dia exige mais contexto e discernimento. O Opus merece ser considerado quando a compreensão do problema constitui uma parte substancial da tarefa. O Fable merece uma decisão à parte para trabalhos mais exigentes; ele ficou fora do nosso teste de codificação com os três modelos.

Esses são pontos de partida, não garantias automáticas de qualidade. Uma resposta mais barata pode acabar saindo cara se precisar de várias revisões ou de uma análise minuciosa. Por outro lado, um modelo maior pode agregar pouco a uma transformação simples que já atende às suas verificações. Para um uso mais amplo, além do Código Claude, comparar as famílias de modelos Claude.

Comparação atual de modelos da Anthropic com o Fable 5.1, o Opus 5.5, o Sonnet 5 e o Haiku 4.5.
Gama de modelos do Anthropic, consultada em 28 de setembro de 2026. A disponibilidade no Código Claude depende da sua operadora e da sua conta.

O visão geral oficial dos modelos apresenta janelas de contexto de 1 milhão de tokens para Fable 5.1, Opus 5.5 e Sonnet 5, e de 200 mil para o Haiku 4.5. Trata-se de especificações de API. Seu provedor do Claude Code, sua conta e sua configuração determinam as opções de contexto disponíveis em uma sessão. Uma janela ampla é útil para o contexto necessário; preenchê-la com material não relacionado ainda gera trabalho para o modelo.

Como alternar entre modelos em uma sessão

Durante uma sessão interativa, realizada /modelo para abrir o seletor de modelos. Selecione a linha do modelo e pressione s se essa for uma alteração pontual. Ao pressionar Entrar salva a seleção como sua configuração padrão. Digitando /soneto modelo Isso também salva diretamente nas versões atuais.

Escolha o comando de acordo com a duração da alteração

Comportamento do código Claude documentado, verificado em 28 de setembro de 2026
Seu objetivoO que fazerAs alterações nas configurações padrão foram salvas?
Alternar apenas esta sessão interativaAberto /modelo, selecione um modelo, pressione s.Não.
Salvar um modelo preferidoAberto /modelo e pressione Entrar, ou digite /soneto modelo.Sim, quando as configurações do usuário permitem gravação.
Inicie uma única sessão no OpusLançamento claude --modelo opus.Não.
Voltar ao padrão de tempo de execução da contaUso /modelo padrão.Limpa a substituição do modelo; o padrão definido pode depender das configurações da conta e da organização.
Verifique o modelo ativoExecutar /status.Não.

Configurações de projeto ou gerenciadas, substituições de ambiente e sessões retomadas podem afetar a próxima inicialização. Verifique o modelo ativo quando a reprodutibilidade for importante.

Fonte: Configuração do modelo de código Claude.

Em uma nova sessão do terminal, escolha o modelo na inicialização. Esses comandos também se aplicam quando o Claude Code é executado no terminal integrado do VS Code. Os exemplos selecionam uma versão explicitamente:

claude --model claude-opus-5-5
claude --model claude-sonnet-5

Execute o comando correspondente à sessão desejada; os exemplos são alternativas. Você pode abrir terminais diferentes com diferentes -modelo valores sem precisar alterar repetidamente um padrão salvo compartilhado. Use /status para verificar o modelo ativo.

Sobrenomes como opus e soneto podem ser atualizadas para versões mais recentes. Sua resolução também depende do provedor: a API Anthropic atualmente as mapeia para Opus 5.5 e Sonnet 5, enquanto os mapeamentos dos provedores de nuvem podem variar. Use um ID de modelo completo quando precisar de uma execução reproduzível e verifique o nome específico do provedor se o seu ambiente exigir isso.

O Opus 5.5 requer o Claude Code versão 2.1.280 ou posterior; o Sonnet 5 requer a versão 2.1.197 ou posterior. O documentação de configuração do modelo é a referência para aliases atuais, requisitos de versão e mapeamentos de provedores. Os comandos aqui apresentados são exemplos da documentação; nossa seção prática avalia o código gerado separadamente.

Documentação do código Claude explicando a seleção do modelo e o funcionamento das teclas Enter e s.
A tecla Enter salva o modelo como padrão; a tecla s altera apenas a sessão atual.

Como definir um modelo padrão

Para uma configuração padrão pessoal, selecione um modelo em /modelo e pressione Entrar, ou digite uma seleção como, por exemplo, /soneto modelo. O código Claude grava o modelo campo nas suas configurações de usuário quando esse arquivo estiver gravável. Abra uma nova sessão e verifique o modelo ativo para confirmar o resultado.

Uma preferência salva não substitui todas as outras configurações. Um parâmetro de inicialização, MODELO_ANTRÓPICO no shell, nas configurações do projeto ou gerenciadas, ou se um padrão da organização estiver configurado para substituir as escolhas do usuário, é possível selecionar outra opção na inicialização. Uma sessão retomada também pode manter o modelo a partir de seu histórico salvo. Verifique as informações de inicialização e /status antes de concluir que a escolha estava perdida.

/modelo padrão limpa a substituição do seu modelo e retorna ao padrão de tempo de execução para sua conta e configuração. A palavra padrão é um valor de redefinição, e não o nome de um modelo Claude específico. Ele não deve ser usado como um identificador reproduzível do modelo.

Para configurações avançadas, MODELO_ANTRÓPICO_PADRÃO oferece uma opção inicial alternativa a partir da versão v2.1.236. Ela aparece abaixo das seleções explícitas de inicialização, ambiente, configurações e organização, e ignora valores como haiku e opusplan. No caso de uma preferência pessoal comum, o seletor é mais fácil de verificar. Veja Configurações do código Claude quando há uma configuração compartilhada.

O que o Opusplan realmente faz

opusplan utiliza o Opus no modo de planejamento e o Sonnet na execução. O atrativo é simples: usar um modelo de raciocínio mais robusto para elaborar a abordagem e, em seguida, um modelo de codificação cotidiana para colocar esse plano em prática.

O Opusplan segue o modo de funcionamento

Modo de planejamentoOpusAplique essa abordagem.
ExecuçãoSonetoColoque o plano em prática.

Comportamento de roteamento documentado. As versões associadas a esses nomes de família dependem do seu provedor e da sua configuração.

Fonte: Configuração do modelo de código Claude

Essa é uma regra que depende do modo. Ela não analisa cada solicitação e escolhe automaticamente a família adequada mais econômica. Os mapeamentos do provedor e as restrições de acesso continuam valendo para os modelos subjacentes. Além disso, o nome não garante economia: o custo total depende do nível de planejamento, implementação, revisão e processamento de contexto que a tarefa exigir.

Pense nisso, para variar, como uma situação em que o projeto se beneficia de uma análise mais aprofundada e a implementação segue um plano claro. Para uma pequena correção, esse planejamento adicional pode ser desnecessário.

O que as duas tarefas de programação revelaram

Para oferecer uma visão concreta da seleção de modelos, testamos uma refatoração restrita do Unicode e uma correção do seletor de rotas com requisitos inter-relacionados. A diferença entre uma função correta e a entrega completa do que foi solicitado acabou se mostrando mais importante do que uma simples pontuação.

Como testamos os resultados da codificação

Em 28 de setembro de 2026, atribuímos aos modelos Claude Haiku 4,5, Claude Sonnet 5 e Claude Opus 5,5 as mesmas duas tarefas em JavaScript por meio do GlobalGPT. Cada modelo retornou código-fonte; inspecionamos o código e executamos verificações locais fixas. As instruções de troca de modelo do Claude, apresentadas em outra seção deste guia, foram extraídas de sua documentação oficial.

Cada solicitação tinha um limite de saída de 4.096 tokens, sem ferramentas nem histórico de conversas, e configurações padrão do modelo. Mantivemos a primeira resposta avaliável, incluindo respostas incompletas. Um erro de serviço na tarefa de roteamento do Sonnet teve direito a uma tentativa de repetição: sete solicitações geraram seis saídas.

Essas duas pequenas tarefas avaliam o código retornado e a integridade da entrega. Elas não avaliam a execução do agente do Claude Code, a exploração do repositório nem uma sessão de desenvolvimento completa. Os valores reais cobrados em dólares não foram informados. Uma única observação por tarefa não permite estabelecer uma classificação geral de velocidade ou confiabilidade.

Visualizar os IDs exatos dos modelos e as condições de avaliação

Identificadores solicitados: claude-haiku-4-5-20251001, claude-soneto-5, e claude-opus-5-5. Os testes locais foram realizados com o Node.js v24.19.0. As instruções se destinam ao Node.js 18 ou superior; o Node.js 18 em si não foi testado.

Oito grupos de comportamento foram definidos para a tarefa da lesma e doze para o seletor de rota. A conformidade com o formato e a entrega completa são relatadas separadamente. Uma verificação posterior de revisão de código é identificada separadamente e não altera essas contagens. Não editamos o código-fonte devolvido para que fosse aprovado.

Tarefa 1: Preservar o Unicode em uma refatoração de um slug pequeno

A função precisava manter as letras não latinas e os sinais combinatórios, normalizar os acentos decompostos e preservar seu comportamento ASCII existente.

Primeiros resultados retornados, com verificações de comportamento local corrigidas
ModeloVerificações de comportamentoFormato da respostaConcluir a entrega solicitada
Claude Haiku 4.58/8Erro: contêiner de MarkdownSim: função completa
Claude Soneto 58/8Passar: JSON brutoSim: função completa
Claude Opus 5,58/8Passar: JSON brutoSim: função completa

Resultado observado: Todas as três funções passaram os mesmos oito grupos. O Sonnet e o Opus também atenderam ao requisito de resposta em JSON bruto. O Haiku apresentou sua resposta em Markdown, e sua nota de revisão descreveu incorretamente o NFC como a decomposição de caracteres; seu código, porém, chamou corretamente o NFC.

Nessa refatoração específica, a atualização não melhorou o comportamento da função testada. Os requisitos de formatação e a precisão da explicação que a acompanha ainda precisavam ser revisados.

Veja o prompt compartilhado completo e o código de entrada
SYSTEM
You are completing a bounded JavaScript coding task. Return only the requested JSON object with complete source files and brief review notes. Do not claim to have edited files, run commands, or used tools. You have no tool access. Do not include hidden reasoning.

USER
Implement the following Node.js 18+ CommonJS function from its current source. Return complete replacement source for src/slugify.js. Do not add dependencies, imports, I/O, or other files.

Required behavior:
1. slugify(value) returns an empty string for every non-string input.
2. Normalize string input to Unicode NFC, then lowercase it using JavaScript toLowerCase().
3. Preserve Unicode letters, numbers, and combining marks. Replace each consecutive run of all other characters with one ASCII hyphen.
4. Trim leading and trailing hyphens. Preserve the CommonJS export { slugify }.
5. Existing ASCII behavior must continue to work. Examples: Hello, World! -> hello-world; two   words -> two-words; null -> empty string.
6. Additional examples: Café déjà vu -> café-déjà-vu; decomposed Cafe\u0301 -> café; 中文 测试 42 -> 中文-测试-42; **hi___there** -> hi-there; only punctuation or whitespace -> empty string.

Current src/slugify.js:
```javascript
function slugify(value) {
  if (typeof value !== "string") return "";
  return value
    .trim()
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-+|-+$/g, "");
}

module.exports = { slugify };


```

Return exactly one JSON object with this shape:
{"files":{"src/slugify.js":"complete JavaScript source as a JSON string"},"review_notes":["at most four brief implementation or assumption notes"]}
No Markdown wrapper. You are returning code for someone else to evaluate locally; do not say that tests passed or that you ran them.
Veja a resposta completa do Claude Haiku 4.5, tal como foi enviada
```json
{
  "files": {
    "src/slugify.js": "function slugify(value) {\n  if (typeof value !== \"string\") return \"\";\n  \n  // Normalize to NFC and lowercase\n  const normalized = value.normalize(\"NFC\").toLowerCase();\n  \n  // Replace consecutive runs of non-letter, non-number, non-combining-mark characters with a single hyphen\n  // Unicode letter categories: L* (Lu, Ll, Lt, Lm, Lo)\n  // Unicode number categories: N* (Nd, Nl, No)\n  // Unicode combining mark categories: M* (Mn, Mc, Me)\n  const slugged = normalized.replace(/[^\\p{L}\\p{N}\\p{M}]+/gu, \"-\");\n  \n  // Trim leading and trailing hyphens\n  return slugged.replace(/^-+|-+$/g, \"\");\n}\n\nmodule.exports = { slugify };"
  },
  "review_notes": [
    "Uses String.prototype.normalize(\"NFC\") to decompose composed characters like é into base+combining mark, then toLowerCase() applies to normalized string",
    "Unicode property escapes (\\p{L}, \\p{N}, \\p{M}) with /u flag preserve all Unicode letters, numbers, and combining marks while replacing other consecutive characters with single hyphens",
    "Existing ASCII behavior is preserved: punctuation and whitespace are replaced with hyphens, then leading/trailing hyphens are trimmed",
    "Non-string inputs return empty string as required; normalized decomposed characters (e.g., Cafe\\u0301) are handled correctly by NFC normalization"
  ]
}
```
Veja a resposta completa da Claude Sonnet 5, tal como foi enviada
{"files":{"src/slugify.js":"function slugify(value) {\n  if (typeof value !== \"string\") return \"\";\n  return value\n    .normalize(\"NFC\")\n    .toLowerCase()\n    .replace(/[^\\p{L}\\p{N}\\p{M}]+/gu, \"-\")\n    .replace(/^-+|-+$/g, \"\");\n}\n\nmodule.exports = { slugify };\n"},"review_notes":["Used Unicode property escapes (\\p{L}, \\p{N}, \\p{M}) with the u flag to preserve letters, numbers, and combining marks across scripts.","NFC normalization ensures decomposed sequences like Cafe + combining acute compose to café before lowercasing.","Runs of any other characters (punctuation, whitespace, symbols) collapse to a single hyphen, then leading/trailing hyphens are trimmed."]}
Veja a resposta completa do Claude Opus 5,5’ tal como foi enviada
{"files":{"src/slugify.js":"function slugify(value) {\n  if (typeof value !== \"string\") return \"\";\n  return value\n    .normalize(\"NFC\")\n    .toLowerCase()\n    .replace(/[^\\p{L}\\p{N}\\p{M}]+/gu, \"-\")\n    .replace(/^-+|-+$/g, \"\");\n}\n\nmodule.exports = { slugify };\n"},"review_notes":["The input is normalized to NFC before lowercasing, so decomposed input like Cafe\\u0301 composes to café.","A Unicode property regex with the u flag keeps letters (\\p{L}), numbers (\\p{N}) and combining marks (\\p{M}). Each run of any other characters, including underscores and whitespace, becomes one hyphen.","The explicit trim() was removed because the final step strips leading and trailing hyphens, which covers surrounding whitespace.","Lowercasing happens after NFC normalization, as the spec orders. toLowerCase can occasionally produce non-NFC output for rare characters, and it is not re-normalized here."]}

Tarefa 2: Reparar um seletor de rota e apresentar os resultados dos testes

A função precisava resolver correspondências de prefixos mais longos, precedência de métodos, limites de segmentos, regras com formato incorreto e entradas imutáveis. A resposta solicitada também incluía um novo arquivo de teste.

Primeiros resultados retornados, com verificações de comportamento local corrigidas
ModeloVerificações de comportamentoFormato da respostaConcluir a entrega solicitada
Claude Haiku 4.512/12 apenas na função completaFalha: JSON truncadoNão: arquivo de teste foi cortado
Claude Soneto 512/12 apenas na função completaFalha: JSON truncadoNão: arquivo de teste foi cortado
Claude Opus 5,512/12 apenas na função completaFalha: JSON truncadoNão: arquivo de teste foi cortado

Resultado observado: Nenhum modelo concluiu a resposta solicitada de dois arquivos dentro do limite de saída compartilhado. Todos os três pararam em 4.096 tokens de conclusão relatados. Cada um já havia retornado uma função de roteador completa, que foi aprovada nos doze grupos de comportamento fixos; os novos arquivos de teste estavam incompletos e não foram executados.

Extraímos apenas cada sequência de código-fonte totalmente fechada. As respostas truncadas originais permanecem intactas a seguir. Portanto, uma pontuação de aprovação na função não significa que a solicitação completa tenha sido bem-sucedida.

Outra constatação da revisão de código: um empate por igualdade de raízes

Após as verificações de correção, percebemos que o Haiku se normalizou /// para uma string vazia, em vez de /. Uma verificação local separada utilizou duas regras GET, com prefixos /// e /, visando primeiro e segundo nessa ordem. Para /qualquer coisa, o contrato exige que primeiro.

Haiku voltou segundo; Sonnet e Opus voltaram primeiro. Essa verificação adicional foi solicitada durante a revisão de código e é independente das doze verificações definidas antes dos testes. Ela não altera as pontuações dessas verificações.

O Sonnet encontrou um erro de serviço antes que sua tentativa de repetição permitida retornasse a resposta truncada exibida. Essa falha de serviço é independente da qualidade do código. Nenhum modelo recebeu outra tentativa para melhorar ou concluir sua resposta.

Veja o prompt compartilhado completo e o código de entrada
SYSTEM
You are completing a bounded JavaScript coding task. Return only the requested JSON object with complete source files and brief review notes. Do not claim to have edited files, run commands, or used tools. You have no tool access. Do not include hidden reasoning.

USER
Repair a Node.js 18+ CommonJS route selector. Return complete replacement src/router.js and an additional test/router-added.test.js using node:test and node:assert/strict. Do not add dependencies or edit existing tests. Do not use I/O other than the test runner, network, child processes, timers, or any files beyond the two requested outputs.

Contract for chooseRoute(request, rules):
1. Invalid request or rules returns null, without throwing. Request must be a non-null, non-array object; method must be a nonempty ASCII-letter string; path must be a string beginning with /. Rules must be an array.
2. Before matching, remove the request path's query and fragment starting at the earliest ? or #. Do not URL-decode or collapse interior slashes.
3. Ignore invalid rules. A valid rule is a non-null, non-array object with method '*' or a nonempty ASCII-letter string, prefix a string starting with / containing neither ? nor #, and target a nonempty string.
4. Compare methods case-insensitively. Prefer any matching exact-method rule over all wildcard-method '*' rules, even if a wildcard has a longer prefix. Use wildcard rules only if no exact-method route matches the path.
5. Remove trailing slashes from a rule prefix, except that an all-slash prefix normalizes to /. A prefix matches the path only at a segment boundary: /api matches /api and /api/users, never /apix. Root / matches every valid request path.
6. Within the chosen method group, choose the longest normalized matching prefix. On equal prefix length, choose the earlier rule in the original input array. Return its target. Return null if none matches.
7. Do not mutate the request, rules array, or rule objects, including order or prefix strings. Preserve module.exports = { chooseRoute }.
8. Add tests for segment boundaries, query/fragment removal, method precedence, ties, malformed inputs and immutability. Existing simple GET /api/users and POST-no-match cases must still pass.

Current src/router.js:
```javascript
function chooseRoute(request, rules) {
  if (!request || !Array.isArray(rules)) return null;
  for (const rule of rules) {
    if (request.method === rule.method && request.path.startsWith(rule.prefix)) {
      return rule.target;
    }
  }
  return null;
}

module.exports = { chooseRoute };


```

Existing regression cases (unchanged): rules [{method:'GET',prefix:'/api',target:'api'},{method:'GET',prefix:'/api/admin',target:'admin'}]; GET /api/users returns 'api'; POST /api/users returns null.

Return exactly one JSON object with this shape:
{"files":{"src/router.js":"complete JavaScript source as a JSON string","test/router-added.test.js":"complete JavaScript tests as a JSON string"},"review_notes":["at most four brief implementation or assumption notes"]}
No Markdown wrapper. You are returning code for someone else to evaluate locally; do not say you edited files, ran tests, or observed passing results.
Veja a resposta completa do Claude Haiku 4.5, tal como foi enviada

Esta é a resposta completa recebida. Ela termina no meio da saída porque atingiu o limite; o conteúdo que falta não foi preenchido.

```json
{
  "files": {
    "src/router.js": "function chooseRoute(request, rules) {\n  // Validate request\n  if (request === null || Array.isArray(request) || typeof request !== 'object') {\n    return null;\n  }\n  if (typeof request.method !== 'string' || request.method.length === 0 || !/^[a-zA-Z]+$/.test(request.method)) {\n    return null;\n  }\n  if (typeof request.path !== 'string' || !request.path.startsWith('/')) {\n    return null;\n  }\n\n  // Validate rules\n  if (!Array.isArray(rules)) {\n    return null;\n  }\n\n  // Remove query and fragment from path\n  const cleanPath = request.path.split(/[?#]/)[0];\n\n  // Filter and validate rules\n  const validRules = [];\n  for (const rule of rules) {\n    if (rule === null || Array.isArray(rule) || typeof rule !== 'object') {\n      continue;\n    }\n    \n    const method = rule.method;\n    if (typeof method !== 'string' || (method !== '*' && (method.length === 0 || !/^[a-zA-Z]+$/.test(method)))) {\n      continue;\n    }\n    \n    const prefix = rule.prefix;\n    if (typeof prefix !== 'string' || !prefix.startsWith('/') || prefix.includes('?') || prefix.includes('#')) {\n      continue;\n    }\n    \n    const target = rule.target;\n    if (typeof target !== 'string' || target.length === 0) {\n      continue;\n    }\n    \n    validRules.push(rule);\n  }\n\n  // Normalize prefixes and partition into exact-method and wildcard groups\n  const exactMethodRules = [];\n  const wildcardRules = [];\n  \n  for (const rule of validRules) {\n    const normalizedPrefix = rule.prefix === '/' ? '/' : rule.prefix.replace(/\/+$/, '');\n    \n    const entry = {\n      originalRule: rule,\n      normalizedPrefix: normalizedPrefix,\n      method: rule.method\n    };\n    \n    if (rule.method === '*') {\n      wildcardRules.push(entry);\n    } else {\n      exactMethodRules.push(entry);\n    }\n  }\n\n  const requestMethod = request.method.toUpperCase();\n\n  // Helper to check if a prefix matches the path at a segment boundary\n  function prefixMatches(prefix, path) {\n    if (prefix === '/') {\n      return true;\n    }\n    if (!path.startsWith(prefix)) {\n      return false;\n    }\n    // Check segment boundary: next character must be '/' or end of string\n    const nextChar = path[prefix.length];\n    return nextChar === undefined || nextChar === '/';\n  }\n\n  // Try exact-method rules first\n  let bestMatch = null;\n  let bestLength = -1;\n  \n  for (const entry of exactMethodRules) {\n    if (entry.method.toUpperCase() === requestMethod) {\n      if (prefixMatches(entry.normalizedPrefix, cleanPath)) {\n        if (entry.normalizedPrefix.length > bestLength) {\n          bestMatch = entry.originalRule;\n          bestLength = entry.normalizedPrefix.length;\n        }\n      }\n    }\n  }\n  \n  if (bestMatch !== null) {\n    return bestMatch.target;\n  }\n\n  // Try wildcard rules only if no exact-method match\n  bestMatch = null;\n  bestLength = -1;\n  \n  for (const entry of wildcardRules) {\n    if (prefixMatches(entry.normalizedPrefix, cleanPath)) {\n      if (entry.normalizedPrefix.length > bestLength) {\n        bestMatch = entry.originalRule;\n        bestLength = entry.normalizedPrefix.length;\n      }\n    }\n  }\n  \n  if (bestMatch !== null) {\n    return bestMatch.target;\n  }\n\n  return null;\n}\n\nmodule.exports = { chooseRoute };",
    "test/router-added.test.js": "const test = require('node:test');\nconst assert = require('node:assert/strict');\nconst { chooseRoute } = require('../src/router.js');\n\n// Regression: existing test cases\ntest('GET /api/users matches /api prefix (exact method)', () => {\n  const rules = [\n    { method: 'GET', prefix: '/api', target: 'api' },\n    { method: 'GET', prefix: '/api/admin', target: 'admin' }\n  ];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/users' }, rules), 'api');\n});\n\ntest('POST /api/users returns null (no matching method)', () => {\n  const rules = [\n    { method: 'GET', prefix: '/api', target: 'api' },\n    { method: 'GET', prefix: '/api/admin', target: 'admin' }\n  ];\n  assert.equal(chooseRoute({ method: 'POST', path: '/api/users' }, rules), null);\n});\n\n// Invalid request handling\ntest('null request returns null', () => {\n  assert.equal(chooseRoute(null, []), null);\n});\n\ntest('array request returns null', () => {\n  assert.equal(chooseRoute([], []), null);\n});\n\ntest('request with missing method returns null', () => {\n  assert.equal(chooseRoute({ path: '/api' }, []), null);\n});\n\ntest('request with empty method returns null', () => {\n  assert.equal(chooseRoute({ method: '', path: '/api' }, []), null);\n});\n\ntest('request with non-letter method returns null', () => {\n  assert.equal(chooseRoute({ method: 'GET-POST', path: '/api' }, []), null);\n});\n\ntest('request with numeric method returns null', () => {\n  assert.equal(chooseRoute({ method: '123', path: '/api' }, []), null);\n});\n\ntest('request with missing path returns null', () => {\n  assert.equal(chooseRoute({ method: 'GET' }, []), null);\n});\n\ntest('request with path not starting with / returns null', () => {\n  assert.equal(chooseRoute({ method: 'GET', path: 'api' }, []), null);\n});\n\ntest('null rules returns null', () => {\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, null), null);\n});\n\ntest('non-array rules returns null', () => {\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, { method: 'GET' }), null);\n});\n\n// Query and fragment removal\ntest('query string is removed before matching', () => {\n  const rules = [{ method: 'GET', prefix: '/api', target: 'found' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/users?foo=bar' }, rules), 'found');\n});\n\ntest('fragment is removed before matching', () => {\n  const rules = [{ method: 'GET', prefix: '/api', target: 'found' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/users#section' }, rules), 'found');\n});\n\ntest('earliest ? or # is used as boundary', () => {\n  const rules = [{ method: 'GET', prefix: '/api', target: 'found' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/users?foo#bar' }, rules), 'found');\n});\n\ntest('fragment before query is used as boundary', () => {\n  const rules = [{ method: 'GET', prefix: '/api', target: 'found' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/users#foo?bar' }, rules), 'found');\n});\n\n// Segment boundary matching\ntest('prefix /api matches /api/users at segment boundary', () => {\n  const rules = [{ method: 'GET', prefix: '/api', target: 'found' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/users' }, rules), 'found');\n});\n\ntest('prefix /api does not match /apix (no segment boundary)', () => {\n  const rules = [{ method: 'GET', prefix: '/api', target: 'found' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/apix' }, rules), null);\n});\n\ntest('prefix /api matches /api exactly at segment boundary', () => {\n  const rules = [{ method: 'GET', prefix: '/api', target: 'found' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, rules), 'found');\n});\n\ntest('root / matches any valid path', () => {\n  const rules = [{ method: 'GET', prefix: '/', target: 'root' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/anything/here' }, rules), 'root');\n});\n\ntest('root / matches /', () => {\n  const rules = [{ method: 'GET', prefix: '/', target: 'root' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/' }, rules), 'root');\n});\n\n// Prefix normalization (trailing slash removal)\ntest('trailing slash is removed from prefix', () => {\n  const rules = [{ method: 'GET', prefix: '/api/', target: 'found' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/users' }, rules), 'found');\n});\n\ntest('multiple trailing slashes are removed', () => {\n  const rules = [{ method: 'GET', prefix: '/api///', target: 'found' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/users' }, rules), 'found');\n});\n\ntest('all-slash prefix normalizes to single /', () => {\n  const rules = [{ method: 'GET', prefix: '///', target: 'found' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, rules), 'found');\n});\n\n// Method case-insensitivity\ntest('method comparison is case-insensitive', () => {\n  const rules = [{ method: 'get', prefix: '/api', target: 'found' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, rules), 'found');\n});\n\ntest('request method case does not affect matching', () => {\n  const rules = [{ method: 'GET', prefix: '/api', target: 'found' }];\n  assert.equal(chooseRoute({ method: 'get', path: '/api' }, rules), 'found');\n});\n\n// Exact-method vs wildcard precedence\ntest('exact-method rule preferred over wildcard with longer prefix', () => {\n  const rules = [\n    { method: '*', prefix: '/api/admin/users', target: 'wildcard' },\n    { method: 'GET', prefix: '/api', target: 'exact' }\n  ];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/test' }, rules), 'exact');\n});\n\ntest('wildcard rule used when no exact-method matches', () => {\n  const rules = [\n    { method: '*', prefix: '/api', target: 'wildcard' },\n    { method: 'GET', prefix: '/other', target: 'exact' }\n  ];\n  assert.equal(chooseRoute({ method: 'POST', path: '/api/users' }, rules), 'wildcard');\n});\n\n// Longest prefix matching\ntest('longest matching prefix is chosen', () => {\n  const rules = [\n    { method: 'GET', prefix: '/api', target: 'short' },\n    { method: 'GET', prefix: '/api/admin', target: 'long' }\n  ];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/admin/users' }, rules), 'long');\n});\n\n// Tie-breaking (first rule wins on equal prefix length)\ntest('first rule wins on equal prefix length', () => {\n  const rules = [\n    { method: 'GET', prefix: '/api', target: 'first' },\n    { method: 'GET', prefix: '/api', target: 'second' }\n  ];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/users' }, rules), 'first');\n});\n\n// Invalid rules are ignored\ntest('null rule is ignored', () => {\n  const rules = [\n    null,\n    { method: 'GET', prefix: '/api', target: 'found' }\n  ];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, rules), 'found');\n});\n\ntest('array rule is ignored', () => {\n  const rules = [\n    [],\n    { method: 'GET', prefix: '/api', target: 'found' }\n  ];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, rules), 'found');\n});\n\ntest('rule with invalid method is ignored', () => {\n  const rules = [\n    { method: '', prefix: '/api', target: 'invalid' },\n    { method: 'GET', prefix: '/api', target: 'valid' }\n  ];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, rules), 'valid');\n});\n\ntest('rule with non-letter method (if not wildcard) is ignored', () => {\n  const rules = [\n    { method: 'G3T', prefix: '/api', target: 'invalid' },\n    { method: 'GET', prefix: '/api', target: 'valid' }\n  ];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, rules), 'valid');\n});\n\ntest('rule with prefix not starting with / is ignored', () => {\n  const rules = [\n    { method: 'GET', prefix: 'api', target: 'invalid' },\n    { method: 'GET', prefix: '/api', target: 'valid' }\n  ];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, rules), 'valid');\n});\n\ntest('rule with query in prefix is ignored', () => {\n  const rules = [\n    { method: 'GET', prefix: '/api?foo=bar', target: 'invalid' },\n    { method: 'GET', prefix: '/api', target: 'valid' }\n  ];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, rules), 'valid');\n});\n\ntest('rule with fragment in prefix is ignored', () => {\n  const rules = [\n    { method: 'GET', prefix: '/api#section', target: 
Veja a resposta completa da Claude Sonnet 5, tal como foi enviada

Esta é a resposta completa recebida. Ela termina no meio da saída porque atingiu o limite; o conteúdo que falta não foi preenchido.

{"files":{"src/router.js":"function isValidRequest(request) {\n  return (\n    request !== null &&\n    typeof request === 'object' &&\n    !Array.isArray(request) &&\n    typeof request.method === 'string' &&\n    request.method.length > 0 &&\n    /^[A-Za-z]+$/.test(request.method) &&\n    typeof request.path === 'string' &&\n    request.path.startsWith('/')\n  );\n}\n\nfunction isValidRule(rule) {\n  if (rule === null || typeof rule !== 'object' || Array.isArray(rule)) {\n    return false;\n  }\n  const { method, prefix, target } = rule;\n\n  if (typeof method !== 'string') return false;\n  if (method !== '*' && !(method.length > 0 && /^[A-Za-z]+$/.test(method))) {\n    return false;\n  }\n\n  if (\n    typeof prefix !== 'string' ||\n    !prefix.startsWith('/') ||\n    prefix.includes('?') ||\n    prefix.includes('#')\n  ) {\n    return false;\n  }\n\n  if (typeof target !== 'string' || target.length === 0) return false;\n\n  return true;\n}\n\nfunction normalizePrefix(prefix) {\n  if (/^\/+$/.test(prefix)) return '/';\n  return prefix.replace(/\/+$/, '');\n}\n\nfunction prefixMatches(normalizedPrefix, path) {\n  if (normalizedPrefix === '/') return true;\n  if (path === normalizedPrefix) return true;\n  return path.startsWith(normalizedPrefix + '/');\n}\n\nfunction stripQueryAndFragment(path) {\n  let cutIndex = path.length;\n  for (let i = 0; i < path.length; i++) {\n    const c = path[i];\n    if (c === '?' || c === '#') {\n      cutIndex = i;\n      break;\n    }\n  }\n  return path.slice(0, cutIndex);\n}\n\nfunction chooseRoute(request, rules) {\n  if (!isValidRequest(request) || !Array.isArray(rules)) return null;\n\n  const path = stripQueryAndFragment(request.path);\n  const reqMethodLower = request.method.toLowerCase();\n\n  let bestExact = null; // { len, idx, target }\n  let bestWildcard = null;\n\n  for (let idx = 0; idx < rules.length; idx++) {\n    const rule = rules[idx];\n    if (!isValidRule(rule)) continue;\n\n    const normPrefix = normalizePrefix(rule.prefix);\n    if (!prefixMatches(normPrefix, path)) continue;\n\n    const len = normPrefix.length;\n\n    if (rule.method === '*') {\n      if (\n        bestWildcard === null ||\n        len > bestWildcard.len ||\n        (len === bestWildcard.len && idx < bestWildcard.idx)\n      ) {\n        bestWildcard = { len, idx, target: rule.target };\n      }\n    } else if (rule.method.toLowerCase() === reqMethodLower) {\n      if (\n        bestExact === null ||\n        len > bestExact.len ||\n        (len === bestExact.len && idx < bestExact.idx)\n      ) {\n        bestExact = { len, idx, target: rule.target };\n      }\n    }\n  }\n\n  if (bestExact !== null) return bestExact.target;\n  if (bestWildcard !== null) return bestWildcard.target;\n  return null;\n}\n\nmodule.exports = { chooseRoute };\n","test/router-added.test.js":"const test = require('node:test');\nconst assert = require('node:assert/strict');\nconst { chooseRoute } = require('../src/router');\n\ntest('segment boundary: prefix matches at slash boundary only', () => {\n  const rules = [\n    { method: 'GET', prefix: '/api', target: 'api' },\n  ];\n  assert.equal(\n    chooseRoute({ method: 'GET', path: '/api/users' }, rules),\n    'api'\n  );\n  assert.equal(\n    chooseRoute({ method: 'GET', path: '/api' }, rules),\n    'api'\n  );\n  assert.equal(\n    chooseRoute({ method: 'GET', path: '/apix' }, rules),\n    null\n  );\n});\n\ntest('root prefix matches every valid path', () => {\n  const rules = [{ method: 'GET', prefix: '/', target: 'root' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/' }, rules), 'root');\n  assert.equal(\n    chooseRoute({ method: 'GET', path: '/anything/here' }, rules),\n    'root'\n  );\n});\n\ntest('trailing slashes in rule prefix are normalized', () => {\n  const rules = [{ method: 'GET', prefix: '/api///', target: 'api' }];\n  assert.equal(\n    chooseRoute({ method: 'GET', path: '/api/users' }, rules),\n    'api'\n  );\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, rules), 'api');\n});\n\ntest('all-slash prefix normalizes to /', () => {\n  const rules = [{ method: 'GET', prefix: '////', target: 'root' }];\n  assert.equal(\n    chooseRoute({ method: 'GET', path: '/whatever' }, rules),\n    'root'\n  );\n});\n\ntest('query and fragment are stripped before matching', () => {\n  const rules = [{ method: 'GET', prefix: '/api', target: 'api' }];\n  assert.equal(\n    chooseRoute({ method: 'GET', path: '/api/users?x=1&y=2' }, rules),\n    'api'\n  );\n  assert.equal(\n    chooseRoute({ method: 'GET', path: '/api/users#section' }, rules),\n    'api'\n  );\n  assert.equal(\n    chooseRoute({ method: 'GET', path: '/api/users?x=1#frag' }, rules),\n    'api'\n  );\n});\n\ntest('query/fragment stripping does not decode or collapse slashes', () => {\n  const rules = [{ method: 'GET', prefix: '/a//b', target: 'weird' }];\n  assert.equal(\n    chooseRoute({ method: 'GET', path: '/a//b?x=1' }, rules),
Veja a resposta completa do Claude Opus 5,5’ tal como foi enviada

Esta é a resposta completa recebida. Ela termina no meio da saída porque atingiu o limite; o conteúdo que falta não foi preenchido.

{"files":{"src/router.js":"'use strict';\n\nconst LETTERS = /^[A-Za-z]+$/;\n\nfunction isPlainObject(value) {\n  return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction isMethodName(value) {\n  return typeof value === 'string' && value.length > 0 && LETTERS.test(value);\n}\n\nfunction stripQueryAndFragment(path) {\n  const q = path.indexOf('?');\n  const h = path.indexOf('#');\n  let cut = -1;\n  if (q !== -1 && h !== -1) cut = Math.min(q, h);\n  else if (q !== -1) cut = q;\n  else if (h !== -1) cut = h;\n  return cut === -1 ? path : path.slice(0, cut);\n}\n\nfunction normalizePrefix(prefix) {\n  let end = prefix.length;\n  while (end > 0 && prefix[end - 1] === '/') end -= 1;\n  return end === 0 ? '/' : prefix.slice(0, end);\n}\n\nfunction prefixMatches(path, prefix) {\n  if (prefix === '/') return true;\n  return path === prefix || path.startsWith(prefix + '/');\n}\n\nfunction chooseRoute(request, rules) {\n  try {\n    if (!isPlainObject(request) || !Array.isArray(rules)) return null;\n    const method = request.method;\n    const rawPath = request.path;\n    if (!isMethodName(method)) return null;\n    if (typeof rawPath !== 'string' || rawPath[0] !== '/') return null;\n\n    const path = stripQueryAndFragment(rawPath);\n    const upperMethod = method.toUpperCase();\n\n    let bestExact = null;\n    let bestWildcard = null;\n\n    const count = rules.length;\n    for (let i = 0; i < count; i += 1) {\n      const rule = rules[i];\n      if (!isPlainObject(rule)) continue;\n      const ruleMethod = rule.method;\n      const prefix = rule.prefix;\n      const target = rule.target;\n      const isWildcard = ruleMethod === '*';\n      if (!isWildcard && !isMethodName(ruleMethod)) continue;\n      if (typeof prefix !== 'string' || prefix[0] !== '/') continue;\n      if (prefix.indexOf('?') !== -1 || prefix.indexOf('#') !== -1) continue;\n      if (typeof target !== 'string' || target.length === 0) continue;\n\n      const normalized = normalizePrefix(prefix);\n      if (!prefixMatches(path, normalized)) continue;\n\n      const candidate = { length: normalized.length, target };\n      if (isWildcard) {\n        if (bestWildcard === null || candidate.length > bestWildcard.length) bestWildcard = candidate;\n      } else if (ruleMethod.toUpperCase() === upperMethod) {\n        if (bestExact === null || candidate.length > bestExact.length) bestExact = candidate;\n      }\n    }\n\n    if (bestExact !== null) return bestExact.target;\n    if (bestWildcard !== null) return bestWildcard.target;\n    return null;\n  } catch (err) {\n    return null;\n  }\n}\n\nmodule.exports = { chooseRoute };\n","test/router-added.test.js":"'use strict';\n\nconst test = require('node:test');\nconst assert = require('node:assert/strict');\nconst { chooseRoute } = require('../src/router.js');\n\nconst baseRules = [\n  { method: 'GET', prefix: '/api', target: 'api' },\n  { method: 'GET', prefix: '/api/admin', target: 'admin' }\n];\n\ntest('existing regression cases still hold', () => {\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/users' }, baseRules), 'api');\n  assert.equal(chooseRoute({ method: 'POST', path: '/api/users' }, baseRules), null);\n});\n\ntest('longest prefix wins within method group', () => {\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/admin/x' }, baseRules), 'admin');\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/admin' }, baseRules), 'admin');\n});\n\ntest('segment boundaries', () => {\n  const rules = [{ method: 'GET', prefix: '/api', target: 'api' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, rules), 'api');\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/' }, rules), 'api');\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/users' }, rules), 'api');\n  assert.equal(chooseRoute({ method: 'GET', path: '/apix' }, rules), null);\n  assert.equal(chooseRoute({ method: 'GET', path: '/ap' }, rules), null);\n});\n\ntest('trailing slashes in prefixes are normalized, all-slash is root', () => {\n  const rules = [{ method: 'GET', prefix: '/api///', target: 'api' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, rules), 'api');\n  assert.equal(chooseRoute({ method: 'GET', path: '/apix' }, rules), null);\n  const rootRules = [{ method: 'GET', prefix: '///', target: 'root' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/' }, rootRules), 'root');\n  assert.equal(chooseRoute({ method: 'GET', path: '/anything/else' }, rootRules), 'root');\n  assert.equal(chooseRoute({ method: 'GET', path: '/x' }, [{ method: 'GET', prefix: '/', target: 'r' }]), 'r');\n});\n\ntest('query and fragment are removed at earliest ? or #', () => {\n  assert.equal(chooseRoute({ method: 'GET', path: '/api?next=/api/admin' }, baseRules), 'api');\n  assert.equal(chooseRoute({ method: 'GET', path: '/api#/admin' }, baseRules), 'api');\n  assert.equal(chooseRoute({ method: 'GET', path: '/apix?/api' }, baseRules), null);\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/admin#frag?q' }, baseRules), 'admin');\n  assert.equal(chooseRoute({ method: 'GET', path: '/api?q#/admin' }, baseRules), 'api');\n});\n\ntest('no URL decoding and no slash collapsing', () => {\n  const rules = [{ method: 'GET', prefix: '/api/admin', target: 'admin' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api%2Fadmin' }, rules), null);\n  assert.equal(chooseRoute({ method: 'GET', path: '/api//admin' }, rules), null);\n  assert.equal(chooseRoute({ method: 'GET', path: '/api//admin' }, baseRules), 'api');\n});\n\ntest('methods compare case-insensitively', () => {\n  const rules = [{ method: 'get', prefix: '/a', target: 'lower' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/a' }, rules), 'lower');\n  assert.equal(chooseRoute({ method: 'gEt', path: '/a/b' }, rules), 'lower');\n});\n\ntest('exact method beats longer wildcard; wildcard used only as fallback', () => {\n  const rules = [\n    { method: '*', prefix: '/api/admin', target: 'wild-admin' },\n    { method: 'GET', prefix: '/', target: 'get-root' },\n    { method: 'POST', prefix: '/other', target: 'post-other' },\n    { method: '*', prefix: '/api', target: 'wild-api' }\n  ];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/admin/x' }, rules), 'get-root');\n  assert.equal(chooseRoute({ method: 'POST', path: '/api/admin/x' }, rules), 'wild-admin');\n  assert.equal(chooseRoute({ method: 'POST', path: '/api/x' }, rules), 'wild-api');\n  assert.equal(chooseRoute({ method: 'POST', path: '/other/1' }, rules), 'post-other');\n  assert.equal(chooseRoute({ method: 'PUT', path: '/nothing' }, rules), null);\n});\n\ntest('ties go to earlier rule in input order', () => {\n  const rules = [\n    { method: 'GET', pref

O limite máximo de 4.096 tokens foi o orçamento de saída escolhido para este teste, e não o máximo documentado de nenhum modelo. O resultado do roteamento sugere uma verificação prática antes de uma solicitação maior: estime o tamanho da implementação, dos testes e da explicação que você espera receber. Pode ser adequado dividir os resultados ou alocar mais espaço para a saída; não repetimos essas saídas com configurações diferentes.

Para sua própria tarefa, avalie três aspectos separadamente: se a resposta está completa, se o código passa em verificações úteis e se a revisão identifica lacunas que essas verificações não detectaram. O fato de ter passado em doze verificações de função não tornou nenhuma das respostas truncadas em dois arquivos uma entrega completa.

O que a escolha do modelo altera em relação ao custo

O Code Claude é a ferramenta de codificação; Haiku, Sonnet, Opus e Fable são opções de modelos disponíveis no ambiente compatível. A forma de autenticação e pagamento é outra opção. A mudança de modelo não transforma uma assinatura em uma conta de API nem faz com que todos os limites de uso desapareçam.

Rota de cobrançaO que assistirComo interpretar a escolha do modelo
Acesso por assinatura ao ClaudeUso incluído no plano e quaisquer créditos de uso ativados separadamenteDiferentes modelos podem consumir as cotas de maneiras diferentes; verifique os modelos disponíveis no plano e seus limites
Acesso à API AnthropicTokens de entrada/saída, armazenamento em cache e taxas de API aplicáveisUtilize a tabela de tarifas atual e os dados reais de uso e, em seguida, confirme os valores cobrados no painel de faturamento
Provedor de nuvem ou gatewayIdentificadores, tarifas e registros de cobrança compatíveis com o seu provedorUm exemplo de preço de tabela Anthropic pode não corresponder ao valor cobrado pelo seu provedor
A seleção do plano e o faturamento estão relacionados, mas a modalidade de faturamento determina como o consumo é cobrado.

No código Claude, /uso exibe informações sobre o token da sessão e, quando aplicável, barras de uso da assinatura. O valor em dólares é uma estimativa calculada localmente com base em tabelas de preços ou tarifas configuradas; não se trata de uma fatura. Para assinantes dos planos Pro e Max, esse valor da sessão não significa que uma cobrança adicional pela API foi adicionada à assinatura. Saiba mais sobre Claude: Códigos de precificação e rotas de faturamento se você estiver decidindo como pagar.

Preços atuais da API e um exemplo de “equal-token”

As taxas básicas normais do Anthropic por milhão de tokens de entrada/saída são Haiku 4.5: $1/$5; Sonnet 5: $2/$10; Opus 5.5: $4/$20; Fable 5.1: $10/$50, consultado em 28 de setembro de 2026. O gráfico a seguir mantém o volume do token constante para facilitar a comparação dos cálculos.

O mesmo volume de tokens, quatro custos de API diferentes

Exemplo: 100.000 tokens de entrada não armazenados em cache + 10.000 tokens de saída, com base nos preços de tabela da API da Anthropic, verificados em 28 de setembro de 2026.

Haiku 4.5$0.15
Soneto 5$0.30
Opus 5.5$0.60
Fable 5.1$1.50
Veja as tarifas e o cálculo
Dólares americanos por milhão de tokens e o exemplo de cálculo
ModeloEntrada / 1MSaída / 1MExemplo de total
Haiku 4.5$1$5$0.15
Soneto 5$2$10$0.30
Opus 5.5$4$20$0.60
Fable 5.1$10$50$1.50

Cálculo: 0,1 × taxa de entrada + 0,01 × taxa de saída. Para o Opus 5.5: 0,1 × $4 + 0,01 × $20 = $0,60.

Esta é uma ilustração com um número fixo de tokens. As tarefas reais consomem quantidades diferentes de tokens; gravações e leituras no cache, novas tentativas, ferramentas, cobrança do provedor e limites de assinatura exigem contabilização separada.

Fonte: Preços da API Anthropic.

Tabela de preços da API do Anthropic com tarifas de entrada, saída e cache de prompts.
Os preços de tabela normais da API são cotados por milhão de tokens; as gravações e leituras no cache têm tarifas distintas.

Uma tarefa real do Código Claude consiste em uma sequência de solicitações. O contexto anterior pode ser reenviado, um modelo pode aprofundar a análise e ferramentas ou agentes adicionais podem gerar mais trabalho. O armazenamento em cache de prompts também apresenta taxas distintas de gravação e leitura. A barra mais baixa do exemplo, portanto, não representa o menor custo por alteração aceita.

Cinco maneiras de controlar os custos sem comprometer a qualidade do trabalho

  1. Defina os critérios de aceitação antes de escolher um modelo. Descreva o comportamento esperado, os casos extremos e as restrições existentes. Uma tarefa pequena e bem definida é mais fácil de delegar de forma econômica e mais fácil de revisar.
  2. Forneça o contexto relevante. Inclua os arquivos e os detalhes da falha de que o modelo precisa. Para trabalhos não relacionados, inicie uma conversa nova, em vez de continuar com um histórico extenso apenas porque ele já existe.
  3. Distinga capacidade de esforço. O Anthropic recomenda começar com o nível de esforço padrão do modelo. Se ele tiver lido o contexto correto e ainda assim não conseguir resolver o problema, um modelo mais robusto pode ajudar. Se ele tiver pulado a leitura ou a verificação, verifique a configuração da tarefa e a escolha do nível de esforço.
  4. Orçamento para a resposta completa. O código-fonte, os testes e as explicações precisam de espaço para serem apresentados. Nossa segunda tarefa mostra por que uma função completa, por si só, não é prova de que a entrega solicitada se encaixou no orçamento.
  5. Compare trabalhos aceitos. Registre os resultados úteis, as tentativas de repetição, o tempo de revisão e os dados reais de faturamento em tarefas representativas. Separe os erros dos provedores das falhas relacionadas à qualidade do modelo.

Essas estratégias estão alinhadas com o guia oficial de custos e Orientações sobre modelo e esforço do Anthropic. Um limite semanal ou por sessão válido para todo o plano pode permanecer em vigor após uma troca de modelo; um limite específico do modelo é uma situação diferente. Verifique o limite atual antes de realizar trocas repetidas.

Se o seu trabalho abrange programação, pesquisa, redação e mídia, compare também o fluxo de trabalho pelo qual você está pagando. O espaço de trabalho multimodelo do GlobalGPT reúne essas funções em um único painel com acesso via CLI para tarefas de desenvolvimento. Esse valor mais amplo do fluxo de trabalho deve ser levado em consideração ao avaliar uma rota de API com cobrança por uso; o gráfico da API acima não é uma lista de preços da assinatura do GlobalGPT.

Por que o modelo que você escolheu pode não funcionar

SintomaProvável verificaçãoPróximo passo prático
A próxima sessão utiliza o modelo antigoA configuração pode ter sido válida apenas para a sessãoUse a ação “Enter” do seletor para salvar e, em seguida, selecione uma nova sessão
A preferência é salva, mas um modelo diferente é iniciadoUma configuração de lançamento, shell, projeto, gerenciada ou de organização pode ter prioridadeLeia as informações de inicialização e verifique a configuração relevante com o responsável por ela
Uma conversa retomada segue um modelo diferenteA sessão salva pode restaurar seu modelo anteriorVerifique /status; escolha cuidadosamente o modelo pretendido para retomar o trabalho
O modelo está faltando ou foi rejeitadoDisponibilidade do provedor, regras da organização ou uma versão antiga do Código ClaudeVerifique os IDs dos modelos compatíveis, o acesso à conta e os requisitos de versão
O mesmo sobrenome é interpretado de maneira diferente em outros lugaresOs aliases e os mapeamentos de provedores são diferentesUtilize o ID completo correto do provedor quando uma versão precisar permanecer fixa
A mudança de plano não zera o limite de usoO limite pode se aplicar a todo o planoLeia a mensagem de orientação e redefina o período, em vez de presumir que basta desligar o aparelho da tomada
Avalie a extensão do problema antes de alterar qualquer outra configuração.

Se o código Claude não conseguir gravar suas configurações de usuário, uma opção interativa pode permanecer válida apenas para a sessão atual, sem ser salva. Um arquivo de configurações gerenciado ou gerado pode precisar de uma alteração por parte de seu proprietário, em vez de uma nova tentativa de seleção. Evite remover restrições organizacionais apenas para que uma opção apareça.

Crie um fluxo de trabalho mais abrangente com o GlobalGPT

A seleção de modelos é apenas uma parte do fluxo de trabalho. Você pode precisar pesquisar uma biblioteca, esboçar uma função, explicar uma alteração a um colega de equipe, criar documentação e preparar recursos visuais. O GlobalGPT combina vários modelos e funções de IA de ponta em um único espaço de trabalho acessível, de modo que essas tarefas possam ser realizadas no mesmo painel.

Para o trabalho no terminal, o GlobalGPT CLI conecta as ferramentas da plataforma aos ambientes de desenvolvimento. Sua configuração documentada utiliza o login da sua conta GlobalGPT e o saldo normal da conta. A CLI pode dar suporte a um fluxo de trabalho mais amplo de programação e criação, enquanto o modelo próprio do Claude Code continua sendo uma escolha deliberada por meio de seus controles de modelo.

Por exemplo, elabore e revise um plano de implementação, utilize outro modelo para uma explicação concisa e, em seguida, produza a documentação ou os recursos que acompanham o lançamento. Siga o guia para Conectar a CLI do GlobalGPT ao código do Claude quando você quiser essa integração com a ferramenta. Defina seu modelo de raciocínio de código Claude separadamente, de acordo com a tarefa de codificação.

Escolha um modelo inicial, defina os critérios que determinam o sucesso e avance para a próxima etapa quando a tarefa assim exigir. Analise o resultado final antes de considerar o trabalho concluído. Crie seu fluxo de trabalho com o GlobalGPT quando você deseja que a escolha de modelos, a pesquisa, a programação e as ferramentas criativas estejam interligadas em seu trabalho diário.

PERGUNTAS FREQUENTES

Como faço para alterar o modelo no código Claude?

Execute /model para abrir o seletor. Pressione s para alterar apenas a sessão atual ou Enter para salvar o modelo selecionado como padrão. Para escolher um modelo para uma única sessão nova, inicie o programa com claude –model seguido do nome do modelo.

O /model altera minha configuração padrão salva?

Nas versões interativas atuais, selecionar um modelo com a tecla Enter ou digitar /model sonnet salva a escolha nas configurações do usuário, desde que seja possível gravar. Pressionar a tecla s no seletor é válido apenas para a sessão atual. Outras configurações ainda podem ter prioridade na próxima vez que o programa for iniciado.

Qual é o modelo padrão do código Claude?

O padrão de tempo de execução depende da sua conta, do provedor e da configuração. O valor padrão desfaz uma substituição de modelo; não se trata de um ID de modelo fixo. Verifique o modelo ativo com o comando /status e examine o seletor, em vez de presumir que todas as contas começam com a mesma versão.

O que o Opusplan faz?

Ele utiliza o Opus no modo de planejamento e o Sonnet durante a execução. Ele segue a transição entre os modos, em vez de escolher automaticamente o modelo mais econômico para cada solicitação. O custo real depende do trabalho realizado em cada fase.

Por que um modelo não aparece no seletor?

A disponibilidade pode depender do seu provedor, da sua conta, de restrições da organização e da versão do código Claude. Verifique a documentação do modelo atual e os modelos permitidos no seu ambiente. Um alias de família também pode corresponder a uma versão diferente em outro provedor.

Um modelo mais barato sempre torna uma tarefa mais barata?

Não. O preço do token é apenas um dos fatores. O uso total, as respostas incompletas, as tentativas repetidas e o esforço de revisão afetam o custo de uma alteração aceitável. Em nossa pequena refatoração, todas as três funções foram aprovadas, enquanto todas as três respostas maiores, compostas por dois arquivos, foram truncadas devido ao limite de saída compartilhada.

Fontes

Compartilhe a postagem:

Publicações relacionadas