7 min

Claude Code en monorepos: limitar el contexto y mantener la precisión

Claude Code en monorepos puede desviarse cuando el repo es enorme. Aprende a definir límites, resúmenes locales y flujos repetibles para mantener las respuestas precisas.

Claude Code en monorepos: limitar el contexto y mantener la precisión

Por qué los monorepos grandes hacen a Claude menos preciso

Claude Code en monorepos puede sentirse impredecible por una razón sencilla: el repositorio es más grande de lo que el modelo puede mantener en memoria de trabajo a la vez.

“El contexto” es el conjunto de archivos, fragmentos, notas e instrucciones que se le han mostrado a Claude para esta tarea, además de lo que puede inferir de ellos. Cuando faltan detalles clave, Claude rellena huecos con conjeturas. En un repo grande, eso ocurre con más frecuencia.

Tres modos de fallo aparecen una y otra vez:

Primero, archivos perdidos. Un cambio que parece seguro en una carpeta en realidad depende de un tipo compartido, una regla de configuración o un paso de build definido en otro lugar. Si esa dependencia no está en el contexto, Claude puede editar con seguridad la cosa equivocada o detenerse temprano porque no ve la verdadera fuente de la verdad.

Segundo, similitud falsa. Los monorepos a menudo contienen múltiples paquetes que se parecen: dos módulos de auth, tres clientes de API, o varias apps React con estructuras de carpetas similares. Claude puede mezclar patrones entre ellos, actualizar un helper en el paquete equivocado o importar desde un nombre de módulo “casi correcto”.

Tercero, deriva temporal. Las grandes bases de código suelen tener formas antiguas y nuevas de hacer lo mismo. Si Claude solo ve archivos antiguos, puede copiar patrones obsoletos (opciones de config en desuso, APIs legadas) aunque el equipo ya haya cambiado.

Un ejemplo real común: pides un pequeño cambio en una UI de facturación y Claude edita un componente payments compartido usado por otras apps porque nunca vio el wrapper específico de la app que debería haberse cambiado.

El objetivo no es mostrarle a Claude todo el monorepo. El objetivo es proporcionar entradas más pequeñas y deliberadas que aún respondan la pregunta: el paquete que vas a cambiar, sus dependencias directas y una o dos “fuentes de la verdad” para tipos y configuración. Además, señala zonas de “no tocar” (otras apps, infra, código generado) y confirma qué paquete es el responsable del comportamiento.

Empieza definiendo la tarea, no el repo

La precisión depende menos de cuánto código pegues y más de cuán claramente describas el trabajo.

Empieza con el resultado que quieres: un arreglo específico, un refactor o una respuesta. Una “pregunta sobre el código” puede quedarse a alto nivel. Una solicitud de “hacer un cambio” necesita límites, entradas y comprobaciones de éxito.

Antes de compartir nada, escribe una frase que termine esta oración: “Después de que termines, debo poder…”. Por ejemplo: “ejecutar las pruebas unitarias del paquete X sin fallos” o “ver el nuevo campo en la respuesta de la API para el endpoint Y.” Esa frase se convierte en la estrella del norte cuando el repo es enorme.

Para cambios, comparte el conjunto más pequeño de artefactos que puedan probar que el cambio es correcto: el/los puntos de entrada, los tipos/interfaces o schema relevantes, una prueba que falle o un paso de reproducción con el resultado esperado, y cualquier configuración que afecte este camino (rutas, feature flags, build o reglas de lint). Si ayuda, añade un pequeño mapa de carpetas del paquete para que Claude entienda para qué sirve cada directorio.

Sé explícito sobre qué no mirar. Di: “Ignorar archivos generados, carpetas vendor, outputs de build, snapshots y lockfiles a menos que lo pida.” Eso evita tiempo perdido y ediciones en lugares que no revisarás.

También fija expectativas para la incertidumbre. Pide a Claude que marque suposiciones y desconocidos en lugar de adivinar. Por ejemplo: “Si no puedes ver dónde se llama esta función, dilo y propone 2 formas de localizarla.”

Dibuja límites claros que Claude no debe cruzar

