Ilustración abstracta de dos engranajes de distinto tamaño que no encajan, uno en tonos antiguos y otro en colores vivos, unidos por una pieza de ajuste luminosa

API obsoleta en el código de tu agente: fija la versión


Cuando un agente de código usa una API que no existe en tu proyecto, casi nunca es una alucinación al azar. Escribe el código de la versión de la librería que más vio durante el entrenamiento, y esa no tiene por qué ser la que tienes instalada. El arreglo consiste en darle tu versión real como contexto y en que tus checks fallen cuando se equivoque.

Síntomas: el código funciona en la cabeza del modelo, no en tu repo

El desajuste de versiones da dos síntomas distintos, y el peligroso es el silencioso. El primero salta enseguida: un import que no existe, un método eliminado o una opción de configuración que la librería ya no reconoce. El segundo pasa desapercibido: el código funciona, pero con una API deprecada que dejará de existir en la próxima versión mayor.

Ejemplos reales de ambos tipos, todos documentados por sus mantenedores:

  • Eliminada (falla al ejecutar): en el SDK de Python de OpenAI, openai.ChatCompletion.create() pasó a ser client.chat.completions.create() en la versión 1.0.0, según la guía de migración oficial publicada el 08/11/2023. Llamar a la forma antigua con openai>=1.0.0 da error.
  • Deprecada (funciona con aviso): en Pydantic v2, métodos como .dict() o .parse_obj() se mantienen, pero emiten DeprecationWarning. Lo correcto hoy es usar model_dump() y model_validate().
  • Renombrada en un framework: en Next.js 16, el archivo middleware pasa a llamarse proxy, y revalidateTag con un solo argumento queda deprecado y produce un error de TypeScript.

Si el agente tiene permiso para ejecutar comandos, el primer tipo suele corregirlo solo al ver el error. Con el segundo no ocurre así: los tests pasan, el diff parece limpio y la deuda llega a main.

Causa: fecha de corte y versión dominante

El modelo no sabe qué versión tienes a menos que se lo digas o la lea él mismo. Cada modelo tiene una fecha de corte de conocimiento. En la tabla oficial de modelos de Anthropic, el corte fiable de Claude Haiku 4.5 es febrero de 2025, el de Claude Sonnet 5 es enero de 2026 y el de Claude Opus 5.5 es junio de 2026. Lo que salió después, el modelo no lo conoce de memoria.

Una fecha reciente tampoco lo resuelve todo, por dos motivos:

  • Frecuencia: aunque el modelo haya visto la versión nueva, en sus datos puede haber muchos más ejemplos de la antigua. Sin más pistas, tiende a la forma más habitual.
  • Desajuste inverso: si tu proyecto está anclado a una versión antigua, un modelo muy actual puede escribir una API que tu versión aún no tiene. El problema es la diferencia entre lo que conoce el modelo y lo que dice tu lockfile, no la antigüedad del modelo.

Por eso cambiar de modelo no es la solución de fondo. La solución es que la versión instalada entre en el contexto de la sesión.

Confírmalo con tres comprobaciones

Antes de reescribir nada, confirma que el problema es de versión y no de lógica. Estos comandos responden a tres preguntas: qué versión tienes, si el símbolo existe en ella y si tu código llama a algo deprecado.

# 1. Versión instalada de verdad (no la del package.json ni la que "cree" el agente)
npm ls next
pip show pydantic

# 2. ¿Existe en tu versión el método que ha usado el agente?
grep -rn "def model_dump" "$(python -c 'import pydantic, os; print(os.path.dirname(pydantic.__file__))')"

# 3. ¿Hay llamadas deprecadas escondidas? Conviértelas en fallos
pytest -W error::DeprecationWarning

npm ls con un nombre de paquete muestra solo las rutas del árbol donde está instalado. pip show devuelve Version y Location. Si el grep no devuelve nada, tu Pydantic no tiene ese método y el agente ha escrito código para otra versión. El flag -W de pytest hace que cualquier DeprecationWarning rompa el test que la provoca.

Añade una cuarta comprobación: pregúntale al agente directamente "¿qué versión de X estás asumiendo?". Si la respuesta no coincide con la del paso 1, ya tienes el diagnóstico.

Qué hacer según el resultado

La acción depende de si la API falla, avisa o simplemente no aparece en ninguna documentación a mano. Esta tabla sirve como árbol de decisión.

Lo que encuentrasAcciónQué evitar
La API no existe en tu versión (error al importar o ejecutar)Pásale al agente el error y la versión exacta, y pídele que lea el código fuente instalado antes de corregirQue "lo arregle" cambiando la versión de la dependencia sin pedírtelo
La API existe pero está deprecadaConvierte las deprecaciones en fallos en tests y lint (sección siguiente)Silenciar el warning
La librería incluye documentación para agentes dentro del paqueteApunta tu AGENTS.md a esa carpetaDescargar documentación genérica de internet
La web de la librería publica llms.txtIndica al agente que lo lea antes de tocar esa integraciónPegar páginas enteras de documentación en el chat
Nada de lo anteriorChangelog oficial o un MCP de documentación como Context7Fiarte de la primera respuesta sin comprobar la versión

