AI Slop, fricción y redes sociales

Estos días he estado trabajando en una herramienta que automatiza algunos procesos, sin impacto directo en los clientes. Una buena oportunidad para experimentar: RPI, Don't read the code, dynamic memory con un montón de instrucciones, subagents, y hasta agentes en paralelo en algún momento.

La idea era seguir los consejos de twitter y subir un peldaño más en la escalera del AI Adoption level (1).

  1. Creo que el primero en describir algo así fue Steve Yegge y luego han sido re-escritos y modificados por cualquiera con un blog y tiempo libre.

El resultados:

  • Ficheros con más de 1.000 líneas de código. De aquí viene el artículo de instruir al agente para limitar el número de líneas por fichero.
  • Abstracciones e indirecciones que se solucionaban con un mock para los tests o un if con dos ramas
  • Bucles anidados abriendo y cerrando conexiones a bases de datos
  • 43.4M de tokens gastados el día grande (a ~240 Wh/MTok, unos 8 lavavajillas)
  • 95% de cobertura de tests pero bugs en "producción"
  • ...

Y sí, este post es un rant.

  • Ya sé que algo estoy haciendo mal. No dejaba de ser un experimento. Pero es que es muy fácil hacer mal las cosas con coding agents. Lo único bueno es que cagarla con la AI es aceptable. Puedes decir que tu agente ha perdido 450k$ invirtiendo, pero ni se te ocurra decir que has perdido una base de datos secundaria porqué no hacías pruebas de restauración.
  • Cursor en modo Auto usa modelos ~malos~ suboptimos. Pero los LLM cuestan un buen dinero, cada vez más. Y no todas las empresas tenemos VC quemando $ detrás.
  • Hay una presión brutal en el ámbito del desarrollo. Si te fias de twitter, no trabajar en modo ralph y tener 5 agentes en paralelo es "perder el tiempo". En lugar de aprovechar el incremento de productividad para disfrutar del paisaje, tienes que lanzar un agente desde el móvil mientras esperas que la crianza salga del cole.
  • Los problemas asociados al consumo de recursos, gobernanza y sesgo de los modelos, son reales, y no deberíamos despreciarlos sin más.

Para ir acabando, que esto empezó simplemente para explicar el contexto del primer artículo generado por LLM que ha aparecido en este blog:

Managing file responsibilities and size in Coding Agents

Contenido generado por LLM

Este artículo tiene bastante edición humana y no es un one-shot, si no varias sesiones con distintos agentes, pero el grueso ha sido escrito por un LLM.

El contexto en el que fue escrito está explicado en mi otro artículo de hoy

Está escrito tratando de responder a "pongo en el AGENTS una instrucción de - No escribas ficheros de más 250 líneas - o hay formas mejores de evitar god files"

Coding agents tend to accumulate responsibilities into existing files rather than reasoning about structure. The result is files that grow across sessions, doing too many things — and the problem compounds over time.

The slop can be reduced with instructions, good workflows and strictness but accuracy can also be reduced if not being done correctly.

The Problem

Coding agents tend to follow the path of least resistance. It is computationally "easier" for an LLM to append logic to an existing file than to create a new file, manage imports, and update directory structures. This leads to 1,000+ line "God Files" that combine UI, state, API calls, and business logic.

Key Insight: When an agent builds a monolith, it isn't being smart; it's being lazy. As the human architect, your role is to provide the "structural friction" necessary to keep the codebase clean.

Options Explored

Five approaches came up, each with a different tradeoff profile:

Rules in agents.md — proactive, shapes decisions before code is written. The risk is token cost: instructions sitting in context are paid on every turn, even when irrelevant. Also relies on the agent actually following them, with no enforcement mechanism.

Linter rule + lint after changes — objective and enforceable, near-zero token cost. The limitation is it only catches the problem after it exists, and agents can game it mechanically (splitting a 400-line file into two 200-line files without real refactoring, deleting comments or writing one-liners). Best used as a safety net, not a primary strategy.

