ragjson
遵循 RAG-Storage-Spec 规范的基于文件系统的 RAG 知识库构建工具。
将文档解析为 Markdown、切片、生成向量嵌入,并以 .ragjson 格式存储到文件系统中 —— 零外部数据库依赖。
特性
- 零外部依赖:仅依赖操作系统文件系统,无需向量数据库或中间件
- 文档解析:内置 markitdown 解析引擎
- 文本切片:支持 RecursiveCharacterTextSplitter(默认)和 MarkdownTextSplitter
- Embedding:兼容 OpenAI API 的向量生成
- 原子写入:write-to-tmp + rename 保证写入安全性
- 增量更新:基于 MD5 对比,仅处理变更文件
- 目录级并发:不同目录可并行处理,目录内 flock 互斥
安装
# 全局安装为独立命令(推荐,无需 venv)
uv tool install ragjson
或在项目虚拟环境中使用:
uv venv
source .venv/bin/activate
uv pip install ragjson
本地开发模式(从源码安装):
uv venv
uv pip install -e .
source .venv/bin/activate
配置
在用户 home 目录下创建 ~/.rag.config 文件(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 |
使用方法
查看状态
# 当前目录
rag status
# 指定目录
rag status ./docs
# 递归扫描子目录
rag status ./docs -r
# 单文件
rag status ./docs/readme.md
输出说明:
- 🟢 EMBEDDED — 已完成嵌入且 MD5 一致,无需更新
- 🟢 TRACKED — 子目录存在且被跟踪
- 🔴 NEW / CHANGED — 新文件或 MD5 已变更,需要更新
- 🟡 DELETED / DIR_DELETED / SLICING / EMBEDDING — 中间状态或已标记删除
增量更新
仅处理 MD5 发生变化的文件,执行完整流水线:解析 → 切片 → 嵌入 → 写入
# 使用默认切片器 (recursive)
rag update ./docs
# 递归更新子目录
rag update ./docs -r
# 使用 Markdown 切片器
rag update ./docs --splitter markdown
# 指定并发数
rag update ./docs -r -j 4
# 强制重新处理所有文件(跳过 MD5 检查)
rag update ./docs -f
# 单文件更新
rag update ./docs/readme.md
# 单文件强制更新
rag update ./docs/readme.md -f
参数说明:
| 参数 | 说明 | 默认值 |
|---|---|---|
-r |
递归扫描子目录 | 否 |
-f |
强制重新处理所有文件(跳过 MD5 检查) | 否 |
-j N |
并行处理的目录数 | CPU 核心数 |
--splitter |
切片器类型:recursive / markdown |
recursive |
导出
将 .ragjson 文件打包为 tar.gz 归档:
rag export backup.tar.gz # 仅当前目录
rag export backup.tar.gz -r # 递归包含子目录
rag export backup.tar.gz ./docs/a.md # 导出单文件
清理 .rag 目录
# 清理当前目录
rm -rf .rag
# 递归清理所有子目录
find . -name ".rag" -type d -exec rm -rf {} +
索引同步
将向量同步到向量数据库:
# 增量同步(消费 .mushroom 变更通知)
rag index
# 递归增量同步
rag index -r
# 全量同步(扫描所有 EMBEDDED 的 .ragjson,不依赖 mushroom)
rag index -f
# 递归全量同步
rag index -f -r
# 单文件补偿索引(需要 -f)
rag index -f ./docs/readme.md
参数说明:
| 参数 | 说明 | 默认值 |
|---|---|---|
-r |
递归扫描子目录 | 否 |
-f |
全量同步(跳过 mushroom,扫描所有 .ragjson) | 否 |
向量数据库路径和索引类型在 ~/.rag.config 的 vector_database 节配置。
孤儿向量检测
扫描向量数据库中已删除文件残留的孤儿向量:
# 扫描当前目录下的孤儿向量(仅列出,不删除)
rag orphans
# 扫描指定路径下的孤儿向量
rag orphans /root/ragjson-data
# 扫描并一键清除孤儿向量
rag orphans --clean
参数说明:
| 参数 | 说明 | 默认值 |
|---|---|---|
path |
扫描路径前缀 | .(当前目录) |
--clean |
检测后删除孤儿向量 | 否 |
MCP Server
启动 MCP Server(stdio 模式),供外部 MCP Client(如 Claude Desktop、Cursor)连接:
# 启动 server
rag mcp
MCP Client 配置示例(Claude Desktop claude_desktop_config.json):
{
"mcpServers": {
"ragjson": {
"command": "rag",
"args": ["mcp"]
}
}
}
提供的能力:
| 类型 | 名称 | 说明 |
|---|---|---|
| Tool | query(q, topn) |
语义搜索知识库 |
| Resource | ragjson://directory/{path} |
目录文件列表(渐进浏览) |
| Resource | ragjson://file/{name} |
单文件元数据 |
| Resource | ragjson://chunks/{name} |
文件切片详情 |
| Resource | ragjson://orphans/{path} |
目录下孤儿向量检测 |
注意:Resource 的路径参数需要 URL 编码(FastMCP 的 [^/]+ 正则不支持 /):
原始路径: /root/ragjson-data/data
编码后: %2Froot%2Fragjson-data%2Fdata
URI 示例: ragjson://directory/%2Froot%2Fragjson-data%2Fdata
目录结构
执行 rag update 后的目录结构示例:
docs/
├── .rag/ # 控制目录
│ ├── tmp/ # 原子写入暂存区
│ ├── readme.md.ragjson # 文件条目(readme.md 的元数据)
│ ├── manual.pdf.ragjson # 文件条目(manual.pdf 的元数据)
│ └── appendix.ragjson # 目录条目(跟踪 appendix/ 子目录)
├── readme.md # 源文件
├── manual.pdf # 源文件
└── appendix/ # 被跟踪的子目录
└── ...
.ragjson 文件格式
文件条目
{
"ragjson_version": "2.4",
"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=="
}
]
}
目录条目
用于跟踪子目录的存在性,格式极简:
{"ragjson_version": "2.4"}
支持的文件类型
.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)
目录级别跟踪
rag update 自动跟踪子目录的存在性:
- 新建子目录 → 在父目录的
.rag/下创建目录条目({dirname}.ragjson) - 删除子目录 → rename 为
.ragjson.deleted,mushroom 记录dir_delete事件 - 恢复子目录 → rename 回
.ragjson,mushroom 记录dir_recover事件
rag index 对目录事件的处理:
dir_delete→ 按路径前缀(LIKE)批量删除向量数据库中的孤儿向量dir_recover→ 提示用户清除旧.rag数据后重新 update 和 index
rag status 显示目录跟踪状态:
- 🟢 TRACKED — 子目录存在且被跟踪
- 🟡 DIR_DELETED — 子目录已被删除
项目架构
src/ragjson/
├── commands/ # CLI 命令(status, update, export, index, mcp)
├── embed/ # Embedding 生成(OpenAI 兼容 API)
├── index/ # 向量索引(zvec backend,可扩展)
├── mcp/ # MCP Server(stdio 传输,tool + resource)
├── parser/ # 文档解析(markitdown backend,可扩展)
├── splitter/ # 文本切片(recursive / markdown)
├── store/ # 存储层(ragjson 文件、原子操作、mushroom)
├── config.py # ~/.rag.config 配置加载
├── utils.py # 工具函数(MD5、向量编码、颜色输出)
└── cli.py # CLI 入口
向量数据库 Collection Schema
zvec collection ragjson 的字段定义:
| 字段 | 类型 | 索引 | 说明 |
|---|---|---|---|
source_path |
STRING | InvertIndex | 文件完整绝对路径 |
source_dir |
STRING | InvertIndex | 文件所在目录 |
content |
STRING | — | 切片文本内容 |
content_hash |
STRING | — | 切片内容 MD5 |
embedding |
VECTOR_FP32 | Flat/HNSW | 向量嵌入 |
文档 ID 使用 uuid5(namespace, f"{source_path}#{chunk_index}") 生成:
- 确定性:相同
source_path+chunk_index→ 相同 UUID - 跨后端一致:zvec、pgvector 等后端使用统一 ID 格式
- 支持任意字符:中文、特殊符号等文件名均可正确处理
升级提示:
从 0.4.x 升级到 0.5.0 后,向量数据库 schema 变更(source → source_path,新增 source_dir):
rag index -f -r # 必须重新索引
从 0.3.x 升级到 0.4.0 后:
- 规范版本从 v2.3 升至 v2.4,新增目录级别跟踪能力
- 文件类
.ragjson格式不变,现有数据无需迁移 rag update -r会自动为子目录创建跟踪条目
从 0.3.1 升级到 0.3.2 后(uuid5 文档 ID):
- 需要重新索引所有文档:
rag index -f -r
开发
# 克隆项目
git clone <repo>
cd ragjson
# 创建虚拟环境并安装开发版本
uv venv
uv pip install -e ".[index,mcp]"
source .venv/bin/activate
# 运行 CLI
rag --help
许可证
MIT
Metadata
Release files for ragjson 0.5.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ragjson-0.5.1.tar.gz | 42.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ragjson-0.5.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 85.0 kB
Release files / ragjson-0.5.1.tar.gz
| Download URL | ragjson-0.5.1.tar.gz |
|---|---|
| Size | 42.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
125817638b2fb8fb601a295d16321b0d2cf520e0bff261ff962aff9fe1dc9080
|
|
BLAKE2b-256 checksum How to use checksums |
0da71c35a596cb7ba16c94776448580434df7f247d26a3bb0214fb9b8d4b35f5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.11 {"installer":{"name":"uv","version":"0.12.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / ragjson-0.5.1-py3-none-any.whl
| Download URL | ragjson-0.5.1-py3-none-any.whl |
|---|---|
| Size | 42.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
53b6356b2ea63bdf944633da6b650e342d389197c37b4d5e6849ce7ac2dd2df8
|
|
BLAKE2b-256 checksum How to use checksums |
cfa08819b3738d10b7fd64c87030acbe47e89f76845c8ad054cece804a9f0d7d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.11 {"installer":{"name":"uv","version":"0.12.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|