mcpField
C
c4-architecture

c4-architecture

github.com/softaworks开发2.6k4.2k 次安装34 周前更新
代码仓库

关于 c4-architecture

c4-architecture指导使用 Mermaid C4 图编写软件架构文档,帮助团队按受众选择图表层级,描述系统、组件、关系与部署。

主要功能

  1. 01使用 Mermaid 语法绘制 C4 图
  2. 02提供图表层级选择指引
  3. 03建模系统关系
  4. 04涵盖微服务与事件驱动模式
  5. 05规范架构文档文件命名

适用场景

  1. 01记录系统上下文与容器
  2. 02说明复杂请求流程
  3. 03描述生产环境部署
  4. 04梳理微服务与事件主题

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/softaworks/agent-toolkit --skill c4-architecture

安装后在 Claude Code 中输入/c4-architecture确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
references/
advanced-patterns.md
c4-syntax.md
common-mistakes.md

详细介绍

C4 架构文档

使用 Mermaid 语法的 C4 模型图生成软件架构文档。

工作流

  1. 理解范围 - 根据受众确定需要哪些 C4 层级
  2. 分析代码库 - 探索系统以识别组件、容器和关系
  3. 生成图表 - 在适当的抽象层级创建 Mermaid C4 图
  4. 撰写文档 - 将图表写入 Markdown 文件并附上解释性上下文

C4 图表层级

根据文档需求选择合适的层级:

层级图表类型受众展示内容何时创建
1C4Context所有人系统 + 外部参与者始终(必需)
2C4Container技术人员应用、数据库、服务始终(必需)
3C4Component开发者内部组件仅在确有价值时
4C4DeploymentDevOps基础设施节点用于生产系统
-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 修复重叠的关系标签。

最佳实践

基本规则
  1. 每个元素必须包含:名称、类型、技术(如适用)和描述
  2. 仅使用单向箭头 - 双向箭头会产生歧义
  3. 用动作动词标注箭头 - “使用……发送邮件”、“从……读取”,而不仅仅是“使用”
  4. 包含技术标签 - “JSON/HTTPS”、“JDBC”、“gRPC”
  5. 每张图保持在 20 个元素以内 - 将复杂系统拆分为多张图
清晰度准则
  1. 从层级 1 开始 - 上下文图有助于界定系统范围
  2. 每个文件一张图 - 让图表专注于单一抽象层级
  3. 有意义的别名 - 使用描述性别名(例如 orderService 而非 s1)
  4. 简洁的描述 - 尽可能将描述控制在 50 个字符以内
  5. 始终包含标题 - “[系统名称] 的系统上下文图”
应避免的做法

参见 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容器 + 部署

参考资料

评论

支持 Markdown