En un monorepo grande, la precisión baja cuando el modelo empieza a “ayudar” trayendo código cercano que no forma parte de la tarea. La solución es sencilla: define qué está dentro y qué está fuera antes de pedir cambios.

Empieza con un límite que coincida con cómo está organizado tu repo: un paquete, un servicio, una app o una librería compartida. Si el cambio es “actualizar la UI de checkout”, el límite probablemente sea un paquete de la app, no todos los lugares donde aparece la palabra “checkout”.

Señales que ayudan a Claude a quedarse en su sitio incluyen convenciones de carpetas (apps/, services/, packages/, libs/), manifiestos de paquete (exports y dependencias), puntos de entrada públicos (archivos index, componentes exportados, handlers) y tests (a menudo revelan la superficie prevista). Un README dentro de la carpeta puede ser el marcador de límite más rápido.

Los límites funcionan mejor cuando nombras los puentes entre ellos. Señala las interfaces específicas que Claude puede tocar y trata todo lo demás como fuera de límites. Los puentes típicos son contratos HTTP API, topics de eventos y payloads, tipos compartidos o un pequeño conjunto de funciones exportadas.

También nombra zonas “no tocar” siempre que el cambio no deba afectarlas. Las comunes son configuraciones de infraestructura y despliegue, lógica de seguridad y auth, facturación y pagos, migraciones de datos y esquemas en producción, y librerías compartidas usadas por muchos equipos.

Un detalle concreto de prompt que ayuda:

“Haz cambios solo dentro de packages/cart/ y sus tests. Puedes leer tipos compartidos en packages/types/ pero no los modifiques. No edites infra, auth o billing.”

Cómo escribir resúmenes locales útiles

La precisión mejora cuando proporcionas un mapa pequeño y estable del área que quieres cambiar. Un “resumen local” es ese mapa: lo suficientemente corto para leerse rápido, lo bastante específico para evitar conjeturas.

Mantén cada resumen en unas 10 a 20 líneas. Escríbelo como si le entregases el código a un compañero nuevo que solo necesita tocar este límite, no todo el repo. Usa lenguaje claro y nombres reales del código: carpetas, paquetes, funciones exportadas.

Un resumen útil responde cinco preguntas:

  • Para qué sirve este paquete/servicio y para qué no sirve (límites de alcance)
  • Dónde empieza el trabajo (puntos de entrada principales como archivos clave, rutas, comandos o componentes)
  • Qué es seguro llamar desde fuera (APIs públicas, módulos exportados, eventos, endpoints)
  • De qué depende (bases de datos, colas, caches, config, servicios externos)
  • Qué reglas importan aquí (patrones de nombres, estilo de errores, logging y cómo se escriben las pruebas)

Añade una línea de “gotchas”. Aquí evitas errores costosos: cachés ocultos, feature flags, pasos de migración y cualquier cosa que falle silenciosamente.

Aquí tienes una plantilla compacta que puedes copiar:

Local summary: <package/service name>
Purpose: <1 sentence>
Scope: <what to touch> | Not: <what not to change>
Entry points: <files/routes/commands>
Public surface: <exports/endpoints/events>
Data sources: <tables/collections/queues/caches>
Conventions: errors=<how>, logging=<how>, tests=<where/how>
Gotchas: <flags/caching/migrations/edge cases>

Ejemplo: si editas un paquete de facturación, anota la función exacta que crea facturas, los nombres de tabla a los que escribe y la regla para errores reintentables. Entonces Claude puede enfocarse en ese límite en vez de deambular por auth compartido, config o paquetes no relacionados.

Dónde viven los resúmenes y cómo mantenerlos actualizados

Despliega cuando esté listo
Usa hosting integrado para desplegar y validar comportamiento rápidamente.

El mejor resumen es el que Claude ve cuando lo necesita. Ponlo junto al código que describe para que sea difícil de ignorar y fácil de actualizar. Por ejemplo, mantén un corto SUMMARY.md (o una sección en README.md) dentro de cada paquete, servicio o directorio de app en lugar de un documento gigante en la raíz del repo.

