用 YAML 写 C4 模型:archyl.yaml 格式与 Git 工作流

架构图有一个保质期问题。你在设计讨论后把它画出来,头一周看起来很棒,然后代码不断演进,图却在慢慢腐烂。六个月后,新同事盯着一张容器图发呆:图上画着第二季度就已合并的三个服务,却只字未提第三季度新建的那两个。

Archyl 从第一天起就执着于解决这个问题。AI 发现有助于保持内容新鲜。可视化编辑器让更新变得轻松。但有一类团队——那些把基础设施当代码、把策略当代码、把一切都当代码的团队——想要的是更根本的东西。

他们希望架构存放在 Git 里,就在它所描述的代码旁边。今天我们发布的正是这个。

本文是这个文件本身的参考说明:里面写什么、引用如何解析、如何同步。关于架构即代码的整体价值,以及它与 Structurizr DSL 等格式的比较,请阅读架构即代码指南。

什么是 archyl.yaml?

它是一个以声明方式描述你完整架构的单一 YAML 文件。把它放在仓库根目录,它就成为 Archyl 中 C4 模型的唯一可信来源。

一个最小的文件如下:

version: "1.0"

project:
  name: "My Platform"
  description: "Microservices architecture"

systems:
  - name: Platform
    type: software_system
    containers:
      - name: API Gateway
        type: api
        technologies: [Go, gRPC]
      - name: User Database
        type: database
        technologies: [PostgreSQL]

relationships:
  - from: API Gateway
    to: User Database
    label: "Reads user data"
    type: reads_from

就这么简单。Archyl 读取这个文件,构建完整的 C4 模型,渲染图表,并让一切保持同步。无需在界面里到处点击,无需手动同步,也不会再有"我忘了更新图"。

顶层键

键 内容
version 格式版本,目前为 "1.0"
project 项目名称和描述
technologies 供元素引用的技术目录
environments 部署环境,如预发布和生产
systems 系统,其中嵌套容器、组件和代码元素
relationships 任意两个元素之间的连接,按名称或点号路径指定
overlays 图上的命名可视化分组
events 事件通道(如 Kafka 主题),包含生产者和消费者
api_contracts OpenAPI、gRPC 等规范,关联到暴露它们的元素
releases 发布及其部署的内容
adrs 内联的 ADR,或仓库中的 ADR 文件夹
docs 项目文档,内联或来自某个文件夹
include 要合并的其他 archyl.yaml 文件,适用于单体仓库(monorepo)

顶层只有 version 是必需的。其余都是可选的,所以一个文件可以从一个系统开始,逐步扩展。

一切都在一个文件里

这个 DSL 并不是简化的子集——它覆盖了 Archyl 能建模的全部范围:

全部四个 C4 层级。 系统包含容器,容器包含组件,组件包含代码元素。YAML 的嵌套直接映射了这个层级。

使用点号表示法的关系。 用 Payment Service.API Gateway → Payment Service.Database 这样易读的引用连接任意两个元素。没有 UUID,没有晦涩的标识符。可 grep、对 diff 友好、人类可读。

技术、环境和发布。 定义技术目录,声明部署环境(预发布、生产),并跟踪发布——全部在同一个文件中完成。

ADR 和文档。 可以内联编写架构决策记录,也可以指向仓库中的某个文件夹。项目文档同理。

API 契约和事件通道。 声明你的 OpenAPI 规范、gRPC 定义和 Kafka 主题,并把它们关联到暴露或消费它们的组件。

可视化叠加层。 用命名的叠加层在图上对元素分组,控制颜色和层级。

支持单体仓库。 使用 include 把架构拆分到多个文件中——每个服务、团队或限界上下文一个——Archyl 会自动合并它们。

为什么选 YAML?

我们考虑过构建自定义的 DSL 语法(类似 Structurizr 的 DSL 或 Terraform 的 HCL)。选择 YAML 是出于务实的考虑:

  1. 零学习成本。 每个开发者都已经会 YAML。不需要学新语法,不需要安装解析器,也不需要编辑器插件。

  2. 免费获得 IDE 支持。 我们在 /api/v1/dsl/schema 发布了一个 JSON Schema。把 IDE 指向它,无需任何 Archyl 专用工具,就能获得自动补全、校验和内联文档。

  3. 对 diff 友好。 YAML 的 diff 在拉取请求中干净易读。评审者一眼就能看出"哦,他们给 Payment Service 加了一个新容器,并把它连到了 Redis"。

  4. 工具生态。 各种 linter、格式化工具、模板引擎(Helm、Kustomize)都能直接处理 YAML。

Git 原生工作流

真正的威力在这里。因为 archyl.yaml 存放在你的仓库中,架构变更遵循与代码变更相同的工作流:

  1. 分支。 创建功能分支,编辑 YAML。
  2. 评审。 发起拉取请求。团队在评审代码变更的同时评审架构变更。
  3. 合并。 获批后合并到 main。
  4. 同步。 Archyl 获取变更并自动更新图表。

不会再有"图上说是 X,代码却在做 Y"。不会再有绕过评审的架构变更。也不会再有没人知道已经更新过的文档。

CI/CD 集成

我们为 CI/CD 流水线构建了一流的集成。针对 GitHub,我们提供一个官方的 GitHub Action,包办一切——读取文件、调用 API、报告变更内容。

GitHub Actions(官方 Action):

name: Sync Architecture
on:
  push:
    branches: [main]
    paths: ['archyl.yaml']
jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: archyl-com/actions/sync@v1
        with:
          api-key: ${{ secrets.ARCHYL_API_KEY }}
          project-id: 'your-project-uuid'

就这些。三行配置,每次推送都能让你的架构保持同步。该 Action 支持自定义文件路径(适用于单体仓库)和自托管的 Archyl 实例,并为后续步骤提供 summary、systems-created、relationships-created 等输出。

GitLab CI:

sync-architecture:
  stage: deploy
  script:
    - |
      curl -X POST \
        https://api.archyl.com/api/v1/projects/$ARCHYL_PROJECT_ID/dsl/ingest \
        -H "X-API-Key: $ARCHYL_API_KEY" \
        -H "Content-Type: application/json" \
        -d "{\"content\": \"$(cat archyl.yaml | jq -Rs .)\"}"
  only:
    changes:
      - archyl.yaml

/ingest 端点接受 API 密钥认证,因此在 CI 中不需要 OAuth 流程。它会导入完整模型,创建或更新每个元素,并返回一份详细的变更摘要。

你也可以直接从 Archyl 界面同步。如果项目连接了 Git 仓库,在 Architecture as Code 设置里点击"Sync Now",Archyl 就会直接从仓库拉取该文件。

双向:导出与导入

这个工作流不是单向的。已经在 Archyl 的可视化编辑器里建好了模型?把它导出:

  • Export 根据当前模型生成完整的 archyl.yaml。每个系统、容器、组件、关系、叠加层、ADR、API 契约、事件通道、发布——全部序列化成干净的 YAML。
  • Import 解析 archyl.yaml,并在项目中创建或更新所有元素。它是幂等的:同一个文件导入两次不会产生重复。元素按名称匹配并执行 upsert。
  • Import as Project 从一个 YAML 文件创建一个全新的项目。放入一个 archyl.yaml,一键就能得到一个内容完整的项目。

这意味着你可以从界面开始,导出为 YAML,提交到 Git,然后切换到代码优先的工作流——反过来也可以。你不会被锁定在任何一种方式里。

智能引用解析

DSL 中最棘手的部分之一,是解析关系、叠加层、事件和 API 契约中的元素引用。我们构建了一个能自然处理这件事的解析器:

  • 短名称在没有歧义时可以直接用:如果只有一个元素叫这个名字,API Gateway 会被直接解析。
  • 点号表示法用于消除歧义:Payment Service.API Gateway 与 Analytics.API Gateway。
  • 任意深度都可以:深层嵌套的引用可以写成 System.Container.Component.CodeElement。

解析器会在所有可能的路径深度上为每个元素建立索引,所以你总能使用最短且无歧义的引用。导出时以相反方向使用同样的逻辑——生成尽可能易读的引用。

无副作用的校验

不确定你的 YAML 是否有效?/validate 端点(以及导入弹窗中的"Validate"按钮)会在不触碰数据库的情况下解析并检查你的文件:

  • 模式版本检查
  • 必填字段校验
  • 重复名称检测
  • 类型枚举校验(容器类型、关系类型等)
  • 交叉引用解析

错误会附带精确路径(systems[2].containers[1].name)和清晰的信息返回。把它接入 pre-commit 钩子或 CI 检查,就能在问题进入 main 之前把它拦下。

实际使用模式

单体仓库

# Root archyl.yaml
version: "1.0"
project:
  name: "Our Platform"
include:
  - services/payments/archyl.yaml
  - services/users/archyl.yaml
  - services/notifications/archyl.yaml

每个服务维护自己的 archyl.yaml,定义其容器和组件。根文件把它们合并起来,跨服务的关系在根层级定义。技术和环境会被自动去重。

从零起步

要开始一个新项目?在写任何代码之前先创建一个 archyl.yaml。定义你计划构建的系统和容器。用 Archyl 的"Import as Project"即时生成架构。随着开发推进,YAML 也随代码一起演进。

审计轨迹

因为 YAML 在 Git 里,你免费获得了完整的历史。git log archyl.yaml 会显示每一次架构变更、谁做的、什么时候做的,以及讨论它的那个 PR。试试从绘图工具里拿到这些。

文档生成器

把架构导出为 YAML,再交给任意模板引擎,就能生成 Markdown 文档、Confluence 页面或内部 wiki。结构化的格式让自动化变得轻而易举。

下一步

这是 DSL 格式的 1.0 版本。以下是我们接下来要做的:

漂移检测。 将仓库中的 YAML 与实时模型进行比较并高亮差异——在界面中添加但文件里没有的元素,或者反过来。

PR 预览评论。 当 PR 修改了 archyl.yaml 时,机器人会以可视化 diff 的形式评论架构中发生了哪些变化。

模式演进。 随着 Archyl 增加新功能,DSL 也会随之扩展。我们会保持向后兼容,并提供迁移工具。

立即试用

Architecture as Code 今天起在所有 Archyl 计划中可用。如果你已经有项目:

  1. 进入项目的 Architecture as Code 页面
  2. 点击 Export 生成你的 archyl.yaml
  3. 把它提交到你的仓库
  4. 把官方 GitHub Action加入你的工作流,就完成了

如果从零开始,创建一个 archyl.yaml,使用 Import as Project,几秒钟内你就会得到一个完整渲染的 C4 架构。

你的架构值得和代码一样严谨。给它做版本管理,评审它,把它自动化。


刚接触 C4?从我们的 C4 模型指南开始。想让 AI 生成初始架构?请看 AI 驱动的架构发现。已经在用 AI 助手?通过我们的 MCP 服务器把它们连接起来。