Refactoring subagent — the most powerful option if you have solid test coverage. A dedicated subagent can reason about why to split, not just that something is too big. The downsides are latency, cost (extra token overhead for a new session), and regression risk if the subagent rewrites instead of just extracting.

Hooks — best option for automatic enforcement. A post-edit hook that runs checks and feeds results back to the agent closes the feedback loop without manual intervention. Setup cost is higher and hook failures can be noisy.

Slash-command, on-demand skills or reusable prompts — on-demand invocation of a well-crafted refactoring prompt. Zero cost when not in use, no automation risk, and you control the timing. More powerful than it first appears. The downsides is that is not automatically enforced, requires constant supervision.

Two Key Questions

There are two important aspects about how and when constraining the LLM's file output:

  • Reasoning Degradation. Enforce strict line counts (e.g., "Max 200 lines") too early, may interrupt the LLM's flow. It may focus more on "fitting the code" than "solving the logic," leading to obfuscated code or broken abstractions.
  • Token Waste:. Large files are "Token Killers." Every time a small change is requested in a 1,000-line file, the agent must re-read (and often re-write) the entire context. This wastes money and increases latency.

Does constraining the agent early hurt reasoning quality?

Yes, but the concern is nuanced. The risk is real when constraining how the model thinks — forcing a specific algorithm or architecture mid-problem. A file size limit is an output constraint, closer to formatting guidance, and modern LLMs handle that reasonably well.

That said, write first, refactor later is still directionally correct: the model solves one problem at a time instead of two. Upfront constraints should be soft and structural, not hard limits enforced mid-task.

What matters more: constraint cost or context bloat?

Context bloat is more damaging, and it's not a close call.

Context bloat compounds: large files make context grow, which reduces accuracy, which can produce more bloated code, which grows context further. Each session the problem gets worse.

Constraint cost is fixed and mild by comparison. A slightly worse initial design is recoverable. Degraded model accuracy due to bloated context causes mistakes that are hard to trace.

Critically, the "write big then refactor" approach pays the context cost twice — once for the big file and once for the refactoring pass. A soft upfront constraint that keeps files small is worth it precisely because it controls context size across the session.

Final Recommendation

Three layers, in order of priority:

  • Soft rules in AGENTS.md. Can be combined or replaced by Skills or Rules.
  • Linter rules.
  • Reusable prompt for post refactoring

Soft rules in AGENTS.md — prevention

Keep them concrete and structural, not vague. The goal is to shape decisions before files are written, not to micromanage output. Example:

Before adding logic to an existing file, check if it belongs there.
If a file already has more than one clear responsibility, create a new module instead.
Prefer creating a new file over extending an existing one beyond its scope.
  • Avoid hard line limits here. They constrain reasoning without being reliably enforceable.
  • Prioritize responsibility over lines. Instead of max-lines: 250, enforce one-responsibility-per-file.

Linter rule — passive safety net

Configure a max-lines rule (e.g. ESLint max-lines, Pylint max-module-lines) and run it via a hook or CI. Don't rely on it as the primary mechanism — it catches symptoms, not causes. Pair it with a complexity check (number of exports, cyclomatic complexity) for better signal.

Reusable prompt for periodic refactoring — recovery

A reusable prompt (slash-command, on-demand skill, custom agent, ...) that instructs the agent to review and extract responsibilities from files that have grown. Invoke it when you decide the codebase needs it, not automatically after every turn. The prompt contract should be explicit:

The attached file is to big and have too many responsabilities. Refactor it.

Rules:

- One responsibility per file (name it after what it does)
- If a file needs more than 3 imports from the same module, extract shared logic
- Prefer creating a new file over extending an existing one beyond its scope.
- Only extract, never rewrite logic.
- All tests must pass before and after.

