架构可视化的难点,从来不是"画出好看的图",而是"让图与系统真实一致,并且这种一致性可被机器校验、可被人生信"。
一旦把目标从"出图"改写成"出可追溯的图",很多设计决策就自动清晰了:该按什么维度组织能力、图该用什么格式、AI 生成的东西谁来把关、这些资产如何分发复用。我们把这套东西收敛成四层,从抽象到落地依次是:
| 层 | 一句话 | 解决的问题 |
|---|---|---|
| ① 切分层 | 按场景组织技能,不按工具/格式 | 能力边界稳定,AI 每次理解一致 |
| ② 证据层 | 每个节点/边都锚定代码与运行证据 | 图不再会撒谎 |
| ③ 表达层 | 架构即代码,三格式各归其位 | 图可版本、可 diff、可再生 |
| ④ 把关层 | 确定性校验 + 本地预览收口 | AI 负责生成,工具负责否决 |
下面逐层拆开。
① 切分层:别按"工具"想,按"场景"想
大多数团队做"架构可视化工具集",第一种冲动是按输出格式 切:mermaid-skill、graphviz-skill、plantuml-skill。第二种冲动是按实现步骤 切:建模 → 渲染 → 校验。
这两种切法在 AI 时代都会翻车。因为它们把"用户到底要解决什么问题"这条主线切断了,取而代之的是内部实现细节------而内部细节恰恰最该被封装起来。
我们在选型评估里对比过精选插件包的组织方式,得到一条铁律:
架构领域应暴露"场景技能",而不是为每种图类型或编程语言各开一个技能。C4、Graphviz、输出格式、证据校验与图表预览都是共享能力。
于是这个插件最终收敛成 13 个技能,形态严格 MECE:
#mermaid-svg-681yQHBWbx2Sehaj{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-681yQHBWbx2Sehaj .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-681yQHBWbx2Sehaj .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-681yQHBWbx2Sehaj .error-icon{fill:#552222;}#mermaid-svg-681yQHBWbx2Sehaj .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-681yQHBWbx2Sehaj .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-681yQHBWbx2Sehaj .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-681yQHBWbx2Sehaj .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-681yQHBWbx2Sehaj .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-681yQHBWbx2Sehaj .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-681yQHBWbx2Sehaj .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-681yQHBWbx2Sehaj .marker{fill:#333333;stroke:#333333;}#mermaid-svg-681yQHBWbx2Sehaj .marker.cross{stroke:#333333;}#mermaid-svg-681yQHBWbx2Sehaj svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-681yQHBWbx2Sehaj p{margin:0;}#mermaid-svg-681yQHBWbx2Sehaj .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-681yQHBWbx2Sehaj .cluster-label text{fill:#333;}#mermaid-svg-681yQHBWbx2Sehaj .cluster-label span{color:#333;}#mermaid-svg-681yQHBWbx2Sehaj .cluster-label span p{background-color:transparent;}#mermaid-svg-681yQHBWbx2Sehaj .label text,#mermaid-svg-681yQHBWbx2Sehaj span{fill:#333;color:#333;}#mermaid-svg-681yQHBWbx2Sehaj .node rect,#mermaid-svg-681yQHBWbx2Sehaj .node circle,#mermaid-svg-681yQHBWbx2Sehaj .node ellipse,#mermaid-svg-681yQHBWbx2Sehaj .node polygon,#mermaid-svg-681yQHBWbx2Sehaj .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-681yQHBWbx2Sehaj .rough-node .label text,#mermaid-svg-681yQHBWbx2Sehaj .node .label text,#mermaid-svg-681yQHBWbx2Sehaj .image-shape .label,#mermaid-svg-681yQHBWbx2Sehaj .icon-shape .label{text-anchor:middle;}#mermaid-svg-681yQHBWbx2Sehaj .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-681yQHBWbx2Sehaj .rough-node .label,#mermaid-svg-681yQHBWbx2Sehaj .node .label,#mermaid-svg-681yQHBWbx2Sehaj .image-shape .label,#mermaid-svg-681yQHBWbx2Sehaj .icon-shape .label{text-align:center;}#mermaid-svg-681yQHBWbx2Sehaj .node.clickable{cursor:pointer;}#mermaid-svg-681yQHBWbx2Sehaj .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-681yQHBWbx2Sehaj .arrowheadPath{fill:#333333;}#mermaid-svg-681yQHBWbx2Sehaj .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-681yQHBWbx2Sehaj .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-681yQHBWbx2Sehaj .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-681yQHBWbx2Sehaj .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-681yQHBWbx2Sehaj .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-681yQHBWbx2Sehaj .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-681yQHBWbx2Sehaj .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-681yQHBWbx2Sehaj .cluster text{fill:#333;}#mermaid-svg-681yQHBWbx2Sehaj .cluster span{color:#333;}#mermaid-svg-681yQHBWbx2Sehaj div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-681yQHBWbx2Sehaj .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-681yQHBWbx2Sehaj rect.text{fill:none;stroke-width:0;}#mermaid-svg-681yQHBWbx2Sehaj .icon-shape,#mermaid-svg-681yQHBWbx2Sehaj .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-681yQHBWbx2Sehaj .icon-shape p,#mermaid-svg-681yQHBWbx2Sehaj .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-681yQHBWbx2Sehaj .icon-shape .label rect,#mermaid-svg-681yQHBWbx2Sehaj .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-681yQHBWbx2Sehaj .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-681yQHBWbx2Sehaj .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-681yQHBWbx2Sehaj :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} explore
(路由器 / 探索前门)
场景技能层
system-modeler 结构
flow-visualizer 流程
dependency-impact 依赖影响
deployment-topology 部署
evolution-planner 演进
risk-quality 评审
legacy-visualizer 遗留
communicator 沟通
architecture-health 健康度
共享基础能力
c4model 建模
graphviz 布局
drawio 可编辑交付
关键点是:每个场景技能回答的是一个不同的架构问题------存在什么(结构)、工作怎么流转(流程)、改这一下会波及谁(依赖影响)、它在哪运行(部署)、它该往哪变(演进)、它有没有风险(评审)、证据稀缺的破系统怎么治(遗留)、怎么向某类受众讲清楚(沟通)、这些产物还是不是活的(健康度)。它们不重叠、合起来不遗漏。
而 c4model、graphviz、drawio 这些是被场景调用的共享能力,不是并列入口。就像数据分析插件把"图表/校验/报告"当共享件、把"探索→构建→审计"当场景流一样。
为什么这条对 AI 尤其重要? 因为模型每一次调用都是冷启动。你把"格式"当顶层抽象,等于逼模型每次重新回答"这个任务该用 mermaid 还是 graphviz",决策面越不稳定,输出越飘。稳定的场景边界 = 稳定的提示词语义 = 可复现的产出。 这是把领域知识"喂"给 AI 时最容易被忽略、却回报最高的一步。
② 证据层:图会撒谎,除非它锚定证据
架构图最大的谎言是"看起来很确定"。一张 Order-API → Payment 的箭头,究竟是代码里真有这个调用、还是画的人凭印象连的?传统白板图回答不了,AI 生成的图更回答不了------它太擅长画一条自信满满、实则无据的边了。
我们的解法是把证据模型做成所有技能的统一约定。每个节点、每条边都不是"一个框/一条线",而是一条带出处、带置信度的记录:
json
{
"id": "edge.order-api-to-payment",
"from": "service.order-api",
"to": "service.payment-provider",
"type": "calls",
"protocol": "gRPC",
"sync": "async",
"sourceRefs": ["src/order/paymentClient.ts"],
"confidence": "high"
}
sourceRefs 把一条关系钉回源码/配置/契约的具体位置,confidence 诚实地标出"这条是查证的还是猜的"。证据分七类:
| 证据类型 | 例子 |
|---|---|
| code 代码 | import、handler、client、repository、注解、测试 |
| contract 契约 | OpenAPI、AsyncAPI、Protobuf、事件 schema |
| config 配置 | 环境变量、服务发现、路由、feature flag、包清单 |
| data 数据 | DB schema、迁移、SQL、ORM 映射、血缘任务 |
| runtime 运行时 | 日志、链路追踪、指标、注册中心、部署清单 |
| document 文档 | README、ADR、设计文档、复盘 |
| human-assumption 假设 | 访谈/意图,必须显式标注为假设 |
光有字段还不够,得有硬规则 兜底,否则 sourceRefs 会沦为装饰。我们的校验规则:
- 现状节点:至少一条
high或medium置信的证据来源,否则不许画成"现状"。 - 目标态节点:可以没有代码证据,但必须 打上
target/proposed状态------不能拿"想去的地方"冒充"在的地方"。 - 只存在于运行时的关系:未经确认,不得当作静态设计来画。
- 推断出的关系:置信度调低,并附带一条验证任务。
#mermaid-svg-7ml636qxrRcaxVpl{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-7ml636qxrRcaxVpl .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-7ml636qxrRcaxVpl .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-7ml636qxrRcaxVpl .error-icon{fill:#552222;}#mermaid-svg-7ml636qxrRcaxVpl .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-7ml636qxrRcaxVpl .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-7ml636qxrRcaxVpl .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-7ml636qxrRcaxVpl .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-7ml636qxrRcaxVpl .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-7ml636qxrRcaxVpl .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-7ml636qxrRcaxVpl .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-7ml636qxrRcaxVpl .marker{fill:#333333;stroke:#333333;}#mermaid-svg-7ml636qxrRcaxVpl .marker.cross{stroke:#333333;}#mermaid-svg-7ml636qxrRcaxVpl svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-7ml636qxrRcaxVpl p{margin:0;}#mermaid-svg-7ml636qxrRcaxVpl .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-7ml636qxrRcaxVpl .cluster-label text{fill:#333;}#mermaid-svg-7ml636qxrRcaxVpl .cluster-label span{color:#333;}#mermaid-svg-7ml636qxrRcaxVpl .cluster-label span p{background-color:transparent;}#mermaid-svg-7ml636qxrRcaxVpl .label text,#mermaid-svg-7ml636qxrRcaxVpl span{fill:#333;color:#333;}#mermaid-svg-7ml636qxrRcaxVpl .node rect,#mermaid-svg-7ml636qxrRcaxVpl .node circle,#mermaid-svg-7ml636qxrRcaxVpl .node ellipse,#mermaid-svg-7ml636qxrRcaxVpl .node polygon,#mermaid-svg-7ml636qxrRcaxVpl .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-7ml636qxrRcaxVpl .rough-node .label text,#mermaid-svg-7ml636qxrRcaxVpl .node .label text,#mermaid-svg-7ml636qxrRcaxVpl .image-shape .label,#mermaid-svg-7ml636qxrRcaxVpl .icon-shape .label{text-anchor:middle;}#mermaid-svg-7ml636qxrRcaxVpl .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-7ml636qxrRcaxVpl .rough-node .label,#mermaid-svg-7ml636qxrRcaxVpl .node .label,#mermaid-svg-7ml636qxrRcaxVpl .image-shape .label,#mermaid-svg-7ml636qxrRcaxVpl .icon-shape .label{text-align:center;}#mermaid-svg-7ml636qxrRcaxVpl .node.clickable{cursor:pointer;}#mermaid-svg-7ml636qxrRcaxVpl .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-7ml636qxrRcaxVpl .arrowheadPath{fill:#333333;}#mermaid-svg-7ml636qxrRcaxVpl .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-7ml636qxrRcaxVpl .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-7ml636qxrRcaxVpl .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-7ml636qxrRcaxVpl .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-7ml636qxrRcaxVpl .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-7ml636qxrRcaxVpl .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-7ml636qxrRcaxVpl .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-7ml636qxrRcaxVpl .cluster text{fill:#333;}#mermaid-svg-7ml636qxrRcaxVpl .cluster span{color:#333;}#mermaid-svg-7ml636qxrRcaxVpl div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-7ml636qxrRcaxVpl .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-7ml636qxrRcaxVpl rect.text{fill:none;stroke-width:0;}#mermaid-svg-7ml636qxrRcaxVpl .icon-shape,#mermaid-svg-7ml636qxrRcaxVpl .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-7ml636qxrRcaxVpl .icon-shape p,#mermaid-svg-7ml636qxrRcaxVpl .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-7ml636qxrRcaxVpl .icon-shape .label rect,#mermaid-svg-7ml636qxrRcaxVpl .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-7ml636qxrRcaxVpl .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-7ml636qxrRcaxVpl .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-7ml636qxrRcaxVpl :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} sourceRefs + confidence
生成
CI: --require-source-refs
否
是
证据
code/config/runtime/doc
架构模型 JSON
C4 / DOT / Mermaid 视图
校验通过?
拒绝合入
可信视图 / 报告
这一层是整篇文章的技术内核。架构图从"意见"升级为"证据的可视图",靠的就是节点上那两个字段和那四条规则。把它交给 AI 时尤其关键:你可以容忍模型画得丑,但绝不能容忍它把猜测画成事实------而置信度字段就是那道强制它自证的闸门。
③ 表达层:让图成为代码,而不是成为附件
确定了切分维度和证据要求,下一个问题很实际:图用什么形式存?
答案是架构即代码(Architecture as Code)------图源文件进版本库、可 diff、可被 CI 重渲染,永远不把导出的图片当事实来源。但"用哪门语言描述"要按受众和复杂度选,我们沉淀成一张选型表:
| 需求 | 首选格式 |
|---|---|
| C4 系统全景 / 上下文 / 容器 / 组件 | Structurizr DSL |
| 稠密依赖、影响、数据血缘、遗留地图 | Graphviz DOT |
| Markdown 内嵌的轻量草图、简单状态 | Mermaid |
| 细粒度服务调用时序 | PlantUML 时序图 |
| 研讨会、干系人现场共创 | Excalidraw(不作权威来源) |
| 交付方需要手工编辑 | Draw.io / diagrams.net(派生产物) |
| 出版 / 幻灯片 | SVG + PNG 导出(派生产物) |
三个格式不是"任选一个",而是按图的任务分工:C4 关系和"活架构"交给 Structurizr;一旦规模/密度大到 Mermaid 都糊成一团,果断上 DOT;只是想在 README 里嵌张小流程图,Mermaid 最省事。
一条反复被违反、值得单独钉在墙上的纪律------导出检查清单:
- 源文件与渲染文件放在一起,附一份 README 说明如何重新生成。
- 记录源模型、生成日期、证据覆盖度、已知局限。
- 不要手工编辑导出的 SVG/PNG,编辑要走回源模型。
- 不要把手工改过的 Draw.io 当作权威变更------除非证据模型同步更新。
否则你会得到一堆"看起来是最新版、其实三周前就没人维护"的漂亮图片,重新跌回白板图的老坑。
④ 把关层:AI 负责生成,工具负责否决
前三层定了"画什么、按什么画、用什么画",最后一层回答"画错了怎么办"。在 AI 参与的生产线上,这一层的价值被急剧放大:模型越强,产出越快,你越需要一道不带感情的确定性关卡。
我们的做法是两条:
其一,确定性校验。 每个场景工作流产出模型 JSON 与图源文件后,跑统一校验:JSON 是否可解析、sourceRefs 是否齐、视图是否偏离模型、证据覆盖度是否达标。真实架构模型要用 --source-refs error --require-source-refs 强制------缺证据不是警告,是失败。
其二,本地预览收口。 我们在插件里注册一个 HTTP 路由,把三类文本图产物(Mermaid / DOT / Structurizr DSL)在浏览器里渲染出来做目视检查:
http://127.0.0.1:8088/api/arch-preview/view?path=/abs/path/system-model.mmd
这里有个克制的工程决策 值得一提:我们明确划了边界------只提供这三类文本图预览,不去造第三种自定义架构预览器 (带 sourceRef 下钻、现状/目标 diff 回放、节点绑定的风险整改看板等)。因为那些"很酷但昂贵"的能力,现阶段用"模型 JSON + Markdown 报告"就能表达,不该为它单开一条前端战线。先想清楚哪些不做,比急着做什么更能体现工程成熟度。
还有一条贯穿性原则:能不写脚本就不写脚本 。整个插件几乎不内置语言提取器、模型生成器或转换流水线。理由很硬------仓库架构高度依赖用户的语言、框架、部署栈和领域词汇,写死的提取器很快过时且覆盖面窄;默认工作流是让 AI 读完工程证据后直接产出所需产物,脚本只作为"维护关卡"(校验包、示例冒烟)存在。AI 时代,很多曾经必须写工具的能力,现在是"给模型足够的证据 + 明确的把关"就够了。
把它做成能分发的资产:一次插件化的踩坑实录
方法论再好,锁在自己脑子里就等于没有。我们把这个技能集做成了一个 QwenPaw 通用插件 (plugin.json + plugin.py + 13 个 SKILL.md),让它能被一键安装、跨工作区分发。这里有两个一手细节,值得给准备做同类事的人提个醒。
坑一:技能不会"自动被发现"。 从旧的约定式平台(放个 skills/ 目录就自动加载)移植到 QwenPaw 时,最容易漏的是------QwenPaw 加载插件技能的唯一入口是显式调用:
python
def register(self, api: PluginApi) -> None:
if SKILLS_DIR.is_dir():
api.register_skill_provider(
skills_dir=SKILLS_DIR, # 内含 13 个 SKILL.md
enabled_by_default=True,
)
api.register_http_router(build_router(), prefix="/arch-preview", ...)
不写 register_skill_provider,13 个技能一个都不会生效------它内部注册 startup hook,才把技能复制进各 workspace 并登记清单。声明了 capabilities: ["skill"] 不代表宿主会自动装,能力声明只是元数据。
坑二:测试全绿 ≠ 装得上。 我们的集成测试是 mock 一个假 api、直接调 register(),全绿------但它绕过了宿主 loader 从 entry_point 定位插件对象 这一步。真正决定能否安装的是这段约定:loader 用 getattr(module, "plugin", None) 取实例、再调它的 register。所以 plugin.py 末尾那句 plugin = ArchitectureVisualizationPlugin() 不是可选的样板,它是加载链路的接口契约。发布前必须补一层"解压→校验→模拟定位"的验证,别只信单元测试。
顺带把发布前的一致性清单也固化下来(这次全过才敢出包):版本号目录/plugin.json/CHANGELOG 三处对齐、技能数量全文一致、路由前缀代码与文档对齐、无移植残留、文件权限统一、宿主版本落在 >=min, <max(左闭右开)区间内。
回到架构师:这四层其实可以搬走
如果你只打算记住一件事,别记那个插件,记这个顺序:
- 先问场景,再谈工具------按"用户要解决什么问题"切分能力,把格式/渲染这类实现细节压成共享件。
- 给每个结论配出处 ------
sourceRefs+confidence+ 硬校验,是区分"意见"和"证据"的唯一可靠手段。 - 让图成为代码------进版本库、可再生,永远不拿导出图片当事实来源。
- 用确定性关卡对冲 AI 的速度------AI 负责生成,工具负责否决;并想清楚哪些坚决不做。
这四层不是可视化专属。任何"要把领域知识沉淀成 AI 可执行、可信赖的技能"的场景------数据分析、代码评审、方案设计------都是同一套骨架:稳定的抽象边界 + 可追溯的证据 + 代码化的表达 + 确定性的把关。 架构图只是它第一个被点亮的战场。