Understand Anything 设计解析:用 LLM + 静态分析构建可交互代码知识图谱
本文基于 Understand Anything 的设计文档(设计规格),完整拆解这个项目"把任意代码库变成可探索、可搜索、可问答的知识图谱"的整体架构:包括 pnpm monorepo 的共享核心设计、知识图谱 JSON Schema 的字段定义与实现演进、基于 Git diff 的过期检测与增量更新机制、React 多面板 Dashboard 的技术选型,以及 Claude Code Skill 命令体系。读完本文,你将掌握该项目从设计到落地的完整脉络,并能在源码层面验证每一项设计决策的实际实现。
一、设计背景:代码写得出,却看不懂
设计文档开篇点明了核心问题:AI 编码工具让"写代码"变得容易,但"理解代码"依然困难。初级开发者、非程序员(产品经理、设计师),甚至熟悉别的语言的资深工程师,都难以看懂自己没写的、或者 AI 代写的代码库——而真正"理解"代码的只有 AI 本身。
Understand Anything 的定位就是弥合这一鸿沟:一个结合 LLM 智能与静态分析(static analysis)的开源工具,为任意代码库生成一个多角色(multi-persona)的交互式理解仪表盘。它的运行形态是一个 Claude Code skill(复用当前活跃的 AI 会话,零额外成本),并对外提供功能完整的 Web Dashboard。
二、架构决策:Monorepo + 共享核心引擎
设计文档将项目组织为一个 pnpm workspaces 管理的 monorepo,其核心意图是:skill 与 dashboard 共享同一个核心分析引擎(core),避免逻辑重复。
原始设计目录结构如下:
understand-anything/
├── packages/
│ ├── core/ # Shared analysis engine
│ │ ├── analyzer/ # LLM + tree-sitter analysis
│ │ ├── graph/ # Knowledge graph builder & schema
│ │ ├── plugins/ # Plugin system for language analyzers
│ │ └── persistence/ # JSON read/write, staleness detection
│ ├── skill/ # Claude Code skill (5 commands)
│ └── dashboard/ # React + TypeScript multi-panel workspace
├── plugins/ # Built-in language analyzer plugins
│ └── tree-sitter/ # Tree-sitter based multi-language analyzer
├── docs/
│ └── plans/
├── package.json # Monorepo root (pnpm workspaces)
├── tsconfig.json
└── .gitignore
三项关键架构决策(Key decisions)在设计文档中明确列出:
- Monorepo(pnpm workspaces)——skill 和 dashboard 共享 core 分析引擎。当前仓库的 pnpm-workspace.yaml 与 understand-anything-plugin/pnpm-workspace.yaml 证实了这一组织方式,dashboard 的 package.json 中通过
"@understand-anything/core": "workspace:*"以工作区依赖方式引用核心引擎。 - JSON interchange(JSON 交换格式)——知识图谱就是一个 JSON 文件,skill 与 dashboard 都能读取,不依赖数据库或私有格式。
- Committable + auto-sync(可提交 + 自动同步)——图谱持久化在项目内数据目录中,可以提交到 git,并通过 git diff 自动检测过期(staleness)。
从源码结构看,当前仓库的目录布局在 packages/core、packages/dashboard 等核心划分上与设计文档一致(见 understand-anything-plugin/packages),并在此基础上扩展了 languages/(语言配置注册)、plugins/extractors(各语言静态提取器)与 plugins/parsers(非代码文件解析器)等模块。
三、知识图谱 Schema:系统的"契约"
知识图谱是整个系统的交换格式,设计文档给出了完整的 TypeScript 接口定义,这也是 skill 生成、dashboard 消费两端共同遵守的契约:
interface KnowledgeGraph {
version: string;
project: ProjectMeta;
nodes: GraphNode[];
edges: GraphEdge[];
layers: Layer[];
tour: TourStep[];
}
interface ProjectMeta {
name: string;
languages: string[];
frameworks: string[];
description: string; // LLM-generated project summary
analyzedAt: string; // ISO timestamp
gitCommitHash: string; // For staleness detection
}
interface GraphNode {
id: string;
type: "file" | "function" | "class" | "module" | "concept";
name: string;
filePath?: string;
lineRange?: [number, number];
summary: string; // Plain-English description
tags: string[]; // Searchable tags
complexity: "simple" | "moderate" | "complex";
languageNotes?: string; // Language-specific explanations
}
interface GraphEdge {
source: string;
target: string;
type: EdgeType;
direction: "forward" | "backward" | "bidirectional";
description?: string;
weight: number; // 0-1 importance
}
type EdgeType =
// Structural
| "imports" | "exports" | "contains" | "inherits" | "implements"
// Behavioral
| "calls" | "subscribes" | "publishes" | "middleware"
// Data flow
| "reads_from" | "writes_to" | "transforms" | "validates"
// Dependencies
| "depends_on" | "tested_by" | "configures"
// Semantic
| "related" | "similar_to";
interface Layer {
id: string;
name: string; // e.g., "API Layer", "Data Layer"
description: string;
nodeIds: string[];
}
interface TourStep {
order: number;
title: string;
description: string; // Markdown explanation
nodeIds: string[]; // Nodes to highlight
languageLesson?: string; // Optional language concept explanation
}
各字段的语义要点:
GraphNode是图谱的基本单元,type区分文件、函数、类、模块与抽象概念;summary是 LLM 生成的自然语言描述,tags用于搜索,complexity三档(simple/moderate/complex)供不同角色的视角做差异化展示,languageNotes承载语言特定解释(配合 Learn 模式)。GraphEdge用type表达 5 类关系(结构/行为/数据流/依赖/语义),direction区分方向,weight(0–1)表达关系强度。Layer把节点按逻辑分层(如 API Layer、Data Layer),支撑"分层视图"。TourStep是引导式项目导览的步骤序列,languageLesson允许在用户自己的代码上下文中讲解语言概念。ProjectMeta.gitCommitHash是过期检测的锚点,后续第五节详述。
3.1 实现演进:从 17 种边类型到 38 种、多类型图谱
对比当前源码中的 Zod 校验实现 schema.ts,可以观察到设计落地后的两处重要演进:
边类型扩展。设计文档定义了 17 种 EdgeType;实现中 EdgeTypeSchema 已扩展到 38 个值、9 个类别,新增了基础设施(deploys、serves、provisions、triggers)、Schema/数据(migrates、documents、routes、defines_schema)、业务域(contains_flow、flow_step、cross_domain)、知识图谱(cites、contradicts、builds_on、exemplifies 等)与设计(Figma)四类。这说明图谱模型从"纯代码库"泛化到了基础设施、知识库与界面设计等多种 kind。
节点类型扩展与容错管线。设计文档中节点类型只有 5 种;实现的 GraphNodeSchema 扩展到 26 种(含 config、service、table、endpoint、pipeline、domain、flow、article、page、component 等)。更关键的是,由于节点主要由 LLM 生成,schema 文件构建了一条四层容错管线:
- sanitize(
sanitizeGraph):null 归一化为空数组/删除,枚举字段转小写; - normalize(
normalizeGraph):把 LLM 常见的类型别名映射回规范类型,如func/fn/method→function,struct→class,ci→pipeline;边别名如extends→inherits、invokes→calls; - auto-fix(
autoFixGraph):缺type默认"file",缺complexity默认"moderate",weight缺失默认 0.5、字符串强转数字、越界值钳制到 [0,1],且每一步都记录可审计的GraphIssue; - validate(
validateGraph):逐节点/边/Layer/TourStep 校验,非法项被丢弃(dropped)而非整体失败,同时做引用完整性检查——边的source/target必须存在于节点集合中,layers/tour中悬空的nodeIds会被过滤。
这套"宽容输入、分级处理(auto-corrected / dropped / fatal)"的策略,是对"LLM 产出必然带噪声"这一现实的工程化应对,相关行为有 schema.test.ts 覆盖。
四、Dashboard:多面板工作区
设计文档用一张 ASCII 图定义了 Dashboard 的四象限布局:
┌─────────────────────────────────────────────────────────┐
│ 🔍 Natural Language Search: "communication layer" │
├──────────────────────┬──────────────────────────────────┤
│ │ │
│ GRAPH VIEW │ CODE VIEWER │
│ (React Flow) │ (Monaco Editor, read-only) │
│ │ │
│ Interactive node │ Source code + syntax highlight │
│ graph. Click to │ LLM annotations inline. │
│ select. Search │ │
│ highlights. │ │
├──────────────────────┼──────────────────────────────────┤
│ │ │
│ CHAT PANEL │ LEARN PANEL │
│ │ │
│ Context-aware Q&A │ Tour mode + Contextual mode │
│ about selected │ Language lessons in context │
│ nodes / project. │ of YOUR code. │
└──────────────────────┴──────────────────────────────────┘
设计文档给出的技术栈是:React 18 + TypeScript + Vite、React Flow(节点图可视化,优于裸 D3)、Monaco Editor(与 VS Code 同款代码查看器)、TailwindCSS、Zustand(轻量状态管理)。对照 dashboard/package.json,实际依赖与设计选型基本吻合且版本前进:React 已升至 19,@xyflow/react(即 React Flow)12.x、zustand 5.x、TailwindCSS 4.x、Vite 6.x 均在列,并新增了 elkjs/d3-force/graphology + Louvain 社区发现等布局算法依赖,支撑大图的分层与聚类布局(见 elk-layout.ts 与 louvain.ts)。从源码结构看,代码查看器最终采用了 prism-react-renderer 做语法高亮而非 Monaco,组件为 CodeViewer.tsx。
4.1 三种角色视角(Persona Modes)
设计文档按读者身份定义了三种模式,核心思路是"同一份图谱,不同的信息密度":
| 角色 | 展示策略 |
|---|---|
| Non-technical(非技术人员) | 只呈现高层概念节点,隐藏代码查看器,放大 Learn 面板 |
| Junior dev(初级开发者) | 全部面板可见,Learn 面板突出,显示复杂度指示 |
| Experienced dev(资深开发者) | 代码查看器突出,Chat 面板用于深入探讨 |
4.2 自然语言搜索
设计文档规定搜索作用于节点的 tags、summary、name 字段,"如可用则使用 embedding 相似度,否则回退到关键词匹配",命中后在图中高亮并过滤列表。源码中这一设计落地为两条路径:
- 关键词/模糊搜索:search.ts 基于 Fuse.js 实现
SearchEngine,对四个字段加权(name0.4、tags0.3、summary0.2、languageNotes0.1),阈值 0.4,并把空格分隔的查询词用|连接做 OR 匹配——即输入 "auth contrl" 能同时命中含任一 token 的节点。 - 语义搜索:embedding-search.ts 实现了余弦相似度计算(含对查询向量范数预计算的优化路径),对应设计 Phase 4 中"可选增强"的 embedding 语义检索。
五、Skill 命令体系与 LLM 策略
设计文档定义了 5 条 Claude Code Skill 命令:
| 命令 | 说明 |
|---|---|
/understand |
完整分析(若图谱已存在则增量更新)+ 打开 Dashboard |
/understand-chat "<query>" |
在终端内基于知识图谱进行问答 |
/understand-diff |
分析当前 PR/diff——解释改动、受影响区域与风险 |
/understand-explain <path> |
对特定文件或函数做深入解释 |
/understand-onboard |
为团队成员生成结构化上手指南 |
LLM 策略分三种场景:在 Claude Code 内部运行时复用当前活跃会话(零额外成本);独立 Dashboard 场景下由用户提供 API key 驱动 Chat 功能;而图谱浏览、搜索、Learn 模式完全离线工作(基于预生成数据)。
对照当前仓库的 SKILL.md,/understand 命令的实装比设计文档更丰富,支持参数包括:
--full:强制全量重建,忽略已有图谱;--auto-update/--no-auto-update:开启/关闭提交时自动更新图谱(写入autoUpdate到配置);--review:运行完整的 LLM 图谱审查而非内联确定性校验;--language <lang>:以指定语言(ISO 639-1 代码或友好名称)生成全部文本内容;--exclude <patterns>:附加排除的 glob 模式,支持 gitignore 语法与!取反;- 直接传一个目录路径,分析该目录而非当前工作目录。
此外 SKILL.md 还规定了对 git worktree 的重定向逻辑:若检测到 PROJECT_ROOT 位于 worktree(通过对比 git rev-parse --git-dir 与 --git-common-dir),会把图谱输出重定向到主仓库根目录,避免会话结束后 worktree 被销毁导致图谱丢失(可用环境变量 UNDERSTAND_NO_WORKTREE_REDIRECT=1 关闭)。相关行为有 worktree-redirect.test.mjs 验证。5 个 skill 目录(understand、understand-chat、understand-diff、understand-explain、understand-onboard 及扩展的 understand-dashboard、understand-knowledge 等)均可在 skills 目录 下找到各自的 SKILL.md。
六、持久化与过期检测:自动同步如何工作
6.1 数据目录布局
设计文档定义的持久化结构如下:
.understand-anything/
├── knowledge-graph.json # The full graph (committable)
├── meta.json # Analysis metadata
│ {
│ "lastAnalyzedAt": "2026-03-14T...",
│ "gitCommitHash": "abc123",
│ "version": "1.0.0",
│ "analyzedFiles": 47
│ }
├── cache/ # Per-file analysis cache
│ ├── src__index.ts.json
│ └── src__auth__login.ts.json
└── tours/
└── default-tour.json
其中 meta.json 的 gitCommitHash 是增量更新的锚点,cache/ 存放按文件键(路径分隔符替换为 __)的分析缓存。需要注意:当前实现中数据目录已重命名为更短的 .ua/,persistence/index.ts 的 resolveUaDirName 做了向后兼容——旧项目若已存在 .understand-anything/ 则继续使用该目录读写,新项目则使用 .ua/,无需迁移。同一文件中还有一个值得注意的隐私保护细节:sanitiseFilePaths 在写盘前把所有节点 filePath 从绝对路径转为相对路径(项目外的绝对路径只保留文件名),避免把开发者的家目录、用户名等布局信息泄露进可提交的 JSON。
6.2 自动同步流程(Auto-sync Flow)
设计文档定义了四步流程:
- Skill 启动 → 读取
meta.json→ 获取上次分析的 commit hash; - 执行
git diff <last-hash>..HEAD --name-only→ 得到变更文件列表; - 若无变更 → 直接提供现有图谱;
- 若有变更 → 只重新分析变更文件 → 合并进现有图谱 → 更新 meta。
源码 staleness.ts 忠实实现了这条链路,并做了三层能力增强:
- 基础判定:
getChangedFiles正是同步流程第 2 步(git diff <hash>..HEAD --name-only);isStale据此返回{ stale, changedFiles }。 - 精细的新鲜度模型:
getGraphFreshness把图谱状态细化为fresh/dirty(无提交差异但工作区有未提交改动)/stale/unknown(含missing-graph-commit、git-command-timeout等 5 种原因码)。stale还区分behind/ahead/diverged三种拓扑关系,并给出commitsBehind/commitsAhead计数——通过git rev-list --left-right --count与merge-base --is-ancestor判定。所有 git 子命令都带 5 秒超时与 4MB 缓冲上限,且用 pathspec 排除.ua/、.understand-anything/自身,防止图谱文件自身的变更污染判定。相关测试见 staleness.test.ts 与 graph-freshness.integration.test.ts。 - 增量合并:
mergeGraphUpdate实现同步流程第 4 步的具体合并算法——(1) 按filePath删除属于变更文件的旧节点;(2) 删除source或target落在被删节点集合中的旧边;(3) 追加新节点与新边;(4) 更新project.gitCommitHash与analyzedAt。这种"按文件整体替换"的策略保证了增量更新与全量重建的语义一致性,同时避免全图重算的成本。
七、插件系统:tree-sitter 静态分析 + 语言注册表
设计文档给出的分析器插件接口:
interface AnalyzerPlugin {
name: string;
languages: string[];
analyzeFile(filePath: string, content: string): StructuralAnalysis;
resolveImports(filePath: string, content: string): ImportResolution[];
extractCallGraph?(filePath: string, content: string): CallGraphEntry[];
}
设计意图是"结构靠 tree-sitter,语义靠 LLM":Day 1 的 tree-sitter 插件使用 node-tree-sitter 加载 TypeScript/JavaScript、Python、Go、Java、Rust、C/C++ 等语言文法,提取函数/类边界、import/export 语句与调用点,再与 LLM 分析结合得到语义理解;未来开放社区插件做语言级深度分析。
从当前源码结构看,这一方向已显著扩展:
- tree-sitter-plugin.ts 与 registry.ts 实现插件注册与发现;
- plugins/extractors 下为 12 种语言(C++、C#、Dart、Go、Java、Kotlin、PHP、Python、Ruby、Rust、Scala、Swift、TypeScript)提供独立提取器,配套逐语言单测;
- plugins/parsers 覆盖非代码文件(Dockerfile、环境变量、GraphQL、JSON、Makefile、Markdown、Protobuf、Shell、SQL、Terraform、TOML、YAML);
- languages/language-registry.ts 维护语言 ID → 配置的注册表,支持按文件扩展名与文件名(如
Makefile、docker-compose.yml)两种方式解析,languages/configs 下有 40 余种语言配置; - 层级自动检测(设计 Phase 2 第 13 项)落地为 layer-detector.ts:内置目录模式 → 层级名的启发式映射表(routes/controller/api → API Layer;service/business → Service Layer;model/repository → Data Layer;component/page/ui → UI Layer;worker/queue/cron → Background Tasks;test/spec → Test Layer 等,先匹配先生效),并支持 LLM 返回
filePatterns做补充判定。
八、实施阶段与验证标准
设计文档把落地拆成四个阶段,共 22 项任务:
- Phase 1:Foundation(MVP)——项目脚手架;core 的图谱 schema + JSON 持久化;LLM 分析引擎(基于 prompt 的逐文件分析);tree-sitter 结构分析集成;
/understand命令;Dashboard 基础应用 + React Flow 图谱视图 + Monaco 代码查看器。 - Phase 2:Intelligence——图谱节点自然语言搜索;
/understand-chat终端问答;Dashboard Chat 面板;过期检测 + 增量更新;层级自动检测。 - Phase 3:Learn Mode——导览(Tour)生成;点击即解释的上下文解释;以用户代码为语境的特定语言课程;三种角色模式。
- Phase 4:Advanced——
/understand-diff、/understand-explain、/understand-onboard三条命令;社区插件系统;基于 embedding 的语义检索(可选增强)。
设计文档同时给出了 6 条端到端验证标准,也是回归这套设计的实用清单:
- Skill 分析:在示例项目上运行
/understand,验证生成的knowledge-graph.json符合 schema; - 增量更新:修改一个文件后再次运行
/understand,验证只有变更文件被重新分析; - Dashboard:打开本地开发服务(Vite 默认端口 5173,
pnpm --filter @understand-anything/dashboard dev即可启动),验证图谱渲染、节点可点击、搜索可用; - Chat:在聊天面板提问,验证答案基于知识图谱生成;
- Learn 模式:启动 Tour,验证能逐步走查整个项目;
- Tree-sitter:分析一个 TypeScript 文件,验证函数边界与 import 关系同真实代码一致。
设计文档建议的四类测试项目——小型 TypeScript 项目(工具自身)、Python Flask/Django API、Go 微服务、混合语言 monorepo——也覆盖了单语言、多框架、服务化与 monorepo 四种典型形态。
九、小结
这份 2026-03-14 的设计文档确立了 Understand Anything 的三个支柱:以 JSON 知识图谱为单一事实来源(schema 是契约,且通过 sanitize/normalize/auto-fix/validate 四层管线消化 LLM 输出的噪声)、以 Git 为同步时钟(commit hash 锚定、diff 驱动增量、合并算法保证一致性)、以多角色视角为出口(同一份数据服务非技术人员、初级与资深开发者)。对照当前仓库源码可以确认,文档中的核心机制——git diff <hash>..HEAD 的增量链路、mergeGraphUpdate 的文件级替换合并、层级启发式检测、加权模糊搜索——都有明确的实现文件与测试用例支撑;而边类型从 17 扩到 38 种、节点类型扩到 26 种、数据目录从 .understand-anything/ 迁移到 .ua/ 等演进,则展示了这套设计在落地过程中从"代码库分析"向"基础设施/知识/设计多 kind 图谱"泛化的实际轨迹。对于想构建"LLM + 静态分析"类代码理解工具的开发团队,这套"契约先行、宽容校验、Git 驱动增量"的工程模式具备直接的参考价值。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