Una estructura simple y repetible ayuda. Manténlo lo bastante corto como para que la gente lo mantenga:

  • Qué es esta carpeta (propósito en 1–2 frases)
  • Superficie pública (puntos de entrada principales, módulos exportados o APIs)
  • Dependencias clave (internas y externas)
  • Límites (qué no debe importar o modificar)
  • Cómo probar (la comprobación local más rápida)
  • Last updated: YYYY-MM-DD - <what changed in one sentence>

Los resúmenes quedan obsoletos por razones predecibles. Trata las actualizaciones como actualizar una definición de tipo: parte de terminar el trabajo, no una tarea separada.

Actualiza el resumen cuando un refactor cambia estructura o nombres, un nuevo módulo se convierte en la forma principal de hacer algo, cambia un API/event/schema (aunque las pruebas sigan pasando), se mueven límites entre paquetes o se elimina/reemplaza una dependencia.

Un hábito práctico: cuando haces merge de un cambio, añade una línea “Last updated” indicando qué cambió. Herramientas como Koder.ai pueden ayudarte a mover más rápido en el cambio de código, pero el resumen es lo que mantiene futuros cambios precisos.

Un flujo paso a paso para permanecer dentro del contexto correcto

La precisión a menudo depende de cómo dosificas la conversación. Haz que Claude gane contexto en piezas pequeñas en lugar de adivinar a partir de un gran volcado.

Paso 1: Pide primero un mapa rápido

Antes de cualquier edición, pide a Claude que describa lo que ve y qué necesita. Un buen mapa es corto: paquetes clave implicados, punto de entrada del flujo y dónde viven tests o tipos.

Prompt:

“Crea un mapa de este cambio: paquetes implicados, flujo principal y puntos probables de toque. No propongas código aún.”

Paso 2: Empieza con una porción y un límite

Elige una porción estrecha: una feature, un paquete, un flujo de usuario. Declara el límite con claridad (por ejemplo: “Solo cambia packages/billing-api. No toques shared-ui o infra.”).

Un flujo que te mantiene en control:

  • Define el objetivo y el límite en una frase.
  • Exige suposiciones y desconocidos (Claude debe listarlos).
  • Pide los archivos exactos que necesita a continuación (limítalo a 3–6).
  • Proporciona solo esos archivos, luego repite.
  • Exige un plan corto antes de cualquier parche.

Paso 3: Obliga a suposiciones explícitas y solicitudes de archivos

Si a Claude le falta algo, debe decirlo. Pídele que escriba: (1) suposiciones que está haciendo, (2) qué las podría falsar, y (3) los archivos siguientes necesarios para confirmarlas.

Ejemplo: necesitas añadir un campo a una respuesta Invoice en un paquete. Claude solicita el handler, la definición DTO/tipo y una prueba. Compartes solo esos. Si usas un builder basado en chat como Koder.ai, aplica la misma regla: proporciona el conjunto mínimo de archivos fuente y expande solo cuando realmente sea necesario.

Usa restricciones y contratos en tus prompts

Tu mejor defensa contra ediciones erróneas es un pequeño “contrato” dentro del prompt: qué puede tocar Claude, cómo juzgarás el éxito y qué reglas debe seguir.

Empieza con un límite fácil de obedecer y verificar. Sé explícito sobre dónde se permiten ediciones y nombra las zonas “no tocar” para que no haya tentación de deambular.

Plantilla de contrato:

  • Solo modificar archivos bajo packages/payments/.
  • No editar packages/auth/, infra/ ni configs compartidos.
  • Si necesitas cambios fuera del alcance, detente y pregunta primero.
  • Mantén los cambios mínimos: arregla el bug, evita refactors.

Luego define comprobaciones de aceptación. Sin ellas, Claude puede producir código que parece correcto pero rompe las reglas reales del repo.

  • Ejecutar pruebas unitarias del paquete (nombra el comando que usas).
  • Ejecutar lint/format (nombra la herramienta, o di “usa la config existente”).
  • Ejecutar typecheck/build para el paquete.
  • Confirmar que la app sigue arrancando (un comando de run simple basta).

