Intégrer Graphify dans un workflow Gradle : du Knowledge Graph au diagramme PlantUML en une commande
Pubblicato il 19 April 2026
- Il problema: diagrammi sempre in ritardo sul codice
- La soluzione: un pipeline deterministico Knowledge Graph → PlantUML
- Passo 1: Installare Graphify ed estrarre il Knowledge Graph
- Passo 2: Il plugin Gradle trasforma il Knowledge Graph in PlantUML
- Passo 3: Uso quotidiano
- Il pipeline completo in un workflow Gradle
- Il dogfooding: il plugin si documenta da sé
- Perché è deterministico (e perché conta)
- Diagrammi del pipeline stesso
- Integrazione nella governance del progetto
- Impostazione: checklist in 5 minuti
- Trappole e mitigazioni
- Ciò che si ottiene alla fine
- Link
La tua codebase sta crescendo. Le dipendenze tra i moduli si moltiplicano. La documentazione dell’architettura diventa obsoleta prima ancora di essere scritta. E se il tuo build Gradle potesse automaticamente generare diagrammi aggiornati a partire dalla struttura reale del codice? Questo è esattamente ciò che fa il pipeline Graphify + PlantUML Gradle Plugin :`graphify . --no-viz`estratto il Knowledge Graph,`./gradlew generateKnowledgeGraphDiagram`lo trasforma in diagrammi PlantUML. Zero LLM, zero manuale, 100% deterministico.
Il problema: diagrammi sempre in ritardo sul codice
Ogni progetto che supera qualche migliaio di righe conosce questa sindrome:
-
Si disegna un diagramma di architettura all’inizio del progetto
-
Il codice evolve, le dipendenze cambiano
-
Il diagramma diventa una menzogna decorativa
-
Nessuno lo aggiorna perché è noioso
-
I nuovi arrivati si basano su di esso e commettono errori
@startuml
skinparam backgroundColor #FEFEFE
skinparam ActivityBackgroundColor #FDEDEC
skinparam ActivityDiamondBackgroundColor #FFF3CD
start
:Diagramme d'architecture créé\n(manuellement, à la main);
:Le code évolue\n(nouvelles classes, nouvelles dépendances);
:Diagramme obsolète\n(ne reflète plus le code);
if (Qui met à jour ?) then (Personne)
:Documentation mensongère;
note right: Les nouveaux développeurs\nse basent dessus... et font des erreurs
else (Quelqu'un)
:Mise à jour manuelle\n(2-3 heures de travail);
note right: Déjà obsolète\nà la prochaine PR
endif
stop
@enduml
La domanda non è bisogna avere dei diagrammi? — tutti sanno che sì. La domanda è :chi li mantiene aggiornati?
La risposta: nessuno. Salvo se è automatica.
La soluzione: un pipeline deterministico Knowledge Graph → PlantUML
Il principio è semplice: invece di disegnare i diagrammi a mano, ligenera dalla struttura reale del codice.
@startuml skinparam backgroundColor #FEFEFE skinparam componentStyle rectangle actor Développeur component "Graphify\n(pip install graphifyy)" as Graphify collections "graphify-out/graph.json\n(Knowledge Graph)" as KGJSON component "PlantUML Gradle Plugin\n(generateKnowledgeGraphDiagram)" as Plugin component "KnowledgeGraphParser" as Parser component "KnowledgeGraphRenderer" as Renderer component "PlantumlService\n(validation + rendu 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
Due comandi. È tutto.
# Étape 1 : extraire le Knowledge Graph
graphify . --no-viz
# Étape 2 : générer les diagrammes PlantUML
./gradlew generateKnowledgeGraphDiagram
Il risultato? Dei file`.puml` et .png`in`diagrams/knowledge-graph/, versionati in Git, sempre aggiornati con il codice.
Passo 1: Installare Graphify ed estrarre il Knowledge Graph
Installazione
Graphify è uno strumento Python che analizza il tuo codebase e costruisce un grafo di conoscenza strutturato :
# Méthode recommandée
uv tool install graphifyy && graphify install --platform opencode
# Alternative avec pip
pip install graphifyy && graphify install --platform opencode
Configurare le esclusioni
Creare un file`.graphifyignore`alla radice del progetto per escludere i file che non fanno parte della logica di business:
# Secrets — JAMAIS dans le graphe
*-context.yml
*.env
# Fichiers générés
build/
.gradle/
# Tests fonctionnels
src/functionalTest/
Estrarre il Knowledge Graph
graphify . --no-viz
Il flag`--no-viz`Salta la generazione HTML (inutile in un pipeline Gradle). Il risultato è un file.`graphify-out/graph.json`contenente :
-
Nodi: classi, funzioni, file — con il loro tipo e comunità
-
spigoli: relazioni tra nodi (ESTRATTO dal codice, INFERITO dall’LLM)
-
Comunità: raggruppamenti automatici di nodi collegati
{
"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}
]
}
|
Il codice sorgente ( |
Passo 2: Il plugin Gradle trasforma il Knowledge Graph in PlantUML
Architettura del pipeline
Il plugin`com.cheroliv.plantuml`integra un compito`generateKnowledgeGraphDiagram`che trasforma`graph.json`in diagrammi PlantUML in modototalmente deterministico:
@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 : read
Task -> Parser : parse(graph.json)
Parser --> Task : KnowledgeGraph\n(noeuds + arêtes + communautés)
Task -> Renderer : render(graph, filters)
Renderer --> Task : code PlantUML\n(déterministe)
Task -> PS : validateSyntax(plantumlCode)
alt syntaxe valide
Task -> PS : generateImage → .png
else syntaxe invalide
Task -> Task : save .puml avec warning
end
@enduml
I componenti interni
| Componente | Ruolo |
|---|---|
|
Analizza`graph.json`— supporta 3 formati: graphify nativo ( |
|
Trasforma deterministicamente un`KnowledgeGraph`in codice PlantUML. Gruppi per tipo, comunità in package, leggenda automatica. |
|
Attività Gradle che orchestra: analizza → renderizza → valida → PNG. Configurabile tramite proprietà Gradle. |
|
Modelli di dati :`KnowledgeGraph`, |
|
Validazione sintattica + rendering PNG (riutilizzato da tutte le attività del plugin). |
Regole di rendering
Il renderer applica convenzioni visive deterministiche :
| Tipo di spigolo | Notazione PlantUML | Significato |
|---|---|---|
EXTRACTED |
|
Relazione estratta dal codice sorgente (certezza) |
dedotto |
|
Relazione inferita dall’LLM (punteggio di fiducia) |
ambiguo |
|
Relazione ambigua (da verificare) |
Le comunità sono rese come pacchetti PlantUML con una palette di colori automatica.
Passo 3: Uso quotidiano
Diagramma completo
# Générer le diagramme du Knowledge Graph complet
./gradlew generateKnowledgeGraphDiagram
Uscita :`diagrams/knowledge-graph/knowledge-graph-full.puml`+.png
Filtra per comunità
# 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
Filtrare per tipo di spigolo
# Uniquement les relations certaines (EXTRACTED)
./gradlew generateKnowledgeGraphDiagram \
-Pplantuml.kg.edgeTypes=EXTRACTED
# Relations certaines + inférées
./gradlew generateKnowledgeGraphDiagram \
-Pplantuml.kg.edgeTypes=EXTRACTED,INFERRED
Filtra per tipo di nodo e confidenza
# 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
Directory di output personalizzata
./gradlew generateKnowledgeGraphDiagram \
-Pplantuml.kg.outputDir=docs/architecture
Riferimento completo delle proprietà
| Proprietà | Difetto | Descrizione |
|---|---|---|
|
(tutte) |
Filtra le comunità per nome (corrispondenza di sottostringa) |
|
(tutti) |
Tipi di spigoli separati da virgole :`EXTRACTED`, |
|
|
Soglia minima di confidenza per gli archi |
|
(illimitato) |
Numero massimo di nodi da visualizzare |
|
(tutti) |
Tipi di nodi separati da virgole (es. |
|
|
Directory di output per i file`.puml` et |
Il pipeline completo in un workflow Gradle
Tipo di flusso di lavoro
@startuml
skinparam backgroundColor #FEFEFE
skinparam ActivityBackgroundColor #E8F4FD
skinparam ActivityDiamondBackgroundColor #FFF3CD
skinparam ActivityBorderColor #2C3E50
start
partition "EXTRACTION" {
:graphify . --no-viz;
note right: Analyse le code source\ntree-sitter (local, pas de LLM)
:graphify-out/graph.json;
note right: Noeuds + arêtes\n+ communautés
}
partition "GÉNÉRATION" {
:./gradlew generateKnowledgeGraphDiagram;
note right: Pipeline déterministe\nparse → render → validate → PNG
if (Filtres actifs ?) then (Oui)
:Appliquer filtres\n(community, edgeTypes,\nmaxNodes, nodeTypes);
else (Non)
:Diagramme complet;
endif
:diagrams/knowledge-graph/\nknowledge-graph-full.puml\nknowledge-graph-full.png;
}
partition "INTÉGRATION" {
:git add diagrams/knowledge-graph/;
:git commit;
note right: Diagrammes versionnés\ntoujours à jour avec le code
}
stop
@enduml
Integrazione nel ciclo di sviluppo
Il pipeline si integra naturalmente nelle fasi chiave dello sviluppo:
@startuml skinparam backgroundColor #FEFEFE state "Développement" as dev state "Extraction\ngraphify . --no-viz" as extract state "Génération\n./gradlew generateKnowledgeGraphDiagram" as generate state "Commit\ndiagrammes versionnés" 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
Aggiornamento incrementale
Quando il codice cambia, non ricostruiamo l’intero grafo da zero :
# Mise à jour incrémentale (fichiers modifiés uniquement)
graphify . --update
# Puis régénérer les diagrammes
./gradlew generateKnowledgeGraphDiagram
|
|
Il dogfooding: il plugin si documenta da sé
Il plugin PlantUML esiste per trasformare i prompt in diagrammi. Può anche trasformare il Knowledge Graph della sua propre codebase in diagrammi di documentazione. È dogfooding : il plugin consuma il proprio servizio.
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
package "Pipeline normale\n(utente → diagrammi)" 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(deterministica, nessun 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 → documentazione 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 "Stesso LlmService, stesso ApiKeyPool,\nstesso PlantumlService\n— ZERO duplicazioni" as N
@enduml
Attività Gradle associate :
| Compito | LLM ? | Descrizione |
|---|---|---|
|
No |
Trasforma`graph.json`in PlantUML (deterministico) |
|
Sì |
Genera dei`.prompt`dal grafo, li elabora tramite LLM (dogfooding) |
# Documentation déterministe (rapide, pas de LLM)
./gradlew generateKnowledgeGraphDiagram
# Documentation LLM (plus riche, consomme des tokens)
./gradlew generateDiagramDocs
Perché è deterministico (e perché conta)
Il punto chiave del pipeline`generateKnowledgeGraphDiagram` : non chiama nessun LLM. La trasformazione`graph.json`PlantUML è una funzione pura.
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
rectangle "Pipeline DETERMINISTICA\n(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 "Pipeline LLM\n(processPlantumlPrompts)" 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
Stesso input → stesso output
Nessuna latenza di rete
Nessun costo in token
Riproducibile in CI
end note
note bottom of llm
Stesso input → output variabile
Latenza di rete (1-5s)
Costo in token
Richiede una chiave API
end note
@enduml
I vantaggi concreti :
| Vantaggio | Impatto |
|---|---|
Riproducibilità |
Anche`graph.json`→ lo stesso diagramma. Esattamente. Ogni volta. |
Zero costo |
Nessuna chiamata LLM = nessun token = nessuna fattura API. |
Zero latenza |
Parse + render richiede ~100ms, non 1-5 secondi. |
Compatibile CI |
Nessuna chiave API necessaria. Nessun test flaky dovuto a una risposta LLM variabile. |
versionabile |
Le |
Diagrammi del pipeline stesso
Per chiudere il cerchio, ecco il diagramma del pipeline come sarebbe generato dal plugin:
@startuml
skinparam backgroundColor #FEFEFE
participant "Développeur" 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 : execute
Task -> JSON : read
Task -> Parser : parse(graph.json)
Parser --> Task : KnowledgeGraph
alt filtres actifs
Task -> Task : appliquer filtres\n(community, edgeTypes, maxNodes…)
end
Task -> Renderer : render(graph, filters)
Renderer --> Task : code PlantUML
Task -> PS : validateSyntax()
alt valide
Task -> PS : generateImage()
PS --> Out : .puml + .png
else invalide
Task -> Out : .puml (avec warning)
end
@enduml
Integrazione nella governance del progetto
Nel nostro progetto, questo pipeline si integra in una strategia di gestione del contesto EAGER/LAZY per l’agente IA. Il Knowledge Graph sostituisce la documentazione dell’architettura manuale con un grafo strutturato, queryable e aggiornato automaticamente.
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
package "EAGER\n(toujours chargé)" 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 — Stratégie\n(sur demande)" as lazy_strat {
[Méthodologies] as meth
[Archives sessions] as sessions
}
package "LAZY — Graphify\n(requêtes ciblées)" as lazy_graph {
[graph.json] as gj
[Queries\n(query/path/explain)] as queries
}
package "Pipeline PlantUML\n(auto-généré)" 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
Il matrimonio dei due sistemi è complementare:
-
La strategia gestisce il QUAND e il COMMENT— governance, flusso di lavoro, archiviazione
-
Graphify gestisce il COSA e il DOVE— struttura del codice, relazioni, query mirate
_ La strategia di sessione gestisce ilquando et le COME(governance, workflow, soglie), Graphify gestisce ilCHE et le dove(struttura del codice, relazioni, query mirate). Il pipeline PlantUML gestisce ilCon cosa?(diagrammi deterministici, versionati, sempre aggiornati). _
Impostazione: checklist in 5 minuti
| # | Fase | Ordine |
|---|---|---|
1 |
Installa Graphify |
|
2 |
Configurare le esclusioni |
Creare`.graphifyignore` |
3 |
Estrarre il Knowledge Graph |
|
4 |
Generare i diagrammi |
|
5 |
Committa i risultati |
|
# 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/
Trappole e mitigazioni
| Trappola | Descrizione | Mitigazione |
|---|---|---|
Grafo troppo denso |
Un grande progetto genera centinaia di nodi illeggibili |
usare`-Pplantuml.kg.maxNodes=30`e filtrare per comunità |
Esclusioni troppo larghe |
Troppi file in`.graphifyignore`riduce il valore del grafo |
Iniziare escludendo solo credentials e build |
Direzione delle frecce |
Gli archi INFERRED possono avere una direzione ambigua |
Filtra per`-Pplantuml.kg.edgeTypes=EXTRACTED`per le relazioni certe solo |
Grafo obsoleto |
Il codice cambia ma il grafo non viene ricostruito |
Utilizzare`graphify . --update`regolarmente o il hook git`graphify hook install` |
Costo aggiornato |
Gli aggiornamenti incrementali sono quasi gratuiti (tree-sitter local) |
Solo i docs ( |
Ciò che si ottiene alla fine
@startuml
skinparam backgroundColor #FEFEFE
rectangle "PRIMA" as avant {
card "Diagrammi disegnati a mano\nSempre obsoleti\nNessuno li aggiorna" as av1 #FDEDEC
}
rectangle "DOPO" as apres {
card "Diagrammi generati automaticamente\nSempre aggiornati con il codice\nVersionati in Git\nDeterministici e riproducibili" as ap1 #E8F8E8
}
avant --> apres : graphify . --no-viz\n+ ./gradlew generateKnowledgeGraphDiagram
@enduml
I benefici concreti:
| Beneficio | Dettaglio |
|---|---|
Documentazione sempre aggiornata |
I diagrammi riflettono il codice corrente, non uno snapshot manuale |
Zero sforzo di manutenzione |
I diagrammi si rigenerano a ogni build |
Riduzione del debito tecnico |
Non c’è più bisogno di mantenere i diagrammi a mano |
Contesto visivo per i nuovi |
Un nuovo sviluppatore comprende l’architettura osservando i diagrammi |
Potenziale fine-tuning |
Le coppie (sottografo → diagramma) sono esempi di addestramento IA |
Validazione automatica |
`PlantumlService.validateSyntax()`verifica ogni diagramma generato |
Onboarding rapido |
5 diagrammi = vista completa dell’architettura |
_ Chi ha un _perché può sopportare tutti i come. __
Il perché : diagrammi sempre aggiornati. Il come : due comandi in una pipeline Gradle.
Link
-
Il super tips del comando fg— articolo precedente sul workflow terminale