Como reescrever um serviço de uma linguagem para outra com o Claude Opus 5.5 sem perder comportamento?

fluxo de migração de código com o Claude Opus 5.5 mantendo o mesmo comportamento do serviço original
Resposta rápida

Migração de código com o Claude Opus 5.5 funciona bem quando você trata o porte como problema de validação, não de tradução. O caminho é em três frentes: mapear o contrato do serviço (entradas, saídas, efeitos colaterais, erros), congelar uma suíte de regressão que roda contra a implementação atual e só então gerar equivalentes em fatias pequenas, validando paridade a cada fatia. No Claude Code, use o plan mode para levantar o contrato, selecione o modelo com /model e defina o effort explicitamente (o padrão do Opus 5.5 é medium). Sem testes, não existe paridade, só palpite

O código novo compila, os testes ficam verdes, o serviço sobe

E aí, três semanas depois, alguém descobre que o timeout mudou, que um erro que antes virava 503 agora virava 200 com corpo vazio, e que aquele arredondamento de centavos ficou diferente em 0,01

Porte de linguagem quase nunca quebra com estrondo, ele quebra em silêncio

O Claude Opus 5.5 chegou em 22 de setembro de 2026 como sucessor do Claude Opus 5, e a Anthropic posiciona ele exatamente pra esse tipo de trabalho: raciocínio exigente, código e tarefa agêntica de horizonte longo, do tipo mudança multi-etapa espalhada por uma base grande

Ou seja, migração e auditoria

Só que "o modelo aguenta" não é o mesmo que "o porte deu certo". Então neste post eu monto o processo em três frentes: contrato, fatias e paridade

Bora?

Por que o Opus 5.5 mudou a conversa sobre reescrita entre linguagens

O anúncio do modelo trouxe um caso que é praticamente o experimento clássico de porte: traduzir o HAProxy de C para Rust

A Anthropic rodou isso internamente com o Opus 5.5 e com o Fable 5.1. As duas reescritas passaram em quase todos os testes de regressão do próprio HAProxy

Teste interno de tradução do HAProxy (C para Rust) Claude Opus 5.5 Claude Fable 5.1
Tempo até concluir 9,5 horas 12 horas
Custo 51% menor referência
Testes de regressão do HAProxy quase todos passando quase todos passando

Tem mais dois números que vieram de testadores antecipados citados no anúncio: uma migração de 680.000 linhas de código concluída em menos de um dia, trabalho que levaria semanas pra uma equipe de engenharia

E uma auditoria com correção numa base de 200.000 linhas em menos de três horas, contra mais de 20 horas do Opus 5, que ainda consumiu 2,5x mais tokens no TOTAL pra entregar o mesmo trabalho

Agora repara no detalhe que ninguém comenta e que é o mais importante de todos

O que dá sentido ao número do HAProxy não é o modelo, é a suíte de regressão do HAProxy

Sem uma malha de testes independente rodando contra as duas implementações, ninguém tem como dizer que a reescrita preservou comportamento. Tem como dizer que ela compila, que é outra coisa completamente diferente

Então a lição prática do anúncio é meio anticlimática: o gargalo do porte assistido não é a geração de código, é o oráculo que julga o código gerado

O que você precisa ter antes de escrever a primeira linha na linguagem nova

Antes de abrir o terminal, quatro coisas

1. Comportamento observável documentável

Se você não consegue escrever num documento o que entra, o que sai, quais efeitos colaterais existem (banco, fila, arquivo, rede) e como o serviço erra, você não tem um porte, você tem uma adivinhação

Erro aqui é caro: o modelo vai inferir o contrato a partir da implementação antiga, e implementação antiga tem bug. Bug portado fielmente continua sendo bug, só que agora em Rust 🙂

2. Suíte de regressão executável contra a implementação ATUAL

Ela precisa estar verde HOJE, no código velho. Se ela não roda no original, ela não é oráculo de nada

3. Ambiente da linguagem de destino compilando e rodando

Toolchain, build, runner de teste, tudo funcionando com um hello world antes de qualquer coisa. Tome cuidado: metade dos loops de reparo travados que eu vejo é modelo tentando consertar código por causa de erro de ambiente

4. Acesso ao Opus 5.5

O modelo está disponível na Claude API (identificador claude-opus-5-5), Amazon Bedrock, Google Cloud e Microsoft Foundry, além dos planos Pro e Max, do Claude Code e do Cowork