Las restricciones de estilo también importan. Dile a Claude qué patrones seguir y cuáles evitar, según lo que tu base de código ya hace. Por ejemplo: “Usa los helpers de error existentes en este paquete; no agregues dependencias nuevas; mantén nombres en camelCase; no introduzcas una nueva capa arquitectónica.”

Finalmente, exige un plan corto antes de cualquier edición:

“Antes de editar, lista los 3–5 archivos que esperas tocar y el cambio de comportamiento exacto. Espera aprobación.”

Ejemplo:

“Arreglar el redondeo de totales en invoices. Solo editar packages/billing/src/ y tests en packages/billing/test/. Aceptación: pnpm -C packages/billing test y typecheck. Sigue los utils de money existentes; no reescribir tipos API. Proporciona un plan de 4 pasos primero.”

Trampas comunes que causan deriva y ediciones erróneas

Trabaja en porciones pequeñas
Construye una característica a la vez en chat en lugar de volcar todo un monorepo.

La forma más rápida de obtener ediciones equivocadas en un monorepo es darle a Claude demasiado a la vez. Cuando pegas un gran montón de código, a menudo recurre a patrones genéricos en lugar del diseño específico que tu repo ya usa.

Otra trampa es dejar que adivine la arquitectura. Si no muestras puntos de entrada reales, puede elegir el primer archivo que parezca plausible y cablear la lógica allí. En la práctica, la precisión viene de un pequeño conjunto de archivos “fuente de la verdad” (módulos de entrada, routers, registradores de servicios, docs de límites de paquetes). Si esos no están en contexto, el modelo rellena huecos.

Los nombres también lo engañan. Los monorepos suelen tener paquetes como ui, ui-kit, shared-ui, o helpers duplicados como date.ts en dos lugares. Si mezclas snippets de ambos, Claude puede parchear un archivo mientras razona sobre el otro. Ejemplo: pides cambiar un estilo de botón, edita packages/ui/Button.tsx, pero la app importa packages/ui-kit/Button.tsx. El diff parece correcto, pero nada cambia en producción.

La configuración es otra fuente de deriva silenciosa. El comportamiento puede depender de env vars, feature flags, settings de build o tooling del workspace. Si no lo mencionas, Claude puede quitar una comprobación “rara” que solo importa cuando un flag está activo, o añadir código que rompe un paso de build.

Señales de alerta de deriva:

  • La respuesta habla de “patrones típicos” sin nombrar tus archivos reales
  • Introduce un nuevo util compartido en vez de usar uno existente
  • Cambia imports entre límites de paquete
  • Ignora feature flags o ramas específicas de env
  • Sugiere añadir una dependencia a un paquete compartido central

Trata los imports entre paquetes como una decisión, no como el comportamiento por defecto. Mantén las ediciones locales a menos que expandas el alcance intencionalmente.

Lista rápida antes de pedirle algo a Claude

La forma más rápida de obtener ediciones correctas es empezar con límites, no con volumen. Un buen prompt se siente un poco estricto: le dice a Claude dónde mirar, qué ignorar y qué significa “hecho”.

Antes de pegar código, escribe una breve introducción que fije el trabajo en un lugar del repo. Nombra el paquete, la carpeta exacta y el objetivo específico. Luego incluye un resumen local (propósito, dependencias clave, convenciones importantes) y el archivo de entrada que ancle el cambio.

Checklist:

  • Límite: Trabaja solo en <package>/<path>. Objetivo: <one sentence>. Ignorar todo lo demás a menos que se pida.
  • Inicio de contexto: Resumen local: <5-10 lines>. Archivo de entrada: <path/to/file>.
  • Restricciones: Carpetas permitidas: <...>. No debe cambiar: <folders/files or APIs>. Mantener comportamiento: <what must stay true>.
  • Solicitudes de archivos primero: “Antes de proponer cambios, lista los archivos mínimos que necesitas ver (max 5) y por qué.”
  • Formato de salida: “Responde primero con un plan corto. Tras mi confirmación, da sugerencias en estilo patch por archivo.”

