tiempo de lectura : 12 minutes

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:

  1. Se dibuja un diagrama de arquitectura al inicio del proyecto

  2. El código evoluciona, las dependencias cambian

  3. El diagrama se convierte en una mentira decorativa

  4. Nadie lo actualiza porque es tedioso

  5. Los recién llegados se basan en ello y cometen errores

probleme diagrammes obsoletes

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

Ejemplo de estructura`graph.json`
{
  "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 (.kt, .java) se analiza localmente por tree-sitter,inapelable LLM. Sólo los archivos de documentación (.adoc, .md) requieren una llamada LLM para la extracción semántica. Así que`--update`sobre código Kotlin es casi instantáneo.

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 :

architecture pipeline kg

Los componentes internos

Componente rol

KnowledgeGraphParser

Analizar`graph.json`— soporta 3 formatos : graphify nativo (nodes+links), legado (communities), plano. Resuelve los IDs numéricos en etiquetas.

KnowledgeGraphRenderer

Transforma deterministamente un`KnowledgeGraph`en código PlantUML. Grupos por tipo, comunidades en paquetes, leyenda automática.

GenerateKnowledgeGraphDiagramTask

Tarea Gradle que orquesta: parse → render → validate → PNG. Configurable mediante propiedades Gradle.

kgmodels.kt

Modelos de datos:`KnowledgeGraph`, KnowledgeGraphNode, KnowledgeGraphEdge, KnowledgeGraphCommunity, EdgeType.

PlantumlService

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

-→(línea continua, negro)

Relación extraída del código fuente (certeza)

DEDUCIDO

..>(línea punteada)

Relación inferida por el LLM (puntuación de confianza)

AMBIGUOUS

--x(línea roja punteada)

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

plantuml.kg.community

(todas)

Filtrar las comunidades por nombre (coincidencia de subcadena)

plantuml.kg.edgeTypes

(todos)

Tipos de aristas separados por comas :`EXTRACTED`, INFERRED, AMBIGUOUS

plantuml.kg.minConfidence

0.0

Umbral mínimo de confianza para las aristas

plantuml.kg.maxNodes

(ilimitado)

Número máximo de nodos a mostrar

plantuml.kg.nodeTypes

(todos)

Tipos de nodos separados por comas (ej.class, code)

plantuml.kg.outputDir

diagrams/knowledge-graph

Directorio de salida para los archivos`.puml` et .png

El pipeline completo en un flujo de trabajo Gradle

Tipo de flujo de trabajo

workflow complet

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

--update`reextrae únicamente los archivos modificados (detectados por SHA256 en`graphify-out/cache/). En código Kotlin, es casi instantáneo porque tree-sitter trabaja localmente sin llamada a LLM.

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

generateKnowledgeGraphDiagram

No

Transforma`graph.json`en PlantUML (determinista)

generateDiagramDocs

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 .puml`generado es texto. Podemos lo`diff, el revisor en PR, versionarlo en Git

Diagramas del propio pipeline

Para cerrar el ciclo, aquí tienes el diagrama del pipeline tal como sería generado por el plugin :

pipeline sequence

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

uv tool install graphifyy

2

Configurar las exclusiones

Crear`.graphifyignore`

3

Extraer el Knowledge Graph

graphify . --no-viz

4

Generar los diagramas

./gradlew generateKnowledgeGraphDiagram

5

Confirmar los resultados

git add diagrams/knowledge-graph/

# 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 (.adoc) consumen tokens LLM

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

Articles connexes