waktu membaca : 12 minutes

Kode basis Anda tumbuh. Dependensi antar module bertambah banyak. Dokumentasi arsitektur menjadi ketinggalan zaman bahkan sebelum ditulis. Dan jika build Gradle Anda bisa otomatis menghasilkan diagram terkini dari struktur kode sebenarnya? Itu persis yang dilakukan oleh pipeline Graphify + PlantUML Gradle Plugin :`graphify . --no-viz`mengekstrak Knowledge Graph,`./gradlew generateKnowledgeGraphDiagram`mengubahnya menjadi diagram PlantUML. Tanpa LLM, tanpa manual, 100% deterministik.

tik

[]

Masalah: diagram selalu tertinggal dari kode

Setiap proyek yang melebihi beberapa ribu baris mengalami sindrom ini:

  1. Kita membuat diagram arsitektur di awal proyek

  2. Kode berkembang, dependensi berubah

  3. Diagram menjadi kebohongan dekoratif

  4. Tidak ada yang memperbaruinya karena itu 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

Pertanyaan itu bukan apakah diperlukan diagram? — semua orang tahu bahwa ya. Pertanyaan adalah :Siapa yang menjaga mereka tetap terkini?

Jawaban: tidak ada. Kecuali jika itu otomatis.

Solusi: alur deterministik Knowledge Graph → PlantUML

Prinsipnya sederhana: alih-alih menggambar diagram dengan tangan, kitamengasilkan dari struktur kode sebenarnya.

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

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

Hasilnya ? Berkas`.puml` et .png`dalam`diagrams/knowledge-graph/, yang tercatat versinya di 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

Mengonfigurasi pengecualian

Membuat file`.graphifyignore`di akar proyek untuk mengecualikan 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 diperlukan dalam pipeline Gradle). Hasilnya adalah sebuah file`graphify-out/graph.json`mengandung :

  • Simpul: kelas, fungsi, berkas — dengan jenis dan komunitas mereka

  • tulang ikanrelasi antar node (EXTRACTED dari kode, INFERRED oleh LLM)

  • Komunitas: kelompokan otomatis dari 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,tidak dapat dirayakan LLM. Hanya file dokumentasi (.adoc, .md) membutuhkan panggilan LLM untuk ekstraksi semantik. Jadi`--update`Saat bekerja dengan kode Kotlin hampir seketika.

Langkah 2: Plugin Gradle mengubah Knowledge Graph menjadi PlantUML

Arsitektur pipeline

