Hi everyone! My name is Alexey Pronsky, and I'm an architect in the AI department of a large financial services company. We build agentic systems, AI assistants, OCR systems, speech analytics, and Classic ML models. Since we follow enterprise development principles, every project is backed by a Solution Architecture Document (SAD) — a document that goes through approval with business stakeholders, enterprise architecture, information security, and owners of adjacent systems. We maintain our SADs in Confluence and draw diagrams in Draw.io. The typical cycle from receiving business requirements to an approved SAD takes two to three weeks on average.
Over the past year, LLM assistants have revolutionized code writing. In this article, I'll show how to achieve the same effect in architecture — by adopting the Architecture as Code approach and delegating the routine to an LLM. We use Structurizr to describe architecture and Claude Code as our LLM assistant. I'll demonstrate examples based on these tools; the demo repository is available on GitHub.
The Problem: An Architect Is Not Someone Who Draws Boxes
Let's be honest: traditionally, most of an architect's time goes not into making decisions, but into documenting them. A typical workday looks like this:
- Received business requirements (BR) — read through them, analyzed a 40-step BPMN process.
- Identified which systems are affected, which need to be created, which need modifications.
- Created a page with the solution in Confluence, opened the Draw.io plugin, drew a container diagram, then essentially duplicated it in a data flow diagram.
- Formatted the data flows into a table, filling in the required fields: code, data object, source, consumer, type, etc.
- Filled in the mandatory security sections: role model, flows containing protected data, statuses.
- Wrote non-functional requirements and implementation guidelines.
- Sent for approval. Received 15 comments. Half of them — "these fields aren't filled in," "responsible parties not specified," "section content doesn't meet standards." Fixed. Sent again.
Sound familiar? The main pain here isn't that the work is difficult. It's mechanical. The architecture decision is made in an hour. But documenting it takes two days. And then another week iterating on comments, half of which are obvious inaccuracies and inconsistencies.
What Changes with the Architecture as Code Approach
The idea of Architecture as Code is simple: describe architecture not as pictures, but as text in a DSL. Diagrams are generated automatically from the code. We use Structurizr — a tool for describing architecture in the C4 Model format.
Instead of drawing in Draw.io, you write a model:
// Define systems
white_tower = softwareSystem "The White Tower" "Main hall for communicating with wizards"
bree_crossroads = softwareSystem "Bree Crossroads" "Middle-earth's hub station"
// Define relationships with protocol specification
white_tower -> bree_crossroads "Requests scrolls via Crossroads" "MCP/HTTPS"
white_tower -> radagast "Forwards questions to Radagast" "REST/HTTPS"
Structurizr generates diagrams from this code — IT landscape, system context (C1 level), containers within a system (C2 level). One model, many views.
IT landscape diagram automatically generated from DSL code
Here's what this gives you in practice.
Single source of truth. We have 20+ systems in our IT landscape. Previously, each SAD contained its own diagrams — separate files that quickly became outdated and fell out of sync with each other. To maintain the landscape, we had to review numerous recent SADs, piece together an understanding of architectural changes, and manually update the landscape diagram. That's a lot of work. Now, after switching to describing SADs in Structurizr, we get our department's landscape diagram for free.
The structure in our architecture repository looks as follows:
structurizr/
workspace.dsl # Main file — assembles everything via !include
workspace.json # Element coordinates on diagrams
common.dsl # Shared actors and external systems
domains/ # Architecture domains - each team owns its domain
genai/
agents/
ocr/
...
Each domain is a separate pair of files: model.dsl (model) + views.dsl (diagrams). Shared elements — actors, external systems — are extracted into common.dsl. Teams work with their own domain without touching others.
Version control and diffs. Architecture is stored in git — you can view history, do code reviews, compare versions. With binary .drawio files, this is impossible.
Multiple diagrams from one model. Imagine you need to show system architecture with relationships reflecting component dependencies, and right alongside it — data flows across the same architecture. In Draw.io, you'd have to draw two diagrams with differently directed and labeled arrows. And what if the SAD diagrams need to visually highlight new and modified elements, but the landscape diagram doesn't? In Draw.io, that means manually duplicating diagrams and coloring elements in different colors.
In Structurizr DSL, there's a tagging mechanism for this. The model stays unified, model elements are tagged, and they render differently in different views.
In code, it's described as follows (data flows are tagged with Dataflow):
// Container relationships
aragorn -> isengard_listeners "Picks up transcripts from stream" "Kafka"
aragorn -> moria_vault "Saves to the Vault" "TCP"
aragorn -> ravens "Sends Ravens with tasks" "AMQP"
// Data flows
isengard_listeners -> aragorn "INF01. Speech transcripts" "" "Dataflow"
moria_vault -> aragorn "INF02. Transcripts and analysis results" "" "Dataflow"
aragorn -> ravens "INF03. Processing tasks" "" "Dataflow"
And two views are created: one excluding relationships tagged Dataflow, and another including only those.
container aragorn_palantir "aragorn_palantir_containers" "Aragorn's Palantir: architecture" {
include *
exclude relationship.tag==Dataflow
}
container aragorn_palantir "aragorn_palantir_dataflow" "Aragorn's Palantir: data flows" {
include *
exclude relationship.tag!=Dataflow
}
When components are changed or added to the architecture, both views are re-rendered automatically.
Container diagram: component dependencies
Same model, but showing data flows
Automation. Once architecture turns from a picture into code, it can become a participant in CI/CD processes just like application code.
In practice, common CI/CD automations include:
- Architecture validation. Structurizr parses the DSL and catches errors: non-existent references, duplicate identifiers, C4 rule violations. In Draw.io, you can draw an arrow to nowhere — and nobody notices until review.
-
Diagram export. After merging to
main, a script runs that renders all diagrams to SVG and exports them to Confluence or uploads the architecture to an architecture portal (in our case, Structurizr On-Prem). - Analytics. Since the model is structured code, you can programmatically analyze the architecture. For example, automatically generate a table of all HTTP interactions for the network team.
- Security checks. Verify that all calls to the public internet go through a proxy, that personal data is transmitted only over secure protocols.
- Architecture drift detection. Compare service relationships from tracing (OpenTelemetry) with relationships in the DSL. If there's a call in the traces that doesn't exist in the architecture — alert the architect.
- Infrastructure linkage. Generate infrastructure deployment scripts from the architectural model.
All of this sounds great. But there's a catch.
Writing DSL code is noticeably harder and slower than dragging boxes with a mouse, especially for those not used to working with code. Drawing a diagram with 10 systems in Draw.io takes 20 minutes. Describing the same model in DSL — figuring out the syntax, scoping rules, constraints — takes an hour to an hour and a half. Add creating views, configuring styles, exporting diagrams. Architecture as Code delivers the benefits listed above — but you pay for it with coding time.
And this is where LLMs enter the picture.
What If We Add an LLM?
Using an LLM changes the game in two key ways.
1. LLMs Solve the Main Problem of Architecture as Code
Code is the native language for LLMs. Language models don't care what they write in: Python, Java, or Structurizr DSL.
For humans, switching from a visual editor to code is cognitive overhead. For an LLM, it's actually a simplification. The model can not only generate DSL code, but also understand the architecture described in it. It reads the existing model, determines context, adds new containers in the right places, and applies tags following your conventions.
The barrier to entry I mentioned above disappears. You don't need to write DSL from scratch by hand. You describe architecture in natural language, and the LLM translates it into valid architecture code.
2. LLMs Take Process Automation to a Fundamentally New Level
We're used to automation meaning rigid scripts. They're deterministic — they do exactly what's written. But now we're seeing a paradigm shift in many areas — from rigid algorithms to an agentic approach.
Autonomous agents are already trading on stock exchanges, handling complex customer support conversations, and even ordering food for the office. An agent doesn't just execute the command "press the button" — it understands the goal: "find a cheap ticket," "resolve a scheduling conflict," "sell stocks if the trend changes."
Since architecture is now represented as code, we can apply the same agentic approach to architecture, creating a sort of "architecture agent". We're not just asking a robot to "move a box." We set a task at the level of meaning: "Check whether this architecture meets security requirements," "Compare the implementation with the business requirements," or "Prepare the solution for release."
Our Tool: Claude Code and Skills
As the foundation for our architecture agent, we use Claude Code — a tool that runs in the terminal (or as an IDE plugin) and has access to the project's file system.
Its killer feature for us is Skills. These aren't code but custom commands described in natural language (in Markdown). Essentially, you write a prompt instruction once, give it a name, and Claude remembers this complex action algorithm.
We've defined 5 core skills in our project that cover our main routine tasks:
-
SAD generation (
arch-generate-solution) — the main skill. Takes a business requirements file as input, asks clarifying questions, modifies the DSL model, validates it, and generates a ready Markdown document describing the solution. -
Architecture review (
arch-review-solution) — emulates 5 approvers (Solution Architect, Enterprise Architect, Security, Business, Adjacent System Owners). Reads the finished solution and produces a list of comments from each role. -
Diagram export (
arch-make-svg) — automates rendering. Iterates through all Structurizr views while managing element visibility (e.g., hiding items not yet in production) and saves up-to-date SVG files. -
Resource collection (
arch-list-resources) — parses the DSL and compiles a summary table of all containers with CPU/GPU/RAM/SSD/Replicas fields. We use it for hardware resource tracking. -
Conflict resolution (
arch-merge-conflict) — an essential skill for collaborative work. The tool we use locally (Structurizr Lite) has a major issue. Theworkspace.jsonfile (which stores manually positioned element coordinates) constantly causes horrific merge conflicts. Resolving them manually is practically impossible. But this skill comes to the rescue and handles the task perfectly.
In the next section, I'll break down in detail how our two main skills — solution generation and review — work.
Breaking Down the Core Skills: How It Works Inside
Let's look at how the magic works.
1. Skill: Solution Architecture Document Generation (arch-generate-solution)
This is our "heavyweight". The skill is a complex pipeline of six phases that transforms raw business requirements into a Solution Architecture Document with a complete set of artifacts.
The skill takes input data: a file with business requirements and process diagrams (BPMN). It generates:
- Updated Structurizr DSL (new systems, containers, relationships).
- A set of SVG diagrams.
- A draft Solution Architecture Document (SAD).
BPMN processes like these are provided as input
Here's how Claude Code progresses through the phases of this skill.
Phase 1: Context and Understanding
Claude scans the inputs/ folder, reads the business requirements, studies the BPMN process, and loads the current architectural model (.dsl files). At this stage, it builds a change map for itself: "I see, I need to add a new microservice to the AI domain, connect it to the existing API Gateway, and store data in Postgres."
Claude Code screenshot during the context gathering phase
Phase 2: Clarification
This is a critically important stage. The LLM doesn't rush to write code immediately. The skill explicitly instructs the model to ask the architect questions: "Which domain should the new service go into?" "Do we need a separate database instance or should we use an existing one?" "What protocol do they communicate over?"
Only after receiving answers does the agent proceed to coding.
Claude Code screenshot during the clarification phase
Phase 3: DSL Modification
The agent makes changes to .dsl files. Strict conventions defined in our instructions apply here:
- New elements are tagged with
New. - Modified elements are tagged with
Changed. - Data flows receive
INFXXXcodes.
If the change affects multiple systems, the agent automatically creates a consolidated view combining the relevant containers in a single diagram.
Phase 4: Validation and Export
Claude runs a shell validation script. This isn't just a syntax check. The script calls the Structurizr API (running locally in Docker) to verify that the model parses correctly. If there's an error (e.g., a duplicate ID or circular dependency), the agent sees the error log, fixes the DSL, and tries again. The cycle repeats until success. This automatic feedback loop is the secret to high-quality output.
After successful validation, SVG diagram rendering is triggered.
Phase 5: Document Generation
The agent creates an SAD-<Name>.md file following our corporate template. It doesn't just copy-paste requirements — it fills in specific architecture sections:
- Change registry: a table of new components.
- Integration flows: a relationship table (Who -> To Whom -> Why -> Protocol).
- Security requirements: pre-fills data classification based on context.
The architect ends up with not a blank page, but a document that's 80% ready. All that's left is to verify the logic, add nuances, and insert links to Jira and CMDB.
Fragment of the generated document in Markdown format
2. Skill: Architecture Review (arch-review-solution)
The second skill addresses the "tunnel vision" problem and saves real people's time on reviews. Its job is to find obvious mistakes before the document reaches enterprise architects or security specialists.
We configured this skill to sequentially assume 5 different roles and examine the solution from different angles.
Agent roles during review:
- Solution Architect: checks technical integrity. Do the diagrams match the text? Are all arrows on the diagram described in the integration table? (This is the most common reason for documents being sent back for revision.)
- Enterprise Architect: looks at compliance with corporate standards. Are approved tech radar technologies being used? Is there duplication of functionality with other systems?
- Security Specialist: searches for design vulnerabilities. Do all external calls go through the gateway? Where are secrets stored? Is there authentication on inter-service calls?
- Adjacent System Owner: assesses the impact on their system. Will this solution break neighboring services?
- Business Stakeholder: verifies requirement coverage. Are all items from the BR implemented?
The skill's output is a Markdown table with comments:
| ID | Role | Severity | Section | Comment |
|---|---|---|---|---|
| SA-1 | Solution Architect | Medium | 1.2 | The flow table says REST, the diagram says gRPC. Need to synchronize. |
| SEC-1 | Security | High | 2.1 | Service accesses the internet directly, bypassing the proxy. Standard violation. |
| BIZ-1 | Business | Low | 3.0 | Error handling scenario for external API unavailability is not described. |
In my opinion, the business requirements coverage table turns out to be particularly interesting. These kinds of errors are often discovered only at late implementation stages, when the result is demonstrated to the stakeholder.
| Business Requirement | Status |
|---|---|
| BPMN 2.0 XML generation from text | ✅ Covered |
| BRD generation from template | ✅ Covered |
| Import of existing BPMN XML | ❌ Not covered |
| Editing via prompt chain | ⚠️ Partially covered |
Why This Is Great
In our experience, this skill catches 60–70% of typical comments. This means that with real human approvers, we discuss the substance of the architecture rather than spending 30 minutes arguing about why "the arrow points the wrong way."
Our Results
We believe that an LLM cannot (and should not) make architecture decisions for humans. Choosing a design pattern, CAP theorem trade-offs, stakeholder negotiations — that's still our job.
But an LLM brilliantly handles what architects hate: documentation, artifact synchronization, and initial validation.
We ran several experiments comparing the time to create a SAD using the old process (Confluence + Draw.io) versus the new one (Structurizr + Claude Code). The results are preliminary but telling:
| Stage | Before (traditional approach) | After (LLM agent) | Savings |
|---|---|---|---|
| Requirements analysis | 2–3 days | 1–2 days | ~30% (you still have to think, but the LLM helps) |
| Diagram creation | 1–2 days | 2–3 hours | ~80% (DSL + SVG generation) |
| Writing the SAD text | 1–2 days | 2–3 hours | ~80% (draft generation) |
| Preliminary review | 1 day | 10 minutes | ~98% (auto-review across 5 roles) |
| Approval + revisions | 5–8 days | 3–4 days | ~40% (fewer silly mistakes) |
| TOTAL | ~2–3 weeks | ~1 week | 2x+ speedup |
The main win — we stopped spending days on "moving boxes around" and hunting for typos in integration tables. Now the machine does that.
How to Replicate This: A Minimal Setup
If you want to try this approach, you don't need to build a complex agent system right away. Here's the minimum you need to get started:
- Tool: Structurizr Lite (free, runs in Docker).
- LLM assistant: Claude Code (runs in terminal, requires an API key or subscription).
-
Knowledge base (
CLAUDE.md): create aCLAUDE.mdfile in your project root. This is critically important. In it, describe:- your repository structure (where
.dslfiles are, where images go); - key conventions (e.g., "We use C4 Model, new elements are tagged with
New"); - validation rules (e.g., "Always run the
./validate.shscript after modifying the DSL").
- your repository structure (where
-
Your first skill: start simple — automate the review. Create an instruction file (e.g.,
.claude/skills/review.md) describing what to look for when reviewing architecture.
This is enough to feel the difference. From there, you can add diagram generation and full document generation.
To see how everything described in the article works, check out the demo repository on GitHub: https://github.com/AlexPronsky/vibe-structurizr
Limitations and Pitfalls
It would be wrong to say everything works perfectly. We hit many bumps (and continue to hit them) before the process started running smoothly.
-
workspace.jsonis a fragile artifact. Structurizr stores element coordinates in a separate JSON file. If two architects move blocks on a diagram in parallel,git mergeturns into a nightmare. We solved this by writing a special skill for smart JSON merging, but the problem still requires attention. -
DSL hallucinations. Sometimes Claude invents non-existent syntax or tries to link containers across different scopes (which Structurizr prohibits). This is exactly why the API validation step is mandatory. Without the
validate-dsl.shscript, the agent produces non-working code roughly a third of the time. -
Not all diagrams are generated perfectly. Sometimes data flow numbering drifts (requiring additional instructions in the skill or in
CLAUDE.md), or relationship labels on diagrams overlap each other (requiring you to open the Structurizr Lite UI and manually reposition boxes), or other rough edges appear. Manual validation and fixing of imperfections are still necessary. - Context window. If you have a large IT landscape described in a monolithic DSL file, the LLM can start "forgetting" its details. We solved this with strict modularity: each domain is a separate file, and the agent loads only the necessary pieces. We also try to split large skills into several smaller ones. These solutions significantly reduced the scale of the problem, but LLM context still overflows periodically.
Conclusion: Architecture as Dialogue
We started with the fact that an architect spends 80% of their time on bureaucracy and only 20% on making architecture decisions. Architecture as Code alone didn't solve this problem (it just swapped the mouse for a keyboard).
But adding an LLM agent changes everything fundamentally. Our process has transformed from the routine "drew — documented — approved" into a living dialogue with an intelligent assistant:
— "Add Kafka in the center, connect it to billing"
— "Done. Should I account for replication requirements?"
— "Yes, and check if we're violating any security patterns"
Now we literally talk to our architecture. This is the future of an architect's work. We stop being "box drawers" and rise to the level of architectural meaning, operating with it in natural language. And this is a future that has already arrived.
P.S. A Few Words About Security
Using cloud LLMs in a corporate environment always raises many security-related questions. "Won't our architecture secrets leak into Anthropic's training data?" — a more than fair question.
We take this seriously at our company. We have a strict information security department standard: direct requests to public cloud provider APIs are not allowed.
For working with LLMs — whether product features, AI assistants in IDEs, or our architecture agent — we use a corporate AI Gateway.
This is a single entry point that acts as a "smart proxy" and does two things:
- Data masking: on the fly, it strips or replaces sensitive information (customer PII, specific IP addresses, passwords, and other sensitive data) before sending it to the external cloud.
- Audit and control: logs access events, manages quotas, and enables centralized management of model providers.
So when our arch-generate-solution sends a diagram for analysis, it does so through a secured perimeter, and "raw" corporate data never leaves the boundary. If you're planning to implement a similar approach — address this concern first.
If you have any questions, I'd be happy to answer them via email or LinkedIn:
pronskiyalexey@gmail.com








Top comments (1)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.