Integrar Graphify en un flujo de trabajo Gradle: del Knowledge Graph al diagrama PlantUML en un comando
Publié le 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.
- tic
-
[ ]
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
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.
Failed to generate image: PlantUML preprocessing failed: [From <input> (line 11) ] @startuml skinparam backgroundColor #FEFEFE skinparam componentStyle rectangle actor Développeur component "Graphify\n(pip install graphifyy)" as Graphify collections "graphify-out/graph.json\n(Grafo de Conocimientos)" as KGJSON component "Complemento Gradle PlantUML\n(generateKnowledgeGraphDiagram)" as Plugin component "KnowledgeGraphParser" as Parser component "Renderizador de KnowledgeGraph" as Renderer component "PlantumlService ^^^^^ Syntax Error? (Assumed diagram type: component) @startuml skinparam backgroundColor #FEFEFE skinparam componentStyle rectangle actor Développeur component "Graphify\n(pip install graphifyy)" as Graphify collections "graphify-out/graph.json\n(Grafo de Conocimientos)" as KGJSON component "Complemento Gradle PlantUML\n(generateKnowledgeGraphDiagram)" as Plugin component "KnowledgeGraphParser" as Parser component "Renderizador de KnowledgeGraph" as Renderer component "PlantumlService (validación + renderizado PNG)" as PS collections "diagrams/knowledge-graph/\n(.puml + .png)" as Output Développeur --> Graphify : graphify . --no-viz Graphify --> KGJSON : extrait la structure\ndu code source Développeur --> Plugin : ./gradlew generateKnowledgeGraphDiagram Plugin --> Parser : parse(graph.json) Parser --> Plugin : KnowledgeGraph\n(noeuds + arêtes + communautés) Plugin --> Renderer : render(graph, filters) Renderer --> Plugin : code PlantUML\ndéterministe Plugin --> PS : validateSyntax + generateImage PS --> Output : .puml + .png note bottom of Plugin Pipeline DÉTERMINISTE Aucun appel LLM Résultat reproductible 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 :
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
Integración en el ciclo de desarrollo
El pipeline se integra naturalmente en las etapas clave del desarrollo:
Failed to generate image: PlantUML preprocessing failed: [From <input> (line 6) ] @startuml skinparam backgroundColor #FEFEFE state "Desarrollo" as dev state "Extracción\ngraphify . --no-viz" as extract state "Generación ^^^^^ Syntax Error? (Assumed diagram type: state) @startuml skinparam backgroundColor #FEFEFE state "Desarrollo" as dev state "Extracción\ngraphify . --no-viz" as extract state "Generación ./gradlew generateKnowledgeGraphDiagram" as generate state "Commit\ndiagramas versionados" as commit [*] --> dev dev --> extract : Code modifié extract --> generate : graph.json à jour generate --> commit : .puml + .png générés commit --> dev : Diagrammes dans le repo note right of extract Quasi instantané sur du code Kotlin (tree-sitter, pas de LLM) end note note right of generate Déterministe Pas de LLM Résultat reproductible 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.
Failed to generate image: PlantUML preprocessing failed: [From <input> (line 6) ]
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
package "Pipeline normal
(usuario → diagramas)" as normal {
^^^^^
Syntax Error? (Assumed diagram type: activity)
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
package "Pipeline normal
(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 "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 "Incluso LlmService, incluso ApiKeyPool,
incluso PlantumlService
— 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.
Failed to generate image: PlantUML preprocessing failed: [From <input> (line 6) ]
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
rectangle "Pipeline DETERMINISTA
(generateKnowledgeGraphDiagram)" as det {
^^^^^
Syntax Error? (Assumed diagram type: activity)
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
rectangle "Pipeline DETERMINISTA
(generateKnowledgeGraphDiagram)" as det {
[graph.json] as json
[KnowledgeGraphParser] as parser
[KnowledgeGraphRenderer] as renderer
[PlantUML code] as puml
json --> parser : parse
parser --> renderer : KnowledgeGraph
renderer --> puml : render (fonction pure)
}
rectangle "Canalización LLM\n(procesarPlantumlPrompts)" as llm {
[.prompt] as prompt
[LlmService] as llmSvc
[ChatModel] as model
[PlantUML code] as puml2
prompt --> llmSvc
llmSvc --> model : API call
model --> puml2 : réponse non-déterministe
}
note bottom of det
Même entrée → même sortie
Pas de latence réseau
Pas de coût en tokens
Reproductible en CI
end note
note bottom of llm
Même entrée → sortie variable
Latence réseau (1-5s)
Coût en tokens
Nécessite une 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 :
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.
Failed to generate image: PlantUML preprocessing failed: [From <input> (line 16) ]
@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
^^^^^
Syntax Error? (Assumed diagram type: component)
@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
(consultas específicas)" 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 : Lit en début de session
Agent ..> lazy_strat : Charge si type détecté
Agent ..> lazy_graph : Query si besoin structurel
kgTask --> diagrams : Déterministe
ddTask --> diagrams : Via LLM
note right of gr
Condensé du Knowledge Graph
God nodes + communautés
Remplace ECOSYSTEM_OVERVIEW
(225 lignes → 50 lignes)
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
Failed to generate image: PlantUML preprocessing failed: [From <input> (line 10) ]
@startuml
skinparam backgroundColor #FEFEFE
rectangle "ANTES" as avant {
card "Diagramas dibujados a mano\nSiempre obsoletos\nNadie los actualiza" as av1 #FDEDEC
}
rectangle "DESPUÉS" as apres {
card "Diagramas generados automáticamente
Siempre actualizados con el código
^^^^^
Syntax Error? (Assumed diagram type: activity)
@startuml
skinparam backgroundColor #FEFEFE
rectangle "ANTES" as avant {
card "Diagramas dibujados a mano\nSiempre obsoletos\nNadie los actualiza" as av1 #FDEDEC
}
rectangle "DESPUÉS" as apres {
card "Diagramas generados automáticamente
Siempre actualizados con el código
Versionados en Git
Deterministas 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