plugin`com.cheroliv.plantuml`mengintegrasikan sebuah tugas`generateKnowledgeGraphDiagram`yang mengubah`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 "PlantumlLayanan" 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 tiga format : graphify asli (nodes+links), warisan (communities), flat. Menyelesaikan IDs numerik menjadi label.

KnowledgeGraphRenderer

Mentransformasi secara deterministik satu`KnowledgeGraph`dalam kode PlantUML. kelompok berdasarkan tipe, komunitas dalam paket, legenda otomatis.

GenerateKnowledgeGraphDiagramTask

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

kgmodels.kt

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

PlantumlService

Validasi sintaks + rendering PNG (dipakai ulang oleh semua tugas plugin).

Aturan rendering

Renderer menerapkan konvensi visual yang deterministik :

Jenis tepi Notasi PlantUML Arti

Diekstrak

-→(garis lurus, hitam)

Relasi yang diekstrak dari kode sumber (keyakinan)

disimpulkan

..>(garis bertitik)

Relation yang disimpulkan oleh LLM (skor kepercayaan)

abur

--x(garis titik merah)

Hubungan ambigu (perlu dicek)

Komunitasdirender sebagai 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

Menyaring berdasarkan jenis sisi

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

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

Filter berdasarkan tipe 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

sifat default Deskripsi

plantuml.kg.community

(semua)

Filter komunitas berdasarkan nama (cocokan substring)

plantuml.kg.edgeTypes

(semua)

Jenis sisi yang dipisahkan dengan koma :`EXTRACTED`, INFERRED, AMBIGUOUS

plantuml.kg.minConfidence

0.0

Ambang kepercayaan minimum untuk tepi

plantuml.kg.maxNodes

(tidak terbatas)

Jumlah maksimum node yang akan ditampilkan

plantuml.kg.nodeTypes

(semua)

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

plantuml.kg.outputDir

diagrams/knowledge-graph

Direktori output untuk file`.puml` et .png

Pipeline lengkap dalam workflow Gradle

Tipe workflow

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

start

partition "extraksi" {
    :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 ke dalam siklus pengembangan

Pipeline ini secara alami terintegrasi ke dalam tahap kunci 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 ber-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, tidak membuat 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`mengekstrak ulang hanya file yang dimodifikasi (terdeteksi oleh SHA256 dalam`graphify-out/cache/). Pada kode Kotlin, ini hampir seketika karena tree-sitter bekerja secara lokal tanpa memanggil LLM.

Dogfooding: plugin mendokumentasikan dirinya sendiri

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

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "Alur 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
(deterministik, 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
— duplikasi nol" as N

@enduml

Tugas Gradle terkait :

tugas LLM ? Deskripsi

generateKnowledgeGraphDiagram

Tidak

Transformasikan`graph.json`dalam PlantUML (deterministik)

generateDiagramDocs

Ya

Menghasilkan beberapa`.prompt`dari grafik, mereka memproses 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 dari pipeline`generateKnowledgeGraphDiagram`</think>Dia tidak memanggil LLM apa pun.. transformasi`graph.json`→ PlantUML adalah fungsi murni.

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

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

Keuntungan konkret :

Keuntungan dampak

Reproduktivitas

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

biaya nol

Tanpa panggilan LLM = tanpa token = tanpa tagihan API.

Nol latensi

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

Kompatibel CI

Tidak perlu kunci API. Tidak ada ujian flaky karena respons LLM yang variabel.

dapat di-versikan

Le .puml`adalah teks yang dihasilkan. Kita bisa`diff, reviewer untuk PR, me-versionnya di Git.

Diagram pipeline itu sendiri

Untuk menutup lingkaran, ini adalah diagram pipeline seperti yang akan dibuat oleh plugin :

@startuml
skinparam backgroundColor #FEFEFE

participant "Pengembang" as Dev
participant "Gradle" as G
participant "GenerateKnowledgeGraphDiagramTask" as Task
participant "KnowledgeGraphParser" as Parser
participant "PerenderGrafPengetahuan" 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 manajemen konteks EAGER/LAZY untuk agen IA. Knowledge Graph menggantikan dokumentasi arsitektur manual dengan sebuah graphe terstruktur, yang dapat di-query, dan diperbarui secara 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
(atas permintaan)" as lazy_strat {
    [Méthodologies] as meth
    [Archives sessions] as sessions
}

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

package "Pipeline PlantUML\n(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 kedua sistem tersebut komplementer :

  • Strategi mengelola kapan dan bagaimana— tata kelola, alur kerja, pengarsipan

  • Graphify mengelola APA dan DIMANA— struktur kode, hubungan, kueri target

_ Strategi sesi mengelolaKAPAN et le bagaimana(pemerintahan, alur kerja, batas), Graphify mengelolaapa et le di mana(struktur kode, hubungan, kueri yang ditargetkan). Pipeline PlantUML mengelolaDENGAN APA(diagram deterministik, terversion, selalu terkini). _

Penyiapan : daftar periksa dalam 5 menit

# Tahap pesanan

1

Instal Graphify

uv tool install graphifyy

2

Mengkonfigurasi pengecualian

membuat`.graphifyignore`

3

Ekstrak Knowledge Graph

graphify . --no-viz

4

Menghasilkan diagram

./gradlew generateKnowledgeGraphDiagram

5

Mengkomit 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/

Jebakan dan mitigasi

jerat deskripsi mitigasi

Grafik terlalu padat

Sebuah proyek besar menghasilkan ratusan simpul yang tidak terbaca

menggunakan`-Pplantuml.kg.maxNodes=30`dan filter berdasarkan komunitas

Pengecualian terlalu luas

Terlalu banyak file di`.graphifyignore`mengurangi nilai grafik

Memulai dengan hanya mengecualikan credentials dan build

Arah panah

Sisi-sisi INFERRED dapat memiliki arah ambigu

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

Graf usang

Kode berubah tetapi grafik tidak dibangun ulang

menggunakan`graphify . --update`sekara teratur atau hook git`graphify hook install`

Biaya yang diperbarui

Pembaruan inkremental hampir gratis (tree-sitter lokal)

Hanya dokumen (…​).adoc) mengkonsumsi token LLM

Yang didapatkan di akhir

@startuml
skinparam backgroundColor #FEFEFE

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

rectangle "setelah" as apres {
    card "Diagram yang dihasilkan secara otomatis
Selalu diperbarui dengan kode
Disimpan dalam Git dengan sistem versi
Determinis dan dapat direproduksi" as ap1 #E8F8E8
}

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

@enduml

Manfaat konkret :

Keuntungan Detail

Dokumentasi selalu terkini

Diagram tersebut mencerminkan kode saat ini, bukan snapshot manual

Tidak ada upaya pemeliharaan

Diagram diregenerasi 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()`memeriksa setiap diagram yang dihasilkan

Onboarding cepat

5 diagram = tampilan lengkap dari arsitektur

_ Siapa yang memiliki _mengapa dapat menahan semua bagaimana. __

Alasannya: diagram selalu terkini. Cara: dua perintah dalam pipeline Gradle.

Tautan

Artikel terkait