PlantUML with AI — prompt patterns for Copilot / Cursor auto-generation

puml.online

In 2025-2026, LLMs can already convert a 5-sentence description into PlantUML code. This post distils the prompt templates, common errors, debugging tricks, and human-review rules I’ve tested.

LLMs writing PlantUML today (mid-2026)

Empirically:

  • Copilot / Cursor / Cline: with .puml file context, 5-10 line prompts reach ~80% correct code
  • ChatGPT / Claude / Gemini: system prompt + detailed description → working code in 5-15 seconds
  • Key gap: the UML semantics LLM handles; the visual layout (node position, spacing, colour) it gets wrong constantly — needs human review

Making LLMs output correct PlantUML

1. Constrain the output format

LLMs struggle to self-constrain output. Force the boundary in your prompt:

1
2
3
Output ONLY the PlantUML code block, no explanation outside the block.
Do NOT include any markdown prefix like ```plantuml or ```.
Just the @startuml ... @enduml contents.

Otherwise you’ll get:

1
2
3
4
5
```plantuml
@startuml
Alice -> Bob: hi
@enduml
```

followed by “Here is the PlantUML code…” commentary. You want pure content.

2. Lock the diagram type

PlantUML has 20+ diagram types — LLMs often guess wrong:

1
2
3
4
5
6
7
8
9
Draw a UML sequence diagram in PlantUML with EXACTLY these participants:
- 3 actors: User, Frontend, AuthService
- 4 messages in this exact order:
1. User -> Frontend: click login
2. Frontend -> AuthService: POST /login
3. AuthService --> Frontend: 200 token
4. Frontend --> User: redirect
Use plain PlantUML `->` for synchronous messages and `-->` for replies.
Do NOT use any skinparam customization.

Force “EXACTLY these participants” + order + relation type + “no skinparam”.

3. Provide examples (few-shot)