This approach keeps token cost under control (only paid on demand), avoids constraining original reasoning, and gives you a deliberate moment to review structure before it accumulates further debt.

A bash script to catch big files could be also useful

min_lines=200
# ripgrep respects .gitignore and has --type
# Ignore ./docs as we use it for examples, temporary clone other repos, ...
rg --files \
    -g '!docs/**' --type typescript --type js --type python \
    | while IFS= read -r file; do
        line_count=$(wc -l < "${file}")
        if ((line_count >= min_lines)); then
            printf '%10d %s\n' "${line_count}" "${file}"
        fi
    done \
    | sort -nr

Skills and Rules

Skills and Rules can provide accurate design guidance to the model for the concrete task at hand. A react-guidelines skill can promote architecture constraints. As example:

# Architectural Constraints

1. **Separation of Concerns:** UI components must not contain business logic or raw API calls.
2. **The "Hook" Rule:** If a component exceeds 3 state variables, move state logic to a custom Hook.
3. **The "Service" Rule:** All data fetching must reside in `/services`. Do not use `fetch` or `axios` directly in components.
4. **Complexity Trigger:** If you are about to add a second distinct responsibility to a file, you MUST propose a file split before writing the code.
5. **Pre-emptive Architecture:** Prefer creating 3 focused files (Type, Logic, View) over 1 multi-purpose file.

Cómo funcionan las rules y el AGENTS.md en distintos Coding Agents

Serie de artículos sobre funcionalidades para inyectar contexto en los coding agents:
  1. Funcionalidades de "inyección de contexto"
  2. Commands en Cursor
  3. Commands en Gemini
  4. Commands en Claude (Codex y OpenCode)
  5. Cómo funcionan las rules en distintos Coding Agentes

En esta artículo nos centramos en cómo funcionan las rules en distintos coding agents.

El AGENTS.md es equivalente a una regla de Siempre y en la documentación de algunas herramientas lo tratan en conjunto, así que también lo haremos así en este artículo.

Las herramientas en general llaman rules a archivos markdown con un frontmatter que controla bajo que condiciones se inyecta en el contexto:

  • Siempre. Always on, loaded unconditionally. Equivalente (en algunas herramientas) a referenciar documentos con @ desde el AGENTS.md.
  • Bajo criterio del modelo. Apply Intelligently, model_decision, lazy loading. Equivalente a una regla en el AGENTS.md estilo: Read docs/python-guidelines.py when working with python code.
  • Manual. Equivalente chat referenciar un documento con @ en la conversación.
  • glob. Cuando se trabaje en un fichero que cumpla el glob el markdown es inyectado. Lo más parecido serían las herramientas que leen AGENTS.md en subcarpetas y lazy loading.

¿Qué significa equivalente?

  • Los modelos son cajas negras estocásticas. Dada la misma entrada no tienen porqué producir la misma salida. Sólo se puede decidir cual la mejor entrada para obtener la salida deseada a base de prueba y error.
  • El harness es tan relevante cómo el modelo en sí. En las herramientas que tienen el código fuente disponible es más fácil tomar decisiones informadas. Las técnicas tipo Man in the Middle también ayuda.
  • Harness y Modelos cambian a menudo, se debería estar haciendo una evaluación continua y eso no está al alcance de todos los equipos. De hecho, ni siquiera es viable para muchos equipos leer los "resúmenes".

Así que hay que tomarse equivalente, o cualquier artículo de internet con mucho cuidado.

Por ejemplo, la documentación de Claude indica específicamente que una regla tiene la misma prioridad en el contexto que él CLAUDE.md. Pero no tiene porqué ser así en otras herramientas. Cuando poner un documento en la parte de arriba o bajo del prompt, puede modificar en un 30% la calidad del resultado, la forma en que el harness wrapee e inyecte el contexto al modelo puede tener mucho impacto.

Es decir. Qué @path desde el AGENTS.md se envíe siempre al llm, al igual que una regla de Always on, no tiene porqué significar que se fuerce la misma atención del modelo sobre los dos métodos.