Se você for pela API, o preço entra no planejamento: US$ 4 por milhão de tokens de entrada e US$ 20 por milhão de tokens de saída

Vale fazer a conta grosseira antes, porque porte é um trabalho que relê MUITA coisa: contrato, fatia atual, teste, saída de erro, de novo e de novo

Passo a passo: conduzindo o porte com o Claude Opus 5.5

A sequência abaixo é a espinha do processo. Ela é chata de propósito, porque porte bom é chato

  1. Mapear o contrato do serviço no plan mode, antes de gerar uma linha de código

No Claude Code, pressione Shift+Tab até a barra de status mostrar o plan mode ligado, ou já abra a sessão assim:

claude --permission-mode plan

No plan mode o Claude lê arquivos e responde sem alterar nada, que é exatamente o que você quer nessa fase

O pedido é mais ou menos esse:

Leia o serviço em src/ e produza um documento de contrato observável.
Para cada endpoint/função pública, descreva: entradas e tipos, saídas e formatos,
efeitos colaterais externos, modos de erro e o que o chamador observa em cada um,
e invariantes que o código assume (ordenação, precisão numérica, encoding, limites).
Não proponha implementação. Marque como DÚVIDA tudo que você inferiu sem evidência no código.

Esse bloco de DÚVIDA é ouro, é ali que aparece o comportamento que ninguém sabia que existia

Erro comum deste passo: deixar o modelo escrever contrato e código na mesma conversa. Aí o contrato vira justificativa da implementação que ele já decidiu fazer, e você perde o juiz

  1. Selecionar o modelo de forma explícita

No Claude Code dá pra trocar de várias formas. A mais simples é digitar /model e escolher no menu interativo: a troca vale na hora e fica salva nas suas configurações

# dentro da sessão
/model <alias|nome>

# ou já iniciando
claude --model <alias|nome>

Também dá pra definir a variável ANTHROPIC_MODEL ou o campo model no arquivo de settings, se você quiser fixar isso por projeto

Tem um alias que merece atenção aqui: o opusplan usa Opus no plan mode e troca automaticamente pra Sonnet no modo de execução

Pra desenvolvimento do dia a dia isso é ótimo. Pra porte, pensa duas vezes: a parte "mecânica" da tradução é justamente onde a semântica escorrega, então provavelmente você quer Opus nas duas pontas, plano e execução

Erro comum deste passo: assumir qual modelo está ativo. Confira com /model antes de começar uma sessão longa, porque descobrir isso no meio de um porte de três horas é frustrante demais

  1. Calibrar o parâmetro effort

O padrão do Opus 5.5 é medium. Requisição que omite effort roda em medium (no Opus 5 o padrão era high), então se você reaproveitou configuração antiga, atenção: mudou debaixo dos seus pés

Os níveis disponíveis são low, medium, high, xhigh e max, sendo max o raciocínio mais profundo

A recomendação oficial é começar no medium, definir o valor explicitamente e testar vários níveis contra as suas próprias avaliações, em vez de copiar o ajuste que você usava no Opus 5

E um detalhe que dá erro na cara: o thinking no Opus 5.5 está sempre ligado. Mandar thinking: {"type": "disabled"} ou um budget manual retorna erro 400 invalid_request_error

Erro comum deste passo: subir tudo pra max "pra garantir". Você paga mais tempo e mais token sem evidência de que aquela fatia precisava, e perde a capacidade de comparar

  1. Congelar a malha de regressão e o oráculo de paridade

Antes de gerar equivalente, a suíte vira imutável pro modelo. Literalmente: você diz que ele não pode editar os testes

A pasta tests/ é somente leitura nesta tarefa.
Se um teste falhar, o código novo está errado até prova documentada em contrário.
Se você achar que o teste é que está errado, PARE e me explique, não altere.

Esse "PARE e me explique" evita o pior padrão de todos, que eu comento lá embaixo

  1. Fatiar o serviço e pedir um módulo por vez

Fatia boa é aquela que tem fronteira clara de entrada e saída e que cabe numa revisão humana honesta

O contrato entra como entrada FIXA em toda fatia, colado no prompt ou referenciado como arquivo:

Porte SOMENTE o módulo parser/ para Rust, seguindo CONTRATO.md.
Mantenha os mesmos modos de erro, inclusive os que parecem estranhos.
Não refatore nada fora do escopo desta fatia.
Não "melhore" comportamento: se algo parece errado, anote em NOTAS.md e mantenha igual.

