Integrar Graphify en un flujo de trabajo Gradle: del Knowledge Graph al diagrama PlantUML en un solo comando
Publicado el 19 April 2026
- El problema: los diagramas siempre están por detrás del código
- La solución: un pipeline determinista Knowledge Graph → PlantUML
- Paso 1: Instalar Graphify y extraer el Knowledge Graph
- Paso 2 : El plugin Gradle transforma el Knowledge Graph en PlantUML
- Paso 3: Uso diario
- El pipeline completo en un flujo de trabajo Gradle
- El dogfooding : el plugin se documenta a sí mismo
- ¿Por qué es determinista (y por qué importa)?
- Diagramas del propio pipeline
- Integración en la gobernanza del proyecto
- Preparación: checklist en 5 minutos
- Trampas y mitigaciones
- Lo que se obtiene al final
- enlaces
Tu base de código crece. Las dependencias entre módulos se multiplican. La documentación de la arquitectura se vuelve obsoleta antes incluso de estar escrita. ¿Y si tu build de Gradle pudiera automáticamente generar diagramas actualizados a partir de la estructura real del código? Eso es exactamente lo que hace el pipeline Graphify + Plugin Gradle PlantUML :`graphify . --no-viz`extrae el Knowledge Graph,`./gradlew generateKnowledgeGraphDiagram`lo transforma en diagramas PlantUML. Cero LLM, cero manual, 100% determinista.
El problema: los diagramas siempre están por detrás del código
Todo proyecto que supera algunos miles de líneas conoce este síndrome:
-
Se dibuja un diagrama de arquitectura al inicio del proyecto
-
El código evoluciona, las dependencias cambian
-
El diagrama se convierte en una mentira decorativa
-
Nadie lo actualiza porque es tedioso
-
Los recién llegados se basan en ello y cometen errores
@startuml
skinparam backgroundColor #FEFEFE
skinparam ActivityBackgroundColor #FDEDEC
skinparam ActivityDiamondBackgroundColor #FFF3CD
start
:Diagrama de arquitectura creado\n(manualmente, a mano);
:El código evoluciona\n(nuevas clases, nuevas dependencias);
:Diagrama obsoleto\n(ya no refleja el código);
if (Qui met à jour ?) then (Personne)
:Documentación engañosa;
note right: Los nuevos desarrolladores\nse basan en eso... y cometen errores
else (Quelqu'un)
:Actualización manual\n(2-3 horas de trabajo);
note right: Ya obsoleto\nen la próxima PR
endif
stop
@enduml
La pregunta no es ¿es necesario tener diagramas? — todo el mundo sabe que sí. La pregunta es :¿Quién los mantiene actualizados?
La respuesta : nadie. Excepto si es automático.
La solución: un pipeline determinista Knowledge Graph → PlantUML
El principio es simple : en lugar de dibujar los diagramas a mano, losgenera desde la estructura real del código.
@startuml skinparam backgroundColor #FEFEFE skinparam componentStyle rectangle actor Développeur component "Graphify\n(pip install graphifyy)" as Graphify collections "graphify-out/graph.json\n(Gráfico de Conocimiento)" as KGJSON component "PlantUML Gradle Complemento\n(generateKnowledgeGraphDiagram)" as Plugin component "KnowledgeGraphParser" as Parser component "KnowledgeGraphRenderer" as Renderer component "PlantumlService\n(validación + renderizado PNG)" as PS collections "diagramas/knowledge-graph/\n(.puml + .png)" as Output Développeur --> Graphify : graphify . --no-viz Graphify --> KGJSON : extrae la estructura\ndel código fuente Développeur --> Plugin : ./gradlew generateKnowledgeGraphDiagram Plugin --> Parser : parse(graph.json) Parser --> Plugin : KnowledgeGraph\n(nodos + aristas + comunidades) Plugin --> Renderer : render(graph, filters) Renderer --> Plugin : código PlantUML\ndeterminista Plugin --> PS : validateSyntax + generateImage PS --> Output : .puml + .png note bottom of Plugin Pipeline DÉTERMINISTE Ninguna llamada LLM Resultado reproducible end note @enduml
Dos comandos. Eso es todo.
# Étape 1 : extraire le Knowledge Graph
graphify . --no-viz
# Étape 2 : générer les diagrammes PlantUML
./gradlew generateKnowledgeGraphDiagram
¿El resultado? Archivos`.puml` et .png`en`diagrams/knowledge-graph/, versionados en Git, siempre actualizados con el código.
Paso 1: Instalar Graphify y extraer el Knowledge Graph
Instalación
Graphify es una herramienta de Python que analiza su codebase y construye un grafo de conocimiento estructurado:
# Méthode recommandée
uv tool install graphifyy && graphify install --platform opencode
# Alternative avec pip
pip install graphifyy && graphify install --platform opencode
Configurar las exclusiones
Crear un archivo`.graphifyignore`en la raíz del proyecto para excluir los archivos que no forman parte de la lógica de negocio:
# Secrets — JAMAIS dans le graphe
*-context.yml
*.env
# Fichiers générés
build/
.gradle/
# Tests fonctionnels
src/functionalTest/
Extraer el Knowledge Graph
graphify . --no-viz
La bandera`--no-viz`Omite la generación HTML (inútil en un pipeline Gradle). El resultado es un archivo`graphify-out/graph.json`conteniendo :
-
nudos: clases, funciones, archivos — con su tipo y comunidad
-
Aristas: relaciones entre nodos (EXTRACTED desde el código, INFERRED por el LLM)
-
Comunidades: agrupamientos automáticos de nodos vinculados
{
"nodes": [
{"id": "0", "label": "LlmService", "file_type": "code", "community": 0},
{"id": "1", "label": "ApiKeyPool", "file_type": "code", "community": 0},
{"id": "2", "label": "PlantumlService", "file_type": "code", "community": 1}
],
"links": [
{"source": "1", "target": "0", "relation": "uses", "confidence": "EXTRACTED", "weight": 0.9},
{"source": "0", "target": "2", "relation": "calls", "confidence": "INFERRED", "weight": 0.7}
]
}
|
El código fuente ( |
Paso 2 : El plugin Gradle transforma el Knowledge Graph en PlantUML
Arquitectura del pipeline
El plugin`com.cheroliv.plantuml`incluye una tarea`generateKnowledgeGraphDiagram`que transforma`graph.json`en diagramas PlantUML de maneratotalmente determinista :
@startuml
skinparam backgroundColor #FEFEFE
participant "Gradle" as G
participant "GenerateKnowledgeGraphDiagramTask" as Task
participant "KnowledgeGraphParser" as Parser
participant "KnowledgeGraphRenderer" as Renderer
participant "PlantumlService" as PS
collections "graphify-out/graph.json" as JSON
G -> Task : execute
Task -> JSON : leer
Task -> Parser : parse(graph.json)
Parser --> Task : KnowledgeGraph\n(nodos + aristas + comunidades)
Task -> Renderer : render(graph, filters)
Renderer --> Task : código PlantUML\n(determinista)
Task -> PS : validateSyntax(plantumlCode)
alt syntaxe valide
Task -> PS : generateImage → .png
else syntaxe invalide
Task -> Task : guardar .puml con advertencia
end
@enduml
Los componentes internos
| Componente | rol |
|---|---|
|
Analizar`graph.json`— soporta 3 formatos : graphify nativo ( |
|
Transforma deterministamente un`KnowledgeGraph`en código PlantUML. Grupos por tipo, comunidades en paquetes, leyenda automática. |
|
Tarea Gradle que orquesta: parse → render → validate → PNG. Configurable mediante propiedades Gradle. |
|
Modelos de datos:`KnowledgeGraph`, |
|
Validación sintáctica + renderizado PNG (reutilizado por todas las tareas del plugin). |
Reglas de renderizado
El renderer aplica convenciones visuales deterministas:
| Tipo de arista | Notación PlantUML | Significado |
|---|---|---|
EXTRACTED |
|
Relación extraída del código fuente (certeza) |
DEDUCIDO |
|
Relación inferida por el LLM (puntuación de confianza) |
AMBIGUOUS |
|
Relación ambigua (por verificar) |
Las comunidades se representan como paquetes PlantUML con una paleta de colores automática.
Paso 3: Uso diario
diagrama completo
# Générer le diagramme du Knowledge Graph complet
./gradlew generateKnowledgeGraphDiagram
Salida :`diagrams/knowledge-graph/knowledge-graph-full.puml`+.png
Filtrar por comunidad
# Une seule communauté
./gradlew generateKnowledgeGraphDiagram \
-Pplantuml.kg.community=community_0
# Limiter le nombre de noeuds (lisibilité)
./gradlew generateKnowledgeGraphDiagram \
-Pplantuml.kg.community=community_0 \
-Pplantuml.kg.maxNodes=15
Filtrar por tipo de arista
# Uniquement les relations certaines (EXTRACTED)
./gradlew generateKnowledgeGraphDiagram \
-Pplantuml.kg.edgeTypes=EXTRACTED
# Relations certaines + inférées
./gradlew generateKnowledgeGraphDiagram \
-Pplantuml.kg.edgeTypes=EXTRACTED,INFERRED
Filtrar por tipo de nodo y confianza
# Uniquement les classes de code
./gradlew generateKnowledgeGraphDiagram \
-Pplantuml.kg.nodeTypes=code
# Seuil de confiance minimum (pour les INFERRED)
./gradlew generateKnowledgeGraphDiagram \
-Pplantuml.kg.minConfidence=0.7
Directorio de salida personalizado
./gradlew generateKnowledgeGraphDiagram \
-Pplantuml.kg.outputDir=docs/architecture
Referencia completa de las propiedades
| Propiedad | Defecto | Descripción |
|---|---|---|
|
(todas) |
Filtrar las comunidades por nombre (coincidencia de subcadena) |
|
(todos) |
Tipos de aristas separados por comas :`EXTRACTED`, |
|
|
Umbral mínimo de confianza para las aristas |
|
(ilimitado) |
Número máximo de nodos a mostrar |
|
(todos) |
Tipos de nodos separados por comas (ej. |
|
|
Directorio de salida para los archivos`.puml` et |
El pipeline completo en un flujo de trabajo Gradle
Tipo de flujo de trabajo
@startuml
skinparam backgroundColor #FEFEFE
skinparam ActivityBackgroundColor #E8F4FD
skinparam ActivityDiamondBackgroundColor #FFF3CD
skinparam ActivityBorderColor #2C3E50
start
partition "EXTRACTION" {
:graphify . --no-viz;
note right: Analice el código fuente\n tree-sitter (local, sin LLM)
:graphify-out/graph.json;
note right: Nodos + aristas\n+ comunidades
}
partition "GÉNÉRATION" {
:./gradlew generateKnowledgeGraphDiagram;
note right: Pipeline determinista\nparse → render → validate → PNG
if (Filtres actifs ?) then (Oui)
:Aplicar filtros\n(community, edgeTypes,\nmaxNodes, nodeTypes);
else (Non)
:Diagrama completo;
endif
:diagramas/knowledge-graph/\nknowledge-graph-full.puml\nknowledge-graph-full.png;
}
partition "INTÉGRATION" {
:git add diagrams/knowledge-graph/;
:git commit;
note right: diagramas versionados\nsiempre actualizado con el código
}
stop
@enduml
Integración en el ciclo de desarrollo
El pipeline se integra naturalmente en las etapas clave del desarrollo:
@startuml skinparam backgroundColor #FEFEFE state "Desarrollo" as dev state "Extracción\ngraphify . --no-viz" as extract state "Generación\n./gradlew generateKnowledgeGraphDiagram" as generate state "Commit\ndiagramas versionados" as commit [*] --> dev dev --> extract : Código modificado extract --> generate : graph.json actualizado generate --> commit : .puml + .png generados commit --> dev : Diagramas en el repo note right of extract Casi instantáneo en código Kotlin (tree-sitter, sin LLM) end note note right of generate Deterministico No LLM Resultado reproducible end note @enduml
Actualización incremental
Cuando el código cambia, no se reconstruye todo el grafo desde cero:
# Mise à jour incrémentale (fichiers modifiés uniquement)
graphify . --update
# Puis régénérer les diagrammes
./gradlew generateKnowledgeGraphDiagram
|
|
El dogfooding : el plugin se documenta a sí mismo
El plugin PlantUML existe para transformar prompts en diagramas. También puede transformar el Knowledge Graph de su propre codebase en diagramas de documentación. Es dogfooding: el plugin consume su propio servicio.
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
package "Pipeline normal\n(usuario → diagramas)" as normal {
[Fichier .prompt] as prompt
[LlmService\n+ ApiKeyPool] as llm1
[ProcessPlantumlPromptsTask] as task1
[Diagramme PNG] as out1
prompt --> task1
task1 --> llm1
llm1 --> out1
}
package "Grafo de conocimiento del pipeline\n(determinista, sin LLM)" as kg {
[graphify-out/graph.json] as kgjson
[KnowledgeGraphParser] as parser
[KnowledgeGraphRenderer] as renderer
[PlantumlService] as ps
[Diagramme PNG\n(documentation du plugin)] as out2
kgjson --> parser
parser --> renderer
renderer --> ps
ps --> out2
}
package "Pipeline Dogfooding\n(LLM → documentación del plugin)" as dogfood {
[GraphifyPromptAdapter] as gpa
[Fichiers .prompt\nauto-générés] as auto_prompt
[LlmService\n+ ApiKeyPool] as llm2
[ProcessPlantumlPromptsTask] as task2
[Diagramme PNG\n(documentation LLM)] as out3
kgjson --> gpa
gpa --> auto_prompt
auto_prompt --> task2
task2 --> llm2
llm2 --> out3
}
note "Mismo LlmService, mismo ApiKeyPool,\nmismo PlantumlService\n— CERO duplicación" as N
@enduml
Tareas Gradle asociadas :
| tarea | LLM ? | Descripción |
|---|---|---|
|
No |
Transforma`graph.json`en PlantUML (determinista) |
|
Sí |
Genera de`.prompt`desde el grafo, los trata a través de LLM (dogfooding) |
# Documentation déterministe (rapide, pas de LLM)
./gradlew generateKnowledgeGraphDiagram
# Documentation LLM (plus riche, consomme des tokens)
./gradlew generateDiagramDocs
¿Por qué es determinista (y por qué importa)?
El punto clave del pipeline`generateKnowledgeGraphDiagram`:Él no llama ningún LLM. La transformación`graph.json`PlantUML es una función pura.
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
rectangle "Canalización DÉTERMINISTE\n(generateKnowledgeGraphDiagram)" as det {
[graph.json] as json
[KnowledgeGraphParser] as parser
[KnowledgeGraphRenderer] as renderer
[PlantUML code] as puml
json --> analizar : analiza
parser --> renderer : KnowledgeGraph
renderer --> puml : render (función pura)
}
rectangle "Canalización LLM\n(processPlantumlPrompts)" as llm {
[.prompt] as prompt
[LlmService] as llmSvc
[ChatModel] as model
[PlantUML code] as puml2
prompt --> llmSvc
llmSvc --> model : API llamada
model --> puml2 : respuesta no determinista
}
note bottom of det
Misma entrada → misma salida
Sin latencia de red
Sin costo en tokens
Reproducible en CI
end note
note bottom of llm
Misma entrada → salida variable
Latencia de red (1-5s)
Costo en tokens
Requiere una clave API
end note
@enduml
Los beneficios concretos:
| Ventaja | Impacto |
|---|---|
Reproducibilidad |
incluso`graph.json`→ mismo diagrama. Exactamente. Todas las veces. |
Costo cero |
Sin llamada LLM = sin tokens = sin factura API |
Cero latencia |
Parse + render tarda ~100ms, no 1-5 segundos. |
Compatible con CI |
No se necesita una clave API. No hay prueba inestable debido a una respuesta variable del LLM. |
Versionable |
Le |
Diagramas del propio pipeline
Para cerrar el ciclo, aquí tienes el diagrama del pipeline tal como sería generado por el plugin :
@startuml
skinparam backgroundColor #FEFEFE
participant "Desarrollador" as Dev
participant "Gradle" as G
participant "GenerateKnowledgeGraphDiagramTask" as Task
participant "KnowledgeGraphParser" as Parser
participant "KnowledgeGraphRenderer" as Renderer
participant "PlantumlService" as PS
collections "graphify-out/graph.json" as JSON
collections "diagrams/knowledge-graph/" as Out
Dev -> G : ./gradlew generateKnowledgeGraphDiagram
G -> Task : ejecutar
Task -> JSON : leer
Task -> Parser : parse(graph.json)
Parser --> Task : KnowledgeGraph
alt filtres actifs
Task -> Task : aplicar filtros\n(community, edgeTypes, maxNodes…)
end
Task -> Renderer : render(graph, filters)
Renderer --> Task : código PlantUML
Task -> PS : validateSyntax()
alt valide
Task -> PS : generateImage()
PS --> Out : .puml + .png
else invalide
Task -> Out : .puml (con advertencia)
end
@enduml
Integración en la gobernanza del proyecto
En nuestro proyecto, este pipeline se integra en una estrategia de gestión de contexto EAGER/LAZY para el agente IA. El Knowledge Graph reemplaza la documentación de arquitectura manual por un grafo estructurado, consultable y autoactualizado.
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
package "EAGER\n(siempre cargado)" as eager {
[PROMPT_REPRISE.adoc\n(contexte session)] as pr
[INDEX.adoc\n(vue d'ensemble)] as idx
[GRAPH_REPORT.adoc\n(~50 lignes)] as gr
}
package "LAZY — Estrategia\n(bajo demanda)" as lazy_strat {
[Méthodologies] as meth
[Archives sessions] as sessions
}
package "LAZY — Graphify\n(consultas dirigidas)" as lazy_graph {
[graph.json] as gj
[Queries\n(query/path/explain)] as queries
}
package "Pipeline PlantUML\n(generado automáticamente)" as puml {
[generateKnowledgeGraphDiagram] as kgTask
[generateDiagramDocs] as ddTask
[Diagrammes PNG] as diagrams
}
Agent --> eager : Leído al inicio de la sesión
Agent ..> lazy_strat : Cargar si se detecta el tipo
Agent ..> lazy_graph : Consulta si es estructuralmente necesario
kgTask --> diagrams : Determinista
ddTask --> diagrams : A través de LLM
note right of gr
Resumen del Knowledge Graph
Nodos God + comunidades
Reemplaza ECOSYSTEM_OVERVIEW
(225 líneas → 50 líneas)
end note
@enduml
El matrimonio de los dos sistemas es complementario :
-
La estrategia gestiona el CUÁNDO y el CÓMO— gobernanza, workflow, archivado
-
Graphify gestiona el QUOI y el OÙestructura del código, relaciones, consultas dirigidas
__ La estrategia de sesión gestiona elCUANDO et le CÓMO(gobernanza, flujo de trabajo, umbrales), Graphify gestiona elqué et le DÓNDE(estructura del código, relaciones, consultas específicas). El pipeline PlantUML gestiona elCON QUÉ(diagramas deterministas, versionados, siempre actualizados). (No output needed because no source text provided.)
Preparación: checklist en 5 minutos
| # | Etapa | Orden |
|---|---|---|
1 |
Instalar Graphify |
|
2 |
Configurar las exclusiones |
Crear`.graphifyignore` |
3 |
Extraer el Knowledge Graph |
|
4 |
Generar los diagramas |
|
5 |
Confirmar los resultados |
|
# Script complet en 5 commandes
uv tool install graphifyy
cat > .graphifyignore << 'EOF'
*-context.yml
*.env
build/
.gradle/
EOF
graphify . --no-viz
./gradlew generateKnowledgeGraphDiagram
git add graphify-out/GRAPH_REPORT.adoc graphify-out/graph.json diagrams/knowledge-graph/
Trampas y mitigaciones
| Trampa | Descripción | Mitigación |
|---|---|---|
Grafo demasiado denso |
Un gran proyecto genera cientos de nodos ilegibles |
Utilizar`-Pplantuml.kg.maxNodes=30`et filtrar por comunidad |
exclusiones demasiado amplias |
Demasiados archivos en`.graphifyignore`reduce el valor del grafo |
Comenzar por excluir solo credentials y build |
Dirección de las flechas |
Las aristas INFERRED pueden tener una dirección ambigua |
Filtrar por`-Pplantuml.kg.edgeTypes=EXTRACTED`Solo para las relaciones ciertas |
Grafo obsoleto |
El código cambia pero el grafo no se reconstruye |
usar`graphify . --update`regularmente o el hook git`graphify hook install` |
Costo actualizado |
Las actualizaciones incrementales son prácticamente gratuitas (tree-sitter local) |
Sólo los docs ( |
Lo que se obtiene al final
@startuml
skinparam backgroundColor #FEFEFE
rectangle "AVANT" as avant {
card "Diagramas dibujados a mano\nSiempre obsoletos\nNadie los actualiza" as av1 #FDEDEC
}
rectangle "APRÈS" as apres {
card "Diagramas generados automáticamente\nSiempre actualizados con el código\nVersionados en Git\nDeterministas y reproducibles" as ap1 #E8F8E8
}
avant --> apres : graphify . --no-viz\n+ ./gradlew generateKnowledgeGraphDiagram
@enduml
Los beneficios concretos:
| Beneficio | Detalle |
|---|---|
Documentación siempre actualizada |
Los diagramas reflejan el código actual, no una instantánea manual |
Cero esfuerzo de mantenimiento |
Los diagramas se regeneran en cada compilación |
Reducción de la deuda técnica |
Ya no es necesario mantener los diagramas a mano |
Contexto visual para los nuevos |
Un nuevo desarrollador comprende la arquitectura mirando los diagramas |
potencial de ajuste fino |
Los pares (subgrafo → diagrama) son ejemplos de entrenamiento IA |
Validación automática |
`PlantumlService.validateSyntax()`verifica cada diagrama generado |
Onboarding rápido |
5 diagramas = vista completa de la arquitectura |
__ El que tiene un por qué puede soportar todos los cómo. </think>
El porqué : diagramas siempre actualizados. El cómo : dos comandos en un pipeline de Gradle.
enlaces
-
Los super tips del comando fg— artículo anterior sobre el flujo de trabajo terminal