Antigravity

Antigravity maneja dos conceptos similares, en la misma sección de la documentación: rules y workflows.

Los workflows:

  • Son ficheros markdown con un frontmatter (propiedad description)
  • Se almacenan en ~/.gemini/antigravity/global_workflows o .agents/workflows.
  • Parece que sólo se puede invocar de forma manual, usando: /my-workflow. Y unos workflows pueden llamar a otros
  • Los definen así:
    • While Rules provide models with guidance by providing persistent, reusable context at the prompt level, Workflows provide a structured sequence of steps or prompts at the trajectory level, guiding the model through a series of interconnected tasks or actions.

Las rules:

  • Son ficheros markdown con un frontmatter
  • Se almacenan en .agents/rules
  • No hay reglas globales. A nivel global, coge el documento que se haya definido para gemini-cli ~/.gemini/GEMINI.md
  • Se pueden invocar manualmente con @my-rule.md. Y siguen los criterios de: siempre, manual, el modelo decide, glob.

El frontmatter sería:

trigger: manual | always_on | glob | model_decision

# Sólo cuando trigger = 'glob'
globs: \*.py

# Sólo cuando trigger = 'model_decision'
description: "foo"

WTF

  • rules y workflows se pueden crear mano, o desde la GUI. Cuando en Antigravity se abre un fichero en esas carpetas, el editor no es el de texto normal, si no, uno con widgets pensado para la edición de estos documentos.
  • Reglas y Workflows están limitados a 12.000 caracteres.
    • Por estimación gruesísima, 12.000 caracteres de lorem-ipsum son 1.753 palabras, 3.716 tokens.
    • Aunque según un LLM la documentación técnica en inglés tiene de media 5 caracteres por palabra más un espacio. Eso serían unas 2.000 palabras, 2.666 tokens. En castellano los números salen un poco peor.
    • O de otra forma asumiendo 1 token = 4 caracteres (inglés) serían 2.500 tokens.
  • La documentación no tiene buscador y no he encontrado ninguna mención a AGENTS.md

OpenCode

En el caso de OpenCode bajo la sección rules hacen referencia directa al uso de AGENTS.md.

Un único fichero en el root del proyecto o uno global en ~/.config/opencode/AGENTS.md. También permite definir la lista de ficheros que se añadirán automáticamente al contexto. Es una funcionalidad interesante porque permite usar globs (para los ficheros a leer no para cuando se leen) y urls.

{
    "$schema": "https://opencode.ai/config.json",
    "instructions": [
        "CONTRIBUTING.md",
        "docs/guidelines.md",
        ".cursor/rules/*.md",
        "https://myurl.com/style.md"
    ]
}

Al contrario que otras herramientas no siguen automáticamente referencias @path. Recomiendan el uso de lazy loading a través del AGENTS.md: For testing strategies and coverage requirements: @test/testing-guidelines.md

gemini-cli

Tampoco tiene rules. Lo más parecido es el AGENTS.md que engloban bajo Manage Context and Memory. Por defecto usan el fichero GEMINI.md pero se puede usar otro mediante configuración.

Se pueden poner en la raíz del proyecto, o en ~. También en subdirectorios de modo que sólo cargue cuando se trabaje con ficheros en bajo ese árbol.

gemini tiene además una tool de save_memory. Un prompt cómo remember that by database is at port 5433 añadirá una línea a ~/.gemini/GEMINI.md

Si se usa @path en un documento lo carga automáticamente.

Tiene también un comando /memory show que permite ver las instrucciones que se están usando. Muy útil para depurar.

WTF

  • Tienen dos páginas donde cuentan prácticamente lo mismo "Manage Context and Memory" y Project Context.
  • Permite modificar el System Prompt.

OpenAI Codex CLI

