Convertidor OpenAI ⇄ Anthropic
Convierte arrays de messages entre OpenAI Chat Completions y Anthropic Messages API. Maneja system messages, tool calls, bloques de imagen, multi-turno. En el navegador, sin API keys.
¿Para qué sirve?
La Chat Completions API de OpenAI y la Messages API de Anthropic permiten conversaciones multi-turno, pero estructuran el JSON de forma suficientemente distinta como para que los prompts y trazas de tool-calls no caigan bien al cambiar de proveedor. Las diferencias son pequeñas (posición del system message, tool-call vs tool-use, forma de bloques de imagen, role: 'tool' vs tool_result en content) pero cada una es un agujero de 10 minutos cuando estás contra el reloj. Este convertidor hace la traducción para que pegues una conversación OpenAI y obtengas una versión Anthropic (o al revés).
Qué se traduce
- System messages. OpenAI usa un mensaje normal con
role: "system". Anthropic lo pone top-level comosystem. Movemos y concatenamos si hay varios. - Tool-calls (lado assistant). OpenAI:
tool_calls: [{id, type:'function', function:{name, arguments:'JSON-string'}}]. Anthropic: bloquetool_usedentro decontentcon{id, name, input}(objeto parseado, no string). Parseamos los argumentos escapados de OpenAI ainputestructurado para Anthropic; al revés se re-serializa. - Tool results. OpenAI: mensaje aparte con
role: "tool",tool_call_idycontent. Anthropic: bloquetool_resultdentro del siguiente mensaje user contool_use_id. Mensajestoolconsecutivos de OpenAI se fusionan en un user de Anthropic con múltiplestool_result. - Imágenes. OpenAI:
{type:'image_url', image_url:{url}}. Anthropic:{type:'image', source:{type:'base64',media_type,data}}o URL-source. Detectamos URLsdata:y convertimos; URLs simples pasan como URL-source. - Texto plano. OpenAI usa string; Anthropic acepta string o array
[{type:'text', text}]de un elemento. Usamos lo más simple.
Qué no se traduce
- Eventos de streaming. Manejamos JSON de request/response, no streams SSE. Si tienes un dump de stream, reconstruye el mensaje final primero.
- Campos específicos del proveedor. Cosas como
logprobsde OpenAI,stop_sequencesde Anthropic, parámetros de sampling — viven en el top-level del request, no dentro de los messages. - Pistas de cache-control. El
cache_control: {type:'ephemeral'}de Anthropic no tiene equivalente en OpenAI. Sobrevive OpenAI → Anthropic (no hay fuente), pero se descarta al revés. - Definiciones de tools. El schema de tus tools (campo
toolsdel request) vive fuera del array de messages. Formato distinto entre proveedores — convierte aparte.
Errores comunes
- Escaping de argumentos de OpenAI.
argumentsde OpenAI es un string JSON-codificado, no un objeto parseado. Si está roto (raro, pasa con modelos chicos), lo metemos en_raweninputde Anthropic en vez de lanzar. - System top-level de Anthropic. En OpenAI → Anthropic el resultado es
{system, messages}. Si solo quieres el array, usa.messages— pero acuérdate de pasarsystemal request por separado. - Alternancia estricta. Anthropic exige user/assistant alternado (tras el system opcional). El convertidor lo preserva en general; si tu fuente OpenAI tiene dos users consecutivos, la salida Anthropic también — y la API lo rechazará. Fusiona antes.
- Multi-modal en OpenAI. Un mensaje user de OpenAI con imágenes usa content array en vez de string. Lo manejamos; solo asegúrate de que tu entrada parsee como JSON.
- Privacidad. Nada sale de la página. Conversión en JS puro; sin API keys, sin red.