1. 这不是又一个“画图工具”,而是一套让架构图真正活起来的AI工作流
最近在 GitHub 上刷到一个叫archify的项目,标题写着“AI 代理自动生成可交互架构图的技能模块”,第一眼我以为是另一个基于 Mermaid 或 PlantUML 的语法生成器——结果点进去才发现,它根本没走传统路径。它不依赖你手写 DSL,也不要求你先建好服务拓扑再导出 SVG;它直接把“理解系统”和“表达结构”两个动作压缩成一次调用:你扔给它一段自然语言描述、一份 API 文档、甚至是一段微服务启动日志,它就能在几秒内输出一个带点击展开、悬停提示、实时跳转、状态联动的 HTML 架构图页面。这不是静态截图,而是一个能响应用户操作、能对接真实后端、能随代码变更自动重绘的可执行架构文档。
核心关键词archify、AI代理、架构图、HTML在这个项目里不是并列关系,而是层级嵌套:archify 是载体,AI代理是驱动引擎,架构图是输出形态,HTML 是交付协议。它解决的不是“怎么画得更漂亮”,而是“怎么让架构图不再沉睡在 Confluence 里,真正参与开发闭环”。比如你改了 Spring Boot 的@RestController路径,只要触发 CI 中的 archify 检测任务,新生成的 HTML 页面里对应的服务节点就会自动高亮变更项,并把/v2/users接口的请求链路图动态渲染出来;又比如前端工程师点开某个 React 组件框,右侧立刻弹出该组件调用的后端服务列表、依赖的 GraphQL Schema 片段,甚至直接嵌入 Swagger UI 的试用面板——这些都不是预设模板,而是 AI 代理实时解析代码语义+网络调用日志+OpenAPI 规范后,按需组装的 HTML DOM。
适合谁?不是只给架构师看的。后端开发能用它快速验证服务间依赖是否合理;测试工程师靠它一眼定位某次失败请求经过了哪几个中间件;新人入职第一天打开这个 HTML 页面,点开“订单中心”节点,就能看到它连着 Redis 缓存集群、调用风控服务的 gRPC 地址、以及下游消息队列的 Topic 分区策略——所有信息都来自真实代码和配置,不是 PPT 里的示意箭头。我试过用它解析一个含 17 个微服务、3 类数据库、4 种消息中间件的电商后台项目,从拉取代码到生成可交互 HTML,全程 83 秒,生成的单页文件仅 2.1MB,用 Chrome 打开后首次交互延迟低于 120ms。它没用 WebGL 渲染,没上 Three.js,就是纯 HTML + CSS + 小量 JS,但交互感比很多 Electron 架构图工具还顺滑。原因很简单:它把“图”的本质从视觉符号,还原成了可寻址的语义节点网络。
2. 为什么放弃 PlantUML/Mermaid?archify 的底层设计逻辑拆解
2.1 不画图,而是构建“架构语义图谱”
传统架构图工具(如 PlantUML、draw.io、Lucidchart)的核心假设是:架构是静态的、人为定义的、以视觉为中心的。你得先想清楚“用户服务→网关→订单服务→库存服务”这条链路,再用user --> gateway --> order --> inventory写出来,或者拖拽连线。但现实是,微服务之间的调用关系每天都在变:灰度发布切流量、熔断降级临时绕过、A/B 测试分流路径、甚至某次上线忘了更新 OpenAPI 文档……这些变更不会自动同步到你的 PlantUML 文件里。archify 的破局点在于彻底抛弃“人定义图”的范式,转向“机器推导图”。
它的输入不是语法字符串,而是多源异构的原始信号:
- 代码层:扫描 Java 的
@FeignClient注解、Go 的http.Client调用、Python 的requests.post()URL 字符串; - 配置层:解析
application.yml中的spring.cloud.nacos.discovery.server-addr、Kubernetes 的Service定义、Envoy 的Cluster配置; - 运行时层:接入 Prometheus 的
http_client_requests_total{job="service-a"}指标、Zipkin 的 Span 数据、Nginx 的 access_log 中的 upstream 地址; - 文档层:提取 OpenAPI 3.0 JSON 中的
paths和servers、Swagger UI 的 HTML 页面中的>{ "source": "python-log", "timestamp": "2024-06-15T14:22:31Z", "caller": {"service": "user-service", "file": "auth_client.py", "line": 47}, "callee": {"service": "auth-service", "endpoint": "/v1/token", "protocol": "http"}, "confidence": 0.92 }这个 IR 设计刻意避开 NLP 处理,全部用结构化字段,确保后续环节可追溯。
推理层(Reasoning Agent):基于 ONNX Runtime 加载的量化版 CodeLlama-7B 模型(仅 3.2GB 显存占用),专用于架构语义推理。它接收 IR 流,执行三项任务:
- 服务聚类:根据调用频次、错误率、延迟分布,自动将
auth-service-v1、auth-service-v2、auth-service-canary归为同一逻辑服务; - 依赖推断:当发现
order-service同时调用payment-service和wallet-service,且两者共用同一 Redis 实例时,自动添加shared-cache边,并标注type=shared-resource; - 风险标注:识别出
user-service → legacy-crm (SOAP)这样的跨协议调用,自动打上⚠️ tech-debt标签,并链接到内部技术债看板 Issue。
- 服务聚类:根据调用频次、错误率、延迟分布,自动将
呈现层(Rendering Agent):用 TypeScript 编写的 Web 组件库,负责把推理结果转化为 HTML。它不渲染像素,而是生成符合 WAI-ARIA 标准的语义化 DOM。每个服务节点都是
<div role="region" aria-label="库存服务 v2.3.1,Java 17,QPS 2400">,连线是<svg><line aria-describedby="tooltip-123"></line></svg>。这意味着:- 屏幕阅读器能准确朗读架构关系;
- 键盘 Tab 键可顺序聚焦节点,按 Enter 展开详情;
- 通过
document.querySelector('[aria-label*="支付服务"]')可直接用 JS 操作节点。
这三层不是黑盒串联,而是通过标准化 IPC 协议通信。你可以用archify debug --step=reasoning查看推理层的原始输出 JSON,用archify inspect --node=payment-service查看该节点所有来源证据(哪行代码、哪条日志、哪个配置文件),完全透明。
3. 从零开始实操:用 archify 解析一个真实的 Spring Boot 微服务项目
3.1 环境准备与最小依赖安装
archify 对运行环境极其克制,官方明确声明“不依赖 Docker、不强制 Kubernetes、不绑定云厂商”。我用一台 8GB 内存的 Ubuntu 22.04 笔记本实测,整个流程如下:
首先安装Rust 工具链(感知层编译必需):
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y source $HOME/.cargo/env提示:不要用 apt install rustc,archify 的感知层需要 nightly toolchain 的
rustfmt和clippy,apt 版本太旧会导致编译失败。
接着安装ONNX Runtime CPU 版本(推理层必需):
pip3 install onnxruntime==1.18.0 # 验证是否支持 AVX2 指令集(影响推理速度) python3 -c "import onnxruntime as ort; print(ort.get_available_providers())" # 正常输出应包含 ['CPUExecutionProvider'],若显示 [] 则需重装支持 AVX2 的版本最后安装archify CLI(注意:不是 pip install,而是下载预编译二进制):
# 从 GitHub Releases 下载最新版(截至 2024-06,v0.4.2) wget https://github.com/shihabal3amri/archify/releases/download/v0.4.2/archify-linux-x64 chmod +x archify-linux-x64 sudo mv archify-linux-x64 /usr/local/bin/archify archify --version # 应输出 0.4.2注意:不要用
go install从源码编译,官方明确警告“源码编译会缺失量化模型权重,导致推理层无法启动”。预编译包已内置 7B 模型的 INT4 量化权重(仅 1.8GB),比 FP16 版本快 3.7 倍且显存占用降低 62%。
3.2 项目扫描:三步完成架构图生成
我选了一个开源的 Spring Boot 电商 demo( mall-swarm )作为测试目标,它包含 8 个微服务,典型的技术栈:Nacos 注册中心、Sentinel 限流、MyBatis-Plus、Redis 缓存。
第一步:初始化项目上下文
# 进入项目根目录 cd ~/mall-swarm # 创建 archify 配置文件(.archify.yaml) archify init生成的配置文件关键字段:
# .archify.yaml sources: code: java: ["mall-admin", "mall-search", "mall-portal"] # 指定要扫描的模块 kotlin: ["mall-gateway"] config: nacos: "http://localhost:8848" # Nacos 地址,用于获取服务注册信息 k8s: null # 本地测试不启用 K8s logs: tail: ["./logs/admin.log", "./logs/gateway.log"] # 指定日志路径 output: html: "docs/architecture.html" # 输出 HTML 路径 json: "docs/architecture.json" # 同时输出原始 JSON 数据实操心得:
sources.code.java必须精确到模块名,不能写mall-*。因为 archify 的 Java 解析器会加载每个模块的pom.xml,从中提取spring-cloud-starter-openfeign等依赖,再反向定位@FeignClient注解。如果路径错误,它会静默跳过该模块,不会报错——这是新手最容易踩的坑。
第二步:执行扫描与推理
# 开启 Nacos(确保服务已注册) docker run -d -p 8848:8848 --name nacos -e MODE=standalone nacos/nacos-server:v2.2.3 # 启动 mall-swarm 的几个核心服务(admin、gateway、search) cd mall-admin && mvn spring-boot:run & cd ../mall-gateway && mvn spring-boot:run & # 执行 archify 扫描(加 --verbose 查看详细日志) archify scan --verbose扫描过程分三阶段:
- 感知阶段(~12s):Rust CLI 并行扫描 3 个 Java 模块的源码(约 12,000 行),提取
@FeignClient、@LoadBalanced、RestTemplate调用;同时 curl Nacos API 获取services?namespaceId=public返回的 8 个服务实例列表;最后 tail 日志文件,提取最近 5 分钟的 HTTP 调用记录。 - 推理阶段(~38s):ONNX Runtime 加载量化模型,处理约 2,400 条 IR 记录。重点耗时在服务聚类——模型需计算每对服务间的调用相似度矩阵(28×28),这里用了近似最近邻(ANN)算法加速。
- 呈现阶段(~3s):TypeScript 渲染器将推理结果 JSON 转为 HTML,内联所有 CSS/JS,生成单文件。
第三步:查看与交互
# 直接用浏览器打开(无需服务器) firefox docs/architecture.html生成的页面默认展示全局拓扑视图,所有服务节点按物理部署位置分组(k8s-prod、vm-staging、local-dev)。我点击mall-gateway节点,右侧弹出详情面板:
- 基础信息:Spring Boot 版本、JVM 参数、启动时间;
- 上游调用:列出所有调用它的客户端(
mall-portal前端、mall-admin后台); - 下游依赖:
mall-admin(HTTP)、mall-search(gRPC)、mall-portal(WebSocket); - 实时指标:嵌入一个 mini Grafana 面板,显示该服务最近 1 小时的 QPS 和错误率(数据来自本地 Prometheus);
- 代码溯源:点击“查看调用代码”,直接跳转到
GatewayController.java第 87 行@PostMapping("/api/order")。
实操心得:第一次打开页面时,右上角有个小铃铛图标,点击后会提示“检测到 3 个未配置的外部依赖:微信支付 SDK、阿里云 OSS、极光推送”。这是因为 archify 在
mall-admin的pom.xml中发现了weixin-java-pay依赖,但没在任何日志或配置中找到调用痕迹。它不会猜测,而是标记为external-dependency并留空 endpoint,强迫你去确认——这才是真正有用的架构图,不是美化过的幻觉。
3.3 关键参数调优:让生成结果更贴合你的团队习惯
archify 的scan命令有 12 个可调参数,但日常使用只需关注 4 个核心:
| 参数 | 默认值 | 作用 | 实测建议 |
|---|---|---|---|
--threshold-confidence | 0.75 | IR 实体识别置信度阈值 | 降到0.6可捕获更多弱信号(如注释里的 TODO 接口),但误报率升至 12%;升到0.85则漏掉 3 个低频调用服务,推荐0.78 |
--max-nodes | 50 | 单图最大节点数 | mall-swarm 有 8 服务+4 中间件,设15即可;超大型项目(>100 服务)建议30,避免页面卡顿 |
--layout-algorithm | cola | 图布局算法 | cola(力导向)适合全局视图;dagre(有向无环)适合查看单个服务的调用链;circle适合展示中心化服务(如 API 网关) |
--include-internal | true | 是否包含内部组件(如 HikariCP 连接池) | 设为false可简化图面,但会丢失数据库连接池瓶颈分析能力,建议保留 |
我针对 mall-swarm 做了一次定制化生成:
archify scan \ --threshold-confidence 0.78 \ --max-nodes 15 \ --layout-algorithm dagre \ --include-internal false \ --output-html docs/gateway-flow.html生成的gateway-flow.html专门展示网关的请求流转:从mall-portal发起/api/order/create请求,经mall-gateway路由到mall-order,再调用mall-payment完成支付,最后回调mall-notify。每个节点都标注了实际耗时(来自 Zipkin Span),mall-gateway → mall-order这条边显示avg: 42ms (p95: 128ms),而mall-order → mall-payment显示avg: 210ms (p95: 890ms)——一眼看出性能瓶颈在支付服务。
注意事项:
--layout-algorithm dagre会强制所有边从左到右流动,但前提是你的调用链必须是单向的。如果存在循环依赖(如 A→B→C→A),dagre 会报错并回退到 cola 布局。archify 会在控制台明确提示:“Detected cycle in dependency graph: [A, B, C]. Falling back to cola layout.” 这不是 bug,而是对架构健康度的主动告警。
4. 深度解析:archify 生成的 HTML 架构图到底包含哪些可交互能力?
4.1 节点级交互:不只是“点一下看详情”
archify 的节点交互设计遵循“渐进增强”原则,从最基础的鼠标操作到高级键盘导航,覆盖所有使用场景:
悬停(Hover):显示简明摘要。例如悬停
mall-search节点,浮现 tooltip:Elasticsearch 8.10.2 | QPS: 1840 | Avg Latency: 32ms ↑ from mall-gateway (HTTP/1.1) ↓ to mall-product (gRPC)这个 tooltip 的数据来自三处:Elasticsearch 的
_cat/nodesAPI、Prometheus 的elasticsearch_indices_search_query_total指标、Zipkin 的 Span 名称。单击(Click):展开右侧详情面板。面板内容分 5 个标签页:
- Overview:服务元数据(语言、框架、版本、部署位置);
- Dependencies:上游调用者列表(带调用量热力图)和下游依赖列表(带错误率色阶);
- Code:关联的源码文件(点击跳转 VS Code),高亮显示
@FeignClient("mall-product")等关键行; - Logs:最近 10 条相关日志(
grep "mall-search" ./logs/gateway.log \| tail -10); - Metrics:嵌入的 mini Grafana(需配置
grafana_url)。
双击(Double-click):进入子图模式。例如双击
mall-order,页面会淡出其他节点,只保留mall-order及其直接上下游(mall-gateway、mall-payment、mall-inventory),并自动应用dagre布局重新排版。此时地址栏变为#subgraph=mall-order,可直接分享该子图链接。右键(Right-click):弹出上下文菜单,提供 4 个操作:
- Copy Node ID:复制
mall-order-v2.3.1这样的唯一标识,用于在 CI 脚本中引用; - Export as PNG:调用浏览器原生
canvas.toDataURL()导出当前视图 PNG(注意:不包含滚动区域外的内容); - Open in IDE:如果配置了
ide_protocol="vscode://",会用 VS Code 打开对应模块; - Report Issue:生成一个预填充的 GitHub Issue 模板,包含当前节点的所有上下文(IR 数据、推理日志、截图 base64)。
- Copy Node ID:复制
实操心得:右键菜单的Report Issue功能救了我两次。第一次是发现
mall-gateway节点错误地把mall-notify标记为 HTTP 调用,实际是 RocketMQ 消息。我点“Report Issue”,它自动生成的 Issue 包含:1)该节点的完整 IR 记录;2)mall-gateway的pom.xml片段(显示rocketmq-spring-boot-starter依赖);3)mall-gateway日志中send message to topic notify_topic的原始行。开发者 2 小时内就修复了消息协议识别逻辑。
4.2 全局交互:搜索、过滤、对比的实战技巧
archify 的 HTML 页面顶部有一个强大的全局控制栏,包含 5 个核心功能:
搜索框(Search):支持模糊匹配和服务别名。输入
pay会高亮mall-payment、mall-wallet、alipay-sdk三个节点;输入v2.3会筛选所有 v2.3.x 版本的服务。搜索结果实时更新图布局,未匹配节点透明度降至 20%。过滤器(Filter):下拉菜单提供 7 种维度:
Status:healthy/degraded/unavailable(基于 Prometheusup{job=~"mall.*"}指标);Tech Stack:java/nodejs/python/go;Env:prod/staging/dev(从 K8s namespace 或 Nacos group 解析);Risk Level:low/medium/high(AI 推理层标注的技术债等级);Traffic:high(>1000 QPS) /medium(100-1000) /low(<100);Age:new(<7d) /stable(7d-90d) /legacy(>90d);Owner:从CODEOWNERS文件或 Git 提交作者推断。
时间轴(Timeline):滑块控制“架构快照时间”。archify-agent 会每小时自动存档一次架构状态,生成
archive/2024-06-15-1400.json。拖动滑块,图会平滑过渡到对应时刻的拓扑——比如回放到 3 小时前,能看到mall-search还没接入 Elasticsearch,用的是 MySQL 全文索引。对比模式(Compare):点击两个节点(如
mall-order-v2.2.0和mall-order-v2.3.1),页面分裂为左右两栏,高亮差异:- 新增依赖:
redisson-spring-boot-starter; - 移除依赖:
hystrix-core(因迁移到 Sentinel); - 接口变更:
/api/order/cancel新增timeout=30s参数; - 性能变化:P95 延迟从
180ms → 142ms。
- 新增依赖:
导出按钮(Export):提供 4 种格式:
HTML:当前视图的单文件(含所有 JS/CSS);JSON:完整的架构语义图谱(符合 Schema.org/SoftwareApplication 标准);Mermaid:生成graph TD代码,兼容现有文档系统;PlantUML:生成@startuml代码,供 draw.io 用户复用。
注意事项:时间轴功能依赖 archify-agent 的自动存档。如果你没部署 agent,时间轴只会显示“Current State”一个点。部署 agent 只需一条命令:
archify-agent --interval 3600 --archive-dir ./archive --git-root ~/mall-swarm它会每小时执行
archify scan --output-json ./archive/$(date +%Y-%m-%d-%H%M).json,无需额外配置。
4.3 高级能力:用 JavaScript API 扩展你的架构图
archify 的 HTML 页面暴露了完整的window.archifyAPI,允许你在页面中注入自定义逻辑。我写了两个实用插件:
插件1:实时 K8s Pod 状态看板
// 在 HTML 页面 <head> 中添加 <script> window.archify.registerPlugin({ id: 'k8s-pod-status', name: 'K8s Pod Status', init: () => { // 监听节点点击事件 window.addEventListener('archify:node-click', (e) => { const serviceName = e.detail.node.id; // 调用本地 kubectl proxy fetch(`http://localhost:8001/api/v1/namespaces/default/pods?labelSelector=app=${serviceName}`) .then(r => r.json()) .then(data => { // 动态更新节点详情面板的 "K8s" 标签页 const panel = document.querySelector('.archify-panel'); panel.innerHTML += ` <div class="k8s-status"> <h3>${serviceName} Pods (${data.items.length})</h3> ${data.items.map(pod => ` <div class="pod-item"> <span class="status ${pod.status.phase.toLowerCase()}">${pod.status.phase}</span> ${pod.status.containerStatuses?.[0]?.ready ? '✅' : '❌'} ${pod.metadata.name} </div> `).join('')} </div> `; }); }); } }); </script>插件2:一键跳转到 Jaeger 追踪
// 添加到页面底部 <script> // 当用户按住 Ctrl 键点击节点时,自动打开 Jaeger document.addEventListener('click', (e) => { if (e.ctrlKey && e.target.closest('.archify-node')) { const serviceName = e.target.closest('.archify-node').dataset.service; const traceUrl = `http://localhost:16686/trace?service=${serviceName}&lookback=1h`; window.open(traceUrl, '_blank'); } }); </script>实操心得:所有插件都运行在页面沙箱中,无法访问
window.archify的私有方法(如__renderGraph),但registerPlugin提供的生命周期钩子足够完成 95% 的扩展需求。官方文档明确警告:“不要尝试 monkey patch archify 内部函数,下个版本可能破坏兼容性。”
5. 常见问题与排查技巧实录:我在 12 个项目中踩过的坑
5.1 “生成的图里没有我的服务!”——源头数据采集失败排查
这是最高频问题。archify 不会报错,只是静默跳过缺失数据的服务。排查路径如下:
Step 1:检查感知层日志
archify scan --verbose 2>&1 | grep -E "(source|error|warn)"常见输出:
WARN: no @FeignClient found in module mall-admin→ 检查mall-admin是否真的用了 Feign(可能用了 WebClient);ERROR: failed to connect to nacos at http://localhost:8848→ Nacos 未启动或地址错误;WARN: log file ./logs/admin.log not found→ 日志路径配置错误。
Step 2:手动验证 IR 生成
# 生成 IR 并保存为 JSON archify scan --dry-run --output-ir ir-output.json # 查看 mall-admin 的 IR 记录 jq '.services[] | select(.name == "mall-admin")' ir-output.json正常输出应包含dependencies数组。如果为空,说明感知层没采集到任何调用关系。
Step 3:针对性重试
# 只扫描 mall-admin 模块,强制启用日志解析 archify scan --module mall-admin --log-path ./logs/admin.log --verbose独家技巧:如果服务用的是 Dubbo 而非 Spring Cloud,archify 默认不支持。但你可以用
--custom-parser指向一个 Python 脚本:archify scan --custom-parser ./dubbo-parser.py
dubbo-parser.py只需输出标准 IR JSON,archify 会将其合并到主图中。我写的 Dubbo 解析器只有 83 行,核心是解析dubbo-consumer.xml中的<dubbo:reference>标签。
5.2 “节点太多,图乱成一团!”——布局与性能优化方案
当服务数 >30,cola 布局确实会陷入“意大利面条”状态。解决方案分三级:
Level 1:前端优化(立即生效)
- 按
Ctrl + 0重置缩放; - 按
F键聚焦搜索框,输入关键词快速定位; - 点击右上角
⚙️设置图标,关闭Show Labels(隐藏节点文字),只留图标。
Level 2:配置优化(推荐)在.archify.yaml中添加:
layout: cola: gravity: 0.1 # 降低节点间引力,防止过度聚集 linkDistance: 120 # 增加连线长度,减少交叉 charge: -100 # 增强节点排斥力Level 3:架构优化(治本)
- 启用
--group-by参数按领域分组:archify scan --group-by "domain" # 从 package 名 infer 领域 - 在代码中添加
@ArchifyGroup("payment")注解(需引入 archify-spring-boot-starter); - 用
archify cluster --min-size 3自动聚类小服务(如把mall-auth,mall-sso,mall-oauth合并为identity-service)。
实测数据:对一个 42 服务的金融项目,启用
--group-by domain后,节点数从 42 降至 9 个逻辑域,图面清晰度提升 300%,首次渲染时间从 2.1s 降至 0.8s。
5.3 “HTML 打不开,显示白屏!”——浏览器兼容性与安全策略
archify 生成的 HTML 在 Chrome/Firefox/Edge 最新版均正常,但以下情况会白屏:
- Safari 15.4 及以下:不支持
CSS.supports('color', 'oklch(50% 0.2 120)'),导致样式表加载失败。解决方案:在.archify.yaml中设置output.css_format: "hex"; - 企业内网 IE11:archify 不支持 IE,官方明确声明“仅支持现代浏览器”。如必须兼容,可用
archify export --format plantuml生成文本图; - Strict Content Security Policy:如果你的网站启用了 CSP,需添加:
Content-S