Graphify integreren in een Gradle-workflow: van de Knowledge Graph naar het PlantUML-diagram in één commando
Gepubliceerd op 19 April 2026
- Het probleem: diagrammen die altijd achterblijven bij de code
- De oplossing: een deterministische pijplijn Knowledge Graph → PlantUML
- Stap 1: Installeer Graphify en extraheer de Knowledge Graph
- Stap 2: De Gradle-plugin transformeert de Knowledge Graph naar PlantUML
- Stap 3: Dagelijks gebruik
- De volledige pijplijn in een Gradle-workflow
- Dogfooding: de plugin documenteert zichzelf
- Waarom het deterministisch is (en waarom het uitmaakt)
- diagrammen van de pipeline zelf
- Integratie in het projectbestuur
- Voorbereiding: checklist in 5 minuten
- Valkuilen en mitigaties
- Wat men uiteindelijk krijgt
- Links
Je codebase groeit. De afhankelijkheden tussen modules nemen toe. De architectuurdocumentatie wordt verouderd voordat ze zelfs geschreven is. En wat als jouw Gradle-build automatisch up-to-date diagrammen kon genereren op basis van de werkelijke code-structuur? Dat is precies wat de Graphify + PlantUML Gradle Plugin-pijplijn doet:`graphify . --no-viz`extraheert de Knowledge Graph,`./gradlew generateKnowledgeGraphDiagram`zet het om in PlantUML-diagrammen. Geen LLM, geen handleiding, 100% deterministisch.
Het probleem: diagrammen die altijd achterblijven bij de code
Elk project dat 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 werkt het bij omdat het vervelend is
-
De nieuwkomers baseren zich daarop en maken fouten.
@startuml
skinparam backgroundColor #FEFEFE
skinparam ActivityBackgroundColor #FDEDEC
skinparam ActivityDiamondBackgroundColor #FFF3CD
start
:Architectuurdiagram gemaakt\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)
:Misleadingende documentatie;
note right: Nieuwe ontwikkelaars\nbaseren zich daarop... en maken fouten
else (Quelqu'un)
:Handmatige update\n(2-3 uur werk);
note right: Al verouderd\nvoor de volgende PR
endif
stop
@enduml
De vraag is niet moeten we diagrammen hebben? — iedereen weet dat ja. De vraag is :Wie houdt ze up-to-date?
Het antwoord: niemand. Tenzij het automatisch is.
De oplossing: een deterministische pijplijn Knowledge Graph → PlantUML
Het principe is simpel : 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 : extraheert de structuur\nvan de broncode Développeur --> Plugin : ./gradlew generateKnowledgeGraphDiagram Plugin --> Parser : parse(graph.json) Parser --> Plugin : KnowledgeGraph\n(nodes + edges + communities) Plugin --> Renderer : render(graph, filters) Renderer --> Plugin : code PlantUML\ndeterminist Plugin --> PS : validateSyntax + generateImage PS --> Output : .puml + .png note bottom of Plugin Pijplijn 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: Installeer Graphify en extraheer de Knowledge Graph
Installatie
Graphify is een Python-hulpmiddel dat uw codebase analyseert en een gestructureerde kennisgrafiek bouwt :
# Méthode recommandée
uv tool install graphifyy && graphify install --platform opencode
# Alternative avec pip
pip install graphifyy && graphify install --platform opencode
De uitsluitingen configureren
Een bestand maken`.graphifyignore`in de root van het project om bestanden uit te sluiten die geen onderdeel uitmaken van de zakelijke logica:
# 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`Sla de HTML-generatie over (onnodig in een Gradle-pijplijn). Het resultaat is een bestand`graphify-out/graph.json`bevat:
-
knopen: klassen, functies, bestanden — met hun type en gemeenschap
-
randen: relaties tussen knooppunten (EXTRACTED vanuit de code, INFERRED door de LLM)
-
gemeenschappen: automatische groeperingen van gelinkte 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
Pijplijnarchitectuur
De plug-in`com.cheroliv.plantuml`integreert een taak`generateKnowledgeGraphDiagram`die transformeert`graph.json`in PlantUML-diagrammen op een maniervolledig deterministisch</think> </think>
@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 : lezen
Task -> Parser : parse(graph.json)
Parser --> Task : KnowledgeGraph\n(knooppunten + randen + gemeenschappen)
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 : sla .puml op met waarschuwing
end
@enduml
De interne componenten
| Component | Rol |
|---|---|
|
Parseert`graph.json`— ondersteunt 3 formaten: native graphify ( |
|
Verander deterministisch een`KnowledgeGraph`in PlantUML-code. Groepen per type, gemeenschappen in pakketten, automatische legenda. |
|
Gradle-taak die orchestratie uitvoert: parse → render → validate → PNG. Configureerbaar via Gradle-eigenschappen. |
|
Gegevensmodellen:`KnowledgeGraph`, |
|
Syntaxisvalidatie + PNG-rendering (hergebruikt door alle taken van de plugin). |
Regels voor rendering
De renderer past deterministische visuele conventies toe:
| type van rand | Notatie PlantUML | betekenis |
|---|---|---|
geëxtraheerd |
|
Uit de broncode geëxtraheerde relatie (zekerheid) |
AFGELEID |
|
Afgeleide relatie door het LLM (vertrouwensscore) |
ambigu |
|
Onduidelijke relatie (te controleren) |
Gemeenschappen worden weergegeven als PlantUML-pakketten met een automatische 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
Filteren op 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
Filter op randtype
# Uniquement les relations certaines (EXTRACTED)
./gradlew generateKnowledgeGraphDiagram \
-Pplantuml.kg.edgeTypes=EXTRACTED
# Relations certaines + inférées
./gradlew generateKnowledgeGraphDiagram \
-Pplantuml.kg.edgeTypes=EXTRACTED,INFERRED
Filteren op knooppunttype 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 |
|---|---|---|
|
(alles) |
Filter de gemeenschappen op naam (subtekenreeks overeenkomst) |
|
(alle) |
Types van randen gescheiden door komma’s :`EXTRACTED`, |
|
|
Minimum drempel van betrouwbaarheid voor de randen |
|
(onbeperkt) |
Maximum aantal knooppunten om weer te geven |
|
(alle) |
Soorten knopen gescheiden door komma’s (bijv. |
|
|
Uitvoermap voor de bestanden`.puml` et |
De volledige pijplijn in een Gradle-workflow
werkstroomtype
@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: Knopen + randen\n+ gemeenschappen
}
partition "GÉNÉRATION" {
:./gradlew generateKnowledgeGraphDiagram;
note right: Deterministische pijplijn\n→ render → validate → PNG
if (Filtres actifs ?) then (Oui)
:Filters toepassen\n(community, edgeTypes,\nmaxNodes, nodeTypes);
else (Non)
:Volledig diagram;
endif
:diagrammen/knowledge-graph/\nkennisgrafiek-full.puml\nkennisgrafiek-full.png;
}
partition "INTÉGRATION" {
:git add diagrams/knowledge-graph/;
:git commit;
note right: Versioned diagrams\nalways up to date with the code
}
stop
@enduml
Integratie in de ontwikkelingscyclus
De pipeline integreert zich natuurlijk in de essentiële 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\ndiagrammen versiegegeven" as commit [*] --> dev dev --> extract : Gewijzigde code extract --> generate : graph.json bijgewerkt generate --> commit : .puml + .png gegenereerd commit --> dev : Diagrammen in de repo note right of extract Bijna onmiddellijk op code Kotlin (tree-sitter, geen LLM) end note note right of generate Deterministisch Geen LLM Reproduceerbaar resultaat end note @enduml
incrementale update
Wanneer de code verandert, bouwen we niet de hele graaf opnieuw vanaf nul op:
# Mise à jour incrémentale (fichiers modifiés uniquement)
graphify . --update
# Puis régénérer les diagrammes
./gradlew generateKnowledgeGraphDiagram
|
|
Dogfooding: de plugin documenteert zichzelf
Het PlantUML-plugin bestaat om prompts te transformeren naar diagrammen. Het kan ook de Knowledge Graph van zijn eigen codebase omzetten naar documentatiediagrammen. Het is dogfooding : het plugin gebruikt 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 → documentatie van de 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 "Zelfde LlmService, dezelfde ApiKeyPool,\ndezelfde PlantumlService\n— NUL duplicatie" as N
@enduml
Geassocieerde Gradle-taken:
| taak | LLM ? | Beschrijving |
|---|---|---|
|
Nee |
Transformeer`graph.json`in PlantUML (deterministisch) |
|
Ja |
Genereert`.prompt`Vanaf de graaf, verwerkt ze 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 het uitmaakt)
Het sleutelpunt van de pijplijn`generateKnowledgeGraphDiagram`:hij roept geen LLM aan. 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`→ hetzelfde diagram. Exact. Elke keer. |
Geen kosten |
Geen LLM-aanroep = geen tokens = geen API-factuur. |
Nul latentie |
Parse + render duurt ~100ms, niet 1-5 seconden. |
Compatibel CI |
Geen API-sleutel nodig. Geen flaky test door een variabele LLM-reactie. |
versiebaar |
Le |
diagrammen van de pipeline zelf
Om de lus te sluiten, hier is het diagram van de pijplijn zoals dit 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 het projectbestuur
In ons project integreert deze pijplijn 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 opgeladen)" 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(op verzoek)" as lazy_strat {
[Méthodologies] as meth
[Archives sessions] as sessions
}
package "LAZY — Graphify\n(gerichte verzoeken)" 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 : Laad wanneer type gedetecteerd
Agent ..> lazy_graph : Query indien nodig structurele
kgTask --> diagrams : deterministisch
ddTask --> diagrams : Via LLM
note right of gr
Samenvatting van de Knowledge Graph
God nodes + 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— bestuur, workflow, archivering
-
Graphify beheert QUOI en OÙ— code structuur, relaties, gerichte query’s
_ De sessiestrategie beheert hetWanneer et le hoe(governance, werkstroom, drempels), Graphify beheert hetwat et le waar(structuur van de code, relaties, gerichte queries). De PlantUML-pipeline beheert hetMET WAT(deterministische diagrammen, versies, altijd up-to-date). _
Voorbereiding: checklist in 5 minuten
| # | Stap | bestelling |
|---|---|---|
1 |
Installeer Graphify |
|
2 |
Uitsluitingen configureren |
Maken`.graphifyignore` |
3 |
Extraheer de Knowledge Graph |
|
4 |
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 mitigaties
| val | Beschrijving | Mitigatie |
|---|---|---|
Te dichte graf |
Een groot project genereert honderden onleesbare knooppunten |
gebruiken`-Pplantuml.kg.maxNodes=30`en filteren op gemeenschap |
Uitsluitingen te ruim |
Te veel bestanden in`.graphifyignore`vermindert de waarde van de grafiek |
Begin met alleen credentials en build uit te sluiten |
Richting van de pijlen |
De randen INFERRED kunnen een onduidelijke richting hebben |
Filteren op`-Pplantuml.kg.edgeTypes=EXTRACTED`voor de bepaalde relaties alleen |
Verouderd graphe |
De code verandert maar de graaf wordt niet herbouwd |
Gebruiken`graphify . --update`regelmatig of de git-hook`graphify hook install` |
Kosten bijgewerkt |
Incrementale updates zijn praktisch 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 "APRin" as apres {
card "automatisch gegenereerde diagrammen\nAltijd up-to-date met de code\nVersiebeheerd in Git\ndeterminisitische en reproduceerbare" as ap1 #E8F8E8
}
avant --> apres : graphify . --no-viz\n+ ./gradlew generateKnowledgeGraphDiagram
@enduml
De concrete voordelen:
| Winst | Detail |
|---|---|
Documentatie altijd up-to-date |
De diagrammen spiegelen de huidige code weer, niet een handmatige snapshot |
Geen onderhoudsinspanning |
De diagrammen worden bij elke build opnieuw gegenereerd |
Vermindering van de technische schuld |
Je hoeft de diagrammen niet meer handmatig bij te houden. |
Visuele context voor de nieuwe |
Een nieuwe ontwikkelaar begrijpt de architectuur door naar de diagrammen te kijken. |
Potentiële fijnafstelling |
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 |
_ Wie een _waarom heeft, kan elke hoe verdragen. __
De waarom : diagrammen die altijd up-to-date zijn. De hoe : twee opdrachten in een Gradle-pipeline.
Links
-
De super tips van de opdracht fg— vorig artikel over terminal workflow