- En la herramienta de edición de Pi, Claude Opus 4.8 y Sonnet 5 agregaron campos no presentes en el esquema dentro de
edits[], lo que hizo que se rechazaran las llamadas; se observó que los modelos más recientes siguen peor ciertos esquemas de herramientas que los modelos anteriores
- Las llamadas a herramientas son un proceso en el que el modelo genera texto con marcadores especiales y formato JSON, por lo que, con muestreo sin restricciones, las convenciones aprendidas pueden imponerse al esquema
- En los casos de falla,
oldText y newText en sí estaban correctos, pero se añadieron claves falsas como requireUnique, oldText2, matchCase e in_file; la tasa de reproducción variaba según el historial del agente y si se incluían thinking blocks
- Claude Code es un arnés cerrado, pero realiza muchas correcciones laxas, como reintentar llamadas incorrectas, alias de parámetros, ajuste de tipos, recuperación de Unicode y filtrado de claves desconocidas, y no usa el modo
strict
- Las llamadas a herramientas
strict de Anthropic eliminaron este problema; si, a medida que mejora el rendimiento de los modelos, los esquemas alternativos de herramientas pueden quedar en desventaja, los arneses necesitan garantías más fuertes, como restricciones gramaticales
La regresión observada en la herramienta de edición de Pi
- Mientras se seguía un issue de Pi, se descubrió que los modelos Claude más recientes agregaban campos inexistentes dentro del arreglo
edits[] al invocar la herramienta de edición de Pi
- No ocurrió en un modelo pequeño, sino en Opus 4.8, y el mismo fenómeno también se confirmó en Sonnet 5
- El mismo problema no aparecía en modelos anteriores de Anthropic, por lo que los modelos recientes de alto rendimiento se comportan peor en este esquema de herramienta en particular
- Fable no se probó porque existe la posibilidad de que un clasificador degrade silenciosamente la solicitud a Opus
Las llamadas a herramientas se parecen a generar texto
- Las llamadas a herramientas de un LLM funcionan haciendo que el modelo, tras recibir el historial de conversación, el prompt de sistema y la lista de herramientas disponibles, genere un formato de llamada dentro de un gran prompt que incluye marcadores especiales
- Los argumentos previstos para una herramienta de edición de archivos pueden incluir
path y un arreglo edits, como sigue
{
"path": "some/file.py",
"edits": [
{
"oldText": "text to replace",
"newText": "replacement text"
}
]
}
- El arnés valida los argumentos, realiza la edición y vuelve a pasar el resultado al modelo; si la validación falla, el modelo ve el error y normalmente lo intenta de nuevo
- El formato interno de los modelos de Anthropic no es público, pero se han filtrado marcadores
ANTML o han aparecido en comunicaciones públicas
- Este formato parece XML, pero más que XML real es una especie de señalización in-band cómoda para tokenización y entrenamiento
- Los parámetros de cadena de nivel superior pueden ir en línea
- Los arreglos de objetos parecen entrar en forma de serialización JSON
Generación sin restricciones y generación con restricciones gramaticales
- En términos generales, hay dos formas en que un modelo produce salida estructurada
- Pedirle al modelo que genere JSON conforme a un esquema y validarlo después
- Impedir desde el muestreador que se muestreen JSON inválido o formas que no coincidan con el esquema
- La segunda se conoce como decodificación consciente de la gramática o decodificación restringida, y enmascara los tokens que violan la gramática
- Si el esquema solo permite
oldText y newText, el muestreador puede impedir que se generen claves como "in_file" o "type"
- Sin esas restricciones, el modelo genera siguiendo convenciones aprendidas más que cumpliendo estrictamente un contrato abstracto
Patrones reales de falla
- La herramienta de edición de Pi usa un arreglo
edits porque admite múltiples sustituciones exactas de cadenas en una sola llamada
- En las llamadas fallidas se añadían campos no permitidos como estos
{
"oldText": "...",
"newText": "...",
"requireUnique": true
}
{
"oldText": "...",
"newText": "...",
"oldText2": "",
"newText2": ""
}
- Las claves falsas aparecidas en experimentos repetidos fueron variadas:
type, id, kind, unique, requireUnique, matchCase, in_file, forceMatchCount, children, notes, cost, oldText2, newText2, oldText_2, newText_2, event.0.additionalProperties, entre otras
- En las llamadas incorrectas verificadas, los payloads reales de
oldText y newText eran correctos byte por byte, pero al final del objeto se añadían claves absurdas, por lo que la llamada era rechazada
- La reproducción depende mucho del contexto
- No se reprodujo con un prompt nuevo de un solo turno del tipo “edit this file”
- Sí se reprodujo con un historial de agente en el que el modelo leía el archivo, diagnosticaba el problema y armaba una edición de varias líneas
- Hacía falta el transcript de Petr Baudis para reproducirlo
- Al continuar esa sesión de usuario, Opus 4.8 falla con una probabilidad de alrededor del 20%
- Al quitar los thinking blocks del historial, la tasa de falla se reduce a la mitad
- Al activar llamadas a herramientas
strict, el problema desapareció en esa ejecución
Por qué empeoró
- La hipótesis más fuerte es que esto no es una degradación aleatoria del rendimiento, sino un producto del entrenamiento
- Los modelos anteriores de Anthropic fueron entrenados con algunas herramientas, pero antes de que arneses proporcionados por usuarios como Claude Code se consolidaran como un objetivo claro
- Es muy probable que los modelos recientes de Anthropic hayan recibido postentrenamiento con Claude Code o arneses muy parecidos, y que en ese entorno hayan aprendido tanto llamadas exitosas a herramientas como errores tolerados
- La herramienta de edición de Claude Code no tiene la estructura anidada
edits[] de Pi, sino una estructura plana más cercana a file_path, old_string, new_string y el opcional replace_all
- El cliente de Claude Code corrige una cantidad considerable de errores, como reintentos ante uso incorrecto de herramientas, alias de parámetros, coerción de tipos, recuperación de Unicode y filtrado de claves desconocidas
- Si el aprendizaje por refuerzo ocurre dentro de ese arnés o una simulación de él, incluso llamadas a herramientas ligeramente incorrectas pueden completar la tarea y recibir recompensa
- Cuando otro arnés ofrece una herramienta de edición con el mismo significado pero otro esquema, para el modelo puede convertirse cada vez más en una herramienta fuera de distribución
- En el lanzamiento de Opus 4.5 se adaptaba muy bien a otras herramientas de edición, pero la dirección observada ahora muestra que los esquemas alternativos de herramientas pueden quedar en desventaja dentro de un ecosistema de herramientas particularmente permisivo
- Existe una text editor tool documentada, pero Claude Code no sigue exactamente ese formato, y el funcionamiento interno de Claude Code no es visible porque es un arnés de código cerrado
El arnés laxo de Claude Code
- Claude Code es de código cerrado, pero al ver código reducido se aprecia que es muy permisivo con los datos entrantes
- Revisa si en el texto visible del modelo se filtró marcado
<invoke; si es así, emite telemetría y luego reintenta la llamada incorrecta con su propia máquina de estados
- Tiene recuperación de escapes Unicode que corrige secuencias
\uXXXX rotas y lone surrogates dentro de valores de cadena
- También tiene alias de parámetros específicos por herramienta
Edit acepta old_str, old_string, new_str, new_string
- Acepta
path como alias de file_path
- Las claves inesperadas se filtran silenciosamente
- No usa el modo
strict
- Anthropic aplica límites de complejidad a las definiciones de herramientas en modo
strict, lo que puede hacer fallar solicitudes a la API
- Esa parece ser la razón por la que Claude Code no intenta usar el modo
strict
Modo strict y otros ecosistemas
- Tanto los modelos como los arneses de Anthropic son cerrados, por lo que es difícil determinar si el mismo problema aparecerá también en otros arneses
- Los modelos Codex también son cerrados, pero el arnés no lo es
- gpt-oss fue entrenado explícitamente para usar el formato de respuesta harmony de OpenAI, y hay mucha documentación que muestra la forma de pensar de OpenAI
- harmony convierte los canales y los tipos de contenido de llamadas a herramientas en parte del formato del prompt, y puede incluir marcadores como
<|constrain|>json en el cuerpo de la llamada a la herramienta
<|start|>assistant<|channel|>commentary to=functions.get_weather
<|constrain|>json<|message|>{"location":"San Francisco"}<|call|>
<|constrain|>json permite que la pila de inferencia encuentre fácilmente el límite en el que debe cambiar a muestreo restringido por JSON dentro del cuerpo de la llamada a la herramienta
- En los modelos GPT alojados también existe la opción de proporcionar una gramática LARK para la gramática que deben seguir las herramientas de usuario
- Anthropic también parece hacer algo similar en modo
strict, pero con parámetros de arreglos anidados el modelo debe generar contenido largo de archivo multilínea como JSON escapado dentro de literales de cadena
- Las claves falsas aparecen justo después de cerrar una cadena
newText de cientos de tokens, en un punto de alta entropía donde el modelo debe elegir entre } y , "..."
- Opus 4.8 y Sonnet 5 parecen tener una distribución previa más fuerte sobre la forma de las llamadas a herramientas de edición, y esa distribución previa está más cerca del esquema plano de edición de Claude Code
- Que el modo
strict de Anthropic corrija el problema puede deberse a que, del lado del servidor, se rechaza el muestreo de claves no permitidas por la estructura del esquema JSON
- En los modelos Codex probados no se observó este tipo de regresión, y se excluyó 5.6 porque no se tenía acceso
Implicaciones para el diseño de arneses
- En los modelos de Anthropic, los esquemas de herramientas quizá no sean contratos abstractos neutrales
- Algunas formas de herramienta son cercanas a lo visto en el postentrenamiento, y otras son lejanas
- Algunas formas pueden ser fáciles dentro de la codificación oculta del proveedor, mientras que otras obligan a escribir, tras largas cadenas multilínea, objetos JSON escapados grandes dentro de arreglos anidados, lo cual funciona de manera difícil
- Aunque el modelo entienda el esquema, bajo presión puede fallar al muestrear la estructura exacta
- En Anthropic, activar el muestreo
strict puede hacer que este problema desaparezca
- Sin embargo, el comportamiento de los modelos recientes muestra el impacto del aprendizaje por refuerzo en los modelos, y pelear contra la distribución previa de un arnés específico puede ser desfavorable para obtener el máximo rendimiento
- Claude Code no es open source y tampoco se sabe qué hace en su entorno de RL, por lo que es difícil asumir que el comportamiento entrenado para Claude Code se transfiera limpiamente a otras herramientas
- Cuanto más postentrenamiento ocurra dentro de un arnés dominante, más tendrán que heredar otros arneses las peculiaridades de ese arnés
- La decodificación restringida puede tener trade-offs de calidad, pero si los modelos recientes mejoran su capacidad para resolver tareas mientras empeora su capacidad de emitir fielmente esquemas alternativos de herramientas, hace falta una garantía más fuerte en alguna parte del arnés
1 comentarios
Comentarios de Lobste.rs
Si te da curiosidad Fable, entiendo que ahora Fable siempre avisa explícitamente cuando hace un downgrade
A mí también me atrapó el clasificador una vez; supongo que “ordena los bugs por severidad” sonó como investigación de seguridad
Sé que dijeron que no lo harían a escondidas, pero todavía no he podido verificar el mecanismo que usan para el downgrade
Si esta hipótesis es correcta, el impacto podría ir más allá de los agentes de código
Cualquier aplicación que dependa de llamadas a herramientas estables podría sufrir una degradación de rendimiento similar después de que el modelo haya sido ajustado adicionalmente para adaptarse al entorno de ejecución preferido de cierto proveedor
Por cierto, publiqué esto como
ai, no comovibecodingEn este sitio de verdad es difícil entender dónde están los límites de
vibecodingEsta publicación tiene mucho más que ver con los LLM de base, el aprendizaje por refuerzo y la construcción del entorno de ejecución que los rodea
Si hasta esto cuenta como
vibecoding, entonces no sé para qué queda la etiquetaaivibecodingse ha convertido en una enorme letra escarlata que se le pega a cualquier cosa que toque aunque sea un poco a la IA generativa, o que parezca que la tocaEn las últimas semanas, publicaciones de blog con aire pretencioso, README de proyectos importantes que prohíben contribuciones de LLM, e incluso textos llenos de frases tipo “no es X sino Y” terminaron todos con la etiqueta
vibecodingPersonalmente ya renuncié por completo a prestarle atención a esa etiqueta. La comunidad la pone de manera tan refleja que su significado real se perdió
Aun así, en esta publicación en particular sí estoy de acuerdo con que lleve la etiqueta
vibecoding, porque trata sobre modelos que efectivamente se usan para eso, por así decirloAl mismo tiempo, también estoy de acuerdo en que, precisamente por la razón señalada, no se debería quitar
ai. Quisiera volver a agregarla, pero por alguna razón esa opción no aparece en esta publicaciónNo sorprende. La dependencia del proveedor probablemente sea parte del plan
Algo como “si ya pagas la suscripción de Claude y además nos estás enviando todo tu código, entonces también tienes que usar sí o sí una UI gratuita que quizá, por separado del modelo, ni siquiera sea un mecanismo de dependencia lo bastante fuerte” no se parece mucho a cómo suele funcionar la dependencia pura del proveedor
Tiene sentido que el modelo funcione de forma óptima en el entorno de ejecución en el que fue entrenado, es decir, el entorno creado por los desarrolladores del modelo
Si pasó por muchísimo aprendizaje por refuerzo sobre trazas como las de Claude Code, era de esperarse que rindiera bastante peor en un entorno de ejecución que no se comporte como Claude Code
En lo personal, me sorprendió más bien que pareciera funcionar bastante bien incluso en entornos de ejecución de terceros como Pi
También parece razonable que el bug solo aparezca en las partes profundas de la traza del agente
A principios de este año batallé con un bug en los modelos GPT 5.2 y 5.3 donde, en etapas avanzadas de la traza, el agente emitía
ls -ლაen vez dels -laLo dejé anotado brevemente aquí: https://github.com/openai/codex/issues/7988
Según mi experiencia, esto también solo pasaba cuando la traza se hacía profunda
En contextos largos, da la impresión de que el modelo ya no puede “pensar” con claridad y vuelve a instintos más primitivos
Probablemente ese sea el punto donde la diferencia entre la distribución de entrenamiento del modelo y el entorno de ejecución, o la tarea que el usuario le impone al modelo, afecta el rendimiento de la manera más dramática
El problema es que recibió tanto aprendizaje por refuerzo que retrocede en otros entornos de ejecución en comparación con versiones anteriores
A esta altura también habría que preguntarse algo como: “¿no estará empezando además otro tipo de sobreajuste?”