waktu membaca : 12 minutes

Codebase Anda tumbuh. Ketergantungan antar-modul bertambah banyak. Dokumentasi arsitektur menjadi usang bahkan sebelum ditulis. Dan jika build Gradle Anda bisa otomatis membuat diagram terkini dari struktur kode nyata? Ini persis yang dilakukan oleh pipeline Graphify + PlantUML Gradle Plugin :`graphify . --no-viz`mengambil Knowledge Graph,`./gradlew generateKnowledgeGraphDiagram`dia mengubahnya menjadi diagram PlantUML. Nol LLM, nol manual, 100% deterministik.

tok

[]

Masalah: diagram selalu tertinggal dibanding kode

Setiap proyek yang melebihi beberapa ribu baris mengalami sindrom ini:

  1. Kami menggambar diagram arsitektur pada awal proyek

  2. Kode berkembang, dependensi berubah

  3. Diagram menjadi kebohongan dekoratif

  4. Tidak ada yang memperbaruinya karena ini merepotkan

  5. Pendatang baru mengandalkan hal itu dan membuat kesalahan

@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

Pertanyaannya bukan apakah harus ada diagram? — semua orang tahu bahwa ya. Pertanyaannya adalah :Siapa yang menjaga agar tetap terkini?

Jawabannya: tidak ada siapa-siapa. Kecuali jika otomatis.

Solusi: pipeline Knowledge Graph → PlantUML yang deterministik

Prinsipnya sederhana: ali-alih menggambar diagram secara tangan, kita merekadihasilkan dari struktur kode sebenarnya.

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