Esse último parágrafo é o mais importante do prompt inteiro. Modelo bom tem vontade de consertar o que vê pela frente, e num porte isso é justamente o que você NÃO quer

Se a sua fatia é pequena e isolada, o raciocínio é bem parecido com o de converter um script entre linguagens, só que aqui você repete o ritual dezenas de vezes

Erro comum deste passo: mandar "porte o serviço" e ir tomar café. Volta com 4.000 linhas novas que ninguém consegue revisar, e revisar é o único momento em que você realmente ganha confiança

  1. Rodar o loop de reparo guiado por erros e testes a cada fatia

O ciclo é sempre o mesmo: compila, roda a suíte, devolve o erro cru pro modelo, ele corrige, roda de novo

cargo test 2>&1 | tail -n 60

Regra dura: fatia vermelha não avança. Nada de "depois eu volto nesse teste", porque na prática ninguém volta

Erro comum deste passo: resumir o erro pro modelo em vez de colar a saída inteira. A mensagem de compilador e o stack trace são o sinal mais rico que você tem, não desperdice

  1. Validar paridade de ponta a ponta

Suíte verde é o mínimo, não o fim. A validação que importa é execução espelhada: as duas implementações recebendo o mesmo tráfego ou as mesmas entradas gravadas, e você comparando saída, código de status, efeitos no banco, ordem de eventos e latência

E aí vem a parte humana: revisar as diferenças que nenhum teste cobria

Se a linguagem de destino não é a sua praia, esse é o momento de tomar cuidado, e vale ler sobre revisar código de uma linguagem nova antes de aprovar diff no automático

Erro comum deste passo: espelhar só o caminho feliz. O valor está nos 5% patológicos: payload malformado, timeout, concorrência, encoding esquisito

Quando fatiar, quando delegar a subagents e quando subir o effort

Três situações que aparecem em todo porte, e a decisão certa em cada uma

Fatia pequena e mecânica: medium basta

Conversão de struct, serialização, função pura, mapeamento de campo

Aqui não precisa de heroísmo. Nas avaliações de código e de trabalho de conhecimento, o Opus 5.5 em medium iguala ou supera o Opus 5 em high

Ou seja: o medium de hoje já é mais forte que o high que você usava antes. Gastar xhigh pra converter DTO é queimar tempo à toa

Semântica escorregadia: sobe pra high, xhigh ou max

Memória, concorrência, aritmética

É onde C e Rust discordam de verdade, é onde inteiro com sinal e overflow mudam de personalidade, é onde ordem de execução deixa de ser detalhe

Nesses trechos vale subir o effort e, principalmente, testar níveis diferentes contra as suas avaliações, que é exatamente o que a documentação recomenda. Não existe número mágico que sirva pro seu código: existe medição

Separação de papéis com subagents

Um padrão que funciona muito bem em porte é ter dois papéis diferentes: quem traduz e quem audita paridade

No Claude Code, subagents são arquivos Markdown com frontmatter YAML dentro de .claude/agents/. Só name e description são obrigatórios no frontmatter

---
name: auditor-paridade
description: Compara a implementação original e a portada contra o CONTRATO.md e aponta divergências de comportamento. Não escreve código de produção.
---

Você audita paridade de comportamento entre duas implementações.
Sua saída é uma lista de divergências com evidência (arquivo, linha, entrada que diferencia).
Nunca altere testes. Nunca altere o código portado.

Detalhe importante de versão: a partir da v2.1.198 o comando /agents não abre mais o assistente interativo, ele só orienta você a pedir ao Claude ou editar .claude/agents/ diretamente

Então se você viu tutorial antigo mostrando menu bonitinho, não se assuste quando não aparecer

E o fast mode?

Existe o fast mode, que entrega até 2,5x mais tokens de saída por segundo pelo dobro do preço: US$ 8 por milhão de entrada e US$ 40 por milhão de saída

Repara que aqui o multiplicador é de VELOCIDADE de geração (token por segundo), nada a ver com o consumo total de tokens do caso da auditoria lá em cima

Isso é escolha de VELOCIDADE, não de qualidade. Num porte, velocidade de digitação raramente é o gargalo, o gargalo é a revisão. Use com consciência

Os três jeitos de perder comportamento em um porte (e como prevenir)

