AI Agent自动生成架构图:用Skill封装代码分析全流程
画架构图这件事看起来简单做起来却非常消耗精力。模块少的时候还能手动拖几个框一旦代码库到了几十个服务、上百张表、多层依赖关系手工维护一张架构图几乎是不可能的任务。更麻烦的是代码每天都在变架构图画完就已经过时了。最近在项目里尝试了一种新思路把“读代码、理关系、画图”这套流程封装成一个 Skill交给 AI Agent 自动执行。AI 自己遍历代码目录、分析模块依赖、识别分层关系然后直接输出一张可用的架构图。整个过程不需要手动拖框也不需要反复截图沟通。这篇文章就把这套方法的完整思路、Skill 工程结构、关键代码和常见坑点整理出来希望能帮你摆脱“画图五分钟维护两小时”的困境。1. 背景为什么“手动拖框”不是好方案1.1 手动画架构图的三个痛点先聊聊手动画架构图最常见的三个问题。第一信息滞后。架构图通常是阶段性产物开发过程中模块拆分、接口调整、依赖变化非常频繁图上的内容很快就会和真实代码脱节。团队里一旦换了维护人图基本就没人敢动了。第二粒度难以把握。画太细图会变成一张密密麻麻的蜘蛛网没人愿意看画太粗又失去了架构图的价值。手动画图时粒度的取舍完全依赖个人经验不同人画出来的图风格差异极大。第三沟通成本高。架构评审、新人 onboarding、跨团队协作时都需要有人花时间讲解“这张图是怎么来的”。如果图本身不能反映代码真实结构讲解越多误导越深。1.2 为什么选择“让 AI 读代码出图”既然手动画图有这么多问题自然的想法是能不能让工具自动生成架构图传统的静态分析工具确实可以生成调用关系图但它们的输出通常非常机械缺少分层、边界、模块职责这类高层视角。而架构图的核心价值恰恰在于从高层理解系统而不是罗列所有调用细节。AI Agent 的优势在于它可以结合代码内容做语义理解知道哪个模块是入口、哪个模块是基础设施、哪些类属于领域层、哪些属于应用层。它不需要你手动指定关系而是通过阅读代码自动判断。把这一套判断逻辑沉淀成 Skill 之后AI 就能在每次代码变更后快速重新生成图实现“架构图跟随代码更新”的效果。1.3 适用场景这种方案比较适合以下场景接手一个不熟悉的老项目想快速了解模块结构。微服务改造前梳理现有服务之间的依赖关系。代码评审前生成当前分支的模块影响范围图。团队文档建设定期自动更新架构图。如果你的项目非常小只有几个文件手动画图可能更快。但一旦代码库达到中大型规模让 AI 边读代码边出图的效率优势就非常明显了。2. 整体思路AI 读代码出架构图的四个阶段要让 AI 自动生成架构图不能只写一句“帮我画架构图”就完事。清晰、可靠的流程应该拆成四个阶段每个阶段都有明确的输入和输出。2.1 阶段一代码库探测与上下文收集AI 需要先知道代码库里有哪些内容。这一阶段的核心是建立代码地图包括项目目录结构。各模块的入口文件。配置文件、构建文件、部署文件。每个目录的职责说明。这一阶段不需要 AI 读完全部代码而是通过目录结构和关键文件快速建立整体认知。2.2 阶段二模块与依赖建模在了解代码地图后AI 需要深入代码提取模块之间的依赖关系。这里有两个层次静态依赖import、require、依赖注入、接口调用。语义依赖某个模块在业务逻辑上依赖另一个模块提供的能力。静态依赖可以通过脚本辅助提取语义依赖则需要 AI 阅读代码后判断。实际操作中通常是脚本提供候选依赖列表AI 负责筛选和归类。2.3 阶段三分层与边界判断架构图不能只是“谁依赖谁”还要回答“为什么这么分层”。AI 需要判断哪些模块属于入口层Controller、API、界面。哪些模块属于应用层用例、服务编排。哪些模块属于领域层核心业务逻辑。哪些模块属于基础设施层数据库、消息队列、第三方 SDK。分层判断是 AI 读代码出图的核心价值也是最容易出现偏差的地方。2.4 阶段四图渲染与输出建模完成后AI 需要把结果输出为某个具体格式的架构图。常见的选择有格式特点适用场景Mermaid文本即图支持 Markdown 内嵌文档、Wiki、GitLab/GitHubPlantUML类 Java 语法适合 UML 图正式设计文档D2语法简洁布局美观新项目首选Draw.ioXML可继续手动拖拽编辑团队有手动编辑需求ASCII 图纯文本适合快速预览终端环境、临时沟通推荐优先支持 Mermaid 和 Draw.io 两种格式Mermaid 适合自动生成和版本管理Draw.io 适合需要人工继续微调的团队。3. 认识 Skill一个能被 AI 加载的“技能包”3.1 Skill 是什么这里说的 Skill是 AI Agent 生态中的一种可复用能力封装。简单理解Skill 是一组带说明文件、提示词脚本和辅助工具的目录AI 在对话中会根据用户意图自动加载并执行。它和普通 Prompt 的区别在于Prompt 只有文字描述Skill 还可以携带脚本、模板、数据文件。Prompt 每次都要重新写Skill 可以重复使用、跨项目共享。Prompt 依赖用户手动提供上下文Skill 可以主动调用命令读取代码、执行扫描。对于“AI 读代码出架构图”这个需求Skill 是一个非常合适的载体把读代码的策略、依赖提取脚本、出图标准全部封装起来使用者只需要触发一次。3.2 Skill 的目录结构目前主流 AI 编程工具的 Skill 目录一般遵循这样的规范skills/ └── archi-mapper/ ├── SKILL.md # 技能说明AI 首先读取的入口文件 ├── prompts/ # 分步执行的提示词模板 │ ├── 01-scan-code.md │ ├── 02-model-deps.md │ └── 03-render-diagram.md └── scripts/ # 可执行的辅助脚本 ├── scan_imports.py └── build_tree.py3.3 SKILL.md 的关键作用SKILL.md的作用是让 AI 判断“什么时候该用这个技能”以及“怎么按步骤执行”。它通常分为两部分元数据区声明技能名称、描述、触发关键词。正文区说明前置条件、执行步骤、输出规范、注意事项。当用户在对话中说出“画一下这个项目的架构图”时AI 会匹配技能描述然后加载SKILL.md中的执行步骤。3.4 为什么需要配套脚本有人可能会问AI 本身就能读代码为什么还要写脚本原因是效率和准确性。AI 的上下文窗口是有限的。让 AI 逐个文件读代码既慢又容易遗漏。通过脚本先做一轮机械扫描得到目录树、依赖列表等结构化数据再把这些数据交给 AI 做语义分析可以大幅提高准确率。脚本是 AI 的“眼睛”Prompt 是 AI 的“大脑”。两者配合才能稳定输出高质量的架构图。4. 实战从零编写架构图生成 Skill下面进入实战环节。我们以 Claude Code 环境为例写一个名为archi-mapper的 Skill目标是让 AI 读取一个 Python 项目的代码自动生成 Mermaid 格式的架构图。4.1 创建目录结构mkdir -p ~/.claude/skills/archi-mapper mkdir -p ~/.claude/skills/archi-mapper/prompts mkdir -p ~/.claude/skills/archi-mapper/scripts如果你使用的是项目级 Skill也可以将archi-mapper放在项目的.claude/skills/目录下这样只有该项目会加载该技能。4.2 编写 SKILL.md文件路径~/.claude/skills/archi-mapper/SKILL.md--- name: archi-mapper description: 读取当前代码仓库的目录结构和模块依赖生成架构图。当用户提到画架构图生成依赖图梳理模块关系分析项目结构时自动触发。 --- # 架构图自动生成技能 这个技能帮助你快速理解一个代码仓库并输出可视化的架构图。 ## 前置条件 - 当前目录是一个代码仓库或者用户指定了代码路径。 - 代码语言需要能被 Python 脚本扫描支持常见语言重点适配 Python/Java/TypeScript。 ## 执行步骤 1. 使用 scan_imports.py 扫描代码仓库获取文件列表和依赖关系。 2. 阅读扫描结果结合项目 README 和关键配置文件判断模块边界。 3. 将模块按层次归类入口层、应用层、领域层、基础设施层。 4. 输出以下两种产物 - architecture.json结构化架构描述。 - architecture.md包含 Mermaid 架构图的 Markdown 文档。 ## 输出规范 - 架构图必须分层展示同一层的模块放在一个分组中。 - 依赖关系必须注明方向避免出现循环依赖环。 - 如果存在循环依赖在输出报告中额外标注警告。 - 模块命名优先使用代码中的实际包名或目录名。这份SKILL.md遵循了“少量元数据、清晰步骤、明确输出规范”的原则。AI 加载这个文件后就知道自己应该先做什么、怎么做、最终输出什么。4.3 编写代码扫描脚本为了让 AI 高效获取代码结构我们需要一个 Python 脚本用于提取目录树和 import 依赖关系。文件路径~/.claude/skills/archi-mapper/scripts/scan_imports.py#!/usr/bin/env python3 import ast import json import os import sys from collections import defaultdict from pathlib import Path def should_ignore(path: Path) - bool: 判断是否应该跳过该文件或目录。 ignored { .git, __pycache__, node_modules, venv, .venv, dist, build, .idea, .vscode, target } parts set(path.parts) return bool(parts ignored) or path.name.startswith(.) def scan_python_imports(root: Path) - dict: 扫描 Python 文件的 import 依赖。 deps defaultdict(set) for path in root.rglob(*.py): if should_ignore(path): continue try: tree ast.parse(path.read_text(encodingutf-8)) except Exception: continue for node in ast.walk(tree): if isinstance(node, ast.Import): for alias in node.names: deps[str(path)].add(alias.name.split(.)[0]) elif isinstance(node, ast.ImportFrom): if node.module: deps[str(path)].add(node.module.split(.)[0]) return {k: sorted(v) for k, v in deps.items()} def build_tree(root: Path, max_depth: int 3) - dict: 构建目录树限制层数避免输出过大。 result {} try: children sorted( [p for p in root.iterdir() if not should_ignore(p)], keylambda p: (p.is_file(), p.name) ) except PermissionError: return result for child in children: if child.is_dir(): if max_depth 0: result[child.name] build_tree(child, max_depth - 1) else: result.setdefault(__files__, []).append(child.name) return result def main(): root Path(sys.argv[1] if len(sys.argv) 1 else .) output { root: str(root.resolve()), tree: build_tree(root, max_depth3), imports: scan_python_imports(root), } print(json.dumps(output, ensure_asciiFalse, indent2)) if __name__ __main__: main()这个脚本做的事情很明确build_tree()生成最多三层的目录树避免把整个项目结构一次性塞给 AI。scan_python_imports()用 Python 自带的ast模块解析 import 语句提取文件级依赖。最终输出 JSON结构化数据比原始代码更适合 AI 分析。在命令行中运行cd /path/to/your/project python3 ~/.claude/skills/archi-mapper/scripts/scan_imports.py . code-map.json预期输出类似{ root: /path/to/your/project, tree: { app: { __files__: [main.py, config.py], services: { __files__: [order_service.py, user_service.py] } }, domain: { __files__: [models.py, exceptions.py] } }, imports: { app/main.py: [config, services], app/services/order_service.py: [domain] } }有了这份 JSONAI 不需要浏览全部代码就能了解到“谁依赖谁”的骨架信息。4.4 编写分步执行 Prompt在prompts/目录下我们准备三个步骤提示词。AI 会按照SKILL.md中声明的顺序读取并执行这些提示词。文件路径~/.claude/skills/archi-mapper/prompts/01-scan-code.md# 步骤一扫描代码结构 运行以下命令获取项目的代码地图 bash python3 ~/.claude/skills/archi-mapper/scripts/scan_imports.py 项目根目录 code-map.json读取code-map.json后确认以下信息项目的顶层目录有哪些分别承担什么职责。哪些目录属于入口层哪些属于服务层哪些属于数据层。关键入口文件在哪里如main.py、application.py、index.js。不要盲目阅读所有代码只阅读与模块边界判断相关的关键文件。文件路径~/.claude/skills/archi-mapper/prompts/02-model-deps.md markdown # 步骤二建模模块依赖 基于 code-map.json 的 import 关系结合关键模块的代码阅读结果整理出模块依赖列表。 输出要求 - 每个模块一个节点使用真实目录名或包名。 - 每条依赖必须写明方向A - B 表示 A 依赖 B。 - 筛掉无关的第三方库依赖只保留项目内部模块关系。 - 将依赖按层次归类入口层、应用层、领域层、基础设施层。 如果发现循环依赖单独列出并在最终报告中给出警告说明。文件路径~/.claude/skills/archi-mapper/prompts/03-render-diagram.md# 步骤三渲染架构图 根据上一步建立的模型输出 architecture.json 和 architecture.md。 architecture.json 结构示例 json { modules: [ { name: app, layer: presentation, description: HTTP 入口和路由配置 } ], dependencies: [ { from: app, to: services } ] }architecture.md中必须包含一段 Mermaid 代码块使用 subgraph 分组表示层次箭头表示依赖方向。示例片段AI 需要按实际项目调整graph TD subgraph presentation[入口层] app[app] end subgraph application[应用层] services[services] end subgraph domain[领域层] domain[domain] end app -- services services -- domain注意如果项目规模较大按功能域拆分成多张子图不要画一张超大图。图中节点不超过 20 个超过时优先按模块聚合。最后必须补充一段文字说明解释各层职责和关键依赖方向。### 4.5 在 Claude Code 中调用与验证 安装完成后在 Claude Code 会话中输入 text 请帮我梳理一下当前项目的架构并生成架构图。AI 检测到“架构图”关键词后会自动加载archi-mapper技能然后依次执行扫描、建模、渲染三个步骤。如果一切正常当前项目目录下会出现architecture.json architecture.md打开architecture.md就能看到带 Mermaid 架构图的文档。在支持 Mermaid 渲染的编辑器或 GitLab/GitHub 中会直接显示为图形。整个过程中你不需要手动指定任何依赖关系也不需要拖拽任何图形元素。AI 读完代码后直接出图。5. 让 AI 读懂代码的三个关键技巧5.1 控制上下文不要一次性喂全量代码AI 的上下文窗口是有限的。一个中大型项目可能有几千个文件全部塞进去既不现实也没必要。正确做法是用脚本把目录树和依赖关系压缩成 JSON。只让 AI 阅读关键文件例如入口文件、核心模型、配置中心。约定扫描深度避免把第三方源码、生成代码、测试代码也纳入分析。换句话说脚本负责广度AI 负责深度。脚本保证不遗漏大结构AI 集中精力理解关键节点的语义。5.2 让 AI 输出结构化中间结果架构图生成不是一步到位的。中间结果越结构化最终的图就越稳定。这也是我们在prompts中强制要求输出architecture.json的原因。结构化结果有三个好处便于人工审查看 JSON 就能知道 AI 对模块边界的判断是否正确。便于自动化CI 流程可以解析 JSON自动生成架构图。便于后续对话用户可以在 JSON 基础上提出调整不需要让 AI 重新读一遍代码。建议在 Skill 中明确输出 JSON Schema即使一开始不完美也比让 AI 自由发挥要可靠得多。5.3 为架构图选择标准模型“架构图”这个词太宽泛。AI 生成前最好明确图的类型。常用的有模块图展示顶层模块划分与依赖适合快速概览。分层图展示入口层、应用层、领域层、基础设施层适合介绍系统设计。C4 模型Context上下文、Container容器、Component组件、Code代码适合从多个粒度描述系统。如果团队已经使用了 C4 模型可以在 Skill 中预设 C4 的层级模板让 AI 按 Context 图和 Container 图分别输出。这样生成的图在团队内部有统一标准不会出现“每个人画的风格都不一样”的问题。6. 常见问题与排查思路在实际使用这套 Skill 的过程中可能会遇到一些典型问题这里整理成表格供快速排查。问题现象常见原因解决思路AI 没有自动触发 Skill对话内容未命中描述中的关键词在description中补充更多触发词或手动指定技能名称生成的架构图只有目录树没有依赖关系扫描脚本未成功提取 import检查脚本输出确认 Python 文件语法正确排除文件编码问题依赖关系大量缺失项目使用了动态导入、反射或服务发现在 Prompt 中要求 AI 阅读配置文件补充动态注册的依赖图太大、节点太多项目模块数量超过 AI 的简化阈值在 Prompt 中强制要求按业务域聚合节点或者拆分为多张子图分层判断不准确项目架构本身不规范没有清晰层次结合 README、架构文档、DDD 设计说明进行人工修正并反馈Mermaid 渲染报错节点名包含特殊字符或存在重复节点在 Prompt 中约定节点 ID 使用英文小写加下划线避免中文和空格扫描脚本超时代码库过大或存在超大文件在脚本中加入超时控制和文件大小限制只扫描关键目录循环依赖警告过多测试代码与业务代码未分离在脚本中增加忽略测试目录的规则如果 AI 生成的图和你预期相差较大最好的方式不是反复修改 Prompt而是先修正architecture.json再让 AI 重新渲染。因为 JSON 是中间产物修正它比让 AI 重读代码效率高得多。7. 最佳实践与工程建议7.1 从小项目开始试点不要一上来就在超大项目上测试。建议先在 5 到 10 个模块的中小型项目中试用人工检查 AI 的模块划分和依赖理解是否准确。等提示词和脚本打磨稳定后再逐步扩展到更大的项目。7.2 保留人工复核环节AI 读代码出图再高效也不能完全替代架构师的人工判断。特别是以下场景人工复核至关重要模块边界涉及业务领域知识时。历史遗留代码存在架构腐化时。依赖关系隐藏在异步消息、事件驱动中时。比较推荐的做法是AI 生成初稿架构师审查并修改architecture.json然后将修正后的版本回传给 AI 重新渲染。这样既发挥了 AI 的效率也保留了人的经验。7.3 将架构图纳入版本管理建议把architecture.md、architecture.json以及扫描结果一起提交到 Git 仓库。每次代码变更后可以通过 CI 任务自动更新架构图。这样做的好处是代码评审时可以直观看到改动影响的范围。新人入职后可以快速了解项目全貌。架构图的历史版本可追溯方便复盘架构演进。7.4 为 Skill 增加更多语言支持本文的示例脚本只处理了 Python 的 import。对于 Java 项目可以使用类似思路解析 import 语句对于 TypeScript 项目可以解析 import/require。不需要把脚本写得很完美只要能为 AI 提供“候选依赖列表”即可真正的过滤和归类和判断可以交给 AI 完成。7.5 结合团队规范定制输出每个团队对架构图的规范可能不同。有的团队要求必须包含技术选型有的团队要求标注服务负责人有的团队要求生成 C4 模型。这些都可以通过修改SKILL.md的输出规范和prompts目录中的模板来实现。Skill 的优势正在于此它不是一段固定 Prompt而是一套可以按团队需求持续迭代的工程资产。写在最后让 AI 边读代码边出图核心价值不是“自动生成一张图”而是让架构图真正成为代码库的可视化投影。每一次代码变更后你都能用同样的方式重新生成图保证图与代码同步演化而不是画完就变成历史文物。从工程落地角度看最关键的并不是写一段多复杂的 Prompt而是设计好“脚本扫描 AI 分析 结构化中间产物 最终渲染”这条链路。脚本保障广度AI 负责深度JSON 保留可审查的中间结果最后的 Mermaid 图则承担沟通表达职能。把这个链路封装成 Skill 之后团队里任何人说一句“帮我看下项目架构”就能得到一份相对靠谱的架构图初稿。如果你也想在自己的项目里试试建议从本文的archi-mapper目录结构出发先跑通一个最小的 Python 项目再逐步调整提示词和脚本。过程中遇到架构判断不准的问题记得先修正中间 JSON再重新出图而不是反复让 AI 重读代码。这套方法真正用顺之后你会发现架构图的维护成本终于可以降下来了。

相关新闻

最新新闻

日新闻

周新闻

月新闻