← 返回博客

Understand Anything:一个 33K star 的开源项目,把「读代码」变成了「看地图」

AI工具与基础设施

几个月前我写过一篇关于 CodeGraph 的文章,它用 tree-sitter + SQLite 给 AI 编码代理预建了一个可查询的语义索引。

但如果你注意到那篇文章里读到的用例——“怎么降低代理的探索成本""某个函数被谁调了""改这个会影响什么”——会发现这些问题的提问者始终是 AI 代理,不是人。

有个问题藏在这个叙事里:代理理解代码之后,人的理解怎么办?

当团队新人面对一个 20 万行的代码库,他需要的不是”给我这个函数的调用链”,而是”这个项目到底是干什么的""各模块怎么组织的""我先读什么再读什么”。这些问题,纯结构化的代码索引回答不了。

今天要拆的项目——Understand Anything——切入的就是这个缝隙。

它的 README 里有一句话很有代表性,也成了它的 GitHub 话题标签:

“Graphs that teach > graphs that impress.”

不追求图谱看起来多炫,追求图谱能教会你东西。

这篇文章从技术角度拆一下这个 33K+ star 的项目。


一、核心定位差异

先澄清一个容易混淆的点。

在 AI 编码代理生态里,目前有两类”代码知识图谱”工具,看起来相似,目标用户完全不同:

理解这个定位差异,后面的设计选择就都能串起来了。

Understand Anything 把自己定位为一个 Claude Code 插件,而不是一个 MCP 服务器。安装方式也体现了这一点:

/plugin marketplace add Lum1104/Understand-Anything
/plugin install understand-anything
/understand

它不是代理在后台默默调用的基础设施,而是开发者主动触发的分析工具。


二、架构:LLM + tree-sitter 混合

项目的核心洞察是:纯静态分析能提取”结构”,但提取不了”意图”

一段代码的结构信息——定义了什么函数、导入了哪些模块、调用了什么接口——tree-sitter 可以确定性地解析出来。但”这段代码是做什么用的”、“它为什么存在”、“它跟业务逻辑怎么对应”,代码本身不直接回答这些问题。

Understand Anything 的方案是两层:

第一层:tree-sitter(确定性层)

跟大部分代码分析工具一样,底层用 tree-sitter 把源文件解析成 AST。这层是纯确定性的——同样的输入永远得到同样的输出。提取的内容包括:

一个值得注意的实现细节:在扫描阶段,tree-sitter 会预先解析出一个 importMap(整个项目的导入依赖图),在后续的分析中直接传递给各 agent,避免每个 agent 各自重新推导。

第二层:LLM(语义层)

tree-sitter 做不了的事交给 LLM:读取解析后的结构信息加原始源代码,为每个节点生成:

这个分层的选择涉及一个不那么明显的工程权衡:性能与深度的取舍

纯 tree-sitter 的方法可以在几秒内索引整个代码库,但回答不了”这个文件是用来干嘛的”这种看似普通的问题。纯 LLM 的方法可以生成极其丰富的描述,但在大规模代码库上慢到不可接受,而且成本会指数级上升。

Understand Anything 的折中是:用 tree-sitter 处理可以确定的部分(95% 的代码量),用 LLM 处理需要理解的部分(5% 的推理量)。同时也提供了一个可控的优化——精确到文件指纹的增量更新,第二次运行时跳过未变更的文件。


三、多 Agent 流水线

/understand 命令被设计成一个由 7 个 Agent 组成的流水线:

project-scanner → file-analyzer × N(并行)→ architecture-analyzer → tour-builder → graph-reviewer

1. project-scanner(项目扫描器)

负责文件发现和语言/框架检测。扫描项目目录,排除 node_modules.git 等非相关目录。检测项目使用了哪些语言和技术栈(如 React、Django、FastAPI 等),这些信息之后传递给其他 agent 做针对性解析。

2. file-analyzer(文件分析器)

这是实际的”干活”的 agent。每个源文件被送到一个 file-analyzer 实例,提取函数、类、导入关系,产生图节点和边。

运行方式是批量并行的——最多 5 个文件同时分析,每批 20-30 个文件。支持增量模式,只分析自上次运行后有变化的文件,基于 tree-sitter 计算的文件指纹做变更检测。

3. architecture-analyzer(架构分析器)

在所有文件分析完成后运行。分析项目的整体结构、导入关系图,识别出逻辑架构层。它会回答:

输出结果被用于在图谱中用颜色标记架构层归属。

4. tour-builder(导览生成器)

这是最有”人味”的 agent。它会根据依赖顺序自动生成一个由浅入深的代码库导览——先读什么、再读什么、最后读什么。每个”景点”都配了一段通俗解释。

新人在完全不了解项目的情况下,跑一次 /understand,然后跟着导览走一遍,就能在合理时间内建立起对项目的整体认知。