1. Tudo verde, mas o serviço se comporta diferente em produção

Sintoma: suíte 100% passando, deploy feito, e o suporte começa a receber caso estranho

Causa: a suíte foi escrita a partir do CÓDIGO antigo, não do CONTRATO. Ela testa o que a implementação faz, então qualquer coisa que a implementação fazia sem teste virou terra de ninguém

Como prevenir: escrever a regressão a partir do comportamento observável (o documento de contrato) e complementar com execução espelhada sobre tráfego real gravado. Teste derivado de implementação é espelho, não juiz

2. O modelo reescreve idiomático demais e troca semântica no caminho

Sintoma: o código novo está lindo, mais limpo que o original, e sutilmente diferente

Causa: fatia grande demais somada a contrato solto. Quando falta especificação, o modelo preenche com bom gosto, e bom gosto muda comportamento

Como prevenir: fatias menores, contrato explícito dentro do prompt de cada fatia e a instrução direta de não melhorar nada. Peça que toda "melhoria" percebida vire anotação, não commit

3. O loop de reparo entra em círculo consertando o teste em vez do código

Sintoma: três iterações depois, os testes passam, mas o diff mexeu em tests/

Causa: não existe oráculo independente. Se quem escreve o código também pode escrever o teste, o teste vira negociável

Como prevenir: suíte imutável por fatia, revisão humana do diff e, se der, um subagent auditor que não tem permissão de tocar em código de produção

E aqui cabe um dado que ajuda a calibrar expectativa

No benchmark CRUST-Bench, que mede exatamente transpilação de C pra Rust, modelos de raciocínio de fronteira transpilaram com sucesso de 13% a 22% das tarefas em one-shot

Com loop de reparo guiado por erros e testes, isso foi pra 32% a 48%

Ou seja: o loop mais que dobra o resultado. Não é detalhe do processo, é o processo

Do lado bom, o Opus 5.5 obteve as melhores notas entre os modelos da Anthropic em testes de auditoria comportamental, é menos propenso a tomar ações difíceis de reverter ou agir fora dos limites dados, e é mais resistente a prompt injection que o Opus 5

Isso conta MUITO quando você vai deixar ele rodando trecho longo sozinho. Mas conta como redução de risco, não como dispensa de revisão. Os rm -rf da vida seguem existindo 😛

Vale a pena reescrever agora? O que muda na conta do porte

Vamos separar o que os números autorizam do que eles não autorizam

O que eles autorizam a concluir:

  • rodar o Opus 5.5 sai cerca de 40% mais barato que o Opus 5 em tarefas comuns com configurações padrão
  • o anúncio coloca ele operando no nível do Claude Fable 5.1 na maioria das tarefas, com custo menor
  • no teste do HAProxy especificamente, ele terminou em 9,5 horas contra 12 horas e custou 51% menos

O que eles NÃO autorizam a concluir:

  • que o seu porte vai passar em quase todos os testes de regressão, porque o HAProxy tem uma suíte madura e a sua talvez não tenha
  • que o tempo de projeto encolhe na mesma proporção do tempo de geração, porque revisão humana não escala com preço de token

E é aí que está a virada de chave da migração de código com o Claude Opus 5.5: o custo de gerar o código novo deixou de ser o item caro da planilha

O item caro virou escrever a malha de teste que prova paridade, e ler o diff

Se você quer uma referência pública de até onde uma base gerada por modelo já chegou, vale olhar o claudes-c-compiler, mantido na organização anthropics: um compilador C sem dependências escrito em Rust pelo Claude Opus 4.6, com backends pra x86 (64 e 32 bits), ARM e RISC-V, e capaz de compilar um kernel Linux que dá boot

Não é demo de slide, é código que compila kernel

Um último ponto de planejamento: Claude Sonnet 5.5 e Claude Haiku 5.5 são esperados nas semanas seguintes, com ganhos parecidos de desempenho, eficiência e segurança

Se isso se confirmar, as fatias mecânicas do porte (as chatas, as de DTO e serialização) provavelmente ficam mais baratas de rodar, e você concentra o Opus nas fatias escorregadias

Vale esperar? Depende do tamanho do seu porte. Pra começar a escrever contrato e teste, não precisa esperar nada, isso é trabalho humano que serve pra qualquer modelo

Conclusão: o porte é um problema de validação, não de tradução