Codex no tiene rules y hay que ir directamente a la documentación sobre el AGENTS.md. Cómo el resto admiten ficheros a nivel de proyecto y de ~. Tiene además una funcionalidad curiosa, si existe un fichero AGENTS.override.md lee ese en lugar de AGENTS.md

Incluye el AGENTS.md de subdirectorios.

La documentación explica varios puntos interesantes

Merge order: Codex concatenates files from the root down, joining them with blank lines. Files closer to your current directory override earlier guidance because they appear later in the combined prompt.

La forma de premiar la atención de un AGENTS.md sobre otro anidado, es simplemente ponerlo más abajo en el prompt.

Codex skips empty files and stops adding files once the combined size reaches the limit defined by project_doc_max_bytes (32 KiB by default). For details on these knobs, see Project instructions discovery. Raise the limit or split instructions across nested directories when you hit the cap.

Asumiendo UTF8 (de 1 byte para la mayoría de letras hasta 4 bytes para los emojis), pongamos un cálculo grueso de 32k caracteres en inglés, 1 token = 4 caracteres, unos 8.000 tokens.

En la documentación dan varios trucos para depurar las instrucciones.

WTF

  • Codex CLI maneja el concepto de rules pero con un significado totalmente distinto al resto de herramientas. Se usa para definir los permisos de los comandos que Codex puede ejecutar. Muy feo que no se alineen con el resto en cómo llamar a las cosas.
  • No he encontrado en la documentación si sigue automáticamente @path

Claude

La documentación de Claude llama a este tipo de funcionalidades extension layer. En la página resumen hablan muy poco de rules, lo que seguramente significa que no quieren darle mucha relevancia.

En la sección de Memory se extienden tanto en lo referido al AGENTS.md cómo a las rules.

El AGENTS.md:

  • Va en el proyecto, ~ o subdirectorios.
  • Recomiendan que no sea de más de 500 líneas. Y ya tenemos una tercera forma distinta de limitar o recomendar el tamaño de este fichero: caracteres, KiB y líneas
    • Por decir algo 50 caracteres por lína, 4 caracteres por token, serían 6250 tokens.
  • Carga automáticamente las referencias @path
  • Una funcionalidad interesante es que comentarios estilo <!-- maintainer notes --> son eliminados antes de inyectar el fichero en el contexto.

Las rules:

  • Son ficheros markdown con un frontmatter
  • Se almacenan en home (~/.claude/rules/) y el proyecto (.claude/rules/). Admitiendo organizarlas en subdirectorios.
  • Se pueden:
    • invocar manualmente con @.claude/rules/my-rule.md
    • Siempre. Si no tiene frontmatter se cargará automáticamente con la misma prioridad que el CLAUDE.md.
    • Con globs. Cuando en el frontmatter hacia una propiedad paths (ie: paths: *.py), sólo cargan cuando se cumple el glob.

WTF

  • La documentación de Claude es de largo la mejor. Esta visualización interactiva del Context Window es un lujo.
  • Tiene un comando /memory para ayudar a depurar. También recomiendan usar un hook para depurar: "Use the InstructionsLoaded hook to log exactly which instruction files are loaded, when they load, and why"
  • Claude usa CLAUDE.md en lugar de AGENTS.md y no hay posibilidad de configuración.
  • Claude tiene además una funcionalidad de "Auto Memory", que se puede deshabilitar en la configuración.

En una parte de la documentación hablan de las 500 líneas, mientras que en otra escriben:

Size: target under 200 lines per CLAUDE.md file. Longer files consume more context and reduce adherence. If your instructions are growing large, split them using imports or .claude/rules/ files.

A esta frase no le acabo de ver el sentido. Si los imports (@path) se incluyen automáticamente, y las rules tienen la misma prioridad que el AGENTS.md. No sé porqué cinco ficheros de cien líneas es mejor que un AGENTS.md de 500 líneas. Otra cosa sería usar globs y lazy loading.