5. graph-reviewer(图评审器)

默认情况下做内联的确定性验证——检查节点和边的引用完整性、是否有孤立节点、是否有明显缺失的连接。如果加上 --review 参数,则会调用 LLM 做一次完整的图审阅。

6. domain-analyzer(域分析器)

通过 /understand-domain 命令触发。它不是分析”文件怎么组织的”,而是分析”业务逻辑怎么流动的”。提取的内容包括:

输出是另一个图:水平布局的业务流程图。切换视角后,开发者看到的不再是”文件→类的图谱”,而是”认证流程→支付流程→通知流程”。

7. article-analyzer(文章分析器)

用于 /understand-knowledge 命令,分析 Karpathy 风格的知识库 wiki。它从 Markdown 文件中提取实体、关系、声明,再让 LLM 发现隐含连接,最终生成一个带社区聚类的知识图谱。

这个 agent 意味着项目的范围已经超出了”代码理解”——它也能理解文档和知识库。


四、Dashboard 的前端设计

Understand Anything 的可视化前端基于 React Flow + Zustand + TailwindCSS v4 构建。项目在构建时将 Web 资源打包进插件,通过本地服务器提供给用户浏览器,不需要额外的部署步骤。

这是一个独立包(packages/dashboard),通过 packages/core 的浏览器安全子路径导出(./search./types./schema)来避免引入 Node.js 模块。

Dashboard 的几个关键交互特性:

层级化图谱

不是一张平铺的”毛线球”。用户可以从项目层往下钻到文件层,再往下钻到函数/类层,每一层只显示该层的关系。

架构层颜色编码

每个节点根据其架构层着色——API 层是一种颜色、Service 层是另一种、Data 层又是另一种。不用读标签,一眼扫过去就知道冷热区域分布。

角色自适应 UI

一个不太好归类的功能:Persona-Adaptive UI。Dashboard 会根据当前用户的角色(初级开发者、项目经理、高级工程师)调整信息密度和展示视角。

初级开发者看到的是更详细的解释和较少的原始代码;项目经理看到的是高层架构概览和业务流程映射;高级工程师看到的是完整的节点关系和接口细节。

这不是一个 AI 功能——它更像是信息展示策略的分层。

语言概念提示

当图谱中检测到某个常见的编程模式(泛型、闭包、装饰器、异步等),系统会在相关节点的解释中自动插入一段概念说明:“这里用到的 decorator 模式……”。对不熟悉某个语言特性的新人来说,这比切出去搜索快得多。


五、与 CodeGraph 的实质差异

既然前面铺垫了,这里做个直接对比:

维度CodeGraphUnderstand Anything
目标用户AI 编码代理人类开发者
交互方式MCP 工具调用交互式 Web Dashboard
数据源tree-sitter 确定性解析tree-sitter + LLM 语义增强
核心产出可查询的符号图可探索的视觉图 + 自然语言解释
增量更新原生文件监听自动同步文件指纹变更检测
语言覆盖20+ 语言的语法分析26+ 文件类型(含非代码文件)
团队协作CI 集成(affected)可提交的 JSON 图谱 + 自动更新 hook
离线可用完全本地需要 LLM API(除非本地模型)
启动成本自动索引,零配置首次需多 agent 流水线运行(依赖 LLM)

但更值得注意的不是差异,而是互补关系

一个合理的协同场景是:团队新人第一天接手的代码库,先跑 /understand 打开 Dashbord,用 20 分钟把项目结构过一遍。然后第二天开始工作时,Claude Code 加载了 CodeGraph 索引,在编辑时代理能够精确地回答代码导航问题。

两个工具解决的是同一个问题的不同阶段:理解在先,操作在后


六、v2.0 的扩展:非代码文件

2025 年 3 月底的 v2.0 发布是一个重要的里程碑——从”代码分析工具”变成了”项目分析工具”。

新加入的文件类型包括:

对这些文件,解析方式不是 tree-sitter(因为很多格式没有 tree-sitter 语法定义),而是定制的结构化解析器,提取节(sections)、定义(definitions)、服务(services)、端点(endpoints)和引用(references)。

这意味着在一个现代微服务项目中跑一次 /understand,你会看到的不只是源代码的图:API 端点怎么定义的、数据库表结构怎么设计的、容器怎么部署的、CI 流水线怎么跑的——都出现在同一张图谱里。


七、项目架构细节

从 CLAUDE.md 里能看到一些项目本身的工程实践,有些值得借鉴。

Monorepo 结构。用 pnpm workspaces 管理,分成 core(分析引擎)、dashboard(前端)和 skill(插件入口和 agent 定义)。

