# 浏览器端代码知识图谱引擎 `代码分析` `知识图谱` `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 开发中) gitnexus_img --- ## 🔍 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 编排