200 líneas a 50 caracteres por línea son 2.500 tokens.

Cursor

La documentación de Cursor incluye en la sección de reglas tanto lo que estamos llamando rules cómo el AGENTS.md

El AGENTS.md:

  • Va en el proyecto, o en subdirectorios. No se puede usar a nivel global.
  • En las pruebas que he hecho no parecen seguir automáticamente los @path en el AGENTS.md pero si en las rules

Admiten Team Rules para las cuentas de equipo y Enterprise que se configuran a través del dashboard.

Admiten User Rules:

  • No se usan en Tab ni Inline Edits. No definen si funcionan en modo Plan o Debug, pero asumo que sí.
  • Sólo se pueden gestionar a través de la UI. Lo lógico sería almacenarlas ~/.cursor/rules, pero no. Muy mal Cursor.

Admiten project rules:

  • Son ficheros markdown con un frontmatter
  • Se almacenan en .cursor/rules. Admitiendo organizarlas en subdirectorios.
  • Se pueden invocar manualmente con @my-rule.md. Y siguen los criterios habituales (siempre, manual, el modelo decide, glob)
  • Recomiendan mantenerlas por debajo de las 500 líneas.

El frontmatter no está bien definido.

  • description. No se aclara si se usa para algo
  • globs.
  • Hay otras propiedades: Always Apply, Apply Manually, Apply Intelligently. Pero la documentación de cómo se usan es mala. ¿Se supone que son propiedades con ese nombre y valor true false?. ¿Cómo gestionan la prioridad si hay dos a true por error?

El caso más claro parece ser con glob scope:

---
glob: *.py
alwaysApply: false
---

**MUST** use modern (3.13+) type hints for all function signatures in Python code (parameters and return values)

WTF

  • Una visita al foro de ayuda de Cursor sobre reglas o los bug reports, está llena de gente diciendo que las reglas rompen de una versión a otra, no hacen lo esperado, o pidiendo explicaciones de cómo funcionan.

  • La documentación de Cursor sobre reglas empieza mal y luego no mejora.

    Rules provide system-level instructions to Agent. They bundle prompts, scripts, and more together, making it easy to manage and share workflows across your team.

    When applied, rule contents are included at the start of the model context. This gives the AI consistent guidance for generating code, interpreting edits, or helping with workflows.

    ¿scripts?. Este concepto es de las skill no de las rules. En el resto de la documentación no se vuelve a hacer referencia a scripts

  • En Cursor Settings, hay una (mala) UI de creación de reglas. No permite introducir la description, ni el subdirectorio, y el combo de cuando aplicar tiene opciones distintas a la documentación. Escribir un fichero markdown en un TextField teniendo un IDE no tiene sentido.

  • La idea de definir workflows en algo llamado rules, cómo sugiere la documentación no parece tener mucho sentido. No tendría más sentido los commands (ahora las skills) para esto.

Conclusiones

Sobre las reglas
  • Las reglas no son un estándar. Si se quiere usar varias herramientas a la vez es un problema.

  • Las rules parecen una buena idea que apareció en su día, pero que no acaba de funcionar o ser correctamente implementada cómo para ser usada correctamente. A menos que se limiten al glob scope

    • Y, aún así, no tengo claro cuando se ejecuta la regla. En modo plan, si no accede a un fichero *.py para planificar tiene en cuenta las reglas, o sólo cuando pasa a escribir el código.
  • Hay alternativas a las reglas, que al final son un mecanismo un poco oscuro y no estándar:

    • lazy loading aunque consuma más tokens va a funcionar en todos las herramientas.
    • Para las de "Siempre", varias admiten @path y se puede usar lazy loading cómo fallback
    • Skills para workflows y especialización, o incluso comandos para tareas más acotadas cómo /git-commit
