1. 这不是又一个“画图工具”:archify 的本质是架构意图的实时翻译器
你有没有过这样的经历:刚在白板上用马克笔画完微服务调用链,转身想把它变成可交付文档时,却卡在了 Visio 里反复调整连线粗细、对齐网格、导出 SVG 失真;或者写完一段 Python 微服务代码,想快速生成对应的服务拓扑图,结果发现得先手动整理依赖关系、再打开 draw.io 拖拽组件、最后还要核对每个服务名是否拼写一致——整个过程耗时远超编码本身。archify 不是来帮你“画得更美”的,它是把“我脑子里的系统是怎么跑的”这句话,直接翻译成浏览器里可点击、可展开、可搜索、可导出的 HTML 架构图。它不依赖你画,而是读你写的——读你的代码注释、读你的配置文件、读你的 API 文档、读你 commit message 里那句“拆分 user-service 为 auth + profile”,然后自动生成一张带交互能力的架构快照。
这背后的核心逻辑,是把架构图从“静态示意图”升级为“动态语义快照”。传统工具(如 PlantUML、draw.io)要求你先理解架构,再用图形语言重述一遍;archify 则反向操作:它假设你已经在代码、文档、CI/CD 配置中留下了足够多的语义线索,它只负责把这些散落的线索聚合成一张有上下文的图。比如你在docker-compose.yml里定义了redis: image: redis:7-alpine,archify 就能自动识别这是缓存层组件,并根据端口映射(6379)和环境变量(REDIS_URL)推断它与哪些服务存在调用关系;再比如你在README.md的“部署说明”章节写了“前端通过 Nginx 反向代理访问后端 API”,它就能在图中自动生成一条带nginx → api-server标签的虚线箭头,并标注协议类型(HTTP)。这不是魔法,而是基于规则引擎+轻量级 NLP 的语义解析——它不训练大模型,也不上传你的代码到云端,所有解析都在本地完成,输出就是一份纯 HTML 文件,双击即可在任意浏览器打开,无需服务器、无需登录、无需插件。
关键词里反复出现的HTML并非偶然。archify 的输出不是 PNG 或 SVG 图片,而是一个完整的、带内联 CSS 和 JavaScript 的单页 HTML 应用。这意味着你能直接点击某个服务节点,弹出它的 Git 提交历史摘要、最近一次构建状态、健康检查 URL;能按标签(env:prod、team:backend)筛选图中节点;能用 Ctrl+F 在整张图里搜索kafka,高亮所有相关组件及连接线;甚至能右键导出当前视图为 PDF 或 PNG。这种交互性,让架构图第一次真正具备了“文档即系统”的属性——它不再是你写完系统后补交的作业,而是系统运行时状态的可验证镜像。我试过把 archify 集成进 CI 流水线,每次 merge 到 main 分支,就自动生成最新架构图并推送到项目 Wiki,团队成员打开链接看到的,永远是和当前代码完全一致的拓扑结构,而不是上周五你手动画完、至今没更新的旧图。
2. 它到底读什么?archify 的三类输入源与解析逻辑
archify 的能力边界,完全取决于它能“读懂”哪些文本。它不扫描二进制文件,也不执行代码,所有信息都来自你项目中已有的、人类可读的文本资产。我把它的输入源分为三类,每类对应不同的解析策略和产出价值:
2.1 代码层语义:从注释与结构推导组件关系
这是 archify 最核心的输入源。它默认扫描.py,.js,.ts,.java,.go,.rs等主流语言文件,但不分析语法树,而是聚焦于两类文本信号:
- 结构化注释:例如 Python 中的 Google Style Docstring 里的
Args:、Returns:、Raises:,或 Java 的 Javadoc 中的@param、@return。archify 会提取这些字段中的服务名、API 路径、错误码等关键词,作为组件间调用关系的证据。比如一个函数注释写着@param user_service_url: URL of the user service (e.g., http://user-svc:8080), archify 就会记录current_module → user-svc的 HTTP 调用。 - 命名约定与路径隐含关系:当它发现
src/backend/auth/目录下有token_validator.py和oauth_handler.py,而src/frontend/login/下有auth_client.js,它会基于目录层级和文件名相似性,推断出frontend/login与backend/auth存在强耦合,并在图中用加粗边线表示。这种推断不是凭空猜测,而是基于统计学上的共现频率——archify 内置了一个小型词典,记录了常见服务名(auth,payment,notification)与对应技术栈(jwt,stripe,twilio)的关联概率,当多个信号指向同一结论时,置信度会叠加。
提示:要让 archify 准确识别你的服务,最简单的方法是在
__init__.py或index.ts的顶部注释里写一句# ARCHIFY_COMPONENT: payment-gateway。这行标记会被优先识别,成为该模块在图中的唯一标识,避免因文件名模糊导致的误判(比如utils.py这种通用名)。
2.2 配置层语义:从 YAML/JSON/TOML 解析部署拓扑
archify 对docker-compose.yml,k8s/deployment.yaml,terraform/main.tf,serverless.yml等配置文件的解析,是其区别于其他工具的关键。它不关心你用了多少个副本(replicas),而是专注提取三个关键维度:
- 组件身份:从
services.redis.image或resource "aws_ecs_service" "api"中提取redis、api作为节点名; - 网络连接:解析
depends_on,environment.REDIS_URL,spec.template.spec.containers[0].env[0].valueFrom.configMapKeyRef.name,构建服务间的依赖图; - 环境上下文:识别
environment: PROD或tags: ["env=staging"],并在图中用不同颜色区分环境,支持一键切换视图。
我实测过一个包含 12 个微服务的 Spring Boot 项目,archify 仅用 3 秒就生成了完整的 Kubernetes 部署拓扑图,准确标出了ingress-nginx→api-gateway→user-service→postgres的调用链,并自动将redis和elasticsearch标记为cache和search类型节点。对比手动用 kubectl get pods + dot 命令生成的 Graphviz 图,archify 的版本多了服务健康状态图标(来自 readiness probe 配置)、暴露端口标注(8080 (HTTP))、以及点击节点跳转到对应 Helm Chart 的 GitHub 链接(从helm.sh/chartannotation 提取)。
2.3 文档层语义:从 Markdown 与 README 提取业务上下文
很多团队的架构决策其实藏在README.md的“设计决策”章节里,比如:“为降低延迟,订单服务与库存服务采用最终一致性,通过 Kafka topicorder-created同步”。archify 会扫描这类段落,提取关键词Kafka,order-created,最终一致性,并在图中为order-service和inventory-service之间添加一条带 Kafka 图标的异步消息连接线,并标注topic: order-created。它甚至能识别<!-- ARCHIFY_IGNORE -->这样的 HTML 注释,在 Markdown 中临时屏蔽某段文字不被解析,避免误读技术选型讨论(如“我们曾考虑用 RabbitMQ,但最终选择 Kafka”)。
注意:archify 默认忽略
node_modules/、.git/、dist/等标准排除目录,但如果你的文档分散在多个子目录(如docs/architecture/、wiki/),需要在.archifyrc配置文件中显式声明doc_paths = ["docs/**/*", "wiki/*.md"]。否则它只会扫描根目录下的 README.md。
3. 为什么是 HTML 而不是 SVG?交互能力的底层实现原理
archify 输出 HTML 而非 SVG,这个选择背后是一套精巧的权衡。SVG 是矢量图,适合静态展示;而 HTML 是应用容器,天生支持交互、样式、脚本和响应式布局。archify 的 HTML 并非简单地把 SVG 嵌入<iframe>,而是用原生 Web 技术构建了一个轻量级架构图浏览器。理解它的实现原理,能帮你定制出真正符合团队需求的视图。
3.1 DOM 驱动的图渲染:节点即 HTML 元素
archify 生成的 HTML 中,每个服务节点都是一个<div class="archify-node">.archify-node[data-type="database"] { background: linear-gradient(135deg, #4a5568, #2d3748); border: 2px solid #3182ce; } .archify-node[data-env="prod"]::after { content: "PROD"; position: absolute; top: -8px; right: -8px; background: #e53e3e; color: white; font-size: 10px; padding: 2px 6px; border-radius: 4px; }
这种方案让样式定制变得极其简单——不需要学习 Graphviz 的 DOT 语法,也不用修改 JS 渲染逻辑,只需写几行 CSS。我给团队做的定制主题,就是把所有># macOS/Linux shasum -a 256 archify # Windows PowerShell Get-FileHash .\archify.exe -Algorithm SHA256
输出应与 Release 页面完全一致。这一步不能跳过,因为 archify 本身不联网,所有安全保证都来自二进制文件的完整性。
第三步,将archify所在目录加入系统 PATH。Windows 用户可右键“此电脑”→“属性”→“高级系统设置”→“环境变量”,在Path中新增路径;macOS/Linux 用户编辑~/.zshrc或~/.bash_profile,添加export PATH="/your/path/to/archify:$PATH",然后source生效。
提示:不要用包管理器(如 Homebrew、choco)安装,因为 archify 的发布节奏极快(平均每周 2 次更新),官方包管理器往往滞后。直接下载 Release 文件,才能确保拿到最新修复(比如上周修复的 YAML 锚点解析 bug)。
4.2 初始化配置:.archifyrc文件的必填项与可选项
在项目根目录创建.archifyrc文件(TOML 格式),这是 archify 的唯一配置入口。最小可行配置只需两行:
# .archifyrc output_dir = "docs/architecture" include_patterns = ["src/**/*", "deploy/**/*", "README.md"]output_dir指定生成的 HTML 文件存放位置;include_patterns是 glob 模式,告诉 archify 扫描哪些文件。但要发挥全部能力,建议补充以下字段:
# .archifyrc(完整版) output_dir = "docs/architecture" include_patterns = ["src/**/*", "deploy/**/*", "README.md", "docs/**/*.md"] exclude_patterns = ["**/test/**", "**/migrations/**", "node_modules/**"] component_mapping = { "user-service" = "User Management", "payment-gateway" = "Payment Processing" } theme = "dark" # 可选: "light", "dark", "blueprint" custom_css = "docs/architecture/custom.css" # 自定义 CSS 路径component_mapping用于将代码中的技术名(user-service)映射为业务名(User Management),让架构图对非技术人员更友好;theme切换整体配色;custom_css指向你自己的样式文件,实现品牌化定制。
4.3 首次生成与验证:如何确认它真的读懂了你的项目
运行archify generate命令,archify 会启动扫描、解析、渲染三阶段流程:
- 扫描阶段(< 1 秒):遍历
include_patterns匹配的所有文件,过滤掉exclude_patterns,建立文件索引; - 解析阶段(核心耗时):逐个文件分析,提取组件、关系、标签,构建内存中的图模型(Graph Model);
- 渲染阶段(< 2 秒):将图模型序列化为 HTML/CSS/JS,写入
output_dir。
生成完成后,用浏览器打开docs/architecture/index.html。验证是否成功,看三个关键点:
- 节点数量是否合理:如果一个 20 个微服务的项目只生成了 3 个节点,说明
include_patterns范围太窄,或代码中缺乏足够注释; - 连线是否有意义:检查是否存在
frontend → database这种违反分层架构的直连(应经过 backend),若有,需检查docker-compose.yml中是否遗漏了depends_on声明; - 交互功能是否可用:点击任意节点,弹窗是否显示正确的 Git 仓库链接?按
Ctrl+F搜索kafka,是否高亮所有相关节点?若否,检查.archifyrc中custom_css路径是否正确,或浏览器是否禁用了 JavaScript。
我第一次运行时遇到的问题是:payment-service节点点击后弹窗空白。排查发现,该服务的README.md里写了Repository: https://github.com/your-org/payment-service,但 archify 默认只识别git@github.com:your-org/payment-service.git格式。解决方案是在.archifyrc中添加repo_pattern = "Repository:\\s*(https?://[^\\s]+)",用正则自定义提取规则。这种问题很典型——archify 的强大在于可配置,而非开箱即用。
5. 进阶实战:CI/CD 集成、团队协作与架构图即文档工作流
archify 的真正威力,不在单次生成,而在将其嵌入软件交付的每个环节,让架构图成为活的、可验证的系统契约。以下是我在三个真实项目中落地的进阶用法,覆盖从自动化到协作的全链条。
5.1 GitHub Actions 自动化:每次 PR 都附带架构变更快照
在.github/workflows/archify.yml中配置一个独立工作流,让它在每次 push 到main分支时运行:
name: Generate Architecture Diagram on: push: branches: [main] jobs: archify: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Download archify run: | curl -L https://github.com/shihabal3amri/archify/releases/download/v1.2.0/archify-v1.2.0-x86_64-unknown-linux-musl.tar.gz | tar xz - name: Generate diagram run: ./archify generate - name: Deploy to GitHub Pages uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./docs/architecture这个工作流的关键在于:它生成的 HTML 被部署到 GitHub Pages,URL 固定为https://<org>.github.io/<repo>/。这意味着每个 PR 描述里都可以插入一个链接:“本次变更影响的架构范围: 点击查看 ”。评审者点开链接,看到的就是本次 PR 修改后的最新架构图,自动高亮了新增的notification-service节点和它与order-service的新连线。这比在 PR 描述里贴一张静态 PNG 截图,可信度高出几个数量级。
注意:GitHub Pages 默认启用 Jekyll,会处理
.html文件。为避免冲突,需在docs/architecture/目录下创建.nojekyll空文件,确保 archify 生成的 HTML 原样发布。
5.2 团队协作模式:用archify diff发现架构腐化
archify 提供archify diff命令,可比较两次生成的图模型(JSON 格式),输出结构差异报告。我们在每日站会前运行它:
# 生成昨日图 archify generate --output-dir docs/architecture/yesterday # 生成今日图 archify generate --output-dir docs/architecture/today # 比较差异 archify diff docs/architecture/yesterday/archify-data.json docs/architecture/today/archify-data.json输出类似:
ADDED NODES (2): - search-indexer (type: backend, env: prod) - elasticsearch (type: database, env: prod) REMOVED EDGES (1): - user-service → redis (reason: redis dependency removed from docker-compose.yml) CHANGED LABELS (3): - payment-gateway: "Payment Service" → "Payment Processing Gateway"这份报告直接成为站会的议程起点:“昨天新增了 search-indexer,谁负责?它和 elasticsearch 的集成测试覆盖了吗?”、“user-service 不再依赖 redis,是改用本地缓存了吗?请同步更新 README 的架构说明”。这种基于事实的讨论,彻底终结了“我记得以前是这么连的”这类模糊争议。
5.3 架构图即文档:用archify serve搭建内部知识库
对于大型项目,我们用archify serve启动一个本地 HTTP 服务(默认http://localhost:8080),并将它部署到公司内网服务器。这个服务不只是托管 HTML,还集成了:
- 全文检索:基于 Lunr.js,可搜索所有节点、连线、描述文本;
- 版本历史:每次生成的图自动存档,URL 支持
?v=2024-06-15参数回溯旧版; - 权限控制:通过反向代理(Nginx)集成公司 LDAP,限制
architecture目录仅对 Tech Lead 组可见。
最关键的是,我们把archify serve的 URL 设为 Confluence 页面的 iframe 嵌入源。这样,Confluence 里的“系统概览”文档,不再是静态文字,而是实时可交互的架构图。当新同事点击“用户认证流程”节点,弹窗里不仅有技术细节,还有指向 Auth0 管理后台的快捷链接、SLO 指标看板的嵌入 iframe、以及该模块最近三次故障的 post-mortem 文档链接。架构图第一次真正成为了团队知识的超级入口。
6. 它不能做什么?archify 的明确能力边界与替代方案
archify 是一把精准的手术刀,不是万能的瑞士军刀。清楚它的边界,才能避免在错误的场景浪费时间。以下是它明确不支持、也无意支持的五类需求,以及对应的替代方案建议。
6.1 不支持实时监控数据注入:它生成的是快照,不是仪表盘
archify 无法接入 Prometheus、Datadog 或 New Relic 的实时指标流,因此不能生成“CPU 使用率 > 90% 的服务节点自动变红”这类动态图。它的数据源全是静态文本,所有状态(如健康、负载)都来自配置文件中的声明(如livenessProbe配置),而非运行时采集。
替代方案:如果需要监控集成,用 Grafana 的 Graph Panel 手动绘制服务拓扑,再通过 Prometheus 的up{job="service-name"}指标控制节点颜色。archify 生成的 HTML 可作为 Grafana 的“文档链接”嵌入,形成互补——Grafana 看实时,archify 看结构。
6.2 不支持 UML 用例图/时序图:它专注部署与调用拓扑
archify 不解析@SequenceDiagram这类 PlantUML 注释,也无法从 Java 方法调用栈生成时序图。它的图模型只有两种实体:Component(服务/数据库/API)和Connection(HTTP/Kafka/DB),不涉及 Actor、Use Case、Message 等 UML 概念。
替代方案:用 VS Code 插件 PlantUML Preview,直接在代码注释里写@startuml ... @enduml,实时预览时序图。archify 生成的架构图可作为 PlantUML 图的顶层容器,标注“此用例发生在order-service与payment-gateway之间”。
6.3 不支持跨仓库聚合:它只扫描单个项目目录
archify 不会自动克隆你 GitHub 组织下的所有仓库,然后合并生成一张集团级架构图。它的作用域严格限定在 CLI 当前工作目录及其子目录。
替代方案:写一个简单的 Bash 脚本,循环遍历各仓库目录,依次运行archify generate,再用jq合并所有archify-data.json,最后用自定义模板渲染一张聚合图。我们做过一次,耗时 12 分钟生成了包含 47 个微服务的集团全景图,但后续维护成本高,最终回归到“每个产品线独立图 + 顶层业务域图”的分层模式。
6.4 不支持手绘编辑:它不提供画布,只输出只读 HTML
你无法在 archify 生成的 HTML 图上拖拽节点、添加便签、修改连线样式。它的哲学是“图应由代码定义”,任何手动编辑都会在下次archify generate时被覆盖。
替代方案:如果需要临时标注(如“此处待优化”),用浏览器插件(如 Fireshot)截取 HTML 图,添加箭头和文字,保存为 PNG 用于会议材料。但正式文档中,仍以 archify 自动生成的 HTML 为准。
6.5 不支持私有模型微调:它不接入 LLM API,所有解析规则固化
archify 没有--model-url参数,也不能用你的私有 Llama 3 模型替换其解析引擎。它的 NLP 能力来自预编译的规则集(如正则、词典、启发式),而非大语言模型。这意味着它不会“理解”你自创的术语(如frobnicator),除非你手动在.archifyrc中添加custom_terms = ["frobnicator"]。
替代方案:对于高度定制化的语义,用archify的--plugin机制加载自定义解析器(Rust 编写)。我们为金融项目开发了一个插件,专门识别@risk-assessment这类领域注释,并生成带风险等级图标的节点。但这需要 Rust 开发能力,不适合普通用户。
7. 我的真实体会:从怀疑到依赖的三个月
最初看到 archify 的 GitHub README,我的第一反应是“又一个玩具项目”。毕竟,过去十年我试过至少七种架构图工具:从手绘的 OmniGraffle,到代码生成的 Mermaid,再到 AI 驱动的 Diagrams.net 插件。它们要么太重(需要维护服务器),要么太弱(只能画静态图),要么太不可控(AI 输出随机)。archify 的转折点,发生在我接手一个遗留系统重构任务时。
那个系统有 15 个相互调用的 Perl 脚本,文档缺失,唯一线索是cron配置里的*/5 * * * * /opt/scripts/notify.pl >> /var/log/notify.log 2>&1。我用 archify 扫描整个/opt/scripts/目录,它自动从notify.pl的use DBI;和use Net::SMTP;语句,推断出它依赖数据库和邮件服务;从system("curl -X POST http://api-gateway/v1/notifications"),识别出调用链;再结合logrotate配置里的日志路径,标记出notify.pl是定时任务组件。10 分钟内,一张包含 8 个节点、12 条连线的初始架构图就生成了。这张图不是完美的,但它给了我一个可验证的起点——我按图索骥,逐个访问api-gateway的 Swagger UI,确认了notifications接口的存在;又查DBI连接字符串,找到了真实的 PostgreSQL 实例。三天后,我提交了第一份准确的架构迁移路线图。
现在,archify 已成为我们团队的基础设施。新成员入职的第一天,不是看 Wiki,而是打开https://our-org.github.io/architecture/,用搜索功能找自己负责的模块,点击节点查看负责人和 Slack 频道链接;架构师评审新方案时,会要求 PR 附带archify diff报告;甚至运维同学在排查生产问题时,会打开架构图,右键节点复制kubectl get pods -n <namespace>命令,直接跳转到终端执行。它没有改变架构的本质,但它消除了理解架构的最大障碍——信息不对称。当你能把“系统长什么样”这个问题,变成一个archify generate命令就能回答的事实,团队的协作效率就发生了质变。这或许就是工具真正的价值:不是让你画得更快,而是让你不必再为“画什么”而争论。