关于 c4-architecture
c4-architecture指导使用 Mermaid C4 图编写软件架构文档,帮助团队按受众选择图表层级,描述系统、组件、关系与部署。
主要功能
- 01使用 Mermaid 语法绘制 C4 图
- 02提供图表层级选择指引
- 03建模系统关系
- 04涵盖微服务与事件驱动模式
- 05规范架构文档文件命名
适用场景
- 01记录系统上下文与容器
- 02说明复杂请求流程
- 03描述生产环境部署
- 04梳理微服务与事件主题
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ softaworks/ agent-toolkit --skill c4-architecture安装后在 Claude Code 中输入/c4-architecture确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdreferences/advanced-patterns.mdc4-syntax.mdcommon-mistakes.md详细介绍
C4 架构文档
使用 Mermaid 语法的 C4 模型图生成软件架构文档。
工作流
- 理解范围 - 根据受众确定需要哪些 C4 层级
- 分析代码库 - 探索系统以识别组件、容器和关系
- 生成图表 - 在适当的抽象层级创建 Mermaid C4 图
- 撰写文档 - 将图表写入 Markdown 文件并附上解释性上下文
C4 图表层级
根据文档需求选择合适的层级:
| 层级 | 图表类型 | 受众 | 展示内容 | 何时创建 |
|---|---|---|---|---|
| 1 | C4Context | 所有人 | 系统 + 外部参与者 | 始终(必需) |
| 2 | C4Container | 技术人员 | 应用、数据库、服务 | 始终(必需) |
| 3 | C4Component | 开发者 | 内部组件 | 仅在确有价值时 |
| 4 | C4Deployment | DevOps | 基础设施节点 | 用于生产系统 |
| - | C4Dynamic | 技术人员 | 请求流(带编号) | 用于复杂工作流 |
关键洞察: “对于大多数软件开发团队而言,上下文 + 容器图已经足够。”仅在组件/代码图确实能带来价值时才创建它们。
快速开始示例
系统上下文(层级 1)
C4Context
title System Context - Workout Tracker
Person(user, "User", "Tracks workouts and exercises")
System(app, "Workout Tracker", "Vue PWA for tracking strength and CrossFit workouts")
System_Ext(browser, "Web Browser", "Stores data in IndexedDB")
Rel(user, app, "Uses")
Rel(app, browser, "Persists data to", "IndexedDB")
容器图(层级 2)
C4Container
title Container Diagram - Workout Tracker
Person(user, "User", "Tracks workouts")
Container_Boundary(app, "Workout Tracker PWA") {
Container(spa, "SPA", "Vue 3, TypeScript", "Single-page application")
Container(pinia, "State Management", "Pinia", "Manages application state")
ContainerDb(indexeddb, "IndexedDB", "Dexie", "Local workout storage")
}
Rel(user, spa, "Uses")
Rel(spa, pinia, "Reads/writes state")
Rel(pinia, indexeddb, "Persists", "Dexie ORM")
组件图(层级 3)
C4Component
title Component Diagram - Workout Feature
Container(views, "Views", "Vue Router pages")
Container_Boundary(workout, "Workout Feature") {
Component(useWorkout, "useWorkout", "Composable", "Workout execution state")
Component(useTimer, "useTimer", "Composable", "Timer state machine")
Component(workoutRepo, "WorkoutRepository", "Dexie", "Workout persistence")
}
Rel(views, useWorkout, "Uses")
Rel(useWorkout, useTimer, "Controls")
Rel(useWorkout, workoutRepo, "Saves to")
动态图(请求流)
C4Dynamic
title Dynamic Diagram - User Sign In Flow
ContainerDb(db, "Database", "PostgreSQL", "User credentials")
Container(spa, "Single-Page App", "React", "Banking UI")
Container_Boundary(api, "API Application") {
Component(signIn, "Sign In Controller", "Express", "Auth endpoint")
Component(security, "Security Service", "JWT", "Validates credentials")
}
Rel(spa, signIn, "1. Submit credentials", "JSON/HTTPS")
Rel(signIn, security, "2. Validate")
Rel(security, db, "3. Query user", "SQL")
UpdateRelStyle(spa, signIn, $textColor="blue", $offsetY="-30")
部署图
C4Deployment
title Deployment Diagram - Production
Deployment_Node(browser, "Customer Browser", "Chrome/Firefox") {
Container(spa, "SPA", "React", "Web application")
}
Deployment_Node(aws, "AWS Cloud", "us-east-1") {
Deployment_Node(ecs, "ECS Cluster", "Fargate") {
Container(api, "API Service", "Node.js", "REST API")
}
Deployment_Node(rds, "RDS", "db.r5.large") {
ContainerDb(db, "Database", "PostgreSQL", "Application data")
}
}
Rel(spa, api, "API calls", "HTTPS")
Rel(api, db, "Reads/writes", "JDBC")
元素语法
人员与系统
Person(alias, "Label", "Description")
Person_Ext(alias, "Label", "Description") # External person
System(alias, "Label", "Description")
System_Ext(alias, "Label", "Description") # External system
SystemDb(alias, "Label", "Description") # Database system
SystemQueue(alias, "Label", "Description") # Queue system
容器
Container(alias, "Label", "Technology", "Description")
Container_Ext(alias, "Label", "Technology", "Description")
ContainerDb(alias, "Label", "Technology", "Description")
ContainerQueue(alias, "Label", "Technology", "Description")
组件
Component(alias, "Label", "Technology", "Description")
Component_Ext(alias, "Label", "Technology", "Description")
ComponentDb(alias, "Label", "Technology", "Description")
边界
Enterprise_Boundary(alias, "Label") { ... }
System_Boundary(alias, "Label") { ... }
Container_Boundary(alias, "Label") { ... }
Boundary(alias, "Label", "type") { ... }
关系
Rel(from, to, "Label")
Rel(from, to, "Label", "Technology")
BiRel(from, to, "Label") # Bidirectional
Rel_U(from, to, "Label") # Upward
Rel_D(from, to, "Label") # Downward
Rel_L(from, to, "Label") # Leftward
Rel_R(from, to, "Label") # Rightward
部署节点
Deployment_Node(alias, "Label", "Type", "Description") { ... }
Node(alias, "Label", "Type", "Description") { ... } # Shorthand
样式与布局
布局配置
UpdateLayoutConfig($c4ShapeInRow="3", $c4BoundaryInRow="1")
$c4ShapeInRow- 每行的形状数量(默认:4)$c4BoundaryInRow- 每行的边界数量(默认:2)
元素样式
UpdateElementStyle(alias, $fontColor="red", $bgColor="grey", $borderColor="red")
关系样式
UpdateRelStyle(from, to, $textColor="blue", $lineColor="blue", $offsetX="5", $offsetY="-10")
使用 $offsetX 和 $offsetY 修复重叠的关系标签。
最佳实践
基本规则
- 每个元素必须包含:名称、类型、技术(如适用)和描述
- 仅使用单向箭头 - 双向箭头会产生歧义
- 用动作动词标注箭头 - “使用……发送邮件”、“从……读取”,而不仅仅是“使用”
- 包含技术标签 - “JSON/HTTPS”、“JDBC”、“gRPC”
- 每张图保持在 20 个元素以内 - 将复杂系统拆分为多张图
清晰度准则
- 从层级 1 开始 - 上下文图有助于界定系统范围
- 每个文件一张图 - 让图表专注于单一抽象层级
- 有意义的别名 - 使用描述性别名(例如
orderService而非s1) - 简洁的描述 - 尽可能将描述控制在 50 个字符以内
- 始终包含标题 - “[系统名称] 的系统上下文图”
应避免的做法
参见 references/common-mistakes.md 了解详细的反模式:
- 混淆容器(可部署)与组件(不可部署)
- 将共享库建模为容器
- 将消息代理显示为单个容器而非各个主题
- 添加未定义的抽象层级,如“子组件”
- 为“简化”图表而移除类型标签
微服务准则
单一团队负责
将每个微服务建模为一个容器(或容器组):
C4Container
title Microservices - Single Team
System_Boundary(platform, "E-commerce Platform") {
Container(orderApi, "Order Service", "Spring Boot", "Order processing")
ContainerDb(orderDb, "Order DB", "PostgreSQL", "Order data")
Container(inventoryApi, "Inventory Service", "Node.js", "Stock management")
ContainerDb(inventoryDb, "Inventory DB", "MongoDB", "Stock data")
}
多团队负责
当微服务由不同团队负责时,将其提升为软件系统:
C4Context
title Microservices - Multi-Team
Person(customer, "Customer", "Places orders")
System(orderSystem, "Order System", "Team Alpha")
System(inventorySystem, "Inventory System", "Team Beta")
System(paymentSystem, "Payment System", "Team Gamma")
Rel(customer, orderSystem, "Places orders")
Rel(orderSystem, inventorySystem, "Checks stock")
Rel(orderSystem, paymentSystem, "Processes payment")
事件驱动架构
将各个主题/队列显示为容器,而不是单个“Kafka”框:
C4Container
title Event-Driven Architecture
Container(orderService, "Order Service", "Java", "Creates orders")
Container(stockService, "Stock Service", "Java", "Manages inventory")
ContainerQueue(orderTopic, "order.created", "Kafka", "Order events")
ContainerQueue(stockTopic, "stock.reserved", "Kafka", "Stock events")
Rel(orderService, orderTopic, "Publishes to")
Rel(stockService, orderTopic, "Subscribes to")
Rel(stockService, stockTopic, "Publishes to")
Rel(orderService, stockTopic, "Subscribes to")
输出位置
将架构文档写入 docs/architecture/,命名约定如下:
c4-context.md- 系统上下文图c4-containers.md- 容器图c4-components-{feature}.md- 每个功能的组件图c4-deployment.md- 部署图c4-dynamic-{flow}.md- 特定流程的动态图
与受众匹配的详细程度
| 受众 | 推荐的图 |
|---|---|
| 高管 | 仅系统上下文 |
| 产品经理 | 上下文 + 容器 |
| 架构师 | 上下文 + 容器 + 关键组件 |
| 开发者 | 按需提供所有层级 |
| DevOps | 容器 + 部署 |
参考资料
- references/c4-syntax.md - 完整的 Mermaid C4 语法
- references/common-mistakes.md - 应避免的反模式
- references/advanced-patterns.md - 微服务、事件驱动、部署
评论
支持 Markdown