Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .git-ai/lancedb.tar.gz
Git LFS file not shown
9 changes: 0 additions & 9 deletions .git-ai/meta.json

This file was deleted.

4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,9 @@ dist/
.DS_Store

.git-ai/lancedb/
.git-ai/meta.json
.git-ai/cozo.error.json
.git-ai/ast-graph.sqlite
.git-ai/ast-graph.export.json
.git-ai/._*
.tmp-hook-test/
7 changes: 6 additions & 1 deletion .trae/skills/git-ai-mcp/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ description: "通过 git-ai 的 MCP 工具检视/检索代码仓。用户要“
### 1) 符号定位(最稳)
当用户提到函数/类/文件名/模块名:
- `search_symbols({ query: "FooBar", limit: 50 })`
- `search_symbols({ query: "get*repo", mode: "wildcard", case_insensitive: true, limit: 20 })`
- `search_symbols({ query: "^get.*repo$", mode: "regex", case_insensitive: true, limit: 20 })`

输出 rows 后,选最可能的 1-3 个命中点继续读代码:
- `read_file({ file: "src/xxx.ts", start_line: 1, end_line: 220 })`
Expand All @@ -49,6 +51,10 @@ description: "通过 git-ai 的 MCP 工具检视/检索代码仓。用户要“
- `list_files({ pattern: "src/**/*.{ts,tsx,js,jsx}", limit: 500 })`
- `list_files({ pattern: "**/*mcp*", limit: 200 })`

### 4) AST 图查询(递归/关系类问题)
当你需要回答“包含关系/继承关系/子节点列表/递归查询”等问题:
- `ast_graph_query({ query: "<CozoScript>", params: {...} })`