Sobre las herramientas
  • Cursor, Antigravity y Claude, manejan el concepto de reglas.
  • Codex no especifica si sigue @path. OpenCode no sigue automáticamente @path. Cursor no parece seguirlo en el AGENTS.md pero si en las rules. Los demás los siguen tanto en reglas como en AGENTS.md.
  • Excepto Antigravity (que no lo he probado y no pone nada en la documentación), y OpenCode (que necesita personalizarlo en las instructions), todos los demás permiten AGENTS.md en subdirectorios. No hacen override si no merge. Generalmente poniendo más abajo en el prompt el AGENTS.md más cercano al trabajo que se esté haciendo para darle prioridad.
  • No hay consenso en las recomendaciones sobre el tamaño de las reglas de Always apply y el AGENTS, más allá de que las mantengas pequeñas y se usen skills o reglas con scope para instrucciones que no necesiten estar permanentemente en el contexto.

Coding Agentes: Commands en Claude (Codex y OpenCode)

Serie de artículos sobre funcionalidades para inyectar contexto en los coding agents:
  1. Funcionalidades de "inyección de contexto"
  2. Commands en Cursor
  3. Commands en Gemini
  4. Commands en Claude (Codex y OpenCode)
  5. Cómo funcionan las rules en distintos Coding Agentes

Claude describe la mayoría de estas funcionalidades cómo "extension layer: features you add to customize what Claude knows, connect it to external services, and automate workflows.".

Y los divide en:

  • CLAUDE.md adds persistent context Claude sees every session
  • Skills add reusable knowledge and invocable workflows. load on demand. Claude sees skill descriptions at session start, but the full content only loads when a skill is used. For skills you invoke manually, set disable-model-invocation: true to keep descriptions out of context until you need them.
  • MCP connects Claude to external services and tools
  • Hooks run outside the loop entirely as deterministic scripts
  • Plugins and marketplaces package and distribute these features

En este grupo también subagents y agent teams.

La documentación es más extensa que en Cursor y Gemini y en varios puntos comparan las funcionalidades entre sí para explicar que usar en cada caso, lo cual se agradece.

Commands

Lo primero que vemos es que Claude no tiene documentación concreta sobre commands pero hay varias referencias veladas.

Pero lo más relevante está en la página de skills. Ahí indican claramente que los custom commands han sido integrados en las skills.

Agent Skills

El Agent Skills es un formato desarrollado originalmente por Anthropic y publicado cómo estándar abierto.

La spec oficial dice que el name y description de un skill se cargan automáticamente al iniciar una sesión y se recomienda que se puedan "activar" bajo criterio del modelo o bajo invocación del usuario.

Cómo contábamos en un post anterior

A 50-100 tokens por skill, 20-40 skills es un 1% del contexto habitual de 200k.

Pero Claude Code tiene varias extensiones al estándar, entre ellos una propiedad disable-model-invocation: true en el frontmatter de SKILL.md que hace que sólo el usuario y no el modelo pueda invocar la skill y que no se cargue al inicio.

De este modo funciona cómo un substituto perfecto y más potente que los custom commands. Dejando a parte la sobre carga de tener que ir creando directorios todos con el mismo fichero SKILL.md dentro.

Otra de las extensiones dynamic context, da una función parecida a la de interpolación de los comandos de gemini.

Gemini no tiene soporte para esta funcionalidad aunque hay una issue abierta. Cursor soporta exactamente la misma propiedad.

OpenAI Codex CLI

En un vistazo rápido a la documentación de Codex no he encontrado referencias a custom commands.

La página de skills hace referencia a un parámetro allow_implicit_invocation con comportamiento similar a disable-model-invocation pero no indican si se carga al inicio o no.

No le he dado muchas más vueltas porqué no uso Codex, pero en este ticket hay algo de discusión sobre el tema y tickets abiertos relacionados.

OpenCode

OpenCode tiene documentación sobre custom commands. Pueden definirse en JSON o Markdown y tienen opciones de interpolación.