Si Claude propone cambios fuera de tu límite, trátalo como una señal: o aprietas el prompt, o expandes el límite a propósito y lo vuelves a declarar claramente.

Ejemplo: hacer un cambio en un paquete sin despertar todo el monorepo

Prototipa móvil sin fricciones
Boceta un flujo de app Flutter en chat y luego refina pantallas con límites claros.

Imagina que tu monorepo tiene apps/web-store (una app React) y packages/ui-kit (botones, inputs y estilos compartidos). Quieres una feature pequeña: añadir un botón “Save for later” en la página del carrito, usando un nuevo SaveIcon de ui-kit. Nada más debe cambiar.

Antes de pedir ediciones, crea dos resúmenes locales que actúen como límites. Manténlos cortos, específicos y opinativos sobre lo que importa.

# apps/web-store/LOCAL_SUMMARY.md
Purpose: Customer shopping UI.
Entry points: src/routes.tsx, src/pages/cart/CartPage.tsx
Cart rules: cart state lives in src/cart/useCart.ts
Do not touch: checkout flow (src/pages/checkout), payments, auth.
Tests: npm test -w apps/web-store

# packages/ui-kit/LOCAL_SUMMARY.md
Purpose: shared UI components.
Exports: src/index.ts
Icons: src/icons/*, add new icons by exporting from index.
Do not touch: theming tokens, build config.
Tests: npm test -w packages/ui-kit

Luego mantén el loop apretado:

  1. Mapa: “Este cambio está limitado a CartPage y a los íconos de ui-kit. No editar checkout/auth.”
  2. Suposiciones: exige una lista de suposiciones y espera confirmación.
  3. Solicitud de archivos: aprueba solo los pocos archivos que realmente necesita (CartPage, useCart, íconos de ui-kit, index de ui-kit).
  4. Plan: confirma que coincide con los límites.
  5. Ediciones: haz el diff más pequeño, luego solicita tests actualizados.

Después del cambio, documenta para que el contexto futuro siga siendo pequeño:

  • Actualiza ambos resúmenes locales con la nueva exportación y los archivos exactos tocados.
  • Añade una nota corta en el header de la página del carrito: qué hace el botón y dónde se maneja el estado.
  • Registra los comandos de test que pasaron (y cualquier snapshot actualizado).

Próximos pasos: haz esto repetible para tu equipo

Si funciona bien para una persona pero no para el resto, lo que falta suele ser repetibilidad. Haz que la “buena higiene de contexto” sea la opción por defecto, no un hábito personal.

Convierte tus mejores prompts en una plantilla de equipo

Guarda una plantilla de prompt que todos puedan copiar y rellenar. Manténla corta, pero estricta. Incluye el objetivo (qué significa “hecho”), el alcance permitido, límites duros (y por qué), un resumen local y un contrato de salida (plan primero, luego difs por archivo y tests).

Mantén los resúmenes actuales con una cadencia ligera

Evita grandes revisiones mensuales que nadie hace. Adjunta las actualizaciones de resumen al trabajo normal: cuando un cambio altera comportamiento, dependencias o APIs, actualiza el resumen local en la misma PR.

Una regla simple: si un compañero tendría que preguntar “¿dónde vive esto?” o “¿qué depende de esto?”, el resumen está desactualizado.

Si prefieres un flujo orientado a chat, Koder.ai puede ayudar a que este estilo de iteración sea más seguro. El modo de planificación te ayuda a acordar alcance y límites antes de que ocurran ediciones, y los snapshots con rollback te permiten probar cambios sin quedarte atascado cuando una conjetura resulta errónea.

Preguntas frecuentes

¿Por qué Claude es menos preciso en monorepos grandes?

Claude se vuelve menos preciso cuando no puede “ver” la verdadera fuente de la verdad.

En un monorepo grande, el modelo a menudo pierde un archivo de dependencia, confunde dos paquetes similares o copia un patrón antiguo porque eso fue lo que estuvo en contexto.

¿Cuánto código debo mostrar a Claude para una solicitud de cambio?

No intentes incluir todo el repo. Empieza con el conjunto más pequeño que pueda demostrar que el cambio es correcto.

Un buen punto de partida es:

  • Los punto(s) de entrada para el comportamiento
  • El tipo/interfaz/schema clave implicado
  • Una prueba que falla o un repro claro + resultado esperado
  • Cualquier configuración que afecte la ruta (rutas, flags, build/lint)
¿Qué archivos son las mejores “fuentes de la verdad” para incluir primero?

Comparte lo que ancla el comportamiento, no todo lo que tenga un nombre parecido.

Un conjunto práctico es:

  • El archivo donde empieza el comportamiento (ruta/handler/componente)
  • El archivo donde se define el “contrato” (DTO/tipo/schema)
  • La prueba que debería pasar (o un repro mínimo)
  • Uno o dos archivos de configuración que puedan cambiar el comportamiento en tiempo de ejecución
¿Cómo defino un límite claro que Claude no deba cruzar?

Elige un límite que coincida con cómo está organizado tu repo: un paquete, app o servicio.

Luego decláralo explícitamente, incluyendo qué está fuera de alcance. Ejemplos de restricciones:

  • “Solo modificar archivos bajo packages/cart/ y sus tests.”
  • “Puedes leer tipos compartidos, pero no los edites.”
  • “No tocar infra/auth/billing a menos que lo pida.”
¿Por qué a veces Claude edita el paquete equivocado aunque el cambio parezca obvio?

Porque los monorepos suelen contener módulos que se parecen (ui, ui-kit, shared-ui) y helpers duplicados (date.ts en varias ubicaciones).

Claude puede aplicar la idea correcta al paquete equivocado o importar desde un nombre de módulo “casi correcto”. Evítalo nombrando el paquete exacto y los puntos de entrada que quieres.

¿Qué es un “resumen local” y qué debe contener?

Un resumen local es un mapa corto del área exacta que quieres cambiar, normalmente 10–20 líneas.

Incluye:

  • Propósito y alcance (qué es / qué no es)
  • Puntos de entrada
  • Superficie pública (exports/endpoints)
  • Dependencias clave
  • Convenciones (errores/logs/tests)
  • Un “gotcha” que evite errores comunes
¿Dónde deben vivir estos resúmenes y cómo evito que queden obsoletos?

Colócalo junto al código que describe para que sea fácil de encontrar y actualizar.

Una configuración simple por defecto:

  • Un SUMMARY.md o una sección pequeña en el README.md del paquete
  • Un resumen por paquete/servicio/app (no un documento gigante en la raíz)
  • Una línea “Last updated” que cambias cuando estructura, APIs o límites cambian
¿Cómo evito que Claude adivine cuando falta contexto?

Dile a Claude desde el principio que marque suposiciones y desconocidos en lugar de adivinar.

Una regla útil:

  • Si no puede ver dónde se llama algo o cómo se configura, debe decirlo.
  • Debe proponer 2 maneras de localizar la verdad que falta (por ejemplo, “muéstrame el archivo del router” vs “muéstrame los exports del paquete”).
¿Cuál es un buen flujo paso a paso para trabajar en un monorepo?

Usa un bucle corto que obligue a ganar contexto en piezas pequeñas:

  1. Pide un mapa corto de puntos de contacto probables (sin código aún).
  2. Elige una porción + un límite.
  3. Exige una lista de suposiciones y los próximos 3–6 archivos necesarios.
  4. Aprueba solo esos archivos.
  5. Pide un plan y luego solicitudes de parches por archivo más comandos de test.
¿Cómo puedo hacer los prompts más seguros para que los cambios no se salgan del repo?

Escribe un mini “contrato” en tu prompt y hazlo ejecutable:

  • Rutas permitidas y zonas “no tocar”
  • “Detente y pregunta primero” si se necesitan cambios fuera del alcance
  • Política de cambio mínimo (arregla el bug, evita refactors)
  • Comprobaciones de aceptación (tests, lint/format, typecheck/build)

Esto facilita la revisión y reduce ediciones accidentales entre paquetes.

Related posts