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: diagramas siempre atrasados respecto al 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 workflow Gradle
- El dogfooding: el plugin se auto-documenta
- Por qué es determinista (y por qué importa)
- Diagramas del pipeline mismo
- Integración en la gobernanza del proyecto
- Puestra en marcha: lista de verificación 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 incluso antes de ser 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 + PlantUML Gradle Plugin :`graphify . --no-viz`extrae el Knowledge Graph,`./gradlew generateKnowledgeGraphDiagram`lo convierte en diagramas PlantUML. Cero LLM, cero manual, 100% determinista.
El problema: diagramas siempre atrasados respecto al código
Todo proyecto que supera varios 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 mentirosa;
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\npara la próxima PR
endif
stop
@enduml
La pregunta no es ¿se necesitan diagramas? — todo el mundo sabe que sí. La pregunta es :¿Quién los mantiene al día?
La respuesta: nadie. A menos que sea automático.
La solución: un pipeline determinista Knowledge Graph → PlantUML
El principio es simple : en lugar de dibujar los diagramas a mano, nosotros 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 Plugin\n(generateKnowledgeGraphDiagram)" as Plugin component "KnowledgeGraphParser" as Parser component "KnowledgeGraphRenderer" as Renderer component "PlantumlService\n(validación + renderizado PNG)" as PS collections "diagrams/knowledge-graph/\n(.puml + .png)" as Output Développeur --> Graphify : graficar . --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 tu código base y construye un grafo de conocimientos 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`Salta la generación de 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: agrupaciones automáticas 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`integra 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 |
|---|---|
|
Parsear`graph.json`— admite 3 formatos: graphify nativo ( |
|
Transforma determinísticamente un`KnowledgeGraph`en código PlantUML. Grupos por tipo, comunidades en paquetes, leyenda automática. |
|
Tarea Gradle que orquesta: parse → render → validate → PNG. Configurable vía 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 deterministes:
| Tipo de arista | Notación PlantUML | Significado |
|---|---|---|
extraído |
|
Relación extraída del código fuente (certidumbre) |
DEDUCIDO |
|
Relación inferida por el LLM (puntuación de confianza) |
ambiguo |
|
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
Sortie : 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 workflow Gradle
tipo de flujo de trabajo
@startuml
skinparam backgroundColor #FEFEFE
skinparam ActivityBackgroundColor #E8F4FD
skinparam ActivityDiamondBackgroundColor #FFF3CD
skinparam ActivityBorderColor #2C3E50
start
partition "EXTRACTION" {
:graficar . --no-viz;
note right: Analice el código fuente\ntree-sitter (local, sin LLM)
:graphify-out/graph.json;
note right: Nodos + aristas\n+ comunidades
}
partition "GÉNÉRATION" {
:./gradlew generateKnowledgeGraphDiagram;
note right: Canalización determinista\nparse → render → validate → PNG
if (Filtres actifs ?) then (Oui)
:Aplicar filtros\n(community, edgeTypes,\nmaxNodes, nodeTypes);
else (Non)
:Diagrama completo;
endif
:diagrams/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 actualizados 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 al día generate --> commit : .puml + .png generados commit --> dev : Diagramas en el repositorio note right of extract Casi instantáneo sobre el código Kotlin (tree-sitter, sin LLM) end note note right of generate Deterministic 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 auto-documenta
El plugin PlantUML existe para transformar los 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 "Pipeline Knowledge Graph\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 "Dogfooding del pipeline\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`.prompt`desde el grafo, los trata mediante 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`:No llama a ningún LLM. La transformación`graph.json`→ PlantUML es una función pura.
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
rectangle "Pipeline DÉTERMINISTE\n(generateKnowledgeGraphDiagram)" as det {
[graph.json] as json
[KnowledgeGraphParser] as parser
[KnowledgeGraphRenderer] as renderer
[PlantUML code] as puml
json --> analizarr : analizar
parser --> renderer : KnowledgeGraph
renderer --> puml : render (función pura)
}
rectangle "Pipeline 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. Cada vez. |
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 pruebas inestables debido a una respuesta de LLM variable. |
versionable |
Le |
Diagramas del pipeline mismo
Para cerrar el bucle, aquí está 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(a petición)" 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(autogenerado)" as puml {
[generateKnowledgeGraphDiagram] as kgTask
[generateDiagramDocs] as ddTask
[Diagrammes PNG] as diagrams
}
Agent --> eager : Lectura 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, flujo de trabajo, archivo
-
Graphify gestiona el QUOI y el OÙ— estructura del código, relaciones, consultas específicas
__ La estrategia de sesión gestiona elCUANDO et le CÓMO(gouvernance, workflow, seuils), Graphify gestiona elQUÉ et le dónde(estructura del código, relaciones, consultas dirigidas). El pipeline PlantUML gestiona elCON QUÉ(diagramas deterministas, versionados, siempre actualizados) (Empty)
Puestra en marcha: lista de verificación en 5 minutos
| (No output, as the text to translate is empty) | Etapa | Pedido |
|---|---|---|
1 |
Instalar Graphify |
|
2 |
Configurar las exclusiones |
Crear`.graphifyignore` |
3 |
Extraer el Knowledge Graph |
|
4 |
Generar los diagramas |
|
5 |
Committer 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 muy denso |
Un proyecto grande genera cientos de nodos ilegibles |
usar`-Pplantuml.kg.maxNodes=30`y 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`para las relaciones ciertas únicamente |
Grafo obsoleto |
El código cambia pero el grafo no se reconstruye |
Utilizar`graphify . --update`régulièrement o el hook git`graphify hook install` |
Costo actualizado |
Las actualizaciones incrementales son casi gratuitas (tree-sitter local) |
Sólo las 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 actualizado con el código\nVersionados en Git\nDeterministas y reproducibles" as ap1 #E8F8E8
}
avant --> apres : graficar . --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 build |
Reducción de la deuda técnica |
No es necesario mantener los diagramas a mano |
Contexto visual para los nuevos |
Un nuevo desarrollador entiende la arquitectura mirando los diagramas |
ajuste fino potencial |
Los pares (subgrafo → diagrama) son ejemplos de entrenamiento de 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. __
El por qué: diagramas siempre actualizados. El cómo: dos comandos en un pipeline Gradle.
Enlaces
-
Los mejores trucos del comando fg— artículo anterior sobre el flujo de trabajo del terminal