La documentación de skills hace referencia a alguna forma de evitar que carguen al inicio, pero sin experiencia en OpenCode me resulta confusa.

Cómo en Codex hay alguna issue abierta al respecto.

Conclusiones

La forma en que Cursor y Claude implementan las Skills, permite dejar de lado los custom commands y usar únicamente Skills.

OpenCode y Gemini le dan un poco más de magia a los commands con las opciones de interpolación pero:

  • No tengo claro que sea útil
  • No tengo claro que no se puede replicar con un workflow algo más complicado en la skill
  • Seguramente acaben implementando disable-model-invocation

Si el resto de Coding Agents siguen copiando a Claude, también acabarán metiendo interpolación en las skills.

Coding Agentes: Commands en Gemini

Serie de artículos sobre funcionalidades para inyectar contexto en los coding agents:
  1. Funcionalidades de "inyección de contexto"
  2. Commands en Cursor
  3. Commands en Gemini
  4. Commands en Claude (Codex y OpenCode)
  5. Cómo funcionan las rules en distintos Coding Agentes

En esta artículo nos centramos en cómo funcionan los commands en Gemini. Las pruebas han sido hechas sobre la versión 0.33.1.

Gemini no tiene un nombre genérico para estas funcionalidades y en su documentación están dispersas entre "Features", "Usage" y "Configuration". Contempla:

Además de otras funcionalidades cómo modificar el System Prompt, Subagents, Remote Subagents y Plan Mode. Y no tiene un sistema de reglas.

Commands

La documentación oficial es bastante clara.

  • Van en .gemini/commands del proyecto o de ~.
    • Admite namespaces (subdirectorios). .gemini/commands/git/commit.toml se convierte en /git:commit.
  • Por algún motivo inexplicable, usa ficheros TOML
  • Los campos del TOML son description el texto de ayuda que pone para el comando y prompt donde metes las instrucciones en sí.
  • Admite cierto grado de interpolación.
    • {{args}} El placeholder es substituido por el texto que acompaña al comando en el chat.
    • !{{...}}. Ejecuta el comando y substituye el placeholder por la salida. Se puede combinar con args: !{grep -r {{args}} .}
    • @{path/to/file_or_dir}. El placeholder es substituido por el contenido del fichero o los ficheros del directorio. Esta substitución es la primera así que no se puede combinar con {{args}} y pasar el path cómo parámetro.
  • No son composables sólo funciona el / al principio del prompt.

Una de las cosas buenas de que gemini-cli sea software libre es que podemos ver cómo funciona y no hacer observaciones indirectas cómo en Cursor.

El propio gemini tras estudiar su código responde más o menos esto a si es lo mismo usar @ que un command

Gemini CLI uses clear separators and headers to help the model distinguish between your prompt, injected files, and shell command outputs, rather than complex XML tags. For @file references, it uses REFERENCE_CONTENT_START and REFERENCE_CONTENT_END markers, with individual file contents prefixed by --- filename ---. Custom slash commands defined in .toml files expand @{path} with similar --- filename --- headers and use --- Start of content for directory: path --- for directory injections

Shell command output !{command} is appended with exit codes or signal markers if they fail, and if a command doesn't use {{args}}, the raw invocation is appended to the end of the prompt to provide context. Overall, the system relies on these human-readable delimiters to maintain context without over-engineering the prompt structure.

Vamos que no hay magia. Y en las pruebas que he hecho los resultados era similares.

Conclusiones

  • gemini-cli al contrario que Cursor, no hace magia con los comandos, simplemente es un texto añadido al prompt
  • Las opciones de interpolación de los comandos pueden abrir usos creativos. Pero no tengo claro cual puede ser la diferencia entre interpolar un !{git diff} y decirle que use git diff y con la salida escriba el mensaje de commit. Allá de menos requests. Quizás menos consumo de tokens
  • Usar formato TOML para algo cómo esto es tocar las narices. Tiene pinta de over engineering.