actor Développeur
component "Graphify\n(pip install graphifyy)" as Graphify
collections "graphify-out/graph.json
(Graf Pengetahuan)" as KGJSON
component "PlantUML Plugin Gradle
(generateKnowledgeGraphDiagram)" as Plugin
component "KnowledgeGraphParser" as Parser
component "KnowledgeGraphRenderer" as Renderer
component "PlantumlService
(validasi + rendering PNG)" as PS
collections "diagram/graf-pengetahuan
(.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

Dua perintah. Itu saja.

# Étape 1 : extraire le Knowledge Graph
graphify . --no-viz

# Étape 2 : générer les diagrammes PlantUML
./gradlew generateKnowledgeGraphDiagram

Hasil? Berkas`.puml` et .png`di dalam`diagrams/knowledge-graph/, yang tercatat dalam Git, selalu terkini dengan kode.

Langkah 1: Menginstal Graphify dan mengekstrak Knowledge Graph

Instalasi

Graphify adalah alat Python yang menganalisis codebase Anda dan membangun grafik pengetahuan terstruktur :

# Méthode recommandée
uv tool install graphifyy && graphify install --platform opencode

# Alternative avec pip
pip install graphifyy && graphify install --platform opencode

Mengatur pengecualian

Buat sebuah file`.graphifyignore`di root proyek untuk mengecualikan file-file yang bukan bagian dari logika bisnis:

# Secrets — JAMAIS dans le graphe
*-context.yml
*.env

# Fichiers générés
build/
.gradle/

# Tests fonctionnels
src/functionalTest/

Ekstrak Knowledge Graph

graphify . --no-viz

Bendera`--no-viz`melewati pembuatan HTML (tidak berguna dalam pipeline Gradle). Hasilnya adalah sebuah file.`graphify-out/graph.json`berisi :

  • simpul: kelas, fungsi, file — dengan tipe dan komunitas mereka

  • rusuk: relasi antara node (EXTRACTED dari kode, INFERRED oleh LLM)

  • Komunitas: kelompokan otomatis dari node-node yang terhubung

Contoh struktur`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}
  ]
}

Kode sumber (.kt, .java) dianalisis secara lokal oleh tree-sitter,tanpa banding LLM. Hanya file dokumentasi (.adoc, .md) memerlukan panggilan LLM untuk ekstraksi semantik. Jadi`--update`pada kode Kotlin hampir seketika.

Langkah 2 : plugin Gradle mengubah Knowledge Graph menjadi PlantUML

Arsitektur pipa

Plugin`com.cheroliv.plantuml`mengintegrasikan sebuah tugas`generateKnowledgeGraphDiagram`python print(" yang mentransformasi", end='')`graph.json`dalam diagram PlantUML dengan carasepenuhnya deterministik:

@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

Komponen internal

Komponen Peran

KnowledgeGraphParser

mengurai`graph.json`— mendukung 3 format : graphify asli (nodes+links), legacy (communities), flat. Menyelesaikan IDs numerik menjadi label.

KnowledgeGraphRenderer

Transformaskan secara deterministik sebuah`KnowledgeGraph`dalam kode PlantUML. Kelompok berdasarkan tipe, komunitas di paket, legenda otomatis.

GenerateKnowledgeGraphDiagramTask

Tugas Gradle yang mengorakstratkan: parse → render → validate → PNG. Dapat dikonfigurasi melalui properti Gradle.

kgmodels.kt

Model data:`KnowledgeGraph`, KnowledgeGraphNode, KnowledgeGraphEdge, KnowledgeGraphCommunity, EdgeType.

PlantumlService

Validasi sintaksis + rendering PNG (digunakan kembali oleh semua tugas plugin).

Aturan rendering

Perender menerapkan konvensi visual deterministik:

Jenis tepi Notasi PlantUML Arti

diekstrak

-→(garis penuh, hitam)

Relasi diekstrak dari kode sumber (kepastian)

disimpulkan

..>(garis titik-titik)

Relasi yang disimpulkan oleh LLM (skor kepercayaan)

AMBIGUOUS

--x(garis titik merah)

Hubungan ambigu (perlu diperiksa)

Komunitas dirender seperti paket PlantUML dengan palet warna otomatis.

Langkah 3: Penggunaan sehari-hari

Diagram lengkap

# Générer le diagramme du Knowledge Graph complet
./gradlew generateKnowledgeGraphDiagram

Keluaran :`diagrams/knowledge-graph/knowledge-graph-full.puml`+.png

Filter berdasarkan komunitas

# 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 berdasarkan jenis tepi

# Uniquement les relations certaines (EXTRACTED)
./gradlew generateKnowledgeGraphDiagram \
  -Pplantuml.kg.edgeTypes=EXTRACTED

# Relations certaines + inférées
./gradlew generateKnowledgeGraphDiagram \
  -Pplantuml.kg.edgeTypes=EXTRACTED,INFERRED

Filter menurut jenis node dan kepercayaan

# 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

Direktori output khusus

./gradlew generateKnowledgeGraphDiagram \
  -Pplantuml.kg.outputDir=docs/architecture

Referensi lengkap properti

properti default Deskripsi

plantuml.kg.community

(semua)

Filter komunitas berdasarkan nama (cocokan substring)

plantuml.kg.edgeTypes

(semua)

Tipe sisi dipisahkan dengan koma:`EXTRACTED`, INFERRED, AMBIGUOUS

plantuml.kg.minConfidence

0.0

Ambang kepercayaan minimum untuk tepi

plantuml.kg.maxNodes

(tak terbatas)

Jumlah maksimum node yang akan ditampilkan

plantuml.kg.nodeTypes

(semua)

Jenis simpul dipisahkan dengan koma (contoh`class`, code)

plantuml.kg.outputDir

diagrams/knowledge-graph

Direktori output untuk file`.puml` et .png

Seluruh pipeline dalam sebuah workflow Gradle

jenis workflow

@startuml
skinparam backgroundColor #FEFEFE
skinparam ActivityBackgroundColor #E8F4FD
skinparam ActivityDiamondBackgroundColor #FFF3CD
skinparam ActivityBorderColor #2C3E50

start

partition "EKSTRAKSI" {
    :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 "GENERASI" {
    :./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 "INTEGRASI" {
    :git add diagrams/knowledge-graph/;
    :git commit;
    note right: Diagrammes versionnés\ntoujours à jour avec le code
}

stop

@enduml

Integrasi dalam siklus pengembangan

Pipeline ini terintegrasi secara alami ke dalam tahap-tahap kunci dari pengembangan :

@startuml
skinparam backgroundColor #FEFEFE

state "Pengembangan" as dev
state "Ekstraksi
graphify . --no-viz" as extract
state "Generasi
./gradlew generateKnowledgeGraphDiagram" as generate
state "Commit
diagram versi" 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

Pembaruan inkremental

Ketika kode berubah, kita tidak membangun kembali seluruh grafik dari nol:

# Mise à jour incrémentale (fichiers modifiés uniquement)
graphify . --update

# Puis régénérer les diagrammes
./gradlew generateKnowledgeGraphDiagram

--update`hanya mengekstrak kembali file yang telah dimodifikasi (terdeteksi oleh SHA256 di`graphify-out/cache/). Pada kode Kotlin, ini hampir instan karena tree-sitter bekerja secara lokal tanpa panggilan LLM.

Dogfooding : plugin mendokumentasikan dirinya sendiri

Plugin PlantUML ada untuk mengubah prompt menjadi diagram. Dia juga dapat mengubah Knowledge Graph dari codebase propre-nya menjadi diagram dokumentasi. Ini adalah dogfooding : plugin mengonsumsi layanan sendiri.

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "pipeline normal
(pengguna → diagram)" 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
(deterministis, tanpa 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
(LLM → dokumentasi 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 "Sama LlmService, sama ApiKeyPool,
sama PlantumlService
— TIDAK ADA duplikasi" as N

@enduml

Tugas Gradle terkait :

Tugas LLM ? Keterangan

generateKnowledgeGraphDiagram

Tidak

Mentransformasi`graph.json`en PlantUML (determinis)

generateDiagramDocs

Ya

Menghasilkan beberapa`.prompt`dari grafik, mereka memprosesnya melalui LLM (dogfooding)

# Documentation déterministe (rapide, pas de LLM)
./gradlew generateKnowledgeGraphDiagram

# Documentation LLM (plus riche, consomme des tokens)
./gradlew generateDiagramDocs

Mengapa itu deterministik (dan mengapa itu penting)

Titik kunci pipeline`generateKnowledgeGraphDiagram` : Dia tidak memanggil LLM apa pun. Transformasi`graph.json`PlantUML adalah sebuah fungsi murni.

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

rectangle "Pipeline Determinis
(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
(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
  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

Manfaat konkret:

Keuntungan Dampak

Reproduksi

bahkan`graph.json`→ diagram yang sama. Tepat. Setiap kali.

Biaya nol

Tanpa panggilan LLM = tanpa token = tanpa tagihan API

Latensi nol

Parse + render membutuhkan ~100ms, bukan 1-5 detik.

Kompatibel CI

Tidak perlu kunci API. Tidak ada tes flaky karena respons LLM yang bervariasi.

dapat diberi versi

Le .puml`yang dihasilkan adalah teks. Kita bisa`diff, reviewer dalam PR, versikan di Git.

Diagram pipelinenya sendiri

Untuk menutup lingkaran, berikut adalah diagram pipelining seperti yang akan dihasilkan oleh plugin :

@startuml
skinparam backgroundColor #FEFEFE

participant "Pengembang" 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

Integrasi dalam tata kelola proyek

Dalam proyek kami, pipeline ini terintegrasi dalam strategi pengelolaan konteks EAGER/LAZY untuk agen IA. Knowledge Graph menggantikan dokumentasi arsitektur manual dengan sebuah grafi terstruktur yang dapat di-query dan diperbarui otomatis.

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "EAGER\n(selalu terisi)" 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 — Strategi\n(atas permintaan)" as lazy_strat {
    [Méthodologies] as meth
    [Archives sessions] as sessions
}

package "LAZY — Graphify\n(permintaan terarah)" as lazy_graph {
    [graph.json] as gj
    [Queries\n(query/path/explain)] as queries
}

package "Pipeline PlantUML
(oto-generate)" 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

Perkawinan dua sistem adalah komplementer:

  • Strategi mengelola QUAND dan COMMENT— tata kelola, alur kerja, pengarsipan

  • Graphify mengelola APA dan DI MANA— struktur kode, relasi, kueri yang ditargetkan

(Empty) Strategi sesi mengelolakapan et le bagaimana(tata kelola, workflow, batas), Graphify mengelolaAPA et le DI MANA(struktur kode, hubungan, kueri target). Pipeline PlantUML mengelolaDENGAN APA(diagram deterministik, berisi versi, selalu terkini). __

Penyiapan: checklist dalam 5 menit

# Tahap pesanan

1

Instal Graphify

uv tool install graphifyy

2

Mengkonfigurasi pengecualian

Membuat`.graphifyignore`

3

Mengekstrak Knowledge Graph

graphify . --no-viz

4

Menghasilkan diagram

./gradlew generateKnowledgeGraphDiagram

5

Menyimpan hasil

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/

Penjebakan dan mitigasi

jebakan Deskripsi mitigasi

Grafik terlalu padat

Proyek besar menghasilkan ratusan node yang tidak dapat dibaca

Menggunakan`-Pplantuml.kg.maxNodes=30`dan memfilter berdasarkan komunitas

Pengecualian terlalu luas

Terlalu banyak file di`.graphifyignore`mengurangi nilai grafik

Mulai dengan mengecualikan hanya credentials dan build

Arah panah

Sisi-sisi INFERRED dapat memiliki arah yang ambigu

Filter berdasarkan`-Pplantuml.kg.edgeTypes=EXTRACTED`hanya untuk hubungan tertentu

Grafik usang

Kode berubah tetapi grafik tidak dibangun ulang

Menggunakan`graphify . --update`secara teratur atau hook git`graphify hook install`

Biaya diperbarui

Pembaruan inkremental hampir gratis (tree-sitter local)

Hanya dokumen (.adoc) mengonsumsi token LLM

Apa yang kita dapatkan pada akhirnya

@startuml
skinparam backgroundColor #FEFEFE

rectangle "SEBELUM" as avant {
    card "Diagram yang digambar secara tangan
Selalu usang
Tidak ada yang memperbarui mereka" as av1 #FDEDEC
}

rectangle "setelah" as apres {
    card "Diagram yang dihasilkan secara otomatis
Selalu terkini dengan kode
Di-versionkan di Git
Deterministik dan dapat direproduksi" as ap1 #E8F8E8
}

avant --> apres : graphify . --no-viz\n+ ./gradlew generateKnowledgeGraphDiagram

@enduml

Manfaat konkret :

Keuntungan Detail

Dokumentasi selalu terkini

Diagram mencerminkan kode saat ini, bukan snapshot manual

Upaya pemeliharaan nol

Diagram diagram diregenerasikan setiap build

Pengurangan utang teknis

Tidak perlu lagi memelihara diagram secara manual

Konteks visual untuk yang baru

Seorang pengembang baru memahami arsitektur dengan melihat diagram

Potensi penyesuaian halus

Pasangan (subgraf → diagram) adalah contoh pelatihan AI

Validasi otomatis

`PlantumlService.validateSyntax()`Periksa setiap diagram yang dihasilkan

Onboarding cepat

5 diagram = tampilan lengkap dari arsitektur

mengapa : diagram selalu terkini. bagaimana : dua perintah dalam pipeline Gradle.

tautan

Artikel terkait