The fastest way for an LLM to learn is via examples. Give one in the same conversation; later prompts will use the template:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Use this as a reference structure (don't copy verbatim):

@startuml
participant "User" as U
participant "Frontend" as F
participant "Backend" as B

U -> F: click login
F -> B: POST /api/login
B --> F: 200 token
F --> U: redirect
@enduml

Now draw this NEW sequence in the same style:
[your real description]

4 Carry context across turns: first turn defines “sequence-diagram rules”. Second turn says “draw X in the same format”. Third turn says “draw another X” — the LLM applies the prior template.

Practical prompt templates

Template 1: sequence diagram

1
2
3
4
5
6
7
8
9
10
11
12
# Task
[Business description, e.g. "6-step user login flow to payment system"]

# Output requirements
1. PlantUML sequence diagram (@startuml ... @enduml)
2. Participants EXACTLY: list them in order
3. Messages EXACTLY: list them in order with direction (-> or --> or ->>)
4. No skinparam, no theme, use default
5. Output diagram only, no markdown fence

# Verification
After drawing, self-check: (a) every participant participates in ≥1 message? (b) directions correct? If not, redraw.

Template 2: class diagram

1
2
3
4
5
6
7
8
9
# Task
Generate a PlantUML class diagram from this Java class description:
[code snippet]

# Output requirements
1. One `class` block per class, fields and methods listed explicitly (visibility: + public, - private, # protected)
2. Relations: --|> inheritance, *-- composition, o-- aggregation, --> association
3. Don't include getters/setters
4. Output diagram only, no markdown fence

Template 3: activity diagram

1
2
3
4
5
6
7
8
9
10
Convert this flow description into a PlantUML activity diagram:
- Start
- if-branches
- while loop
- End

# Output requirements
1. PlantUML |start| / activity nodes (wrap in () or {})
2. Branches via <branch> ... <branch> ... <merge> or if (...) then (...) endif
3. Output diagram only

Template 4: state machine

1
2
3
4
5
6
7
8
Convert this state enum into a PlantUML state diagram:
[Python enum or JS switch]

# Output requirements
1. Use state "name" as alias for naming
2. Transitions: state1 --> state2 : event/action
3. Composite states via state parent { ... }
4. Output diagram only

Common LLM errors (you must know these)

Error 1: arrow direction nonsense

1
2
3
4
@startuml
Alice <- Bob ' wrong direction
Alice <<- Bob ' doesn't exist
@enduml

LLM training data mixes old PlantUML with Mermaid arrow styles. Reverse arrows are not a thing in PlantUML. Catch these in review and rewrite as Bob -> Alice.

Error 2: wrong composition/aggregation

1
2
User *-- Role     ' user "owns" role (composition)
User --> Profile ' user references profile

Sometimes the LLM writes User -- Profile when it meant composition. Watch --* vs --o: composition uses solid diamond *, weak ownership uses hollow o.

Error 3: bracket / end mismatch

1
2
3
package "Frontend" {
class WebApp { ' ✅
} ' ✅ missing one } to close the package

LLMs often miss a closing brace, end, endif. Always recount.

Error 4: message text containing :

1
2
Alice -> Bob: prefix:value  ' ❌ colon breaks the message
Alice -> Bob: "prefix:value" ' ✅ quote it

LLMs happily paste JSON-style key:value into message text. Always review with quoted message text.

Error 5: gratuitous skinparam

LLMs often emit:

1
2
3
skinparam backgroundcolor #fafafa
skinparam nodesep 100
skinparam color arrow #ff0000

Results are visually ugly. Disable in the prompt: “Use no skinparam customization.”

Error 6: hallucinated !include paths

LLMs write:

1
2
!include ./common/styles.puml
!include ../shared/nodes.puml

These paths may not exist in your repo. Never render LLM-generated !include directly — confirm paths exist and copy files first.

Verification workflow

1. Local PlantUML CLI smoke test

1
2
3
echo "@startuml
$(cat diagram.puml)
@enduml" > _test.puml && plantuml -tsvg _test.puml

If PlantUML errors (YAMLException / $jsException / no dot found), fix source first.

2. Look at it in VS Code

VS Code PlantUML plugin shows the rendering. If you see:

  • overlapping nodes → adjust nodesep or add package
  • edges crossing nodes → bump ranksep or split package
  • weak arrow colour → add skinparam ArrowColor #5B7C99

3. View in the final docs page

The deliverable is the docs page — always check visuals at the final destination (Hexo / GitHub / Notion).

Copilot auto-complete template

In VS Code + Copilot, drop a .copilot-instructions.md at the repo root so it auto-follows PlantUML rules:

1
2
3
4
5
6
When generating PlantUML code (between @startuml and @enduml):
- Use `->` for synchronous messages, `-->` for replies, `->>` for async
- Quote message text with double quotes when text contains ":" or "(" or ")"
- Never use `skinparam backgroundcolor` or other visual customization unless asked
- For class diagrams, use visibility markers: + public, - private, # protected
- Always end the file with @enduml on its own line

Place at repo root → Copilot adopts automatically in .puml files.

Cursor / Cline usage

These two are more agentic — say:

“Add an error-handling branch to docs/diagrams/auth-flow.puml”

The agent will:

  1. read existing auth-flow.puml
  2. execute PlantUML CLI render → view
  3. modify code → re-render → compare
  4. write to docs/diagrams/

Success rate 70-80% empirically — 2 out of 10 steps require the agent itself to debug, but still faster than hand-writing.

Six-axis checklist for LLM-generated diagrams

Axis How to test Expectation
Syntax PlantUML CLI renders without error Required 100%
Semantics Does the diagram express the business relation right? Required 100%
Layout Nodes don’t overlap, edges don’t cross others Required ≥85%
Style Not over-coloured / not flashy 80% restrained
Readability ≤8 nodes “read at a glance” Big diagrams must be split
Maintainability Adding a node touches ≤1 place Low edit cost

Recap

  • LLMs writing PlantUML is “usable” today, but “perfect” still requires human review.
  • Prompt keys: explicit diagram type + listing participants + listing messages + disabling styling.
  • Error hotspots: arrow direction, composition relations, CJK, : in message text.
  • Always validate via PlantUML CLI — don’t trust the LLM’s “should be correct”.

Next

  • Title: PlantUML with AI — prompt patterns for Copilot / Cursor auto-generation
  • Author: puml.online
  • Created at : 2026-07-30 10:31:00
  • Updated at : 2026-08-14 21:34:29
  • Link: https://puml.online/blog/plantuml-ai-generation-en/
  • License: This work is licensed under CC BY-NC-SA 4.0.