# RAGFlow

RAGFlow 是一个开源的 **检索增强生成（RAG）引擎** 具有深度文档理解能力。拥有超过 **50,000 个 GitHub 星标**，它是最全面的 RAG 平台之一——用于提取、分块并推理复杂文档，包括 PDF、Word 文件、电子表格、图像等。

不同于将文档简单分块的基础 RAG 系统，RAGFlow 使用感知布局的解析来理解文档结构、表格、图示和多栏布局。这显著提高了检索精度和答案质量。

主要功能：

* 📄 **深度文档理解** — OCR、表格提取、图像识别
* 🔍 **多种分块策略** — 语义、感知布局、固定大小、问答式
* 🤖 **LLM 集成** — 支持 OpenAI、Ollama、Anthropic、本地模型
* 🌐 **功能齐全的 WebUI** — 拖放式文档管理
* 🔌 **REST API** — 将 RAGFlow 集成到任何应用中
* 📊 **引用追踪** — 答案包含来源文档引用
* 🏗️ **多租户** — 带权限控制的团队工作区

{% hint style="success" %}
所有示例都可以在通过以下方式租用的 GPU 服务器上运行 [CLORE.AI 市场](https://clore.ai/marketplace).
{% endhint %}

***

## 服务器要求

| 参数       | 最低要求                   | 推荐配置                    |
| -------- | ---------------------- | ----------------------- |
| GPU      | NVIDIA RTX 3080（10 GB） | NVIDIA RTX 4090（24 GB）  |
| 显存（VRAM） | 8 GB                   | 16–24 GB                |
| 内存（RAM）  | 16 GB                  | 32–64 GB                |
| CPU      | 8 核                    | 16+ 核                   |
| 磁盘       | 50 GB                  | 100–500 GB              |
| 操作系统     | Ubuntu 20.04+          | Ubuntu 22.04            |
| CUDA     | 11.8+                  | 12.1+                   |
| 端口       | 22, 9380, 80           | 22, 9380, 80            |
| Docker   | 需要                     | Docker + Docker Compose |

{% hint style="warning" %}
RAGFlow 在主应用之外还运行多个服务（Elasticsearch、MinIO、MySQL、Redis、Nginx）。请确保有足够的内存（最少 16 GB，建议 32 GB）和磁盘空间。
{% endhint %}

***

## 在 CLORE.AI 上快速部署

### 1. 找到合适的服务器

前往 [CLORE.AI 市场](https://clore.ai/marketplace) 并按以下条件筛选：

* **显存（VRAM）**: ≥ 8 GB
* **内存（RAM）**：≥ 16 GB
* **磁盘**：≥ 50 GB
* **GPU**：RTX 3090、4090、A100、H100

### 2. 配置您的部署

**Docker 镜像：**

```
infiniflow/ragflow:latest
```

**端口映射：**

```
22   → SSH 访问
80   → RAGFlow Web 界面（HTTP）
9380 → RAGFlow API
```

**启动命令：**

```bash
bash -c "docker-compose -f docker/docker-compose.yml up -d"
```

### 3. 访问 WebUI

```
http://<your-clore-server-ip>:80
```

默认凭据： `admin@ragflow.io` / `admin`

***

## 逐步设置

### 第一步：SSH 登录到您的服务器

```bash
ssh root@<your-clore-server-ip> -p <ssh-port>
```

### 第 2 步：安装 Docker Compose

```bash
apt-get update && apt-get install -y docker-compose-plugin

# 验证
docker compose version
```

### 第 3 步：克隆 RAGFlow 仓库

```bash
cd /workspace
git clone https://github.com/infiniflow/ragflow.git
cd ragflow
```

### 第 4 步：配置环境

```bash
# 复制并编辑环境文件
cp docker/.env.example docker/.env
nano docker/.env
```

需要配置的关键设置：

```env
# LLM 配置
OPENAI_API_KEY=your-openai-api-key

# 或使用本地 Ollama 实例
OLLAMA_BASE_URL=http://localhost:11434

# 存储设置
MINIO_USER=ragflow
MINIO_PASSWORD=infini_rag_flow

# MySQL 设置
MYSQL_PASSWORD=infini_rag_flow

# 应用端口
HTTP_PORT=80
RAGFLOW_API_PORT=9380
```

### 第 5 步：选择合适的镜像变体

```bash
# 检查可用标签
# 适用于 CUDA 12.1（大多数 RTX 卡）
docker pull infiniflow/ragflow:latest

# 针对特定 CUDA 版本
docker pull infiniflow/ragflow:v0.7.0-cuda12.1
```

### 第 6 步：启动所有服务

```bash
cd /workspace/ragflow/docker

# 启用 GPU 支持启动
docker compose -f docker-compose.yml up -d

# 监控启动（需 2-5 分钟）
docker compose logs -f
```

等待：

```
ragflow-server | INFO: Application startup complete.
```

### 第 7 步：创建管理员账号

打开 `http://<server-ip>:80` 并注册第一个管理员账号。

### 第 8 步：配置 LLM 模型

1. 前往 **设置 → 模型提供者**
2. 添加你的 LLM（OpenAI、Ollama 等）
3. 设置默认的聊天模型和嵌入模型

***

## 使用示例

### 示例 1：通过 WebUI 上传并查询文档

1. 登录到 `http://<server-ip>:80`
2. 点击 **“知识库”** → **“创建知识库”**
3. 命名为： `“Clore.ai 文档”`
4. 使用拖放上传 PDF/Word/TXT 文件
5. 等待解析（UI 中显示进度）
6. 前往 **“聊天”** → 创建与您的知识库关联的新助理
7. 就您的文档提出问题

***

### 示例 2：API — 创建知识库并上传文档

```python
import requests
import json
from pathlib import Path

BASE_URL = "http://<your-clore-server-ip>:9380"
API_KEY = "your-ragflow-api-key"  # 在 设置 → API 获取

headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json"
}

# 第 1 步：创建知识库
kb_payload = {
    "name": "Clore.ai Technical Docs",
    "description": "GPU 云市场文档和指南",
    "language": "English",
    "embedding_model": "text-embedding-ada-002",
    "chunk_method": "naive",  # 或 'qa'、'table'、'paper'、'book'
}

response = requests.post(
    f"{BASE_URL}/api/v1/knowledgebase",
    headers=headers,
    json=kb_payload
)
kb = response.json()
kb_id = kb["data"]["id"]
print(f"Created knowledge base: {kb_id}")

# 第 2 步：上传文档
pdf_path = Path("technical_manual.pdf")

with open(pdf_path, "rb") as f:
    files = {"file": (pdf_path.name, f, "application/pdf")}
    upload_response = requests.post(
        f"{BASE_URL}/api/v1/document/upload?kb_id={kb_id}",
        headers={"Authorization": f"Bearer {API_KEY}"},
        files=files
    )

doc = upload_response.json()
doc_id = doc["data"]["id"]
print(f"Uploaded document: {doc_id}")

# 第 3 步：开始解析
parse_response = requests.post(
    f"{BASE_URL}/api/v1/document/run",
    headers=headers,
    json={"doc_ids": [doc_id]}
)
print(f"Parsing started: {parse_response.json()}")
```

***

### 示例 3：通过 API 查询文档

```python
import requests
import json

BASE_URL = "http://<your-clore-server-ip>:9380"
API_KEY = "your-ragflow-api-key"
CHAT_ID = "your-chat-assistant-id"  # 来自 WebUI → 聊天

headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json"
}

def ask_ragflow(question, chat_id, session_id=None):
    """向 RAGFlow 发送问题并获取带引用的答案。"""
    "batch": {
        "question": question,
        "stream": False
    }

    if session_id:
        payload["session_id"] = session_id

    response = requests.post(
        f"{BASE_URL}/api/v1/chat/{chat_id}/completion",
        headers=headers,
        json=payload
    )

    result = response.json()
    if result.get("code") == 0:
        data = result["data"]
        answer = data.get("answer", "")
        references = data.get("reference", {}).get("chunks", [])
        return answer, references
    else:
        return None, []

# 示例查询
questions = [
    “Clore.ai 上可用的 GPU 规格有哪些？”,
    “我如何在市场上租用 GPU 服务器？”,
    “GPU 实例的定价模型是什么？”,
    “支持哪些深度学习框架？”,
]

for question in questions:
    print(f"\n📌 Q: {question}")
    answer, refs = ask_ragflow(question, CHAT_ID)
    print(f"💬 A: {answer}")
    if refs:
        print(f"📚 来源（{len(refs)} 个分块）：")
        for ref in refs[:2]:
            print(f"   - {ref.get('docnm_kwd', 'Unknown')}: {ref.get('content_ltks', '')[:100]}...")
```

***

### 示例 4：批量文档处理流水线

```python
import requests
import base64
from pathlib import Path

BASE_URL = "http://<your-clore-server-ip>:9380"
API_KEY = "your-ragflow-api-key"

headers = {"Authorization": f"Bearer {API_KEY}"}

def upload_and_parse_documents(kb_id, document_paths):
    """上传多个文档并等待解析完成。"""
    doc_ids = []

    # 上传所有文档
    for doc_path in document_paths:
        path = Path(doc_path)
        with open(path, "rb") as f:
            mime = "application/pdf" if path.suffix == ".pdf" else "text/plain"
            files = {"file": (path.name, f, mime)}
            resp = requests.post(
                f"{BASE_URL}/api/v1/document/upload?kb_id={kb_id}",
                headers=headers,
                files=files
            )
            if resp.status_code == 200:
                doc_id = resp.json()["data"]["id"]
                doc_ids.append(doc_id)
                print(f"✓ 已上传: {path.name} → {doc_id}")
            else:
                print(f"✗ 上传失败: {path.name}")

    # 开始批量解析
    if doc_ids:
        requests.post(
            f"{BASE_URL}/api/v1/document/run",
            headers={**headers, "Content-Type": "application/json"},
            json={"doc_ids": doc_ids}
        )
        print(f"\n正在解析 {len(doc_ids)} 个文档...")

        # 轮询直到完成
        while True:
            time.sleep(5)
            status_resp = requests.get(
                f"{BASE_URL}/api/v1/document/list?kb_id={kb_id}",
                headers=headers
            )
            docs = status_resp.json().get("data", {}).get("docs", [])
            pending = [d for d in docs if d.get("status") == "1"]  # 1 = 处理中
            done = [d for d in docs if d.get("status") == "2"]     # 2 = 完成

            print(f"  正在处理: {len(pending)} | 完成: {len(done)}/{len(doc_ids)}")

            if len(pending) == 0:
                break

    print("✓ 所有文档解析完成！")
    return doc_ids

# 使用示例
docs = ["manual_v1.pdf", "faq.txt", "api_reference.pdf"]
doc_ids = upload_and_parse_documents(kb_id="your-kb-id", document_paths=docs)
```

***

### 示例 5：RAGFlow 与本地 Ollama LLM

```bash
# 1. 在同一台 Clore.ai 服务器上安装 Ollama
curl -fsSL https://ollama.ai/install.sh | sh

# 2. 拉取本地模型
ollama pull llama3:8b
ollama pull nomic-embed-text  # 用于嵌入

# 3. 配置 RAGFlow 使用 Ollama
# 在 WebUI 中：设置 → 模型提供者 → 添加 Ollama
# 基础 URL: http://host.docker.internal:11434
# 或者如果 Ollama 在 Docker 中运行： http://ollama:11434
```

```python
# 测试 Ollama 集成
import requests

# 验证 Ollama 是否正在运行
resp = requests.get("http://localhost:11434/api/tags")
models = [m["name"] for m in resp.json()["models"]]
print(f"可用的 Ollama 模型: {models}")

# 使用本地 LLM 查询 RAGFlow（在 WebUI 中配置）
BASE_URL = "http://localhost:9380"
API_KEY = "your-api-key"
CHAT_ID = "your-chat-id"

response = requests.post(
    f"{BASE_URL}/api/v1/chat/{CHAT_ID}/completion",
    headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"},
    json={"question": "Explain the RAGFlow architecture", "stream": False}
)
print(response.json()["data"]["answer"])
```

***

## invokeai.yaml 配置文件

### docker-compose.yml 关键服务

```yaml
services:
  ragflow:
    image: infiniflow/ragflow:latest
    ports:
      - "9380:9380"
      - "80:80"
    environment:
      - HF_ENDPOINT=https://huggingface.co
      - MACOS=0
    depends_on:
      - mysql
      - minio
      - es01
      - redis

  es01:
    image: elasticsearch:8.11.3
    environment:
      - xpack.security.enabled=false
      - discovery.type=single-node
    volumes:
      - esdata01:/usr/share/elasticsearch/data

  mysql:
    image: mysql:8.0.39
    environment:
      - MYSQL_ROOT_PASSWORD=infini_rag_flow

  minio:
    image: quay.io/minio/minio:RELEASE.2023-12-20T01-00-02Z
    command: server /data --console-address ":9001"

  redis:
    image: redis:7.2.4
```

### 分块策略

| 方法       | 适合用于      | 描述         |
| -------- | --------- | ---------- |
| `naive`  | 通用文档      | 固定大小分块并有重叠 |
| `qa`     | 常见问题/问答文档 | 按问答对分割     |
| `table`  | 电子表格、表格   | 保留表格结构     |
| `paper`  | 学术论文      | 章节、摘要、参考文献 |
| `book`   | 长篇书籍、手册   | 支持章节感知的分块  |
| `laws`   | 法律文档      | 按条款分块      |
| `manual` | 技术手册      | 保留章节层级     |

***

## 1. 使用 SDXL-Turbo 或 SDXL-Lightning 以实现快速生成

### 1. 扩展 Elasticsearch 内存

```yaml
# 在 docker-compose.yml 中
es01:
  environment:
    - ES_JAVA_OPTS=-Xms4g -Xmx4g  # 针对大量文档集增加
```

### 2. GPU 加速嵌入

将 RAGFlow 配置为使用基于 GPU 的嵌入模型：

* 在 设置 → 模型提供者 中，通过 Ollama 使用本地 GPU 模型
* 或者指向运行在 Clore.ai GPU 上的专用嵌入服务

### 3. 并行文档处理

RAGFlow 默认并行处理文档。配置工作线程数：

```env
# 在 docker/.env 中
TASK_WORKER_COUNT=4  # 根据 CPU 内核调整
```

### 4. 对大量文档集使用 MinIO

对于包含数千文档的部署，请在您的 CLORE.AI 订单中配置具有更大磁盘分配的专用 MinIO 存储。

***

## 故障排除

### 问题：服务启动失败（内存）

```bash
# 检查内存使用情况
free -h
docker stats

# 减少 Elasticsearch 内存
# 编辑 docker/.env： ES_JAVA_OPTS=-Xms1g -Xmx1g
```

### 问题：无法通过端口 80 访问 WebUI

```bash
# 检查 nginx 是否在运行
docker compose ps

# 检查端口绑定
docker port ragflow-nginx-1

# 在 CLORE.AI 中验证：在您的服务器订单中必须映射端口 80
```

### 问题：文档解析卡住

```bash
# 检查任务工作器日志
docker compose logs ragflow-worker

# 重启工作器
docker compose restart ragflow-worker
```

### 问题：Elasticsearch 堆内存溢出

```bash
# 在 .env 中增加堆大小
ES_JAVA_OPTS=-Xms2g -Xmx2g
docker compose restart es01
```

### 问题：找不到嵌入模型

```bash
# 验证 HuggingFace 模型下载
docker exec ragflow-server ls /ragflow/models/

# 重新下载
docker exec ragflow-server python -c "
from huggingface_hub import snapshot_download
snapshot_download('BAAI/bge-large-en-v1.5')
"
```

***

## 文档

* **GitHub**: <https://github.com/infiniflow/ragflow>
* **官方文档**: <https://ragflow.io/docs>
* **Docker Hub**: <https://hub.docker.com/r/infiniflow/ragflow>
* **API 参考**: <https://ragflow.io/docs/dev/http_api_reference>
* **Discord**: <https://discord.gg/4XxujFgUN7>
* **CLORE.AI 市场**: <https://clore.ai/marketplace>

***

## Clore.ai 的 GPU 建议

| 在 Clore.ai 上的预估费用 | 开发/测试 | RTX 3090（24GB） |
| ----------------- | ----- | -------------- |
| \~$0.12/每 GPU/每小时 | 生产    | RTX 4090（24GB） |
| 生产环境 RAG          | 生产    | RTX 4090（24GB） |
| 高吞吐量嵌入            | 大规模   | A100 80GB      |

> GPU 服务器上。浏览可用 GPU 并按小时租用 — 无需承诺，提供完整的 root 访问权限。 [Clore.ai](https://clore.ai/marketplace) GPU 服务器。浏览可用 GPU 并按小时租用 — 无需承诺，提供完整的 root 访问权限。