web-tree-sitter。项目选择的是 WASM 版本的 tree-sitter(web-tree-sitter),而不是原生的 tree-sitter。原因是原生绑定在 darwin/arm64 + Node 24 上会编译失败。这个细节跟 CodeGraph 早期遇到的 better-sqlite3 问题很类似——跨平台的原生模块始终是一个坑。

Model 字段省略。Agent 定义中的 model 字段被刻意省略了(而不是设成 inherit)。原因是 inherit 是 Claude Code 专有的关键字,在 OpenCode 等工具上会被当作字面量模型 ID 解析并报错 ProviderModelNotFoundError。一个很小的平台兼容细节。

图可提交。知识图谱存为 JSON,可以提交到 git 仓库。团队成员共享一次分析结果,新人开箱即用。对于大于 10MB 的图,推荐用 git-lfs 追踪。.gitignore 模板区分了应该提交和不应提交的文件。


八、分析

Understand Anything 解决的问题是真实的。任何一个经历过接手大型遗留代码库的开发者,都知道那种手里拿着 grep 工具,但脑子里没有地图的感觉。传统的代码文档要么写得不够细(README 概括性描述),要么写得足够细但没人维护(架构文档跟代码脱节)。

项目的价值主张有直觉吸引力:把代码库变成一个可交互的、有自然语言解释的、按架构层着色的知识图谱。视觉本身就是一种信息压缩,比看文件列表快得多。

但有两个问题值得讨论。

第一个问题:LLM 的使用成本

每个文件的语义摘要、架构层分类、标签生成都依赖 LLM。虽然支持增量更新(只重新分析有变化的文件),但首次分析的 LLM 成本是线性的——跟文件数量成正比。对于一个数千文件的中型项目,首次 /understand 可能需要数分钟到十余分钟(取决于 LLM 响应速度和并发数)。

项目做了一个合理的折中:file-analyzer 可以并行运行(最多 5 个并发),同时在扫描阶段就预解析 importMap 来降低重复 LLM 调用。但它仍然不是免费的。

第二个问题:图的时效性

CodeGraph 在”保持新鲜”这件事上有显著优势——原生文件事件监听器让索引在保存后几秒内自动完成更新。Understand Anything 依赖显式的 /understand 命令来触发增量更新。虽然文件指纹机制让增量更新很快(只处理变更过的文件),但”显式触发”意味着你得记着做这件事。

项目提供了一个 --auto-update 选项,通过 post-commit hook 自动触发增量更新。对于有严格 git 工作流的团队,这可以解决时效性问题。但 hook 不是每个人的默认配置。

第三个问题:LLM 产生的”完美”可能是一种误导

像任何依赖 LLM 生成解释的系统一样,存在一个风险:生成的解释太通顺、太肯定,即使它在细节上有误

当一个节点描述写着”这个函数处理用户权限验证”,而实际上它只处理了很小一部分权限检查,会给人错误的全局印象。这个问题在静态代码分析工具里不存在——纯结构的索引要么给你正确的信息,要么给你”没找到”。LLM 生成的解释则提供了第三个选项:看起来合理但可能有偏差的信息。

这不是针对 Understand Anything 的批评——任何 LLM 辅助的代码理解工具都有这个问题。但在设计这类系统时,如何标记 LLM 生成内容的置信度、如何让用户知道哪些信息是确定的(来自 tree-sitter)哪些是推测的(来自 LLM),是一个值得继续探索的方向。


九、跟竞品的定位差异

这个领域近年出现了多个切入点不同的工具:

Understand Anything 的独特之处是:它不是在 IDE 侧增强编码体验的工具,也不是在代理侧提供索引的后端。它是介于两者之间的”理解层”——给人看的项目地图。


写在最后

写这篇文章的过程中,有一个念头反复出现。

2024 年、2025 年,大部分 AI 编码工具的努力方向都在”帮 AI 更好地写代码”。补全更准了、代理能自主调试了、错误定位更快了。AI 编码代理在变得越来越强。

人的编码能力跟上这个速度了吗?

一个团队用 Cursor 和 Claude Code 把代码产出翻了一倍,然后用同样的速度交接给下一个不熟悉代码库的开发——接手的人不会因为 AI 写过这段代码就天然理解它。

Understand Anything 踩中的是这个越来越大的鸿沟:代码正以更快的速度被生成,但人去理解代码的速度没有变化。它选择了一个相对朴素的方向:不是帮 AI 理解代码,而是帮人理解代码。

这个方向在未来几年至少跟”帮 AI 写代码”一样重要。因为最终,代码要有人维护的。


项目地址:https://github.com/Lum1104/Understand-Anything 官方网站:https://understand-anything.com/ 在线演示:https://understand-anything.com/demo/ Discord 社区:https://discord.gg/pydat66RY

原创技术博客 · 开源项目分享 · AI全栈创作社区 idao.fun