Conversor OpenAI ⇄ Anthropic
Converte arrays de messages entre OpenAI Chat Completions e Anthropic Messages API. Trata system messages, tool calls, blocos de imagem, multi-turno. No navegador, sem API keys.
Pra que serve?
A Chat Completions API da OpenAI e a Messages API da Anthropic permitem conversas multi-turno, mas estruturam o JSON de forma diferente o suficiente pra prompts e traces de tool-call não caírem limpos quando você troca de provider. As diferenças são pequenas (posição do system message, tool-call vs tool-use, formato de blocos de imagem, role: 'tool' vs tool_result em content) mas cada uma é um buraco de coelho de 10 minutos quando você tá no prazo. Esse conversor faz a tradução: cola uma conversa OpenAI e recebe versão Anthropic (ou vice-versa).
O que é traduzido
- System messages. OpenAI: mensagem normal com
role: "system". Anthropic: camposystemtop-level do request. Movemos e concatenamos se houver vários. - Tool-calls (lado assistant). OpenAI:
tool_calls: [{id, type:'function', function:{name, arguments:'JSON-string'}}]. Anthropic: blocotool_usedentro docontentcom{id, name, input}(objeto parseado, não string). Parseamos os arguments escapados da OpenAI prainputestruturado; sentido oposto re-serializa. - Tool results. OpenAI: mensagem separada com
role: "tool",tool_call_id,content. Anthropic: blocotool_resultdentro do content do próximo user comtool_use_id. Mensagenstoolconsecutivas da OpenAI são coalescidas em um único user Anthropic com múltiplostool_result. - Imagens. OpenAI:
{type:'image_url', image_url:{url}}. Anthropic:{type:'image', source:{type:'base64',media_type,data}}ou URL-source. Detectamos URLsdata:e convertemos; URLs simples passam como URL-source. - Texto puro. OpenAI usa string; Anthropic aceita string ou array
[{type:'text', text}]de um elemento. Usamos o mais simples.
O que não é traduzido
- Eventos de streaming. Tratamos JSON de request/response, não streams SSE. Se você tem dump de stream, reconstrua a mensagem final primeiro.
- Campos específicos do provider.
logprobsda OpenAI,stop_sequencesda Anthropic, parâmetros de sampling — ficam no top-level do request, não dentro dos messages. - Hints de cache-control. O
cache_control: {type:'ephemeral'}da Anthropic não tem equivalente OpenAI. Sobrevive a OpenAI → Anthropic (sem fonte), mas é descartado em Anthropic → OpenAI. - Definições de tool. O schema dos seus tools (campo
toolsdo request) fica fora do array messages. Formato diferente entre providers — converta separadamente.
Pegadinhas comuns
- Escaping dos arguments da OpenAI.
argumentsda OpenAI é string JSON-encoded, não objeto parseado. Se tá malformado (raro, acontece com modelos pequenos), colocamos em_rawnoinputda Anthropic em vez de lançar erro. - System top-level da Anthropic. Em OpenAI → Anthropic o resultado é
{system, messages}. Se você quer só o array, use.messages— mas lembre de anexarsystemao request separadamente. - Alternância estrita. Anthropic exige user/assistant em alternância estrita (após o system opcional). O conversor preserva em geral; se sua fonte OpenAI tem dois user seguidos, a saída Anthropic também — e a API rejeita. Faça merge antes.
- Multi-modal na OpenAI. Mensagem user da OpenAI com imagens usa content array em vez de string. Tratamos; só garanta que seu input parse como JSON.
- Privacidade. Nada sai da página. Conversão em JS puro; sem API keys, sem rede.