A tese do post inteiro cabe numa linha

Quem conduz bem o Opus 5.5 num porte não é quem escreve o prompt mais bonito, é quem chega na conversa com contrato e testes prontos

O modelo traduz rápido, barato e com bastante cuidado. O que ele não pode fazer por você é decidir o que "mesmo comportamento" significa no seu domínio

Próximo passo, pequeno e concreto, pra fazer ainda hoje:

  1. escolhe UM módulo periférico do serviço, de preferência o mais chato e menos crítico
  2. escreve a regressão dele contra a implementação atual, até ficar verde no código velho
  3. abre o Claude Code em plan mode com o Opus 5.5 e o effort definido explicitamente em medium
  4. porta só aquela fatia e mede quanto tempo a REVISÃO levou

Esse número da revisão é o que vai te dizer se o porte inteiro é viável ou não, muito mais que qualquer benchmark

Depois me conta como foi, bora trocar uma ideia

Até o próximo post! 😀

Perguntas frequentes

Quanto custa usar o Claude Opus 5.5 pela API para migrar um serviço grande de linguagem?

O preço de tabela é US$ 4 por milhão de tokens de entrada e US$ 20 por milhão de tokens de saída. Em tarefas comuns com configurações padrão, o Opus 5.5 sai cerca de 40% mais barato de rodar que o Claude Opus 5, o que pesa numa migração que relê muito contrato e muito teste.

O Claude Opus 5.5 é mais barato que o Claude Fable 5.1 para reescrever código entre linguagens?

No teste interno da Anthropic de tradução do HAProxy de C para Rust, o Opus 5.5 terminou em 9,5 horas contra 12 horas do Fable 5.1 e custou 51% menos. As duas reescritas passaram em quase todos os testes de regressão do próprio HAProxy, então a diferença apareceu em tempo e custo, não em aprovação nos testes.

Dá para usar o Claude Opus 5.5 fora da API, como no Claude Code, para fazer a migração?

Sim, o Opus 5.5 está disponível na Claude API, Amazon Bedrock, Google Cloud e Microsoft Foundry, além dos planos Pro e Max, do Claude Code e do Cowork. No Claude Code você escolhe o modelo com /model, com claude –model, pela variável ANTHROPIC_MODEL ou pelo campo model no arquivo de settings.

O parâmetro effort do Opus 5.5 afeta a qualidade de uma migração de código?

Afeta bastante. O padrão do Opus 5.5 é medium, e requisição que omite o parâmetro roda nesse nível (no Opus 5 o padrão era high, então atenção se você reaproveitou configuração antiga). A recomendação oficial é começar no medium, definir o valor explicitamente e testar os níveis low, high, xhigh e max contra as próprias avaliações, em vez de reaproveitar o ajuste que você usava no Opus 5.

É possível desligar o thinking do Opus 5.5 para acelerar uma migração?

Não. O thinking do Opus 5.5 está sempre ligado, e enviar thinking: {"type": "disabled"} ou um budget manual retorna erro 400 invalid_request_error. Quem precisa de mais velocidade de saída tem o fast mode, que entrega até 2,5x mais tokens de saída por segundo, ou seja, velocidade de geração, pelo dobro do preço (US$ 8 de entrada e US$ 40 de saída por milhão de tokens).

Quão difícil é transpilar C para Rust com modelos de IA, segundo benchmarks?

O benchmark CRUST-Bench mostra que modelos de raciocínio de fronteira transpilam com sucesso de 13% a 22% das tarefas em one-shot. Com um loop de reparo guiado por erros e testes, esse número sobe para 32% a 48%, o que reforça por que ter uma suíte de regressão rodando contra o código original é tão importante quanto o modelo escolhido.



Escrito por | Matheus Battisti

Matheus Battisti
Fundador da Hora de Codar

Programador apaixonado pelo mundo das tecnologias, sempre buscando em aprender e se aprofundar em linguagens, frameworks e o que mais for necessário para executar um bom trabalho. Agora tem uma nova missão que é de passar seu conhecimento adiante para formar novos programadores e especializar mais os que já são.

Subscribe
Notify of
guest

0 Comentários
Oldest
Newest Most Voted

Formações

Formação Vibe Coding

Formação Vibe Coding

Do Prompt ao Produto: Crie Software Real com IA

  • 474 aulas
  • 20 projetos
  • 39h 30min

Blog | Mais populares