Graphify integreren in een Gradle-workflow: van de Knowledge Graph naar het PlantUML-diagram in één opdracht
Gepubliceerd op 19 April 2026
- Het probleem: diagrammen die altijd achterlopen op de code
- De oplossing: een deterministische Knowledge Graph → PlantUML pipeline
- Stap 1 : Graphify installeren en de Knowledge Graph extraheren
- Stap 2: De Gradle-plugin transformeert de Knowledge Graph naar PlantUML
- Stap 3 : Dagelijks gebruik
- De volledige pipeline in een Gradle-workflow
- Dogfooding: het plugin documenteert zichzelf
- Waarom het deterministisch is (en waarom dat telt)
- Diagrammen van de pipeline zelf
- Integratie in de project governance
- Voorbereiding: checklist in 5 minuten
- Valkuilen en verzachtende maatregelen
- Wat men uiteindelijk krijgt
- links
Uw codebase groeit. De afhankelijkheden tussen modules nemen toe. De architectuurdocumentatie wordt verouderd voordat het zelfs is geschreven. En wat als uw Gradle-build automatisch up-to-date diagrammen kon genereren vanuit de echte code-structuur? Dat is precies wat de Graphify + PlantUML Gradle Plugin-pipeline doet:`graphify . --no-viz`extraheert de Knowledge Graph,`./gradlew generateKnowledgeGraphDiagram`het omzet in PlantUML-diagrammen. Geen LLM, geen handleiding, 100% deterministisch.
Het probleem: diagrammen die altijd achterlopen op de code
Elk project dat meer dan enkele duizenden regels overschrijdt kent dit syndroom:
-
We tekenen een architectuurdiagram aan het begin van het project
-
De code evolueert, de afhankelijkheden veranderen
-
Het diagram wordt een decoratieve leugen
-
Niemand updateert het omdat het vervelend is.
-
Nieuwkomers baseren zich daarop en maken fouten
@startuml
skinparam backgroundColor #FEFEFE
skinparam ActivityBackgroundColor #FDEDEC
skinparam ActivityDiamondBackgroundColor #FFF3CD
start
:Architectuurdiagram aangemaakt\n(handmatig, met de hand);
:De code evolueert\n(nieuwe klassen, nieuwe afhankelijkheden);
:Verouderd diagram\n(weerspiegelt de code niet meer);
if (Qui met à jour ?) then (Personne)
:Misleidende documentatie;
note right: De nieuwe ontwikkelaars\nbasen zij zich daarop... en maken fouten
else (Quelqu'un)
:Handmatige bijwerking\n(2-3 uur werk);
note right: Déjà obsolète\nà la prochaine PR
endif
stop
@enduml
De vraag is niet moeten er diagrammen zijn? — iedereen weet dat ja. De vraag is:wie houdt ze up to date?
Het antwoord: niemand. Tenzij het automatisch is.
De oplossing: een deterministische Knowledge Graph → PlantUML pipeline
Het principe is eenvoudig: in plaats van de diagrammen met de hand te tekenen, we zegenereert vanuit de werkelijke structuur van de code.
@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 + weergave PNG)" as PS collections "diagrams/knowledge-graph/\n(.puml + .png)" as Output Développeur --> Graphify : graphify . --no-viz Graphify --> KGJSON : extraheer de structuur\nvan de code bron Développeur --> Plugin : ./gradlew generateKnowledgeGraphDiagram Plugin --> Parser : parse(graph.json) Parser --> Plugin : KnowledgeGraph\n(knopen + randen + gemeenschappen) Plugin --> Renderer : render(graph, filters) Renderer --> Plugin : code PlantUML\ndeterministiek Plugin --> PS : validateSyntax + generateImage PS --> Output : .puml + .png note bottom of Plugin Pipeline DÉTERMINISTE Geen oproep LLM Reproduceerbaar resultaat end note @enduml
Twee commando’s. Dat is alles.
# Étape 1 : extraire le Knowledge Graph
graphify . --no-viz
# Étape 2 : générer les diagrammes PlantUML
./gradlew generateKnowledgeGraphDiagram
Het resultaat? Bestanden`.puml` et .png`in`diagrams/knowledge-graph/, versiebeheerd in Git, altijd up-to-date met de code.
Stap 1 : Graphify installeren en de Knowledge Graph extraheren
Installatie
Graphify is een Python-tool die jouw codebase analyseert en een gestructureerde kennisgraaf opbouwt:
# Méthode recommandée
uv tool install graphifyy && graphify install --platform opencode
# Alternative avec pip
pip install graphifyy && graphify install --platform opencode
Configureer de uitsluitingen
Een bestand maken`.graphifyignore`in de projectmap om bestanden uit te sluiten die geen onderdeel uitmaken van de bedrijfslogica:
# Secrets — JAMAIS dans le graphe
*-context.yml
*.env
# Fichiers générés
build/
.gradle/
# Tests fonctionnels
src/functionalTest/
Extraheer de Knowledge Graph
graphify . --no-viz
De vlag`--no-viz`oversla de HTML-generatie (nutteloos in een Gradle-pipeline). Het resultaat is een bestand`graphify-out/graph.json`bevattend :
-
Knopen: klassen, functies, bestanden — met hun type en gemeenschap
-
randen: relaties tussen knooppunten (EXTRACTED uit de code, INFERRED door de LLM)
-
gemeenschappen: automatische groeperingen van gekoppelde knooppunten
{
"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}
]
}
|
De broncode ( |
Stap 2: De Gradle-plugin transformeert de Knowledge Graph naar PlantUML
Architectuur van de pijplijn
De plugin`com.cheroliv.plantuml`integreert een taak`generateKnowledgeGraphDiagram`die transformeert`graph.json`in PlantUML-diagrammen op een maniervolledig deterministisch:
@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 : uitvoeren
Task -> JSON : lezen
Task -> Parser : parse(graph.json)
Parser --> Task : KnowledgeGraph\n(noeuds + arêtes + communautés)
Task -> Renderer : render(graph, filters)
Renderer --> Task : code PlantUML\n(deterministisch)
Task -> PS : validateSyntax(plantumlCode)
alt syntaxe valide
Task -> PS : generateImage → .png
else syntaxe invalide
Task -> Task : opslaan .puml met waarschuwing
end
@enduml
De interne onderdelen
| Component | Rol |
|---|---|
|
Parse`graph.json`— ondersteunt 3 formaten : graphify natief ( |
|
Transformeert deterministisch een`KnowledgeGraph`in PlantUML-code. Groepen per type, gemeenschappen in packages, automatische legenda. |
|
Gradle-taak die orchestreert : parse → render → validate → PNG. Configureerbaar via Gradle-eigenschappen. |
|
Gegevensmodellen:`KnowledgeGraph`, |
|
Syntactische validatie + PNG-weergave (hergebruikt door alle taken van de plug-in). |
Renderregels
De renderer past deterministische visuele conventies toe:
| Type rand | Notatie PlantUML | Betekenis |
|---|---|---|
EXTRACTED |
|
Uit de broncode geëxtraheerde relatie (zekerheid) |
INFERRED |
|
Relatie afgeleid door de LLM (betrouwbaarheidsscore) |
AMBIGUOUS |
|
Ambigue relatie (te controleren) |
Gemeenschappen worden weergegeven als PlantUML-pakketten met een automatisch kleurenpalet.
Stap 3 : Dagelijks gebruik
Volledig diagram
# Générer le diagramme du Knowledge Graph complet
./gradlew generateKnowledgeGraphDiagram
Uitvoer :`diagrams/knowledge-graph/knowledge-graph-full.puml`+.png
Filter per gemeenschap
# 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
Filteren per randtype
# Uniquement les relations certaines (EXTRACTED)
./gradlew generateKnowledgeGraphDiagram \
-Pplantuml.kg.edgeTypes=EXTRACTED
# Relations certaines + inférées
./gradlew generateKnowledgeGraphDiagram \
-Pplantuml.kg.edgeTypes=EXTRACTED,INFERRED
Filter op knooptype en betrouwbaarheid
# 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
Aangepaste uitvoermap
./gradlew generateKnowledgeGraphDiagram \
-Pplantuml.kg.outputDir=docs/architecture
Volledige referentie van eigenschappen
| Eigendom | Standaard | Beschrijving |
|---|---|---|
|
(alle) |
Filter de gemeenschappen op naam (subtekenreeks-match) |
|
(alle) |
Soorten randen gescheiden door komma’s :`EXTRACTED`, |
|
|
Minimale betrouwbaarheidsdrempel voor de randen |
|
(onbeperkt) |
Maximum aantal knooppunten om weer te geven |
|
(alle) |
Soorten knooppunten gescheiden door komma’s (bijv. |
|
|
Uitvoermap voor de bestanden`.puml` et |
De volledige pipeline in een Gradle-workflow
type workflow
@startuml
skinparam backgroundColor #FEFEFE
skinparam ActivityBackgroundColor #E8F4FD
skinparam ActivityDiamondBackgroundColor #FFF3CD
skinparam ActivityBorderColor #2C3E50
start
partition "EXTRACTION" {
:graphify . --no-viz;
note right: Analyseer de broncode\ntree-sitter (lokaal, geen LLM)
:graphify-out/graph.json;
note right: Knooppunten + randen\n+ gemeenschappen
}
partition "GÉNÉRATION" {
:./gradlew generateKnowledgeGraphDiagram;
note right: determinis tische pijplijn\nparse → render → validate → PNG
if (Filtres actifs ?) then (Oui)
:Toepassen filters\n(community, edgeTypes,\nmaxNodes, nodeTypes);
else (Non)
:Volledig diagram;
endif
:diagrams/knowledge-graph/\nknowledge-graph-full.puml\nknowledge-graph-full.png;
}
partition "INTÉGRATION" {
:git add diagrams/knowledge-graph/;
:git commit;
note right: Diagrammen versiebeheerde\n zijn altijd up‑to‑date met de code
}
stop
@enduml
Integratie in de ontwikkelingscyclus
De pijplijn integreert zich natuurlijk in de belangrijkste stappen van de ontwikkeling :
@startuml skinparam backgroundColor #FEFEFE state "Ontwikkeling" as dev state "Extractie\ngraphify . --no-viz" as extract state "Generatie\n./gradlew generateKnowledgeGraphDiagram" as generate state "Commit\nversiebeheerde diagrammen" as commit [*] --> dev dev --> extract : Gewijzigde code extract --> generate : graph.json up-to-date generate --> commit : .puml + .png tegen commit --> dev : diagrammen in het repo note right of extract Bijna direct op code Kotlin (tree-sitter, geen LLM) end note note right of generate deterministiek Geen LLM resultaat reproduceerbaar end note @enduml
Incrementale update
Als de code verandert, bouwen we niet de hele graaf opnieuw op vanaf nul :
# Mise à jour incrémentale (fichiers modifiés uniquement)
graphify . --update
# Puis régénérer les diagrammes
./gradlew generateKnowledgeGraphDiagram
|
|
Dogfooding: het plugin documenteert zichzelf
De PlantUML-plugin bestaat om prompts om te zetten naar diagrammen. Het kan ook de Knowledge Graph van zijn eigen codebase omzetten naar documentatiediagrammen. Dit is dogfooding : de plug-in maakt gebruik van zijn eigen dienst.
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
package "Normale pipeline\n(gebruiker → diagrammen)" 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 "Knowledge Graph pipeline\n(deterministisch, geen 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 pipeline\n(LLM → plugin-documentatie)" 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 "Zelfde LlmService, zelfde ApiKeyPool,\nzelfde PlantumlService\n— NUL duplicatie" as N
@enduml
Gerelateerde Gradle-taken:
| Taak | LLM ? | Beschrijving |
|---|---|---|
|
Nee |
Verander`graph.json`in PlantUML (deterministisch) |
|
Ja |
Genereer enkele`.prompt`vanaf de graf, ze behandelt via LLM (dogfooding) |
# Documentation déterministe (rapide, pas de LLM)
./gradlew generateKnowledgeGraphDiagram
# Documentation LLM (plus riche, consomme des tokens)
./gradlew generateDiagramDocs
Waarom het deterministisch is (en waarom dat telt)
Het sleutelpunt van de pijplijn`generateKnowledgeGraphDiagram`:Hij belt geen LLM. De transformatie`graph.json`→ PlantUML is een zuivere functie.
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
rectangle "DETERMINISTISCHE Pipeline\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 "LLM Pipeline\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
Zelfde input → zelfde output
Geen netwerklatentie
Geen tokenkosten
Reproduceerbaar in CI
end note
note bottom of llm
Zelfde input → variabele output
Netwerklatentie (1-5s)
Tokenkosten
Vereist een API-sleutel
end note
@enduml
De concrete voordelen :
| voordeel | Invloed |
|---|---|
Reproduceerbaarheid |
zelfs`graph.json`→ zelfde diagram. Precies. Altijd. |
Nul kosten |
Geen LLM-aanroep = geen tokens = geen API-factuur. |
Nul latentie |
Parse + render neemt ~100ms in beslag, niet 1-5 seconden. |
Compatibel CI |
Geen API-sleutel nodig. Geen flaky test door een variabele LLM-antwoord. |
Versiebaar |
Le |
Diagrammen van de pipeline zelf
Om de cirkel rond te maken, hier is het diagram van de pipeline zoals deze door de plugin zou worden gegenereerd :
@startuml
skinparam backgroundColor #FEFEFE
participant "Ontwikkelaar" 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 : uitvoeren
Task -> JSON : lezen
Task -> Parser : parse(graph.json)
Parser --> Task : KnowledgeGraph
alt filtres actifs
Task -> Task : toepassen filters\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 (met waarschuwing)
end
@enduml
Integratie in de project governance
In ons project wordt deze pijplijn geïntegreerd in een strategie voor EAGER/LAZY-contextbeheer voor de AI-agent. Het Knowledge Graph vervangt de handmatige architectuurdocumentatie door een gestructureerde, querybare en automatisch bijgewerkte graaf.
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
package "EAGER\n(altijd geladen)" 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 — Strategie\n(op aanvraag)" as lazy_strat {
[Méthodologies] as meth
[Archives sessions] as sessions
}
package "LAZY — Graphify\n(gerichte aanvragen)" as lazy_graph {
[graph.json] as gj
[Queries\n(query/path/explain)] as queries
}
package "Pipeline PlantUML\n(automatisch gegenereerd)" as puml {
[generateKnowledgeGraphDiagram] as kgTask
[generateDiagramDocs] as ddTask
[Diagrammes PNG] as diagrams
}
Agent --> eager : Gelezen aan het begin van de sessie
Agent ..> lazy_strat : Laden als type gedetecteerd
Agent ..> lazy_graph : indien nodig structureel
kgTask --> diagrams : deterministisch
ddTask --> diagrams : Via LLM
note right of gr
Samenvatting van het Knowledge Graph
God-knooppunten + gemeenschappen
Vervang ECOSYSTEM_OVERVIEW
(225 regels → 50 regels)
end note
@enduml
Het huwelijk van de twee systemen is complementair:
-
De strategie beheert het wanneer en het hoe— governance, werkstroom, archivering
-
Graphify beheert het wat en het waar— code structuur, relaties, gerichte query’s
_ De sessiestrategie beheert deWANNEER et le Hoe(governance, workflow, drempels), Graphify beheert hetwat et le WAAR(code structuur, relaties, gerichte query’s). Het PlantUML-pijplijn beheert hetmet wat(deterministische diagrammen, versiebeheerd, altijd up-to-date). _
Voorbereiding: checklist in 5 minuten
| # | Stap | Bestelling |
|---|---|---|
1 |
Installeer Graphify |
|
2 |
Uitsluitingen configureren |
Creëren`.graphifyignore` |
3 |
Extraheer het Knowledge Graph |
|
4 |
De diagrammen genereren |
|
5 |
Commit de resultaten |
|
# 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/
Valkuilen en verzachtende maatregelen
| val | Beschrijving | mitigatie |
|---|---|---|
Te dichte grafiek |
Een groot project genereert honderden onleesbare knooppunten |
gebruiken`-Pplantuml.kg.maxNodes=30`en filteren op gemeenschap |
Te brede uitsluitingen |
Te veel bestanden in`.graphifyignore`vermindert de waarde van de graaf |
Begin met alleen credentials en build uitsluiten |
Richting van de pijlen |
De randen INFERRED kunnen een ambiguë richting hebben |
Filteren op`-Pplantuml.kg.edgeTypes=EXTRACTED`voor de zekere relaties alleen |
verouderde graf |
De code verandert maar de grafiek wordt niet opnieuw opgebouwd |
Gebruiken`graphify . --update`regelmatig of de git-hook`graphify hook install` |
Bijgewerkte kosten |
Incrementele updates zijn bijna gratis (tree-sitter lokaal) |
Alleen de docs ( |
Wat men uiteindelijk krijgt
@startuml
skinparam backgroundColor #FEFEFE
rectangle "AVANT" as avant {
card "Handgetekende diagrammen\nAltijd verouderd\nNiemand werkt ze bij" as av1 #FDEDEC
}
rectangle "APRÈS" as apres {
card "Automatisch gegenereerde diagrammen\nAltijd up-to-date met de code\nVersiebeheerd in Git\nDeterministisch en reproduceerbaar" as ap1 #E8F8E8
}
avant --> apres : graphify . --no-viz\n+ ./gradlew generateKnowledgeGraphDiagram
@enduml
Concrete voordelen:
| winst | detail |
|---|---|
Documentatie altijd up-to-date |
De diagrammen weerspiegelen de huidige code, niet een handmatige snapshot |
Geen onderhoudsinspanning |
De diagrammen worden bij elke build opnieuw gegenereerd |
Vermindering van de technische schuld |
Geen noodzaak meer om de diagrammen handmatig bij te houden |
Visuele context voor de nieuwe |
Een nieuwe ontwikkelaar begrijpt de architectuur door de diagrammen te bekijken. |
Fine-tuning potentieel |
De paren (ondergraf → diagram) zijn voorbeelden van AI-training |
Automatische validatie |
`PlantumlService.validateSyntax()`controleert elk gegenereerd diagram |
Snelle onboarding |
5 diagrammen = volledig overzicht van de architectuur |
_ Degene die een _waarom heeft kan alle hoe verdragen. __
De waarom : diagrammen altijd up-to-date. De hoe : twee opdrachten in een Gradle-pipeline.
links
-
De super tips van de opdracht fg— vorig artikel over de terminal workflow