RAGFlow/RAG 从文档解析到混合检索的完整链路
1. RAGFlow
采用ragflow v0.25.6
从github上拉取源码,然后拉取镜像,用docker compose启动
注意,默认启动后会自动拉取tiktoken,但内网环境无法联网,可以从外网下载,然后拷贝到内网,同时tiktoken文件挂载到容器时,直接放在ragflow根目录下即可
environment: - TIKTOKEN_CACHE_DIR=/ragflow - DATA_GYM_CACHE_DIR=/ragflow volumes: - ./ragflow-logs:/ragflow/logs # - ./nginx/ragflow.conf:/etc/nginx/conf.d/ragflow.conf # - ./nginx/proxy.conf:/etc/nginx/proxy.conf # - ./nginx/nginx.conf:/etc/nginx/nginx.conf - ./service_conf.yaml.template:/ragflow/conf/service_conf.yaml.template - ./entrypoint.sh:/ragflow/entrypoint.sh - ./tiktoken_cache/9b5ad71b2ce5302211f9c61530b329a4922fc6a4:/ragflow/9b5ad71b2ce5302211f9c61530b329a4922fc6a4:rw2. Eembedding
公司内网采用gte-Qwen2-7B-instruct模型,该模型的默认请求参数为prompt。默认请求链接为
curl -X POST "http://10.0.17.56:50000/api/hirain/pmtggtt/api/embeddings" ^ -H "Content-Type: application/json" ^ -H "Authorization: Bearer a0d3cc35475f43c4b5f17b562123cb6b" ^ -d "{\"model\":\"gte-Qwen2-7B-instruct\",\"prompt\":\"网络管理模块 BusOff 后应该设计哪些测试点?\"}"但是无法直接集成到ragflow中,所以在10.99.0.38服务器上启动一个embedding_adapter.py,该文件使用fastapi的方式,将请求参数中的prompt转换为input,以便于直接集成到RAGFlow中。
启动命令为
pip install fastapi uvicorn requests uvicorn embedding_adapter:app --host 0.0.0.0 --port 18080/********************** embedding_adapter.py **********************/ from typing import List, Union, Any, Dict import requests from fastapi import FastAPI, Header, HTTPException from pydantic import BaseModel INNER_EMBEDDING_URL = "http://10.0.17.56:50000/api/hirain/pmtggtt/api/embeddings" INNER_API_KEY = "a0d3cc35475f43c4b5f17b562123cb6b" DEFAULT_MODEL = "gte-Qwen2-7B-instruct" app = FastAPI(title="Embedding Adapter for RAGFlow") class EmbeddingRequest(BaseModel): model: str = DEFAULT_MODEL input: Union[str, List[str]] encoding_format: str = "float" def call_inner_embedding(text: str, model: str) -> List[float]: payload = { "model": model, "prompt": text, } resp = requests.post( INNER_EMBEDDING_URL, headers={ "Content-Type": "application/json", "Authorization": f"Bearer {INNER_API_KEY}", }, json=payload, timeout=120, ) resp.raise_for_status() data = resp.json() embedding = data.get("embedding") if not embedding: raise RuntimeError(f"内部 embedding 接口返回空 embedding: {data}") if not isinstance(embedding, list): raise RuntimeError(f"内部 embedding 返回格式不是 list: {data}") return embedding @app.get("/v1/models") def list_models() -> Dict[str, Any]: return { "object": "list", "data": [ { "id": DEFAULT_MODEL, "object": "model", "owned_by": "hirain", } ], } @app.post("/v1/embeddings") def create_embeddings(req: EmbeddingRequest): try: inputs = req.input if isinstance(req.input, list) else [req.input] data = [] total_tokens = 0 for idx, text in enumerate(inputs): embedding = call_inner_embedding(text=text, model=req.model) data.append( { "object": "embedding", "index": idx, "embedding": embedding, } ) total_tokens += len(text) return { "object": "list", "data": data, "model": req.model, "usage": { "prompt_tokens": total_tokens, "total_tokens": total_tokens, }, } except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @app.get("/health") def health(): return {"status": "ok"}经过转发之后,emdedding的链接变为
curl -X POST "http://10.99.0.38:18080/v1/embeddings" ^ -H "Content-Type: application/json" ^ -H "Authorization: Bearer a0d3cc35475f43c4b5f17b562123cb6b" ^ -d "{\"model\":\"gte-Qwen2-7B-instruct\",\"input\":\"网络管理模块 BusOff 后应该设计哪些测试点?\"}"同时,也可直接集成进RAGFlow的OpenAI-API-Compatible模型中
注:将embedding_adapter.py设置为开机自启动的服务
APP_DIR="$(pwd)" UVICORN_BIN="$(readlink -f "$(command -v uvicorn)")" RUN_USER="$(whoami)" sudo tee /etc/systemd/system/embedding-adapter.service > /dev/null <<EOF [Unit] Description=Embedding Adapter for RAGFlow After=network-online.target Wants=network-online.target [Service] Type=simple User=$RUN_USER WorkingDirectory=$APP_DIR ExecStart=$UVICORN_BIN embedding_adapter:app --host 0.0.0.0 --port 18080 Restart=always RestartSec=5 Environment=PYTHONUNBUFFERED=1 [Install] WantedBy=multi-user.target EOF sudo systemctl daemon-reload sudo systemctl enable --now embedding-adapter.service systemctl status embedding-adapter.service3. Reranker
公司内网采用bge-reranker-v2-m3模型,可直接集成进RAGFlow。测试命令为
curl -X POST "http://10.0.17.56:50000/api/hirain/pmtggtt/v1/rerank" ^ -H "Content-Type: application/json" ^ -H "Authorization: Bearer 7f80770a1ccd45dda39f481d183a4322" ^ -d "{\"model\":\"bge-reranker-v2-m3\",\"query\":\"什么是RAG?\",\"documents\":[\"RAG是一种结合检索和生成的技术。\",\"今天天气很好。\",\"向量数据库可以用于相似度检索。\"],\"top_n\":3}"4. RAGFow内置pipeline
RAGFlow 官方说明:从 v0.17.0 开始,PDF 的DeepDoc 数据抽取任务和chunking method解耦;PDF parser 用于 OCR、TSR、DLR 等视觉抽取任务,chunking method 决定怎么切块
| 概念 | RAGFlow 里对应 | 作用 |
|---|---|---|
| PDF 解析器 / PDF parser | DeepDoc、Naive、MinerU、Docling、OpenDataLoader、第三方视觉模型 | 负责从 PDF 中提取文本、表格、版面、OCR 内容等 |
| 文档解析方法 / Chunking method / Template | General、Q&A、Resume、Manual、Table、Paper、Book、Laws、Presentation、Picture、One、Tag 等 | 负责把解析出来的内容按不同业务语义切成 chunk,并建立向量/全文索引 |
在 RAGFlow v0.25.6 创建知识库时看到的:
General / Q&A / Resume / Manual / Table / Paper ...主要是内置分块方法,也就是 API 里的chunk_method。
而在某些分块方法下面看到的:
PDF Parser / PDF 解析器 General / Naive / Docling / DeepDOC / MinerU ...是解析器选择,更准确说是:PDF 怎么先被解析成文本、表格、图片、版面结构。
二者关系:
原始文件 ↓ PDF 解析器 / 文档解析器 ↓ 解析后的文本、表格、图片、结构 ↓ chunk_method 分块方法 ↓ chunk ↓ embedding ↓ indexing所以:
PDF 解析器解决:文件怎么读出来 chunk_method 解决:读出来的内容怎么切成 chunk内置pipeline主要解决把“文档入库处理流程”从固定内置 chunk method,扩展成可配置、可编排的解析流水线
传统内置 chunk_method: 上传文档 → RAGFlow 按固定方法解析/切片/embedding Pipeline: 上传文档 → 按你配置的 Parser 组件和后续流程处理 → chunk → embedding → indexing4.1 PDF解析器
| PDF 解析器/选项 | 属于什么 | 主要解决什么 | 优点 | 缺点 | 适合场景 |
|---|---|---|---|---|---|
| General / DeepDOC | PDF 解析/版面识别 | 通用 PDF 解析、布局、OCR、表格识别 | RAGFlow 默认集成度高 | 复杂规范文档仍可能切乱 | 普通 PDF、Word/PDF 混合知识库 |
| Naive | 简单 PDF 文本抽取 | 直接提取文本,不强调版面理解 | 快、简单、稳定 | 表格、图片、复杂排版效果差 | 文本型 PDF、无复杂表格图形的资料 |
| Docling | 文档转换框架 | PDF 转结构化内容,包含布局/表格结构识别 | 对结构化转换友好 | 依赖环境、速度和部署复杂度需验证 | 复杂 PDF、表格多、想转 Markdown/结构化文档 |
| MinerU | 外部 PDF parser | OCR、版面、表格、公式、图片抽取 | 复杂 PDF 解析能力强,适合先转 Markdown | 需要额外部署/配置 | AUTOSAR PDF、标准文档、扫描件、图表多的文件 |
4.1.1 DeepDoc
DeepDoc 是 RAGFlow 内置的文档理解 / 文档解析能力。
它主要负责把原始文件解析成可用于 RAG 的内容,包括:
PDF 版面识别 OCR 表格结构识别 图片 / 文本块识别 文档结构解析RAGFlow 官方 FAQ 里解释,RAGFlow 解析文档比普通 LangChain loader 慢,是因为它会做 layout analysis、table structure recognition、OCR 等文档预处理任务;这些就是 DeepDoc 这类内置文档解析能力承担的工作。
所以 DeepDoc 位于:
文件 → 文本 / 表格 / 版面结构这一层。
它不负责:
embedding rerank chat 回答 向量检索4.1.2 MinerU
MinerU 是外部 PDF 解析器。
RAGFlow 从 v0.22.0 开始把 MinerU 作为可选 PDF parser 集成进来。官方文档明确说,RAGFlow 只是 MinerU 的 remote client:RAGFlow 调用 MinerU API 解析 PDF,然后读取 MinerU 返回的文件。
也就是说,接入 MinerU 后是这个结构:
RAGFlow ↓ 调用 HTTP API MinerU API Server ↓ 解析 PDF 返回 Markdown / JSON / zip 等解析结果 ↓ RAGFlow 继续切片、embedding、索引MinerU 本身是面向文档内容抽取的开源方案,目标是处理 OCR、layout detection、公式识别、复杂 PDF 内容抽取等问题。
MinerU后端
MinerU 的上层功能都是“把 PDF/图片/Office 文档解析成 Markdown/JSON”,但底层可以选择不同的推理后端来完成版面识别、OCR、表格、公式、VLM 解析等任务。
简单说:
同一个 PDF ↓ MinerU ↓ 可选不同 backend pipeline / transformers / vLLM / http-client ↓ 输出 Markdown / JSON / 图片 / 中间结果| 后端 | 是什么 | 核心逻辑 | 适合场景 | 资源要求 | 优点 | 缺点 |
|---|---|---|---|---|---|---|
| pipeline | 传统视觉/OCR流水线后端 | 使用小模型/规则流程完成版面分析、OCR、公式、表格等解析 | 普通 PDF、扫描件、RAG 数据入库、内网 CPU 环境、资源有限环境 | 可 CPU 跑;官方说明如果设备不满足 GPU 要求,可指定-b pipeline纯 CPU 运行;推荐 RAM 16GB+,更建议 32GB+。(OpenDataLab) | 稳定、可控、幻觉少;适合批量生产解析结果 | 对复杂图文、跨页表格、图片理解能力不如 VLM;速度受 CPU/GPU 影响 |
| vlm-transformers | 本地 Transformers 方式跑 VLM | 用 HuggingFace Transformers 直接加载视觉语言模型做文档理解 | 单机验证、小批量解析、没有 vLLM 部署经验但有 GPU | 通常需要 NVIDIA GPU,建议8GB+ 显存;安装依赖相对简单但推理吞吐一般 | 部署链路相对直观,不需要额外 vLLM 服务 | 并发能力弱,长文档慢,显存占用高,生产吞吐不如 vLLM |
| vlm-vllm-engine | 本地 vLLM 加速 VLM 推理 | 用 vLLM 作为 VLM 推理引擎,提高吞吐和并发 | 高并发解析、批量 PDF、服务化部署、多 GPU 推理 | 官方扩展文档说明 vLLM 适合 Volta 及之后架构显卡,建议8GB+ VRAM;安装mineru[core,vllm]。(OpenDataLab) | 吞吐高、适合服务化、多 GPU 更好扩展 | 环境要求高,CUDA、驱动、vLLM 版本容易踩坑 |
| vlm-http-client | 轻量客户端连接远端 VLM 服务 | 本地 MinerU 不加载大模型,只通过 HTTP 调远端 OpenAI-compatible VLM 服务 | 边缘机器、CPU 机器、RAGFlow 容器、内网统一模型服务、GPU 集中部署 | 本地只需 CPU + 网络;远端服务承担 GPU。官方说可安装轻量mineru包,连接 OpenAI-compatible server。(OpenDataLab) | 本地资源占用最低;适合把 GPU 服务集中部署 | 依赖网络和远端服务稳定性;吞吐受远端服务限制 |
| hybrid-auto-engine | 混合后端,本地自动选择/编排 pipeline + VLM | 文本抽取、结构化解析和 VLM 能力结合 | 对准确率要求高,同时希望减少纯 VLM 幻觉 | 需要本地较强 GPU;官方默认 backend 当前是hybrid-auto-engine。(OpenDataLab) | 准确率高,兼顾原生文本抽取与 VLM 理解 | 部署复杂度、资源消耗高于 pipeline |
| hybrid-http-client | 混合后端的远程调用模式 | 本地做部分轻量处理,重模型能力走远端 OpenAI-compatible 服务 | 企业内网集中部署 MinerU/VLM 服务,多客户端接入 | 本地比 auto-engine 轻;远端需要 GPU。官方说明hybrid-http-client用--url连接 OpenAI-compatible backend。(OpenDataLab) | 适合集中式部署,客户端资源低 | 依赖远端服务、网络、API 兼容性 |
4.2 内置分块方法
| UI 名称 | API 值 | 主要含义 | 典型使用场景 | 分片方式大意 | 是否适合 AUTOSAR 规范 |
|---|---|---|---|---|---|
| General | naive | 通用分块方法 | 普通 PDF、Word、Markdown、说明文档 | 按 delimiter、token 数、段落等通用规则切片 | 可用于快速验证,但不适合精细 AUTOSAR 语义切片 |
| Q&A | qa | 问答对分块 | FAQ、问答知识库、客服知识 | 通常按问题-答案对组织 chunk | 不适合 AUTOSAR 标准正文,适合你后续整理测试 FAQ |
| Manual | manual | 手动分块 | 人工维护 chunk、少量高价值知识 | 不依赖自动切片,偏人工维护 | 如果你手动管理 chunk,可以用;但更推荐 empty document + Add chunk |
| Table | table | 表格类分块 | Excel、CSV、参数表、映射表 | 按表格结构处理,尽量保留行列关系 | 适合配置参数表、NRC 映射表,但不适合整本 AUTOSAR PDF |
| Paper | paper | 论文类分块 | 学术论文 PDF | 按论文结构,如摘要、章节、参考文献等处理 | 不适合 AUTOSAR |
| Book | book | 书籍类分块 | 书籍、长篇章节型材料 | 按章节/段落结构切 | 可用于长文档,但 AUTOSAR 仍建议自定义语义切片 |
| Laws | laws | 法律条文类分块 | 法规、标准条款 | 按条、款、项组织 | 与 AUTOSAR 需求条款有点像,但未必能识别 SWS/RS 语义 |
| One | one | 整篇一个 chunk | 很短的文档、单页说明 | 整个文档作为一个 chunk | 不适合长 AUTOSAR 文档 |
| Picture | picture | 图片类文档 | 图片、图像知识 | 偏图片/OCR/图文处理 | 不适合标准主文档 |
| Presentation | presentation | PPT 类分块 | PPT、演示材料 | 按 slide 切片 | 不适合 AUTOSAR PDF |
email | 邮件类分块 | 邮件归档 | 按邮件结构、主题、正文处理 | 不适合 | |
| Tag | tag | 标签集方法 | 通过标签知识库辅助分类/标注 | 和 tag set 配合 | 可作为后续增强,不适合作为主切片 |
| Resume | 未在官方 v0.25.6 API 枚举中确认 | 简历类模板/分支功能可能项 | 简历、候选人资料 | 可能按教育、经历、技能等结构切 | 不适合 AUTOSAR |
5. Autosar AP文档解析&切分方法
从准确性的角度,整个过程不再采用RAGFlow自带的方法
解析采用外部MinerU的方法
切片采用自己编写脚本的方法,对文档切分,具体细则参考 AUTOSAR AP 文档切分方法说明
6. Autosar CP文档解析&切分方法
从准确性的角度,整个过程不再采用RAGFlow自带的方法
解析采用外部MinerU的方法
切片采用自己编写脚本的方法,对文档切分,具体细则参考 AUTOSAR CP 文档切分方法说明
7. 不选择reranker模型时,RAGFlow靠什么回答问题
没选 reranker 时,RAGFlow 不会再用 reranker 做二次重排
它主要使用基础检索排序:
最终相似度 = 向量相似度 + 关键词相似度 的加权组合RAGFlow 配置里有:
similarity_threshold vector_similarity_weight top_n top_k rerank_id官方文档说明vector_similarity_weight是vector cosine similarity 的权重,默认是0.3;也就是说,如果没有 reranker,排序主要依赖向量相似度和关键词相似度的加权结果。
不选 reranker 时的检索链路大致是这样
用户问题 ↓ 问题 embedding ↓ 向量检索:计算 query 向量和 chunk 向量相似度 ↓ 关键词检索:计算 query 关键词和 chunk 文本 / important_keywords / tag_kwd 的匹配 ↓ 按 similarity_threshold 过滤 ↓ 按综合 similarity 排序 ↓ 取 top_n 个 chunk 放进 LLM 上下文 ↓ LLM 生成回答其中:
vector_similarity_weight = 0.3可以理解为:
向量相似度占 30% 关键词相似度占 70%这对 AUTOSAR 场景反而通常更合适,因为这时查询经常是:
SWS_PduR_00216 RS_Nm_00051 PduR_Transmit CanSM_RequestComMode E_NOT_OK这些都是强关键词、强 ID、强符号检索。默认不选 reranker,有时会比选 reranker 更稳。
8. 添加reranker模型后,问答效果更差
rerank 不是必然提升效果,它只是对第一阶段召回结果重新排序;如果 reranker 不适合你的 query 类型、chunk 结构或领域文本,反而会把正确 chunk 排下去。
RAGFlow 的知识库问答配置里,rerank_id是可配置项,同时还有similarity_threshold、vector_similarity_weight、top_n、top_k等检索参数;其中top_k是参与向量余弦计算的 chunk 数,默认示例是 1024,vector_similarity_weight表示向量相似度权重,另一部分是关键词相似度权重
可能的原因:
1.1 你的问题是 ID / API / 错误码型,reranker 不一定擅长
1.2 reranker 模型和 embedding / 文档语言不匹配
1.3 top_n 太小,reranker 把长尾正确证据裁掉了
1.4 similarity_threshold 过滤过早
1.5 chunk 太“结构化”,reranker 更喜欢说明性文字
现有的 chunk 有些是表格、字段、枚举、错误码,不是自然问答风格。reranker 可能更喜欢 section background 或说明性段落,因为它们语义更流畅,但对生成测试用例未必是最关键证据。