Next.js es el ejemplo más claro de la tercera fila. Según su guía de actualización a la versión 16, desde la 16.2 la documentación viene dentro del paquete en node_modules/next/dist/docs/, y npx @next/codemod@canary agents-md genera en AGENTS.md un bloque titulado "This is NOT the Next.js you know". Ese bloque pide al agente que lea esa documentación antes de escribir código.

Para la cuarta fila, la propuesta llms.txt define un archivo Markdown en la raíz del sitio (o en una subruta como /docs/llms.txt) con enlaces curados a versiones limpias de la documentación. Para la última, Context7 se instala en Claude Code con npx ctx7 setup --claude y acepta la versión en el propio prompt. Su README advierte de que los proyectos son contribuidos por la comunidad y no garantiza su exactitud, así que úsalo como apoyo y no como verdad.

Plantilla de AGENTS.md para anclar versiones

Un bloque corto en AGENTS.md evita repetir la versión en cada prompt. Codex lo lee desde la raíz de Git hasta tu directorio actual y deja de añadir archivos al llegar a 32 KiB por defecto. Claude Code, según su documentación de memoria, también puede leer AGENTS.md, solo o junto a CLAUDE.md. Mantén el bloque breve y específico.

Esta plantilla recoge las dependencias en las que un desajuste sale caro, dónde leer su documentación y qué no debe hacer el agente:

## Versiones fijadas (fuente de verdad: lockfile)
- pydantic 2.x: usa model_dump / model_validate. Prohibido .dict() y .parse_obj()
- openai (Python) >= 1.0: usa client.chat.completions.create
- next 16.x: el antiguo middleware es proxy.ts. Docs en node_modules/next/dist/docs/

## Antes de usar una API de estas librerías
1. Comprueba la versión instalada (npm ls / pip show)
2. Lee el código o la doc instalada, no tu memoria
3. Si no encuentras el símbolo, dilo y para. No inventes alternativas

## Prohibido sin permiso explícito
- Subir o bajar versiones de dependencias para que tu código funcione

Como referencia práctica, no como dato: incluye solo las librerías con cambios incompatibles recientes o que usas mucho. Si listas las cuarenta dependencias, el bloque crece y pierde peso frente al resto de instrucciones.

Convierte las deprecaciones en fallos

Las instrucciones son contexto y no obligan a nada, así que la red de seguridad tiene que ser un check que falle. La propia documentación de Claude Code aclara que trata CLAUDE.md como contexto, no como configuración de obligado cumplimiento. Si el agente se salta la plantilla, el check es lo que lo detiene.

En Python, esta configuración hace que cualquier llamada deprecada que se ejecute durante los tests rompa la suite:

# pytest.ini
[pytest]
filterwarnings =
    error::DeprecationWarning

En TypeScript, la regla @typescript-eslint/no-deprecated señala cualquier uso de código marcado con @deprecated en JSDoc. Necesita información de tipos (typed linting, no incluido aquí) y viene activada en la configuración strict-type-checked. Una vez activa, el agente recibe el error en su bucle de lint y puede corregirlo sin que tengas que revisar línea por línea.

Un matiz: error::DeprecationWarning también convierte en error los avisos que lanzan tus dependencias por dentro. Si la suite se llena de fallos ajenos a tu código, filtra por módulo en lugar de quitar la regla.

Cuándo no merece la pena montar todo esto

Todo esto se amortiza en proyectos que vas a mantener, no en código de usar y tirar. Hay casos en los que sobra:

  • Scripts de un solo uso o prototipos: si el código no va a vivir más de una semana, basta con el error de ejecución y un prompt con la versión.
  • Librerías estables sin cambios incompatibles en años: anclar la versión en AGENTS.md solo añade ruido.
  • Versión antigua a propósito: si tu proyecto no puede actualizarse, la plantilla sigue siendo útil, pero entonces el bloque filterwarnings puede generar fallos que no vas a corregir. Aplícalo solo a tu propio paquete.
  • Repositorios de terceros o código privado sensible: antes de conectar un MCP externo de documentación, revisa qué datos salen de tu máquina en cada consulta. No lo actives por defecto.

Preguntas frecuentes

¿Se arregla usando el modelo con la fecha de corte más reciente?

Solo en parte. Reduce los fallos con versiones nuevas, pero puede empeorarlos si tu proyecto usa una versión antigua, porque el modelo tenderá a escribir APIs que aún no tienes. Lo que funciona con cualquier modelo es darle tu versión instalada como contexto.

¿Qué hago si el agente propone actualizar la librería para que su código funcione?

Trátalo como un cambio aparte que decides tú, no como parte de la tarea. Una actualización mayor puede romper otras partes del proyecto que el agente no ha mirado. Pídele que primero adapte el código a la versión instalada y, si la actualización tiene sentido, ábrela en su propia rama con su propio diff.

Compartir X LinkedIn