## 输出要求(给用户的答复)
- 先给结论,再给证据(文件 + 行范围)
- 引用代码位置用 IDE 可点链接(file://...#Lx-Ly)
Expand All @@ -58,4 +64,3 @@ description: "通过 git-ai 的 MCP 工具检视/检索代码仓。用户要“
- MCP 的 `semantic_search` 依赖 `.git-ai/lancedb`:没索引就没结果
- 修改索引后建议 `pack_index`,并把 `.git-ai/lancedb.tar.gz` 提交(如果团队要共享)
- `read_file` 只能读仓库内相对路径,不允许 `../` 越界

5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ yarn global add git-ai
- 开发指引:[DEVELOPMENT.md](./DEVELOPMENT.md)
- 文档中心(使用/概念/排障):[docs/README.md](./docs/README.md)
- 设计说明:[docs/design.md](./docs/design.md)
- 技术原理详解(小白向):[docs/architecture_explained.md](./docs/architecture_explained.md)
- Agent 集成(Skills/Rules):[docs/mcp.md](./docs/mcp.md)

## 基本用法(与 git 类似)
Expand All @@ -48,6 +49,7 @@ git-ai push -u origin main
git-ai ai index --overwrite
git-ai ai query Indexer --limit 10
git-ai ai semantic "semantic search" --topk 5
git-ai ai graph find GitAIV2MCPServer
git-ai ai pack
git-ai ai unpack
git-ai ai serve
Expand All @@ -56,8 +58,9 @@ git-ai ai serve
## MCP Server(stdio)

`git-ai` 提供一个基于 MCP 的 stdio Server,供 Agent/客户端以工具方式调用:
- `search_symbols`:按子串搜索符号并返回文件位置
- `search_symbols`:符号检索(substring/prefix/wildcard/regex/fuzzy)
- `semantic_search`:基于 LanceDB + SQ8 的语义检索
- `ast_graph_query`:基于 CozoDB 的 AST 图查询(CozoScript)

### 启动

Expand Down
17 changes: 17 additions & 0 deletions docs/DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
- `.git-ai/`:索引目录
- `lancedb/`:LanceDB 数据目录
- `lancedb.tar.gz`:打包后的 LanceDB(用于 Git LFS 追踪与传输)
- `ast-graph.sqlite`:AST 关系图数据库(CozoDB,优先 SQLite 引擎)
- `ast-graph.export.json`:AST 图导出快照(仅在非 SQLite 后端时用于跨进程复用)
- `meta.json`:索引元信息(维度、编码、构建时间等)

## 3. 数据模型(两张表)
Expand Down Expand Up @@ -55,6 +57,21 @@
- 扫描 chunks(或按过滤条件缩小)反量化计算 cosine 相似度;
- 取 TopK 后关联 refs 输出定位结果。

## 6.1 AST 图查询(CozoDB)

索引时会把符号及其关系写入 CozoDB,用于表达“包含关系”和“继承关系”等更适合图/递归查询的数据:

### 关系(relations)
- `ast_file(file_id => file)`:文件节点(file_id 为 `sha256("file:" + file)`)
- `ast_symbol(ref_id => file, name, kind, signature, start_line, end_line)`:符号节点(ref_id 与 refs 表一致)
- `ast_contains(parent_id, child_id)`:包含关系边(parent_id 可能是 file_id 或 ref_id)
- `ast_extends_name(sub_id, super_name)`:继承关系(按名字记录,便于后续 join/解析)
- `ast_implements_name(sub_id, iface_name)`:实现关系(按名字记录)

### CLI / MCP
- CLI:`git-ai ai graph ...`
- MCP:`ast_graph_query({query, params})`

## 7. Git hooks 集成
- `pre-commit`:自动重建索引(index --overwrite)并打包(pack),把 `.git-ai/lancedb.tar.gz` 添加到暂存区;若安装了 git-lfs 会自动执行 lfs track。
- `pre-push`:再次打包并校验归档未发生变化;若变化则阻止 push,提示先提交归档文件。
Expand Down
4 changes: 3 additions & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
- 让 Agent 通过 MCP tools 低成本命中符号/片段,再按需读取文件

### 重要目录
- `.git-ai/meta.json`:索引元数据
- `.git-ai/meta.json`:索引元数据(本地生成,通常不提交)
- `.git-ai/lancedb/`:本地向量索引目录(通常不提交)
- `.git-ai/lancedb.tar.gz`:归档后的索引(可提交/可用 git-lfs 追踪)
- `.git-ai/ast-graph.sqlite`:AST 图数据库(CozoDB)
- `.git-ai/ast-graph.export.json`:AST 图导出快照(用于非 SQLite 后端跨进程复用)

## 目录

Expand Down
106 changes: 106 additions & 0 deletions docs/architecture_explained.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# 技术架构与选型深度解析

本文档旨在从架构设计角度,深入剖析 `git-ai` 的核心实现原理、关键技术选型及其背后的决策逻辑。适用于技术评审、架构选型参考及二次开发指导。

## 1. 核心架构设计理念

`git-ai` 的设计目标是构建一个**轻量级、去中心化、零依赖**的代码库语义索引引擎。不同于传统的集中式代码搜索服务(如 Sourcegraph),`git-ai` 采用“Client-Side Indexing”模式,将索引能力下沉至开发者本地环境。

### 1.1 设计哲学:Hybrid RAG 与 高召回策略

我们采用了 **Hybrid RAG (混合检索增强生成)** 的设计思想,通过不同组件的协同来平衡检索的精度与召回率。核心原则是 **"Recall over Precision"(召回优于精度)** —— 宁可多搜几个交给 AI (LLM) 去过滤,也绝不漏掉潜在的关键信息。

* **Tree-sitter (骨架提取)**:负责“精准”的结构化数据。提取代码的类、方法、接口定义,构建代码的“骨架”。
* **CozoDB (关联推导)**:负责“逻辑”连接。处理继承、实现、包含等图关系,支持多跳查询(如“查找所有子类”)。
* **LanceDB (语义仲裁)**:负责“模糊”召回。通过 Hash Embedding 捕捉代码的语义特征,即使不知道确切名字,也能通过上下文找到相关代码。
* **AI (最终过滤)**:作为 RAG 的最后一环,LLM 利用其强大的理解能力,对召回的混合结果进行 Re-ranking 和精确过滤。

**核心约束:**
* **零环境依赖**:不依赖 Docker、JVM、Python 环境,开箱即用。
* **纯本地运行**:数据隐私优先,无需上传代码至云端。
* **高性能**:毫秒级检索,索引体积可控(通常 < 代码体积的 20%)。

---

## 2. 索引流水线 (Indexing Pipeline)

索引构建过程是一个典型的 ETL (Extract, Transform, Load) 流程,分为三个阶段:

### 2.1 结构化解析 (Parsing & Chunking)

为了解决传统基于行的分片(Line-based Chunking)导致的语义截断问题,我们采用了基于 AST(抽象语法树)的结构化分片策略。

* **技术选型:Tree-sitter**
* **背景**:GitHub Atom 团队开发的增量解析系统,现已成为代码解析领域的工业标准。
* **实现机制**:通过 `tree-sitter-{lang}` 生成具体语言的 CST (Concrete Syntax Tree),再通过遍历算法提取 Symbol(类、函数、接口)及其上下文(Range)。
* **优势**:
* **多语言支持**:通过统一的 WASM/Node.js 绑定支持几十种主流语言。
* **容错性**:即使代码存在语法错误,仍能构建部分 AST,保证索引鲁棒性。
* **性能**:基于 C 编写,解析速度极快(单文件 < 10ms)。

### 2.2 向量化 (Embedding)

这是将非结构化代码转换为结构化向量的关键步骤。

* **技术选型:Random Indexing (Deterministic Hash Embedding)**
* **背景**:一种降维技术,基于 Johnson-Lindenstrauss 引理(高维空间中的随机向量近似正交)。
* **实现机制**:
1. **Tokenization**:对代码标识符进行分词与归一化。
2. **Hashing**:计算 Token 的 SHA-256 哈希。
3. **Projection**:将哈希映射到固定维度(如 256 维)的稀疏向量中(+1/-1)。
4. **Aggregation**:叠加所有 Token 向量并归一化。
* **决策依据(VS 深度学习模型)**:
* **Transformer 模型 (如 BERT/OpenAI)**:虽然语义理解强,但模型文件巨大(数百 MB)、推理延迟高、且通常需要 GPU 或云端 API,违背了“轻量级 CLI”的设计初衷。
* **Hash Embedding**:虽然无法捕捉同义词语义(如 Login ≈ SignIn),但在代码搜索场景中,**精确的标识符匹配**(Identifier Match)往往比模糊语义更重要。该方案实现了**零模型文件依赖、纳秒级推理速度**。

### 2.3 关系图谱构建 (Knowledge Graph)

为了弥补向量检索在结构化查询(如继承关系、嵌套结构)上的不足,我们同步构建了 AST 关系图。

* **模型设计**:
* **节点**:File, Symbol (Class, Method, Interface)
* **边**:Contains (包含), Extends (继承), Implements (实现)
* *注:当前版本主要关注“定义(Definition)”关系,暂未包含“引用(Reference/Call Graph)”关系,以保持索引构建的轻量化。*
* **存储**:将 AST 关系降维为 Datalog 事实表(Facts),存入图数据库。

---

## 3. 存储引擎选型 (Storage Engine)

我们采用了“双引擎”策略,分别处理向量检索和图查询。

### 3.1 向量存储:LanceDB

* **技术背景**:基于 Apache Arrow 和 Lance 数据格式的新一代向量数据库。
* **选型理由**:
* **Serverless 架构**:不同于 Milvus/Qdrant 需要独立服务进程,LanceDB 是嵌入式的(类似 SQLite),数据即文件。
* **列式存储**:原生支持 Arrow 格式,Zero-copy 读取,极大降低内存开销。
* **多模态支持**:单表支持向量索引(IVF-PQ)与标量字段(全文检索),便于混合查询。
* **Rust 内核**:保证了极高的 I/O 吞吐和稳定性。

### 3.2 图存储:CozoDB

* **技术背景**:基于 Datalog 的事务型、关系型/图混合数据库。
* **选型理由**:
* **递归查询能力**:原生支持 Datalog 推理规则,能够优雅处理代码中的递归结构(如多层继承链、模块依赖树),这是标准 SQL (SQLite) 难以高效实现的。
* **轻量级嵌入**:底层存储引擎可插拔(支持 RocksDB, SQLite, Sled),我们默认使用 SQLite 后端,保持了单文件部署的简洁性。
* **WASM 支持**:具备回退到纯内存 WASM 模式的能力,保证在极端环境下的可用性。

---

## 4. 技术栈横向对比 (Benchmark & Comparison)

| 维度 | git-ai (本方案) | Sourcegraph (Zoekt) | CTags / GTags | 基于 OpenAI 的方案 |
| :--- | :--- | :--- | :--- | :--- |
| **核心算法** | Hash Embedding + AST Graph | Trigram Index (N-gram) | 正则/词法分析 | LLM Embedding |
| **检索模式** | 混合检索 (语义+结构) | 精确/正则匹配 | 符号跳转 | 纯语义相似度 |
| **依赖环境** | Node.js Runtime (零外部依赖) | Go Server, Docker | C 编译环境 | Python/GPU/API Key |
| **索引体积** | 小 (~15-20%) | 中等 (~30%) | 极小 (<5%) | 极大 (向量维度高) |
| **语义理解** | 中 (基于词袋模型) | 无 | 无 | 高 |
| **部署成本** | **极低 (CLI 工具)** | 高 (需运维集群) | 低 | 中/高 |

## 5. 总结与展望

`git-ai` 的架构本质上是在**检索效果**与**工程成本**之间寻找的一个极致平衡点。

通过 **Tree-sitter + Hash Embedding + LanceDB + CozoDB** 的组合,我们在不引入任何重型依赖的前提下,实现了对代码库的**语义级(Vector)**和**结构级(Graph)**的双重索引。这种架构特别适合作为 AI Agent 的“代码知识外脑”,为其提供精准、快速的上下文检索能力。
33 changes: 33 additions & 0 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,43 @@ git-ai push -u origin main
```bash
git-ai ai index --overwrite
git-ai ai query "search text" --limit 20
git-ai ai query "get*repo" --mode wildcard --case-insensitive --limit 20
git-ai ai semantic "semantic query" --topk 10
git-ai ai graph find "Foo"
git-ai ai graph children src/mcp/server.ts --as-file
git-ai ai graph query "?[name, kind] := *ast_symbol{ref_id, file, name, kind, signature, start_line, end_line}" --params "{}"
git-ai ai pack
git-ai ai unpack
git-ai ai hooks install
git-ai ai serve
```

## 符号搜索模式(ai query)

`git-ai ai query` 默认是子串搜索;当你的输入包含 `*` / `?` 时,或显式指定 `--mode`,可以启用更适合 code agent 的搜索模式:

- `--mode substring`:子串匹配(默认)
- `--mode prefix`:前缀匹配
- `--mode wildcard`:通配符(`*` 任意串,`?` 单字符)
- `--mode regex`:正则
- `--mode fuzzy`:模糊匹配(子序列)

常用参数:
- `--case-insensitive`:大小写不敏感
- `--max-candidates <n>`:先拉取候选再过滤的上限(模式为 wildcard/regex/fuzzy 时有用)

## AST 图搜索(CozoDB)

> **实战指南**:觉得命令太抽象?请查看 [AST 图谱实战指南](./graph_scenarios.md) 了解如何查找定义、父类、子类等常见场景。

`git-ai ai index` 会在 `.git-ai/` 下额外维护一份 AST 关系图数据库(默认文件名:`.git-ai/ast-graph.sqlite`)。

图搜索相关命令:
- `git-ai ai graph find <prefix>`:按符号名前缀(不区分大小写)查找
- `git-ai ai graph children <id>`:列出包含关系的直接子节点(`id` 可以是 `ref_id` 或 `file_id`)
- `git-ai ai graph children <file> --as-file`:把 `<file>` 视作 repo 相对路径,自动换算为 `file_id`
- `git-ai ai graph query "<CozoScript>" --params '<JSON>'`:直接执行 CozoScript 查询

依赖说明:
- 默认优先使用 `cozo-node`(SQLite 持久化)
- 若 `cozo-node` 不可用,会回退到 `cozo-lib-wasm`(内存引擎,通过导出文件实现跨进程复用)
Loading