읽기 시간 : 12 minutes

코드베이스가 커지고 있습니다. 모듈 간의 의존성이 점점 늘어나고 있습니다. 아키텍처 문서는 작성되기도 전에 이미 오래됩니다. 그리고 Gradle 빌드가 자동으로 실제 코드 구조에서 최신 다이어그램을 생성할 수 있다면? 이게 바로 Graphify + PlantUML Gradle Plugin 파이프라인이 하는 일입니다:`graphify . --no-viz`Knowledge Graph를 추출,`./gradlew generateKnowledgeGraphDiagram`PlantUML 다이어그램으로 변환합니다. 제로 LLM, 제로 매뉴얼, 100% 결정적.

강박

[]

문제: 다이어그램이 언제나 코드보다 뒤처진다

몇천 줄을 넘는 모든 프로젝트는 이 증후군을 경험합니다:

  1. 프로젝트 초기에 아키텍처 다이어그램을 그립니다.

  2. 코드가 진화하고, 의존성이 변경됩니다.

  3. 다이어그램은 장식적인 거짓말이 된다

  4. 아무도 업데이트하지 않아요, 왜냐하면 그게 귀찮기 때문이에요

  5. 신규 사용자들은 그것에 의존하여 실수를 합니다.

@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

질문은 faut-il des diagrammes ? 가 아니다 — 모두가 그렇다고 알고 있다. 질문은 :누가 그들을 최신 상태로 유지합니까?

답변: 아무도 없습니다. 단, 자동인 경우에는 예외입니다.

솔루션 : 결정적 Knowledge Graph → PlantUML 파이프라인

원칙은 간단합니다 : 손으로 다이어그램을 그리는 대신, 우리는 그들을실제 코드 구조에서 생성한다.

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

actor Développeur
component "Graphify
(pip install graphifyy)" as Graphify
collections "graphify-out/graph.json
(지식 그래프)" as KGJSON
component "PlantUML Gradle 플러그인
(지식 그래프 다이어그램 생성)" as Plugin
component "KnowledgeGraphParser" as Parser
component "지식 그래프 렌더러" as Renderer
component "PlantumlService
(검증 + 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

두 개의 명령어. 그게 전부야.

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

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

결과 ? 파일들`.puml` et .png`안에`diagrams/knowledge-graph/, Git에서 버전 관리되어 코드와 항상 최신 상태를 유지합니다.

단계 1: Graphify 설치 및 Knowledge Graph 추출

설치

Graphify는 코드베이스를 분석하고 구조화된 지식 그래프를 구축하는 Python 도구입니다 :

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

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

제외 사항 구성

파일 만들기`.graphifyignore`프로젝트 루트에서 비즈니스 로직에 속하지 않는 파일을 제외하기 위해:

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

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

# Tests fonctionnels
src/functionalTest/

지식 그래프 추출

graphify . --no-viz

플래그`--no-viz`HTML 생성을 건너뛰세요 (Gradle 파이프라인에서는 불필요함). 결과는 파일입니다.`graphify-out/graph.json`포함 :

  • 매듭: 클래스, 함수, 파일 — 유형과 커뮤니티와 함께

  • 가시: 노드 간 관계 (EXTRACTED 코드에서, INFERRED LLM에 의해)

  • 커뮤니티: 연결된 노드의 자동 그룹화

구조 예시`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}
  ]
}

소스 코드 (.kt, .java) 로컬에서 tree-sitter에 의해 분석된다,이의를 제기할 수 없는 LLM. 문서 파일들만 (.adoc, .md) 그들이 의미 추출을 위해 LLM 호출이 필요합니다. 따라서`--update`Kotlin 코드 실행은 거의 즉시입니다.

2단계: Gradle 플러그인이 Knowledge Graph를 PlantUML로 변환합니다.

파이프라인 아키텍처

플러그인`com.cheroliv.plantuml`작업을 포함합니다`generateKnowledgeGraphDiagram`변환하는`graph.json`PlantUML 다이어그램 방식으로완전히 결정론적인:

@startuml
skinparam backgroundColor #FEFEFE

participant "Gradle" as G
participant "생성 지식 그래프 다이어그램 작업" as Task
participant "KnowledgeGraphParser" as Parser
participant "지식 그래프 렌더러" 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

내부 구성 요소

컴포넌트 역할

KnowledgeGraphParser

파싱하다`graph.json`— 3가지 형식을 지원합니다 : 네이티브 graphify (nodes+links), 레거시 (communities), flat. 숫자 ID를 라벨로 해결합니다.

KnowledgeGraphRenderer

결정적으로 변환한다`KnowledgeGraph`PlantUML 코드. 유형별 그룹, 패키지 내 커뮤니티, 자동 범례.

GenerateKnowledgeGraphDiagramTask

Gradle 작업: 파싱 → 렌더링 → 검증 → PNG를 오케스트레이션합니다. Gradle 속성을 통해 구성할 수 있습니다.

kgmodels.kt

데이터 모델:`KnowledgeGraph`, KnowledgeGraphNode, KnowledgeGraphEdge, KnowledgeGraphCommunity, EdgeType.

PlantumlService

구문 검증 + PNG 렌더링 (플러그인의 모든 작업에서 재사용됨).

렌더링 규칙

렌더러는 결정적인 시각적 규칙을 적용합니다:

에지 유형 PlantUML 표기법 의미

추출된

-→(실선, 검정)

소스 코드에서 추출된 (확실성)

추론된

..>(점선)

LLM이 추론한 관계 (신뢰도 점수)

모호한

--x(빨간 점선)

모호한 관계 (확인 필요)

커뮤니티는 자동 색상 팔레트를 가진 PlantUML 패키지처럼 렌더링됩니다.

단계 3: 일상 사용

완전한 다이어그램

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

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

커뮤니티별 필터

# 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

엣지 유형별로 필터

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

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

노드 유형과 신뢰도로 필터링

# 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

사용자 지정 출력 디렉터리

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

속성에 대한 완전한 참조

속성 결함 설명

plantuml.kg.community

(모두)

이름(부분 문자열 일치)로 커뮤니티 필터링

plantuml.kg.edgeTypes

(모든)

쉼표로 구분된 엣지 유형 :`EXTRACTED`, INFERRED, AMBIGUOUS

plantuml.kg.minConfidence

0.0

엣지에 대한 최소 신뢰도 임계값

plantuml.kg.maxNodes

(무제한)

표시할 최대 노드 수

plantuml.kg.nodeTypes

(모두)

콤마로 구분된 노드 유형 (ex.class, code)

plantuml.kg.outputDir

diagrams/knowledge-graph

파일용 출력 디렉터리`.puml` et .png

Gradle 워크플로우의 전체 파이프라인

워크플로 유형

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

start

partition "추출" {
    :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 "세대" {
    :./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 "통합" {
    :git add diagrams/knowledge-graph/;
    :git commit;
    note right: Diagrammes versionnés\ntoujours à jour avec le code
}

stop

@enduml

개발 주기 통합

파이프라인은 개발의 주요 단계에 자연스럽게 통합됩니다:

@startuml
skinparam backgroundColor #FEFEFE

state "개발" as dev
state "Extraction\ngraphify . --no-viz" as extract
state "생성
./gradlew generateKnowledgeGraphDiagram" as generate
state "커밋
버전 관리된 다이어그램" 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

증분 업데이트

코드가 변경되면 전체 그래프를 처음부터 다시 구축하지 않는다:

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

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

--update`수정된 파일만 다시 추출 (SHA256로 감지된`graphify-out/cache/). Kotlin 코드에서는 tree-sitter가 로컬에서 작동하고 LLM 호출이 없어 거의 즉시 처리됩니다.

도그푸딩: 플러그인이 스스로 문서화한다

PlantUML 플러그인은 프롬프트를 다이어그램으로 변환하기 위해 존재합니다. 또한 자체 propre 코드베이스의 Knowledge Graph를 문서 다이어그램으로 변환할 수 있습니다. 이것은 _dogfooding_입니다: 플러그인은 자체 서비스를 소비합니다.

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "정상 파이프라인
(사용자 → 다이어그램)" 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 "파이프라인 지식 그래프
(결정론적, 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 → 플러그인 문서)" 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 "같은 LlmService, 같은 ApiKeyPool,
같은 PlantumlService
 — 중복 없음" as N

@enduml

연관된 Gradle 작업:

작업 LLM ? 설명

generateKnowledgeGraphDiagram

아니요

변환해`graph.json`PlantUML (확정적)에서

generateDiagramDocs

예

생성해`.prompt`그래프에서부터, LLM(도그푸딩)을 통해 처리합니다.

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

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

왜 그것이 결정적인가 (그리고 왜 중요한가)

파이프라인의 핵심 포인트`generateKnowledgeGraphDiagram` : 그는 어떤 LLM도 부르지 않는다.. 변환`graph.json`PlantUML은 순수 함수이다.

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

rectangle "결정적 파이프라인
(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\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
  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

구체적인 장점 :

장점 영향

재현성

같은`graph.json`→ 동일한 다이어그램. 정확히. 매번.

제로 비용

LLM 호출이 없으면 토큰도 없고 API 청구서도 없습니다.

제로 지연

Parse + render는 약 100ms가 소요되며, 1-5초가 아닙니다.

CI 호환

API 키가 필요하지 않습니다. 변동하는 LLM 응답으로 인한 불안정한 테스트가 없습니다.

버전 가능한

Le .puml`생성된 것은 텍스트입니다. 그것을 할 수 있습니다.`diff, PR의 리뷰어, Git에 버전 관리.

파이프라인 자체의 다이어그램

루프를 마무리하기 위해, 플러그인이 생성할 파이프라인 다이어그램은 다음과 같습니다 :

@startuml
skinparam backgroundColor #FEFEFE

participant "개발자" as Dev
participant "그래들" as G
participant "지식 그래프 다이어그램 생성 태스크" as Task
participant "KnowledgeGraphParser" as Parser
participant "KnowledgeGraphRenderer" as Renderer
participant "PlantUML 서비스" 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

프로젝트 거버넌스 내 통합

우리 프로젝트에서 이 파이프라인은 AI 에이전트를 위한 EAGER/LAZY 컨텍스트 관리 전략에 통합됩니다. Knowledge Graph는 수동 아키텍처 문서를 구조화되고 쿼리 가능하며 자동으로 업데이트되는 그래프로 대체합니다.

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "EAGER
(항상 충전된)" 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 — 전략\n(요청 시)" as lazy_strat {
    [Méthodologies] as meth
    [Archives sessions] as sessions
}

package "LAZY — Graphify
(목표된 쿼리)" as lazy_graph {
    [graph.json] as gj
    [Queries\n(query/path/explain)] as queries
}

package "Pipeline PlantUML
(자동 생성된)" 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

두 시스템의 결합은 보완적입니다 :

  • 전략은 QUAND와 COMMENT를 관리합니다— 거버넌스, 워크플로우, 보관

  • Graphify는 WHAT과 WHERE를 관리합니다.— 코드 구조, 관계, 목표 쿼리

__ 세션 전략은 를 관리합니다.언제 et le 어떻게(거버넌스, 워크플로우, 임계치), Graphify는それを 관리한다뭐 et le 어디(코드 구조, 관계, 대상 쿼리). PlantUML 파이프라인이 관리무엇으로(결정론적 다이어그램, 버전 관리된, 항상 최신). </think> (Empty)

준비: 5분 체크리스트

# 단계 주문

1

Graphify 설치

uv tool install graphifyy

2

제외 항목 구성

생성하다`.graphifyignore`

3

지식 그래프 추출

graphify . --no-viz

4

다이어그램 생성

./gradlew generateKnowledgeGraphDiagram

5

결과를 커밋하다

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/

함정과 완화

함정 설명 완화

너무 빽빽한 그래프

큰 프로젝트는 수백 개의 읽을 수 없는 노드를 생성

사용하다`-Pplantuml.kg.maxNodes=30`그리고 커뮤니티별로 필터링

너무 넓은 제외

너무 많은 파일이`.graphifyignore`그래프의 값을 줄입니다

먼저 credentials와 build만 제외하기

화살 방향

INFERRED 엣지들은 방향이 모호할 수 있습니다.

필터링 기준`-Pplantuml.kg.edgeTypes=EXTRACTED`확실한 관계에 대해서만

구식 그래프

코드는 바뀌지만 그래프는 재구축되지 않습니다.

사용하다`graphify . --update`정기적으로 또는 git 후크`graphify hook install`

업데이트된 비용

증분 업데이트는 거의 무료입니다 (tree-sitter local)

문서만 (.adoc) LLM 토큰을 소비합니다

결과적으로 얻는 것

@startuml
skinparam backgroundColor #FEFEFE

rectangle "전에" as avant {
    card "수작업으로 그린 다이어그램
항상 구식
아무도 업데이트하지 않는다" as av1 #FDEDEC
}

rectangle "이후" as apres {
    card "자동 생성된 다이어그램
항상 코드와 최신 상태
Git에서 버전 관리됨
결정적이고 재현 가능" as ap1 #E8F8E8
}

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

@enduml

실질적인 혜택 :

이익 세부

항상 최신 문서

다이어그램은 현재 코드를 반영하며, 수동 스냅샷이 아닙니다.

유지 보수 노력 없음

다이어그램은 각 빌드마다 재생성됩니다.

기술 부채 감소

다이어그램을 수동으로 유지할 필요가 없습니다.

신규를 위한 시각적 맥락

새로운 개발자는 다이어그램을 보고 아키텍처를 이해한다

가능한 파인 튜닝

(서브그래프 → 다이어그램) 쌍은 AI 훈련의 예시입니다.

자동 검증

`PlantumlService.validateSyntax()`생성된 각 다이어그램을 확인합니다

빠른 온보딩

5개 다이어그램 = 아키텍처의 완전한 뷰

_ 누가 _pourquoi_를 가지고 있으면 모든 _comment_을 감당할 수 있다. _

왜냐하면 (pourquoi): 항상 최신 상태인 다이어그램. 어떻게 (comment): 그레이들 파이프라인에 두 개의 명령어가 있다.

링크

관련 기사