A raíz del primer artículo, continuamos con la serie sobre cómo integrar la IA dentro de nuestro flujo de trabajo. En el primer artículo vimos la importancia de darle contexto para que la IA se aproxime al resultado deseado, pero es algo que siempre está supervisado por una persona que se encarga de revisar cada uno de los pasos que da. Esto provoca que, al final, siempre haya un cuello de botella en el ingeniero que supervisa la IA.
Vamos a mejorar ese flujo, y ahí es donde entran las Skills que tienen los agentes y cómo podemos ir añadiendo verificaciones automáticas al código que está desarrollando la IA.
¿Cómo lo podemos hacer?#
En primer lugar, es fundamental tener unos requisitos muy buenos y que estos sean claros — esta parte la veremos en el siguiente artículo. La otra pieza clave es asegurarnos de que el agente ha implementado lo que nosotros le indicamos. Para ello entran en juego las Skills en Claude Code o los Copilot Agents en GitHub Copilot.
Un ejemplo claro es crear una skill de Revisor de Pull Request. A este revisor le tenemos que indicar que haga exactamente lo mismo que haría cualquier ingeniero cuando revisa una PR:
- Que el código siga los estándares establecidos en el proyecto
- Que utilice las librerías acordadas, sin introducir dependencias nuevas
- Que incluya tests o que al menos cumpla la cobertura mínima establecida
De esta forma, cuando un agente termine de realizar su tarea, se le puede pasar esta skill para que indique si hay algún problema respecto a main. Si detecta issues, podemos mandar automáticamente a otro agente a solucionarlos.
¿Por qué hacerlo con otro agente?#
Si miramos nuestro ciclo de desarrollo habitual, una buena práctica (o al menos la que yo sigo) es que los revisores de una pull request no sean las mismas personas que han participado en la creación de esa rama, igual que ocurre con el testing.
Aplicar este mismo principio al flujo con IA tiene mucho sentido: el agente que implementa no es el que revisa. Esto reduce el sesgo y nos da una segunda perspectiva automática antes de que un humano tenga que intervenir.
El resultado: menos cuello de botella#
Con este enfoque el flujo cambia significativamente:
- Un agente desarrolla la funcionalidad con el contexto y requisitos dados
- Una skill de revisión analiza el resultado contra nuestros estándares
- Si hay issues, otro agente los corrige
- Solo cuando el ciclo automático pasa, llega a la revisión humana
El ingeniero sigue siendo el responsable final, pero en lugar de revisar cada línea generada, interviene en un punto mucho más alto del proceso, asegurando que el resultado es lo que el producto requiere. Menos trabajo mecánico, más criterio.
Talk is cheap, show me the code#
Partamos de la base del ejemplo que hicimos en el artículo anterior (GitHub).
¿Cuál es el requerimiento que queremos hacer? Queremos tener una página similar a esta. En el ejemplo anterior solo teníamos información relativa al backend, por lo que tendremos que darle a Claude el contexto del frontend: qué versión de React usaremos, qué librería de estilos, y que utilice Vite para la creación del proyecto — exactamente igual que hicimos en el artículo pasado con el backend.
Una vez que el agente nos ha generado la solución, el resultado visual es muy similar al que indicamos en el prompt. Pero ¿está realmente bien implementado? Si ejecutamos nuestra solución vemos el resultado que se queda de esta manera, lo que a primera vista parece correcto
¿cómo analizamos si lo que nos ha dejado es correcto? Aquí es donde entran las skills. Las skills son instrucciones reutilizables que le defines al agente: en lugar de escribir el mismo prompt cada vez, defines una vez cómo debe comportarse y la invocas con un comando como /reviewpr. Por defecto en Claude Code, dado el prompt que tú le indicas, él busca la skill que considera más adecuada. Para flujos más personalizados, yo prefiero adaptar la skill a las necesidades concretas del proyecto. En la web skills.sh puedes encontrar un gran catálogo de skills de la comunidad que puedes usar como base para los tuyos.
En nuestro caso, la skill de revisión de PR queda así:
name: reviewpr
description: You are a Senior Engineer conducting a Pull Request review. Your goal is to ensure the code adheres strictly to the project's Vertical Slice Architecture (VSA), C# Best Practices, React Best Practices.
Role: PR Reviewer 🛡️
You are a Senior Engineer conducting a Pull Request review. Your goal is to ensure the code adheres strictly to the project's Vertical Slice Architecture (VSA), C# Best Practices and React Best Practices.
📋 Review Checklist
1. Vertical Slice Architecture (VSA)
- Cohesion: Check if the endpoint, request, response, and logic are in the same folder/slice.
- Independence: Ensure this slice doesn't reuse Request/Response models from other slices.
- MinApiLib: Verify the use of PostEndpoint<T>, GetEndpoint<T>, etc., and that Configure() sets the correct OpenAPI metadata.
2. C# & .NET 9 Standards
- Async/Await: Verify that CancellationToken is passed to all asynchronous calls (DB, API, etc.).
- Logging: Ensure LoggerMessageAttribute is used for structured logging instead of simple _logger.LogInformation().
- Validation: Check if WithValidation() is called in the slice configuration and a FluentValidation class exists.
- DI: Ensure [RegisterInIServiceCollection] is present on the handler record.
3. React & Frontend Standards
- Architecture & Cohesion: Ensure frontend files (Components, Hooks, Types, API calls) follow a feature-based structure that mirrors the backend's Vertical Slices.
- TypeScript Strictness: Check that strict typing is enforced. The any type is strictly forbidden.
- Hooks & State: Verify that custom hooks are used to extract complex business logic from UI components.
- Performance: Look for unnecessary re-renders. Ensure useMemo and useCallback are used appropriately.
4. Testing
- Integration: Verify there is a test exercising the slice via DelegateAsync.
- Mocks: Check that Moq is used only for external infrastructure, not for domain logic.
- Frontend Testing: Ensure React components are tested using React Testing Library.
💬 Output Format
For each issue found, provide:
- Location: File and line number.
- Problem: Why it violates our standards.
- Suggested Fix: A code snippet showing the correction.Para registrar esta skill en un proyecto, crea el fichero .claude/commands/reviewpr.md en la raíz del repositorio con el contenido anterior. Si quieres que esté disponible en todos tus proyectos, colócala en ~/.claude/commands/reviewpr.md y la tendrás centralizada globalmente.
Lo importante de esta skill es que refleja exactamente los estándares del equipo: VSA en el backend, tipado estricto en el frontend y cobertura mínima de tests. No es una skill genérica — es nuestra definición de “código correcto” traducida a instrucciones para el agente.
Al tratarse de un ejemplo didáctico, he decidido unificar la revisión de backend y frontend en una única skill para que se entienda el flujo completo. A nivel profesional, sin embargo, lo más recomendable es tener skills separadas por especialidad: una para backend y otra para frontend. Esto mejora la precisión de cada revisión y facilita el mantenimiento. Dicho esto, también entran en juego otros factores como el consumo de tokens — una skill unificada es más eficiente en ese sentido. Al final dependería de cada caso y del equilibrio que cada equipo quiera establecer.
El resultado real#
Este es el output que nos devuelve la skill al ejecutar /reviewpr sobre el código generado por el agente:
🛡️ Code Review — Dragon Ball API
1. Vertical Slice Architecture (VSA)#
✅ GetCharacters slice — cohesión correcta: GetCharactersQuery, GetCharactersHandler y GetCharactersEndpoint están cada uno en su carpeta de slice. No reutiliza modelos de otros slices.
⚠️ CreateCharacter slice — CreateCharacterEndpoint.cs
Issue 1 — CreateCharacterRequest definido en el fichero del endpoint
- Location:
src/Api/Characters/CreateCharacterEndpoint.cs:36-40 - Problem:
CreateCharacterRequestestá definido en la capa Api, no enApplication/Characters/CreateCharacter/. Rompe la cohesión: el contrato de entrada del slice vive fuera del slice. - Suggested Fix: Mover a
src/Application/Characters/CreateCharacter/CreateCharacterRequest.cs
Issue 2 — Validación manual con try/catch ValidationException
- Location:
src/Api/Characters/CreateCharacterEndpoint.cs:15-32 - Problem: MinApiLib ofrece
WithValidation()enConfigure()para manejar FluentValidation automáticamente. Eltry/catchmanual es boilerplate innecesario.
2. C# & .NET Standards#
Issue 3 — ImageUrl ausente en CreateCharacterCommand y CreateCharacterRequest 🔴
- Location:
src/Application/Characters/CreateCharacter/CreateCharacterCommand.cs:3-7 - Problem:
CharactertieneImageUrlcomo campo obligatorio (default!), pero ni el command ni el request lo incluyen. Los personajes creados vía API siempre tendránImageUrlnulo en runtime.
Issue 4 — InMemoryCharacterRepository.Add no copia ImageUrl 🔴
- Location:
src/Application/Characters/InMemoryCharacterRepository.cs:27-33 - Problem: El método
Addconstruye un nuevoCharactersin incluirImageUrl. Incluso si se arregla el command, el dato se perdería aquí.
Issue 5 — PowerLevel como int con valores que rozan el límite 🟡
- Problem: Broly tiene
PowerLevel = 1_400_000_000. El máximo deintes2_147_483_647. Cualquier personaje nuevo puede causar overflow silencioso. Solución: cambiar along.
Issue 6 — Sin OpenAPI metadata en los endpoints 🟢
- Problem: Ningún endpoint implementa
Configure()para describir summary, tags o códigos de respuesta. La documentación Scalar/OpenAPI está vacía.
3. Testing#
Issue 7 — Tests de integración sin CancellationToken 🟡
- Location:
GetCharactersEndpointTests.cs:17,25,35yCreateCharacterEndpointTests.cs:19,29,43,53,61,71 - Problem: Las llamadas
_client.GetAsyncy_client.PostAsJsonAsyncno pasanTestContext.Current.CancellationToken(convención obligatoria del proyecto).
Issue 8 — CreateCharacterHandlerTests usa CancellationToken.None 🟡
- Location:
CreateCharacterHandlerTests.cs:26,37,46 - Problem: Mismo problema que el issue 7.
Issue 9 — Sin endpoint ni tests para GET /characters/{id} 🟡
- Problem:
CharacterPage.tsxdel frontend lo necesita y actualmente hace un workaround cargando todos los personajes.
| # | Severidad | Descripción |
|---|---|---|
| 3 | 🔴 Alta | ImageUrl ausente en command y request — personajes sin imagen al crear |
| 4 | 🔴 Alta | InMemoryCharacterRepository.Add no copia ImageUrl |
| 1,2,5,7,8,9 | 🟡 Media | Problemas de estándares (VSA, CancellationToken, overflow) |
| 6 | 🟢 Baja | Sin metadatos OpenAPI en Configure() |
La skill ha detectado 9 issues sin que ningún humano haya tenido que leer el código. Dos de ellos son de severidad alta (datos perdidos en runtime) y el resto son problemas de estándares que en una revisión manual podrían pasar desapercibidos. Exactamente para esto la definimos.
¿Pero cuál es el motivo por el que aparecen estos problemas? Se trata de un problema muy común en la definición de requerimientos: se ha descrito el cómo y el qué, pero no el impacto en el resto del producto. En este escenario, en el primer análisis no se tuvo en cuenta qué ocurre en el momento en el que se crea un personaje. Se modificó el modelo para poder mostrar una imagen tal y como se pedía en el resumen, pero cumplir el requisito visual no justifica introducir inconsistencias en el dominio.
¿Manual o automatizado en la PR?#
¿Y dónde podemos ejecutar esta skill? Se puede ejecutar desde el mismo IDE en el que estás desarrollando. Si la skill se ha colocado en la ubicación correcta de Claude Code, se carga de forma automática y con escribir /reviewpr la ejecuta siguiendo las instrucciones que tú indicas.
Esto es algo propio de Claude Code: si quieres que una skill esté disponible únicamente en un proyecto, la defines dentro de ese repositorio. Si por el contrario quieres que esté disponible en todos tus proyectos, la puedes colocar en la raíz de configuración global y así las tienes centralizadas en un único sitio.
Teniendo esto claro, merece la pena comparar los dos enfoques de ejecución, porque cada uno tiene su lugar:
| Ejecución manual (IDE) | Ejecución automática (PR) | |
|---|---|---|
| ¿Quién la lanza? | El propio desarrollador | GitHub Actions, sin intervención humana |
| ¿Cuándo? | Cuando el desarrollador decide | En cada apertura o actualización de PR |
| Resultado | Visible en el terminal del IDE | Comentario automático en la PR |
| Coste de tokens | Solo cuando se invoca | En cada push a la PR |
| Ideal para | Iteración rápida durante el desarrollo | Validación formal antes del review humano |
La ejecución manual es útil mientras estás desarrollando: lanzas /reviewpr cada vez que quieres un feedback rápido sin salir del IDE. Es inmediata y no consume tokens si no la usas.
La ejecución automática en la PR es la que aporta más valor al equipo: garantiza que ninguna PR llega al revisor humano sin haber pasado por la skill, independientemente de si el desarrollador se acordó de ejecutarla o no. Es la diferencia entre una convención y un control.
Lo habitual es usar ambas: el desarrollador ejecuta la skill manualmente durante el desarrollo para corregir sobre la marcha, y la pipeline actúa como red de seguridad en el momento de abrir la PR.
La idea es sencilla: cada vez que se abra o actualice una PR, GitHub Actions lanza Claude Code en modo no interactivo, ejecuta la skill /reviewpr sobre los cambios y publica el resultado como comentario en la propia PR. Para ello necesitamos la ANTHROPIC_API_KEY como secreto en el repositorio y el siguiente workflow como punto de partida:
Nota: este workflow es orientativo. La sintaxis exacta puede variar según la versión de Claude Code instalada — consulta la documentación oficial para los flags más actualizados.
name: PR Review
on:
pull_request:
branches: [main]
jobs:
review:
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: read
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Claude Code
run: npm install -g @anthropic-ai/claude-code
- name: Run reviewpr skill
id: review
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude --print "/reviewpr" > review_output.txt
echo "result<<EOF" >> $GITHUB_OUTPUT
cat review_output.txt >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Post review as PR comment
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## 🛡️ Revisión automática de PR\n\n${{ steps.review.outputs.result }}`
})Con esto, cada PR recibe automáticamente un comentario con el resultado de la revisión antes de que ningún humano la haya mirado. El revisor humano llega con el análisis hecho y puede centrarse en el criterio, no en la detección mecánica de problemas.
Conclusión#
En este artículo hemos dado un paso más en la integración de IA dentro del flujo de desarrollo. Partimos del problema real: el ingeniero seguía siendo el cuello de botella porque tenía que supervisar cada paso del agente. La solución no es eliminar esa supervisión, sino elevarla: en lugar de revisar línea a línea, definimos los estándares del equipo como una skill y dejamos que sea otro agente quien los verifique.
El resultado es un flujo donde la IA no solo genera código, sino que también lo revisa siguiendo nuestras propias reglas. El ingeniero sigue tomando las decisiones importantes, pero ya no pierde tiempo en la detección mecánica de problemas.
Sin embargo, como hemos visto con los 9 issues detectados, hay un límite claro: la skill puede encontrar lo que falta o lo que está mal implementado, pero no puede compensar unos requisitos mal definidos desde el principio. El agente implementó exactamente lo que se le pidió, y aun así el resultado tenía inconsistencias en el dominio.
Esto nos lleva directamente al siguiente reto: ¿cómo escribimos requisitos que sean lo suficientemente precisos para que el agente no tenga que adivinar nada? En el próximo artículo exploraremos el Spec Driven Development, una forma de definir las especificaciones antes de escribir una sola línea de código, de manera que tanto los agentes como los ingenieros partan del mismo contexto y hablen el mismo lenguaje.
Nota: puedes ver el resultado en el repositorio del ejemplo.
