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 serclient.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 conopenai>=1.0.0da error. - Deprecada (funciona con aviso): en Pydantic v2, métodos como
.dict()o.parse_obj()se mantienen, pero emitenDeprecationWarning. Lo correcto hoy es usarmodel_dump()ymodel_validate(). - Renombrada en un framework: en Next.js 16, el archivo
middlewarepasa a llamarseproxy, yrevalidateTagcon 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::DeprecationWarningnpm 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 encuentras | Acción | Qué 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 corregir | Que "lo arregle" cambiando la versión de la dependencia sin pedírtelo |
| La API existe pero está deprecada | Convierte las deprecaciones en fallos en tests y lint (sección siguiente) | Silenciar el warning |
| La librería incluye documentación para agentes dentro del paquete | Apunta tu AGENTS.md a esa carpeta | Descargar documentación genérica de internet |
La web de la librería publica llms.txt | Indica al agente que lo lea antes de tocar esa integración | Pegar páginas enteras de documentación en el chat |
| Nada de lo anterior | Changelog oficial o un MCP de documentación como Context7 | Fiarte 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 funcioneComo 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::DeprecationWarningEn 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.mdsolo añade ruido. - Versión antigua a propósito: si tu proyecto no puede actualizarse, la plantilla sigue siendo útil, pero entonces el bloque
filterwarningspuede 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.