15 KiB
浏览器端代码知识图谱引擎
代码分析 知识图谱 WebAssembly 语义搜索 静态分析 AI问答
GitNexus V2
零服务器、基于图的代码智能分析引擎 完全在浏览器内通过 WebAssembly 运行。(数据库引擎、嵌入模型、AST 解析,全部在浏览器中完成)
https://github.com/user-attachments/assets/2fb7c522-20d1-48f6-9583-36c3969aa4dc
https://gitnexus.vercel.app 由于是纯客户端运行,部署成本为零,你可以免费使用 :-) (当然,点个 ⭐ 就更好了)
像 DeepWiki,但更深入。 😉
DeepWiki 帮助你理解代码,GitNexus 让你分析代码——因为知识图谱追踪每一个依赖、调用链和关系。
这就是以下两者的区别:
- "这个函数是做什么的?" → 理解
- "如果我修改这个函数,什么会崩溃?" → 分析
一些技术术语:
- 增强搜索:BM25 + 语义搜索 + 通过 Cypher 进行一跳图扩展
- 完整 WASM 栈:Tree-sitter 解析 + KuzuDB 图数据库,全在浏览器内
- 仓库地图:包含 CALLS、IMPORTS、EXTENDS 关系的完整代码知识图谱
- 向量索引:用于语义相似度搜索的 HNSW 嵌入
- Cypher 查询:用于精准上下文检索的关系分析
- 有据可查的 AI:每个答案都以
[[文件:行号]]作为证据引用
你可以做什么:
| 能力 | 描述 |
|---|---|
| 全代码库审计 | 发现层级违规、禁止的依赖 |
| 爆炸半径分析 | 查看某次修改影响到的每个函数 |
| 死代码检测 | 识别零入调用的孤立节点 |
| 依赖追踪 | 跨整个代码库追踪导入链 |
| 带引用的 AI 分析 | 提问、分析,获得带 [[文件:行号]] 证明的答案 |
100% 客户端运行。 你的代码永远不会离开浏览器。
支持语言: TypeScript、JavaScript、Python(Go、Java、C 开发中)
🔍 AI 编码工具的问题所在
Cursor、Claude Code、Cline、Roo Code 和 Windsurf 等工具很强大——但它们有一个共同的根本局限:它们并不真正了解你的代码库结构。
| 工具 | 上下文策略 | 缺口 |
|---|---|---|
| Cursor | 标签页中的文件 + 嵌入 | 无调用图,无法追踪"谁调用了这个?" |
| Claude Code | 文件搜索 + grep | 基于文本,遗漏语义连接 |
| Cline/Roo Code | 仓库地图 + tree-sitter | 静态结构,未追踪运行时依赖 |
| Windsurf | Cascade 上下文 | 依赖深度有限 |
会发生什么:
- AI 编辑
UserService.validate() - 不知道有 47 个函数依赖其返回类型
- 破坏性变更上线 💥
解决方案:图覆盖
知识图谱追踪实际关系,而不只是文件内容:
graph LR
EDIT[AI 想编辑 UserService.validate] --> QUERY[图查询:什么依赖于此?]
QUERY --> DEPS["12个文件中的47个调用者"]
DEPS --> SAFE[AI 先看到完整爆炸半径]
当前状态: GitNexus 是一个独立工具——一个更好的 DeepWiki,100% 客户端运行,带图驱动分析。
未来目标(MCP): 将 GitNexus 作为 MCP 服务器暴露,让 Cursor、Claude Code 等工具可以查询它以获取精准上下文。它们问"什么调用了 X?",GitNexus 返回实际调用图,不再靠猜测。
🚀 快速开始
git clone <仓库地址>
cd gitnexus
npm install
npm run dev
打开 http://localhost:5173,将代码库的 ZIP 文件拖放进去,开始探索。
🏗️ 索引架构
两阶段索引:知识图谱(阻塞式)→ 嵌入(后台)。
第 1-5 阶段:知识图谱构建
flowchart TD
subgraph P1["第1阶段:提取 (0-15%)"]
E1[解压 ZIP] --> E2[收集文件路径]
end
subgraph P2["第2阶段:结构 (15-30%)"]
S1[构建目录树] --> S2[创建 CONTAINS 边]
end
subgraph P3["第3阶段:解析 (30-70%)"]
PA1[加载 Tree-sitter WASM] --> PA2[生成 AST]
PA2 --> PA3[提取符号]
PA3 --> PA4[填充符号表]
end
subgraph P4["第4阶段:导入 (70-82%)"]
I1[查找导入语句] --> I2[解析路径]
I2 --> I3[创建 IMPORTS 边]
end
subgraph P5["第5阶段:调用 + 继承 (82-100%)"]
C1[查找函数调用] --> C2[通过符号表解析]
C2 --> C3[创建 CALLS 边]
C3 --> H1[查找 extends/implements]
H1 --> H2[创建 EXTENDS/IMPLEMENTS 边]
end
P1 --> P2 --> P3 --> P4 --> P5
P5 --> DB[(KuzuDB WASM)]
DB --> READY[图就绪!]
符号表:双哈希映射
函数调用的解析策略:
flowchart TD
CALL[发现调用:validateUser] --> CHECK1{在导入映射中?}
CHECK1 -->|是| FOUND1[使用导入的定义]
CHECK1 -->|否| CHECK2{在当前文件中?}
CHECK2 -->|是| FOUND2[使用本地定义]
CHECK2 -->|否| CHECK3{全局搜索}
CHECK3 -->|找到| FOUND3[使用第一个匹配]
CHECK3 -->|未找到| SKIP[跳过 - 未解析]
FOUND1 --> EDGE[创建 CALLS 边]
FOUND2 --> EDGE
FOUND3 --> EDGE
数据结构:
文件范围:Map<FilePath, Map<SymbolName, NodeID>>
全局: Map<SymbolName, SymbolDefinition[]>
第 6+ 阶段:后台嵌入
flowchart LR
subgraph BG["后台(非阻塞)"]
M1[加载 snowflake-arctic-embed-xs] --> M2[初始化 WebGPU/WASM]
M2 --> E1[批量嵌入节点]
E1 --> E2[INSERT 到 CodeEmbedding 表]
E2 --> V1[创建 HNSW 向量索引]
V1 --> B1[构建 BM25 索引]
end
BG --> AI[AI 搜索就绪!]
嵌入期间用户可以探索图,嵌入完成后 AI 功能解锁。
📊 图模式
节点类型
| 标签 | 描述 | 属性 |
|---|---|---|
Folder |
目录 | name, filePath |
File |
源文件 | name, filePath, language |
Function |
函数定义 | name, filePath, startLine, endLine, isExported |
Class |
类定义 | name, filePath, startLine, endLine |
Interface |
接口定义 | name, filePath, startLine, endLine |
Method |
类方法 | name, filePath, startLine, endLine |
CodeElement |
通用符号 | name, filePath |
关系表:CodeRelation
带 type 属性的单一边表:
| 类型 | 起点 | 终点 | 描述 |
|---|---|---|---|
CONTAINS |
Folder | File/Folder | 目录结构 |
DEFINES |
File | Function/Class/等 | 代码定义 |
IMPORTS |
File | File | 模块依赖 |
CALLS |
Function/Method | Function/Method | 调用图 |
EXTENDS |
Class | Class | 继承 |
IMPLEMENTS |
Class | Interface | 接口实现 |
🛠️ Agent 工具架构
LangChain ReAct Agent 有 5 个工具用于代码探索,这些工具使用索引期间构建的图。
工具 1:search — 带图上下文的混合搜索
结合 BM25(关键词)+ 语义(向量)+ 一跳扩展:
flowchart TD
Q[查询:auth middleware] --> BM25[BM25 关键词搜索]
Q --> SEM[语义向量搜索]
BM25 --> RRF[倒数排名融合]
SEM --> RRF
RRF --> TOP[Top K 结果]
TOP --> HOP[一跳图扩展]
HOP --> OUT["每个结果包含:
• ID、文件、分数
• 入向连接(谁调用了这个)
• 出向连接(这个调用了什么)"]
一跳扩展原理:
MATCH (n {id: $nodeId})
OPTIONAL MATCH (n)-[r1:CodeRelation]->(dst)
OPTIONAL MATCH (src)-[r2:CodeRelation]->(n)
RETURN collect(dst.name), collect(src.name)
Agent 不仅看到什么匹配,还看到什么与之相连。
工具 2:cypher — 带自动嵌入的原生图查询
直接执行 Cypher。如果包含 {{QUERY_VECTOR}},会自动嵌入:
flowchart LR
CQ[带占位符的 Cypher] --> CHECK{包含 QUERY_VECTOR?}
CHECK -->|是| EMBED[嵌入查询文本]
EMBED --> REPLACE[替换占位符为向量]
CHECK -->|否| EXEC
REPLACE --> EXEC[执行 Cypher]
EXEC --> RES[返回结果]
带自动嵌入的示例:
CALL QUERY_VECTOR_INDEX('CodeEmbedding', 'idx', {{QUERY_VECTOR}}, 10)
YIELD node, distance
WHERE distance < 0.4
MATCH (caller:Function)-[:CodeRelation {type: 'CALLS'}]->(n:Function {id: node.nodeId})
RETURN caller.name, n.name
Agent 提供 query: "authentication" → 系统嵌入 → 注入向量。
工具 3:grep — 正则表达式模式匹配
用于精确字符串、错误码、TODO:
flowchart LR
PAT["模式:TODO|FIXME"] --> REGEX[编译正则]
REGEX --> SCAN[扫描所有文件]
SCAN --> MATCH[按行匹配]
MATCH --> RES["文件:行号: 内容"]
工具 4:read — 智能文件读取
带建议的模糊路径匹配:
flowchart TD
REQ[请求:src/utils.ts] --> EXACT{精确匹配?}
EXACT -->|是| RET[返回内容]
EXACT -->|否| FUZZY[按段模糊匹配]
FUZZY --> FOUND{找到?}
FOUND -->|是| RET
FOUND -->|否| SUGGEST[建议相似文件]
工具 5:highlight — 可视化图反馈
发出 UI 解析的标记以高亮节点:
[HIGHLIGHT_NODES:Function:src/auth.ts:validate,Class:src/user.ts:UserService]
💡 关键发现:统一向量 + 图
大多数 Graph RAG 系统使用独立数据库——向量数据库用于语义搜索,图数据库用于遍历。
KuzuDB 支持原生向量索引(HNSW),因此我们在单个 Cypher 查询中同时完成两者:
-- 语义搜索 + 图遍历在一个查询中完成
CALL QUERY_VECTOR_INDEX('CodeEmbedding', 'code_embedding_idx', $queryVector, 20)
YIELD node AS emb, distance
WITH emb, distance WHERE distance < 0.4
MATCH (n:Function {id: emb.nodeId})<-[:CodeRelation {type: 'CALLS'}]-(caller:Function)
RETURN n.name, caller.name, distance
ORDER BY distance
为什么重要:
- 🎯 单次查询执行 — 系统间无往返
- 📊 内置相关性排序 — 距离即分数
- ⚡ 无需独立向量数据库 — 一个数据库,一种查询语言
- 🌳 LLM 友好 — Agent 写一条 Cypher,获得语义 + 结构双重结果
🔬 深度剖析:写时复制内存问题
遇到了一个值得记录的嵌入存储问题。
场景: 将 384 维嵌入与代码节点一起存储。
MATCH (n:CodeNode {id: $id}) SET n.embedding = $vec
问题: 约 20 个节点时正常,约 1000 个时崩溃:
Buffer manager exception: Unable to allocate memory!
根本原因:写时复制(Copy-on-Write)。 每次 UPDATE 都会复制整条记录(约 2KB 的代码内容)。1000 次更新 = 在 WASM 中大量内存复制。
flowchart LR
subgraph COW["写时复制效果"]
OLD[旧:2KB] --> NEW[新:3.5KB]
end
COW -->|"× 1000 个节点"| BOOM[💥 缓冲区耗尽]
解决方案: 单独建立仅 INSERT 的 CodeEmbedding 表:
flowchart TD
subgraph Old["❌ 单表"]
CN1[带嵌入的 CodeNode<br/>UPDATE 触发 COW]
end
subgraph New["✅ 分离表"]
CN2[CodeNode<br/>id, name, content]
CE[CodeEmbedding<br/>nodeId, embedding<br/>仅 INSERT]
end
Old -->|"内存爆炸"| FAIL
New -->|"大规模可用"| WIN
经验: 内存中的 WASM 数据库有硬性限制。在规模下做性能分析,而非只测试理想路径。
⚡ V2 技术改进
Sigma.js + WebGL
- V1:D3.js,约 3k 节点时卡顿
- V2:Sigma.js + GPU 渲染,10k+ 节点流畅运行
双哈希映射符号表
- V1:前缀树(Trie)——聪明但慢
- V2:文件范围 + 全局哈希映射——约 2 倍提速
LRU AST 缓存
- Tree-sitter AST 存储在 WASM 内存中
- LRU 缓存(50 个槽位)配合
tree.delete()清理 - 即使对超大代码库,内存也保持有界
ForceAtlas2 在 Web Worker 中运行
- 布局算法在主线程外运行
- 图定位期间 UI 保持响应
🚧 路线图
积极开发中
- MCP 支持 — 用于工具扩展的模型上下文协议
- 外部数据库支持 — 连接 Neo4j(托管或 Docker)
- 爆炸半径分析工具 — 专用影响分析 UI
- 多 Worker 池 — 跨 Web Worker 并行解析
- Ollama 支持 — 本地 LLM 集成
- CSV 导出 — 导出节点/关系表
🎯 愿景:基于浏览器的 MCP 服务器
目标: 直接从浏览器将 GitNexus 暴露为本地 MCP 服务器。
这将允许 Cursor、Claude Code、Windsurf 等 AI 编码工具连接到你运行的 GitNexus 实例,并使用其知识图谱:
- 🔍 可靠的上下文获取 — AI 获得实际依赖,而非 grep 猜测
- 💥 爆炸半径检测 — 修改前查询什么会被破坏
- 🔐 全代码库审计 — 发现违规、死代码、循环依赖
- 🧠 有据可查的答案 — 每个响应由图遍历支撑,而非幻觉
graph LR
subgraph Browser["GitNexus(浏览器)"]
KG[知识图谱]
MCP[MCP 服务器]
end
subgraph Tools["AI 编码工具"]
CURSOR[Cursor]
CLAUDE[Claude Code]
WIND[Windsurf]
end
KG --> MCP
MCP <-->|localhost| CURSOR
MCP <-->|localhost| CLAUDE
MCP <-->|localhost| WIND
为什么重要: 当前 AI 编码工具对真实依赖是盲目的。它们使用 grep 或嵌入——聊胜于无,但不足以防止破坏性变更。知识图谱 MCP 将为它们提供所需的精准结构化上下文。
近期已完成 ✅
- 带 5 个工具的图 RAG Agent(search、cypher、grep、read、highlight)
- 浏览器嵌入(snowflake-arctic-embed-xs,2200 万参数)
- KuzuDB 中带 HNSW 的向量索引
- 混合搜索(BM25 + 语义 + RRF)
- 带工具可见性的流式 AI 对话
- 有据可查的引用(
[[文件:行号]]格式) - 多 LLM 提供商(OpenAI、Azure、Gemini、Anthropic)
🛠 技术栈
| 层级 | 技术 |
|---|---|
| 前端 | React 18、TypeScript、Vite、Tailwind v4 |
| 可视化 | Sigma.js、Graphology、ForceAtlas2(WebGL) |
| 解析 | Tree-sitter WASM(TS、JS、Python) |
| 数据库 | KuzuDB WASM(图 + 向量 HNSW) |
| 嵌入 | transformers.js、snowflake-arctic-embed-xs(22M) |
| AI | LangChain ReAct Agent、流式输出 |
| 并发 | Web Workers + Comlink |
🔐 安全与隐私
- 所有处理均在你的浏览器中进行
- 无代码上传至任何服务器
- API 密钥仅存储在 localStorage 中
- 开源——自行审计代码
📝 许可证
MIT 许可证
🙏 致谢
- Tree-sitter — AST 解析
- KuzuDB — 带向量支持的嵌入式图数据库
- Sigma.js — WebGL 图渲染
- transformers.js — 浏览器机器学习
- LangChain — Agent 编排