# 浏览器端代码知识图谱引擎
`代码分析` `知识图谱` `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 上下文 | 依赖深度有限 |
**会发生什么:**
1. AI 编辑 `UserService.validate()`
2. 不知道有 47 个函数依赖其返回类型
3. **破坏性变更上线** 💥
### 解决方案:图覆盖
知识图谱追踪**实际关系**,而不只是文件内容:
```mermaid
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 返回实际调用图,不再靠猜测。
---
## 🚀 快速开始
```bash
git clone <仓库地址>
cd gitnexus
npm install
npm run dev
```
打开 http://localhost:5173,将代码库的 ZIP 文件拖放进去,开始探索。
---
## 🏗️ 索引架构
两阶段索引:**知识图谱**(阻塞式)→ **嵌入**(后台)。
### 第 1-5 阶段:知识图谱构建
```mermaid
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[图就绪!]
```
### 符号表:双哈希映射
函数调用的解析策略:
```mermaid
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>
全局: Map
```
### 第 6+ 阶段:后台嵌入
```mermaid
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**(关键词)+ **语义**(向量)+ **一跳扩展**:
```mermaid
flowchart TD
Q[查询:auth middleware] --> BM25[BM25 关键词搜索]
Q --> SEM[语义向量搜索]
BM25 --> RRF[倒数排名融合]
SEM --> RRF
RRF --> TOP[Top K 结果]
TOP --> HOP[一跳图扩展]
HOP --> OUT["每个结果包含:
• ID、文件、分数
• 入向连接(谁调用了这个)
• 出向连接(这个调用了什么)"]
```
**一跳扩展原理:**
```cypher
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}}`,会自动嵌入:
```mermaid
flowchart LR
CQ[带占位符的 Cypher] --> CHECK{包含 QUERY_VECTOR?}
CHECK -->|是| EMBED[嵌入查询文本]
EMBED --> REPLACE[替换占位符为向量]
CHECK -->|否| EXEC
REPLACE --> EXEC[执行 Cypher]
EXEC --> RES[返回结果]
```
**带自动嵌入的示例:**
```cypher
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:
```mermaid
flowchart LR
PAT["模式:TODO|FIXME"] --> REGEX[编译正则]
REGEX --> SCAN[扫描所有文件]
SCAN --> MATCH[按行匹配]
MATCH --> RES["文件:行号: 内容"]
```
---
### 工具 4:`read` — 智能文件读取
带建议的模糊路径匹配:
```mermaid
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 查询**中同时完成两者:
```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 维嵌入与代码节点一起存储。
```cypher
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 中大量内存复制。
```mermaid
flowchart LR
subgraph COW["写时复制效果"]
OLD[旧:2KB] --> NEW[新:3.5KB]
end
COW -->|"× 1000 个节点"| BOOM[💥 缓冲区耗尽]
```
**解决方案:** 单独建立仅 `INSERT` 的 `CodeEmbedding` 表:
```mermaid
flowchart TD
subgraph Old["❌ 单表"]
CN1[带嵌入的 CodeNode
UPDATE 触发 COW]
end
subgraph New["✅ 分离表"]
CN2[CodeNode
id, name, content]
CE[CodeEmbedding
nodeId, embedding
仅 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 猜测
- 💥 **爆炸半径检测** — 修改前查询什么会被破坏
- 🔐 **全代码库审计** — 发现违规、死代码、循环依赖
- 🧠 **有据可查的答案** — 每个响应由图遍历支撑,而非幻觉
```mermaid
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 将为它们提供所需的精准结构化上下文。
### 近期已完成 ✅
- [x] 带 5 个工具的图 RAG Agent(search、cypher、grep、read、highlight)
- [x] 浏览器嵌入(snowflake-arctic-embed-xs,2200 万参数)
- [x] KuzuDB 中带 HNSW 的向量索引
- [x] 混合搜索(BM25 + 语义 + RRF)
- [x] 带工具可见性的流式 AI 对话
- [x] 有据可查的引用(`[[文件:行号]]` 格式)
- [x] 多 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](https://tree-sitter.github.io/) — AST 解析
- [KuzuDB](https://kuzudb.com/) — 带向量支持的嵌入式图数据库
- [Sigma.js](https://www.sigmajs.org/) — WebGL 图渲染
- [transformers.js](https://huggingface.co/docs/transformers.js) — 浏览器机器学习
- [LangChain](https://langchain.com/) — Agent 编排