ragx
by JIEAO-re
README.md
# ragx — 集各家之所长的自研 RAG 检索系统
[](https://github.com/JIEAO-re/ragx/actions/workflows/ci.yml)
[](LICENSE)


**[English](README.en.md) · 简体中文**
一套可直接给 agent 用的检索增强系统:**强解析 + 混合检索 + 重排 + 带引用的 agentic 回答**,
同时提供 **核心引擎(Python 库)+ MCP server + REST API(含 OpenAI 兼容 `/v1/chat/completions`)** 三种接入方式。
## 设计理念(集各家之所长)
| 层 | 借鉴自 | 本项目实现 |
|---|---|---|
| 解析 | RAGFlow DeepDoc | PyMuPDF + python-docx/pptx + openpyxl + trafilatura + 代码感知,按页/幻灯片/工作表分块 |
| 切分 | LlamaIndex | 递归字符切分 + Markdown 标题感知 + 代码 tree-sitter AST 边界(装 `[code]` 时,否则定义行启发式);重叠出口统一施加一次 |
| 向量化 | BGE-M3 | 一个模型同时产出 dense + sparse,混合检索的基础 |
| 向量库 | Qdrant | 本地嵌入式(免 Docker)+ dense/sparse 命名向量 |
| 混合检索 | R2R / Weaviate | 向量召回 + 稀疏召回 → RRF 融合 |
| 重排 | bge-reranker-v2-m3 | cross-encoder 精排 |
| Agentic | Self-RAG / LangGraph | 多查询改写 → 检索 → 重排 → 可选相关性过滤 → 带 [n] 引用生成 |
| 生成 | Claude | Opus 4.8 生成答案,Haiku 4.5 做改写/打分(省钱) |
**模型路线**:embedding/rerank 本地跑(BGE,省钱、可离线建索引),生成用 Claude API(效果最好)。
## 安装
```bash
pip install -e .
# 可选增强(按需):
pip install -e ".[web,code]" # 更好的网页正文抽取 + 代码 AST 切分
pip install -e ".[graph]" # GraphRAG 多跳(LightRAG)
pip install -e ".[vision]" # 更强的表格抽取(图片走核心 PyMuPDF + Claude vision)
pip install -e ".[eval]" # 评测(可选 ragas)
```
配置(复制 `.env.example` 为 `.env`):默认必填 `ANTHROPIC_API_KEY`,其余按需。
首次运行会自动下载 BGE-M3(约 2GB)和 reranker 模型。
### 用 OpenAI 兼容端点 / 中转站(可选)
生成层默认走 Claude,也可切到任意 **OpenAI 格式** 的 `/v1/chat/completions` 端点
(真 OpenAI、Azure、API 中转站、vLLM、Ollama、DeepSeek…):
```bash
pip install -e ".[openai]"
# .env:
RAGX_LLM_PROVIDER=openai
RAGX_OPENAI_BASE_URL=https://你的中转站/v1
RAGX_OPENAI_API_KEY=sk-xxx # 或留空走环境变量 OPENAI_API_KEY
RAGX_ANSWER_MODEL=... # 填端点支持的模型名
RAGX_UTILITY_MODEL=...
```
embedding/rerank 仍是本地 BGE(省钱、可离线),只有生成/改写/打分/vision 走该端点。
结构化输出优先用 `response_format=json_object`,端点不支持时自动回退到 prompt 约束 + 校验,
因此对各类中转站都鲁棒。
## 快速开始
```bash
# 1. 摄入文档(支持 PDF / Word / PPT / Excel / CSV / Markdown / 网页 / 代码)
ragx ingest ./docs
ragx ingest --url https://example.com/article
# 2. 检索(只召回不生成)
ragx search "向量库怎么选"
# 3. 问答(流式输出 + 引用来源)
ragx ask "这个项目用的是什么混合检索方案?"
# 4. 状态
ragx stats
```
### 作为 Python 库
```python
from ragx import RAGEngine
engine = RAGEngine()
engine.ingest_path("./docs")
ans = engine.answer("项目用的什么向量库?")
print(ans.text)
for c in ans.citations:
print(c.marker, c.source, c.metadata)
```
### 作为 MCP server(挂到 Claude Code / Desktop / Cursor)
```bash
ragx serve-mcp
```
Claude Desktop 配置:
```json
{ "mcpServers": { "ragx": { "command": "ragx", "args": ["serve-mcp"] } } }
```
暴露工具:`rag_answer`、`rag_graph_answer`(需开启 GraphRAG)、`rag_search`、`rag_ingest`、`rag_stats`。
### 作为 REST API
```bash
ragx serve-rest --port 8000 # 打开 http://localhost:8000/docs
```
- `POST /ingest` `{path | url | text(+source)}`
- `POST /search` `{query, top_k?, top_n?, use_hybrid?}`
- `POST /answer` `{query, reflect?, route?}` → 答案 + 引用
- `POST /answer/stream` `{query, ...}` → SSE 流式(token / reflection / final 事件)
- `POST /graph/answer` `{query}` → GraphRAG 融合问答(需 `RAGX_ENABLE_GRAPH=true`)
- `POST /eval` `{cases:[...]}` → 批量评测
- `GET /stats`、`GET /health`
> `route` 取值 `auto|vector|graph|hybrid`,非法值返回 422。
#### OpenAI 兼容端点
`POST /v1/chat/completions`(+ `GET /v1/models`)让 ragx 能当成一个"会查你资料的模型",
直接接入任意 OpenAI 客户端(OpenAI SDK / ChatBox / Cherry Studio / LangChain…):
```python
from openai import OpenAI
client = OpenAI(base_url="https://your-host/v1", api_key="<RAGX_API_KEYS 里的一把>")
print(client.chat.completions.create(model="ragx",
messages=[{"role":"user","content":"..."}]).choices[0].message.content)
```
取最后一条 user 消息作为检索 query,答案末尾附 `[n] 来源`;支持 `stream`。
## 架构
```
parsing → chunking → embedding(BGE-M3) → store(Qdrant: dense+sparse)
│
query ─► rewrite ─► retrieve(hybrid+RRF) ─► rerank(BGE) ─► [grade] ─► answer(Claude, 带引用)
│
RAGEngine ── 核心引擎
├── server_mcp.py (MCP)
└── server_rest.py (REST)
```
模块一览:
- 核心:`config` · `types` · `parsing` · `chunking` · `embedding` · `reranking` · `store` · `retrieval` · `agent` · `engine` · `llm` · `prompts`
- v2 地基:`logging` · `errors` · `registry`(去重+vision缓存)
- v2 特性:`eval`(评测)· `media` + `vision`(多模态)· `graph_index` + `router` + `graph_agent`(GraphRAG)
- 接口:`cli` · `server_mcp` · `server_rest`
## 并发说明
默认本地嵌入式 Qdrant 单进程独占目录。若要 REST/MCP 与后台摄入同时跑,用 Docker 起 Qdrant:
```bash
docker run -p 6333:6333 qdrant/qdrant
export RAGX_QDRANT_URL=http://localhost:6333
```
## 高级特性(v2,默认关闭,按需开启)
所有高级特性默认 **关闭**,关闭时与 v1 核心路径行为一致;通过 `.env` 开关或命令行参数启用。
### 增量去重(默认开)
内容 hash 注册表(SQLite),重复摄入自动跳过未变文件;`--force` 强制重建。
摄入采用"先嵌后删",消除数据丢失窗口。
### self-RAG 反思
答案自评,不足则改写查询补检索(bounded 迭代):
```bash
ragx ask --reflect "需要多跳推理的问题"
# 或全局开启:RAGX_ENABLE_REFLECTION=true
```
### 多模态(表格 + 图片 + 公式)
表格结构化抽取(不花钱),图片/图表/公式经 Claude vision 转写后入库,按内容 hash 缓存(重摄入不重复付费):
```bash
pip install -e ".[vision]"
ragx ingest ./report.pdf --vision # 或 RAGX_ENABLE_VISION=true
```
### GraphRAG 多跳(集成 LightRAG)
全局/关系型问题用知识图谱 + 向量证据融合;查询自动路由(含"关系/总体/之间"等信号词走图谱):
```bash
pip install -e ".[graph]"
export RAGX_ENABLE_GRAPH=true
ragx ingest ./docs # 摄入时同步建图
ragx ask --route hybrid "梳理各模块之间的关系"
ragx graph-stats
```
LightRAG 复用本项目的 BGE embedding 与 Claude,存储落在 `.ragx/lightrag/`;未安装 `[graph]` 时图谱功能优雅降级(自动回退向量检索)。
### 评测框架(RAGAS 式)
```bash
ragx eval examples/eval_cases.jsonl --out report.json
# 指标:召回 / 忠实度 / 答案正确性 / 引用准确率 + 平均延迟(LLM-as-judge)
```
## 工程地基(v2)
结构化日志(`RAGX_LOG_LEVEL`)、类型化异常、模型惰性加载线程安全(双重检查锁)、
逐请求覆盖(`top_k/top_n/use_hybrid/reflect/route` 可在 CLI/REST/MCP 单次调用覆盖)、
embedding 维度校验、输入护栏与超时。57 个测试覆盖切分/去重/混合检索/引用/反思/多模态/路由/鉴权/OpenAI 后端。
## 对外部署(Docker:Caddy 自动 HTTPS + Qdrant + 鉴权)
仓库自带 `Dockerfile` / `docker-compose.yml` / `Caddyfile`。架构:**只有 Caddy 暴露公网(443)**,
反代到内部的 ragx(带 Bearer 鉴权),ragx 再连内部 Qdrant;中转站/Anthropic key 只存在 ragx 容器里。
```bash
cp .env.example .env # 填 RAGX_LLM_PROVIDER / RAGX_OPENAI_* / RAGX_API_KEYS(对外必设)
# Caddyfile 把 rag.example.com 换成解析到本机的域名(纯 IP 拿不到 Let's Encrypt 证书)
mkdir -p docs # 要摄入的文档放这里
docker compose up -d --build # 首次构建较久;模型在首次 ingest 时下载并缓存到卷
docker compose exec ragx ragx ingest /data/docs # 摄入(管理操作走容器内 CLI,不经公网)
```
外部调用(带 key):
```bash
curl -X POST https://rag.example.com/answer \
-H "Authorization: Bearer <RAGX_API_KEYS 里的一把>" \
-H "Content-Type: application/json" -d '{"query":"..."}'
```
**鉴权分权**:`RAGX_API_KEYS`=只读(`/answer` `/search` `/stats`);`RAGX_ADMIN_API_KEYS`=可写(`/ingest` `/eval`),
留空则任意读 key 亦可写。`/health` 不鉴权(供探活)。**不配 key=不鉴权,只可用于本地/内网。**
## 路线图(后续)
- [ ] LightRAG 实路径的端到端联调(需安装 `[graph]` + API key)
- [ ] 评测接 ragas 官方指标
- [ ] 异步摄入与多进程并发(配合 Docker Qdrant)
- [ ] 图谱增量重建命令 `graph-rebuild`
## License
MIT
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues