Metadata-Version: 2.4
Name: ragjson
Version: 0.2.0
Summary: 遵循RAG-Storage-Spec的知识库构建工具
Requires-Python: >=3.12
Requires-Dist: langchain-text-splitters>=0.3
Requires-Dist: markitdown[all]
Requires-Dist: openai>=1.0
Provides-Extra: index
Requires-Dist: zvec>=0.5; extra == 'index'
Description-Content-Type: text/markdown

# ragjson

遵循 [RAG-Storage-Spec](docs/RAG-Storage-Spec.md) 规范的基于文件系统的 RAG 知识库构建工具。

将文档解析为 Markdown、切片、生成向量嵌入，并以 `.ragjson` 格式存储到文件系统中 —— 零外部数据库依赖。

## 特性

- **零外部依赖**：仅依赖操作系统文件系统，无需向量数据库或中间件
- **文档解析**：内置 markitdown 解析引擎
- **文本切片**：支持 RecursiveCharacterTextSplitter（默认）和 MarkdownTextSplitter
- **Embedding**：兼容 OpenAI API 的向量生成
- **原子写入**：write-to-tmp + rename 保证写入安全性
- **增量更新**：基于 MD5 对比，仅处理变更文件
- **目录级并发**：不同目录可并行处理，目录内 flock 互斥

## 安装

```bash
# 全局安装为独立命令（推荐，无需 venv）
uv tool install ragjson
```

或在项目虚拟环境中使用：

```bash
uv venv
source .venv/bin/activate
uv pip install ragjson
```

本地开发模式（从源码安装）：

```bash
uv venv
uv pip install -e .
source .venv/bin/activate
```

## 配置

在用户 home 目录下创建 `~/.rag.config` 文件（JSON 格式）：

```json
{
  "embedding_model": {
    "base_url": "https://api.example.com/v1",
    "api_key": "sk-your-token",
    "model_name": "text-embedding-3-small",
    "dimension": 1536
  },
  "splitter": {
    "chunk_size": 1000,
    "chunk_overlap": 200
  },
  "vector_database": {
    "db_url": "zvec:/data/vectordb",
    "index_type": "flat"
  }
}
```

| 配置项 | 说明 |
|--------|------|
| `embedding_model.base_url` | OpenAI 兼容 API 的地址 |
| `embedding_model.api_key` | API 密钥 |
| `embedding_model.model_name` | Embedding 模型名称 |
| `embedding_model.dimension` | 向量维度 |
| `splitter.chunk_size` | 切片最大字符数 |
| `splitter.chunk_overlap` | 切片重叠字符数 |
| `vector_database.db_url` | 向量数据库目录（collection 在其下的 `zvec-db1/`） |
| `vector_database.index_type` | 索引类型：`flat` / `hnsw` |

## 使用方法

### 查看状态

```bash
# 当前目录
rag status

# 指定目录
rag status ./docs

# 递归扫描子目录
rag status ./docs -r
```

输出说明：
- 🟢 **EMBEDDED** — 已完成嵌入且 MD5 一致，无需更新
- 🔴 **NEW / CHANGED** — 新文件或 MD5 已变更，需要更新
- 🟡 **DELETED / SLICING / EMBEDDING** — 中间状态或已标记删除

### 增量更新

仅处理 MD5 发生变化的文件，执行完整流水线：**解析 → 切片 → 嵌入 → 写入**

```bash
# 使用默认切片器 (recursive)
rag update ./docs

# 递归更新子目录
rag update ./docs -r

# 使用 Markdown 切片器
rag update ./docs --splitter markdown

# 指定并发数
rag update ./docs -r -j 4
```

参数说明：

| 参数 | 说明 | 默认值 |
|------|------|--------|
| `-r` | 递归扫描子目录 | 否 |
| `-j N` | 并行处理的目录数 | CPU 核心数 |
| `--splitter` | 切片器类型：`recursive` / `markdown` | `recursive` |

### 销毁

删除 `.rag/` 目录及所有元数据（高危操作，需确认）：

```bash
rag destroy ./docs
rag destroy ./docs -r      # 递归销毁
rag destroy ./docs -y      # 跳过确认提示
```

### 导出

将 `.ragjson` 文件打包为 tar.gz 归档：

```bash
rag export backup.tar.gz          # 仅当前目录
rag export backup.tar.gz -r       # 递归包含子目录
```

### 索引同步

消费 `.mushroom` 变更通知文件，将向量同步到向量数据库（需安装 `ragjson[index]`）：

```bash
# 同步当前目录
rag index

# 递归同步子目录
rag index -r
```

向量数据库路径和索引类型在 `~/.rag.config` 的 `vector_database` 节配置。

安装索引依赖：

```bash
uv pip install ragjson[index]
```

## 目录结构

执行 `rag update` 后的目录结构示例：

```
docs/
├── .rag/                          # 控制目录
│   ├── tmp/                       # 原子写入暂存区
│   ├── readme.md.ragjson          # readme.md 的元数据
│   └── manual.pdf.ragjson         # manual.pdf 的元数据
├── readme.md                      # 源文件
└── manual.pdf                     # 源文件
```

## `.ragjson` 文件格式

```json
{
  "ragjson_version": "2.2",
  "processing": {
    "status": "EMBEDDED",
    "create_dt": "2026-07-14T10:00:00Z",
    "modify_dt": "2026-07-14T12:00:00Z"
  },
  "source": {
    "file_name": "readme.md",
    "md5_hash": "d41d8cd98f00b204e9800998ecf8427e",
    "size_bytes": 2048,
    "mtime": 1710508800,
    "inode": 12345678
  },
  "embedding": {
    "model_name": "text-embedding-3-small",
    "dimension": 1536
  },
  "chunks": [
    {
      "content": "切片完整原文内容...",
      "content_hash": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
      "overlap_size": 0,
      "vector_base64": "P0A/0D9A/0D9A/0D9A=="
    }
  ]
}
```

## 支持的文件类型

`.pdf` `.docx` `.doc` `.pptx` `.ppt` `.xlsx` `.xls` `.md` `.txt` `.html`

## 状态流转

```
INITIAL → CHUNKING → CHUNKED → EMBEDDING → EMBEDDED
                                            ↓
    (源文件变更) ←─────────────────── INITIAL (回退)

    源文件删除：任意状态 → rename .ragjson → .ragjson.deleted
    源文件恢复：.ragjson.deleted → rename .ragjson → (update 检测 MD5)
```

## 项目架构

```
src/ragjson/
├── commands/     # CLI 命令（status, update, destroy, export, index）
├── embed/        # Embedding 生成（OpenAI 兼容 API）
├── index/        # 向量索引（zvec backend，可扩展）
├── parser/       # 文档解析（markitdown backend，可扩展）
├── splitter/     # 文本切片（recursive / markdown）
├── store/        # 存储层（ragjson 文件、原子操作、mushroom）
├── config.py     # ~/.rag.config 配置加载
├── utils.py      # 工具函数（MD5、向量编码、颜色输出）
└── cli.py        # CLI 入口
```

## 开发

```bash
# 克隆项目
git clone <repo>
cd ragjson

# 创建虚拟环境并安装开发版本
uv venv
uv pip install -e ".[index]"
source .venv/bin/activate

# 运行 CLI
rag --help
```

## 许可证

MIT
