资讯动态

RuoYi集成RAGFlow实战:私有化知识库问答与智能体搭建

发布时间:2026/9/29 5:20:10 来源:尧图企业网站定制
上一篇把 RuoYi 和 RAGFlow 的底座搭起来了Docker Compose 部署、内网登录简化这些基础工作做完后很多朋友在问同一个问题底座有了接下来数据到底怎么进去怎么在 RuoYi 后台里让用户上传文档、触发解析、最后还能像聊天一样问出自己的私有知识库这篇就是冲着这些问题来的。这篇实践覆盖的范围比较明确RuoYi 后端怎么封装 RAGFlow 的 OpenAPI、登录用户信息从哪里拿、文档解析怎么选模板、批量导入怎么不把流程写死、本地大模型选 Llama 还是国产开源模型、知识库问答怎么进一步做成智能体最后附上这段时间踩过的坑汇总。适合已经部署完 RAGFlow、想在 RuoYi 框架里做私有化 AI 应用的后端开发也适合正在做开源 RAG 方案选型的朋友参考。1. 这一篇要补上什么1.1 为什么单独把集成拿出来写RuoYi 本身的定位是后台管理框架用户、角色、菜单、权限这一套很成熟但里面没有“知识库”这种东西。RAGFlow 定位是 RAG 引擎文档解析和向量检索很强但它自己的账号体系、权限模型比较弱也不适合让业务人员直接用它的界面去管理企业知识库。两者拼在一起本质上就是让 RuoYi 当入口和权限层把 RAGFlow 当被调用的服务所有文档上传、解析、问答操作都在 RuoYi 的菜单和按钮权限控制下完成。第一次做这个集成时容易犯一个错直接在 RAGFlow 界面里建数据集、传文件然后 RuoYi 只负责跳个链接。这种做法的后果是权限失控任何人都能进 RAGFlow 后台看到所有知识库审计也没法做。这次我写的所有操作都走 RuoYi 后端转发RAGFlow 的 API Key 只保存在后端前端永远接触不到这是私有化知识库最基本的安全底线。1.2 目标架构和这次实践的范围先明确整个集成的目标架构方便后面理解每一步在干什么。展示层RuoYi-Vue 前端新增“知识库管理”和“知识问答”两个菜单。控制层RuoYi 后端Spring Boot负责鉴权、日志、数据落库同时封装 RAGFlow 的 HTTP 接口。RAG 引擎RAGFlow 服务负责文档解析、切片、向量化、检索和问答补全。模型层本地 Ollama 或 vLLM 提供的开源大模型也可以是公司采购的 API但私有化场景我默认用内网部署。这篇默认你已经把 RAGFlow 容器跑起来了RuoYi 后端也能正常登录。如果还没有先回看系列第一篇Docker 部署那部分已经写得很详细这里不再重复。2. RuoYi 后端接入 RAGFlow接口和数据流设计2.1 先搞清楚 RAGFlow 的 OpenAPI 到底能干什么RAGFlow 从很早期版本就提供了 OpenAPI前缀一般是/api/v1用 Bearer Token 鉴权。不同小版本之间参数有过调整所以真实联调时以你们部署版本的 OpenAPI 文档为准但常用接口的形态基本稳定。我平时高频用到的就这么几个创建数据集传数据集名称、权限级别、关联的 Embedding 模型。上传文档往指定数据集里传文件支持 PDF、DOCX、Excel、TXT、Markdown、图片等。触发解析对已上传的文档发起异步解析任务。查询解析状态返回文档的进度、状态、报错信息。执行检索给定问题从指定数据集里召回相关片段。Chat 对话调用已配置好的 Chat Agent直接返回答案和引用。在做 RuoYi 封装之前建议先用 curl 把这几个接口全部通一遍。这一步能帮你提前区分是 RAGFlow 本身的问题还是后面 RuoYi 代码的问题。我在本地调试时最常用的一条命令大概长这样curl -X POST http://localhost:9380/api/v1/datasets \ -H Authorization: Bearer ragflow_xxxxxxxx \ -H Content-Type: application/json \ -d {name:测试数据集,embedding_model:BAAI/bge-zh-v1.5}2.2 登录用户信息从哪里来怎么和操作记录串起来标题里追问的“RuoYi 在哪里写入登录用户的信息”是后端开发绕不开的点。RuoYi 登录成功后用户信息会在SysLoginService里被封装成LoginUser对象通过TokenService.createToken()生成 Token 并写入 Redis。之后每个请求进来拦截器根据 Header 里的 Authorization 从 Redis 取回LoginUser再放到 Spring Security 上下文里。业务代码里拿当前用户标准姿势是调SecurityUtils.getLoginUser().getUserId()和SecurityUtils.getUsername()。后面所有和 RAGFlow 相关的操作我都会把这些信息写入业务表。以文档上传为例RuoYi 里新建一张rag_file表字段包括文件ID、所属数据集ID、RAGFlow 文档ID、文件名、解析状态、创建人。创建人字段不是手填的直接从SecurityUtils.getLoginUser()拿。这样做的好处是所有操作都能追溯到人也符合企业做审计的要求。2.3 核心代码RuoYi 后端 RAGFlow 客户端的封装思路RuoYi 本身没有专门的 RAGFlow 客户端我建议新建一个RagFlowClientService统一封装 HTTP 调用避免业务 Controller 里到处重复写 RestTemplate。先定义一个配置类把 RAGFlow 的地址和 API Key 放到application.yml里不要硬编码ragflow: base-url: http://localhost:9380 api-key: ragflow_xxxxxxxx然后是创建数据集的核心代码Service public class RagFlowClient { private final RestTemplate restTemplate; private final RagFlowProperties props; public RagFlowClient(RestTemplate restTemplate, RagFlowProperties props) { this.restTemplate restTemplate; this.props props; } public String createDataset(String name, String embeddingModel) { HttpHeaders headers new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.setBearerAuth(props.getApiKey()); MapString, Object body new HashMap(); body.put(name, name); body.put(embedding_model, embeddingModel); body.put(permission, team); HttpEntityMapString, Object request new HttpEntity(body, headers); ResponseEntityString response restTemplate.postForEntity( props.getBaseUrl() /api/v1/datasets, request, String.class); if (!response.getStatusCode().is2xxSuccessful()) { throw new ServiceException(RAGFlow 创建数据集失败); } return response.getBody(); } }上传文件时 RestTemplate 处理 multipart 比较啰嗦我实际项目里用的是 OkHttp。核心逻辑就是构造一个MultipartBody附上file字段和 Bearer Token把文件流发给 RAGFlow。解析触发则是 POST 到/api/v1/datasets/{datasetId}/documents/{docId}/parse这个接口是异步的返回后不代表解析完成需要轮询状态。2.4 权限控制和操作日志不能省RuoYi 的价值就在这。每个和 RAGFlow 相关的接口都给配上按钮权限点比如rag:dataset:add、rag:file:upload、rag:chat:send。Controller 上直接加PreAuthorize(ss.hasPermi(rag:file:upload))只有被分配了权限的用户才能上传文件。同时加上Log注解记录操作人、操作模块、操作内容。我第一次做的版本没加日志后来出了个问题有人删了某个数据集整个业务线的知识库都没了但完全查不到是谁删的。从那以后我定了个规矩RAGFlow 相关的写操作一律记日志而且日志里必须带数据集名称。3. 文件解析最容易拉胯的环节3.1 RAGFlow 解析模板怎么选RAGFlow 让我觉得最值钱的就是解析模板这也是“ragflow 解析技巧”里最值得先说的一条。它支持通用、问答、书籍、论文、手册、表格、法律、财报、代码等多种模板不同模板影响的是切分策略。实际选择时我的经验是全电子版 PDF、Word用通用模板最稳。扫描版 PDF必须开 OCR建议用深度解析类模板不然出来的 chunk 全是乱码。表格密集的 Excel 或单据用表格模板RAGFlow 对表格结构还原做得比较细。代码文件用代码模板它会按函数或逻辑块切分而不是死板按字符数切。FAQ 类的文档用问答模板检索时直接返回问题和答案对效果比通用模板好很多。很多人忽略一个关键动作解析完一定要抽查 chunk。RAGFlow 管理界面里能看到文档切出来的所有片段如果发现某个 PDF 解析出来的是乱码或者内容顺序错乱别急着调提示词先换模板或者开 OCR。3.2 批量处理文件时怎么设计流程企业知识库一开始导入就是成百上千个文件不可能让用户一个个在 RAGFlow 界面里操作。RuoYi 这边的批量流程我建议做成这样前端支持多选文件逐个上传到 RuoYi 临时目录。RuoYi 后端完成格式校验后调用 RAGFlow 上传文档接口把文件流转发过去。上传成功后再统一触发解析。前端通过轮询接口查看每个文件的解析状态展示“排队中、解析中、已完成、失败”。这里有三个容易踩的坑。第一不要等 RAGFlow 解析完成后再传下一个文件RAGFlow 有异步任务队列批量提交没问题串行反而慢。第二轮询间隔不要低于 10 秒解析任务在队列里和实际执行中变化很快太频繁只会增加后端压力。第三解析不是实时完成的大 PDF 可能要好几分钟同步接口会很容易超时。我在项目里用 Spring 的Scheduled写了一个定时任务每 15 秒扫描状态为“解析中”的记录调用 RAGFlow 查询接口更新进度超过 30 分钟还没完成的直接标记异常并重试一次。这个方案实测下来稳定也不需要在 RAGFlow 那边额外配置 Webhook。3.3 解析失败的三种典型场景和处理办法解析失败在私有化部署里非常常见不要慌按状态排查就行。一直处于“待解析”说明任务没被消费重启 RAGFlow 的 server 容器或者检查 Redis 是否正常。状态变成了失败报错信息和 PDF 内容相关多半是文件本身的问题比如扫描版 PDF 没开 OCR、文件后缀名和真实格式不一致。建议上传时不要只按扩展名判断用 magic bytes 校验真实文件类型。解析成功但检索不到内容检查数据集捆绑的 Embedding 模型是否配置成功索引构建有延迟。某次客户现场导入一批合同扫描件解析失败率高达 40%后来发现是这批 PDF 没有文本层OCR 又没开。处理办法是统一走深度解析模板加 OCR失败率降到 3% 以下。扫描版文档千万别图省事用通用模板。4. LLM 选型国内私有化部署到底怎么选4.1 Llama 适合国内企业吗“Llama 适合国内企业拿来搞知识库问答和私有化 Agent 部署吗”这个问题我一次次被问到直接说结论不太适合。Llama 3.1 的英文能力确实强但中文语料占比低直接拿来做中文知识库问答经常出现表达生硬、理解偏差的问题。更关键的是 Llama 的中文指令遵循能力一般做 Agent 工具调用时更容易出幺蛾子。国产模型里Qwen 系列、DeepSeek 系列、智谱 GLM 系列的中文底子和社区生态都更合适。如果团队的 GPU 资源紧张首选 Qwen2.5-7B 的 4bit 量化版一张 12G 显存的卡就能跑起来显存有 24G 的两张直接上 Qwen2.5-14B 或 DeepSeek-R1-Distill-Qwen-14B。真要追求深度推理可以在回答链路外面套一层大模型反思但这不是私有化知识库的第一步。4.2 RAGFlow 本地化部署时怎么接模型RAGFlow 支持的模型接入方式很多最省事的是在它的管理后台配置一个 OpenAI 兼容地址指向本地部署的 vLLM 或 Ollama 服务。填 Base URL 的时候注意要填到/v1这一级比如http://10.0.0.15:8000/v1API Key 填一个自定义值就行了本地服务一般不校验。Embedding 模型我建议用BAAI/bge-zh-v1.5或bge-m3中文场景比text-embedding-ada-002稳。如果内网完全隔离Embedding 模型文件需要在部署阶段提前拉取到本地否则容器启动后连不上外网就会一直失败。这个属于 RAGFlow 本地化部署里最容易被忽略的细节。4.3 开源方案对比Dify、RAGFlow、FastGPT 怎么选很多人在 RuoYi 集成前会纠结选 Dify 还是 RAGFlow 还是 FastGPT我从企业落地的角度做个对比方便按场景选。产品最强项明显短板适合场景RAGFlowDeepDoc 解析能力强RAG 调参细召回效果好Agent 编排和业务流程能力相对弱企业文档多且杂核心诉求是私有知识库问答Dify工作流和 Agent 编排丰富插件生态多做成产品很快深度解析和召回调优不如 RAGFlow 细部分企业功能在商业版要快速搭建对话应用、Agent 流程FastGPT中文产品体验好知识库加工作流一体部署简单大规模知识库要额外维护 ES解析能力中规中矩中小团队快速上线知识库助手如果主应用是 RuoYi我更建议把 RAGFlow 当纯 RAG 引擎来用不要纠结它的 Agent 编排够不够强。上层业务编排完全可以由 RuoYi 自己来这样权限、审批、流程都可以用自己的逻辑不冗余。5. 从知识库问答到智能体RAGFlow 在 RuoYi 里的落地方式5.1 在 RAGFlow 里配置一个可用的 Chat AgentRAGFlow 新版里应用管理区分了 Chat Assistant 和 Agent 两类。Chat Assistant 适合直接做知识库问答配置起来最快选一个数据集、选一个大模型、写一段 Prompt保存后就有 chat_id。Prompt 不要写得太大而空就按企业知识库客服的标准写明确“只根据提供的知识库片段回答不要编造事实无法回答时直接说明不知道”。示例 Prompt 里最好带上引用要求让流程后面的引用解析有据可依。5.2 RuoYi 后端封装问答接口RuoYi 后端封装问答接口核心就是转发 RAGFlow 的 Chat 接口。我提供一个简化示例Java 里用 RestTemplate 发起一片问答请求public String chat(String question, String sessionId) { HttpHeaders headers new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.setBearerAuth(props.getApiKey()); MapString, Object body new HashMap(); body.put(question, question); body.put(stream, false); if (sessionId ! null) { body.put(session_id, sessionId); } HttpEntityMapString, Object request new HttpEntity(body, headers); ResponseEntityString response restTemplate.postForEntity( props.getBaseUrl() /api/v1/chats/ props.getChatId() /completions, request, String.class); return response.getBody(); }返回结果里除了答案还有引用文件列表。前端拿到引用后要展示出来因为企业内部知识库问答用户会追问“这句话出自哪份文档”没有引用回答的可信度会大打折扣。我建议把引用解析成结构化数据再传给前端别直接扔原始 JSON。5.3 更进一步在 RuoYi 里做 Function Calling 式智能体如果 RAGFlow 自带 Agent 编排满足不了需求可以在 RuoYi 后端自己做一套轻量智能体。思路是RuoYi 后端直接对接支持 Function Calling 的大模型把查询知识库注册成一个工具函数模型决定需要检索时后端调 RAGFlow 的检索接口把召回片段作为上下文拼进 Prompt最后再由模型生成答复。这样做的最大好处是知识的检索变成了业务系统里的一个能力可以和 RuoYi 自己的业务接口连起来。比如用户在问“最近项目的进度”时模型可以同时检索 RAGFlow 里的项目文档再调 RuoYi 的业务接口拿实时进度数据答案来自两套系统。这种方案对模型的要求是必须支持工具调用。实测下来 Qwen 和 DeepSeek 系列都比较稳太小的 7B 模型可能在复杂工具调用上不稳定可以考虑先用 14B后面再根据实际效果做量化压缩。6. 常见问题与排查实录6.1 Windows 11 下跑 RAGFlow 的注意事项很多开发者的本机是 Windows 11RAGFlow 用 Docker Desktop 跑起来没问题但有几个坑必须先说。WSL2 的内存一定要给足我推荐至少给 6GB 到 8GB否则容器启动中途会被直接杀掉。Docker Desktop 的配置不只是调界面里的内存还要检查.wslconfig文件否则改完不生效。另一个坑是路径别带中文和空格。Windows 下把项目放到“桌面/新建文件夹”这种路径Docker 挂载目录很容易出问题日志里报的错误有时候还很难看懂。我自己的开发目录直接放在D:\dev\ragflow全程没踩路径问题。最后就是性能Windows 11 下解析大批量 PDF 的速度确实慢适合做调试不适合做生产环境。生产环境老老实实放 Linux 服务器。6.2 RuoYi-Vue 去掉验证码的坑私有化内网系统想把验证码去掉是很正常的诉求RuoYi 的配置项是数据库参数sys.account.captchaEnabled。但很多人在改造时只改前端把登录页的验证码组件隐藏了结果后端还在校验验证码登录请求带着空的 code 过去直接报“验证码错误”。正确的做法是前后端一起改。后端在登录逻辑里读取SysConfig的captchaEnabled如果关闭了就跳过校验前端登录页不再加载验证码组件。改完一定要测两件事一是登录成功后用户信息能正常写入 Redis二是退出登录后 Token 失效逻辑不受影响。必须提醒一点验证码是防暴力破解的重要防线去掉只适合可信内网环境。一旦系统暴露在公网强烈建议保留或者至少做登录频率限制。RuoYi 的登录日志接口也能帮我们快速发现异常尝试别把这条道堵死。6.3 集成排查三板斧RuoYi 集成 RAGFlow 出问题时我惯用的排查顺序是这样的。先看 RuoYi 后端日志找不到明显报错就去翻 RAGFlow 的容器日志命令是docker logs ragflow-server -f。这两条加起来能解决大部分问题。如果还不明确直接用 curl 测 RAGFlow 原始接口。比如手动触发一次解析再查询状态如果原始接口都失败问题基本就在 RAGFlow 侧别再折腾 RuoYi 的代码。最后看数据库里的状态记录。RuoYi 侧维护的解析状态表和 RAGFlow 的文档状态可能不一致这种数据对不上是集成时最常见的问题。我用一句话总结先确保 RAGFlow 自己能完成全流程再去查 RuoYi 的封装逻辑。一点个人经验收尾这套 RuoYi 加 RAGFlow 的集成做到能稳定问答之后我最大的体会是知识库项目真正的成败点不在大模型而在文档解析和检索调优。模型再强解析出来一堆乱码 chunk回答质量也不可能好。我建议所有刚开始做私有化知识库的团队先用真实业务文档跑一轮全链路测试仔细看召回片段和引用来源再逐步调解析模板、chunk 大小和提示词。如果后续有机会做第三篇我会重点写召回阶段的具体调优chunk 切多长、重排序加不加、混合检索怎么配。先把解析和检索的地基打牢剩下的模型选型反而不用太焦虑。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