支持私有化部署
AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


学习 RAGFlow 知识库高级配置

发布日期:2025-08-04 10:30:28 浏览次数: 1528
作者:日习一技

微信搜一搜,关注“日习一技”

推荐语

掌握RAGFlow知识库高级配置技巧,让你的检索结果更精准高效!

核心内容:
1. 页面排名(PageRank)在知识库检索中的关键作用
2. 如何为特定知识库设置优先级参数
3. 配置过程中的注意事项与最佳实践

杨芳贤
53AI创始人/腾讯云(TVP)最具价值专家
目前为止,我们已经学习了很多关于 RAGFlow 的知识库配置,包括分块方法,PDF 解析器,嵌入模型,RAPTOR 策略,提取知识图谱等,除此之外,还剩下一些高级配置,我们今天一起来看下:

页面排名



当我们从多个指定的知识库中检索知识时,可能希望某些知识库的知识优先被检索到。比如我们有两个知识库:知识库 A 用于 2024 年新闻,知识库 B 用于 2025 年新闻,但希望优先显示 2025 年的新闻,那么提高知识库 B 的页面排名将非常有用。

PageRank 最初被设计为一种对网页进行排名的算法,RAGFlow 中的这个参数用于为特定的知识库分配更高的 PageRank 分数,这个分数会在文档分块和解析时加到每个文本块上,处理逻辑位于任务执行器的 build_chunks() 方法中:

async def build_chunks(task, progress_callback):
  # ...  if task["pagerank"]:    doc[PAGERANK_FLD] = int(task["pagerank"])

需要注意的是,这个参数是针对整个知识库的,而不是针对单个文档。当我们修改知识库的 pagerank 值时,整个知识库的文本块都会同步更新:

@manager.route('/update', methods=['post'])def update():
  # 当 pagerank 参数有变动时  if kb.pagerank != req.get("pagerank"0):
    # 该参数只支持 ES 文档引擎    if os.environ.get("DOC_ENGINE""elasticsearch") != "elasticsearch":      return get_data_error_result(message="'pagerank' can only be set when doc_engine is elasticsearch")
    if req.get("pagerank"0) > 0:      # 更新知识库中的所有文本块的 PAGERANK_FLD      settings.docStoreConn.update({"kb_id": kb.id}, {PAGERANK_FLD: req["pagerank"]}, search.index_name(kb.tenant_id), kb.id)    else:      # 由于 ES 中的 PAGERANK_FLD 不能为 0,因此删除该字段      settings.docStoreConn.update({"exists": PAGERANK_FLD}, {"remove": PAGERANK_FLD}, search.index_name(kb.tenant_id), kb.id)

可以在 ES 中查看文本块详情,会多一个 pagerank_fea 字段:

自动关键词提取



这个参数的作用是自动为每个文本块提取 N 个关键词,当用户问题包含这些关键词时,可以提高文本块的排名。一般情况下,如果分块大小在 1000 字符左右,那么推荐提取 3-5 个关键词即可;如果你的分块较大,可以适当提高这个值,但是请注意,随着数值的增加,边际收益会递减,最多是 30 个。

提取关键词的逻辑同样位于任务执行器的 build_chunks() 方法中:

async def build_chunks(task, progress_callback):
  # ...  if task["parser_config"].get("auto_keywords"0):
    # 绑定大模型    chat_mdl = LLMBundle(task["tenant_id"], LLMType.CHAT, llm_name=task["llm_id"], lang=task["language"])
    # 调用大模型,为指定文本块生成 N 个关键词    async def doc_keyword_extraction(chat_mdl, d, topn):
      # 缓存机制      cached = get_llm_cache(chat_mdl.llm_name, d["content_with_weight"], "keywords", {"topn": topn})      if not cached:        # 限制大模型并发路数,默认 10 路        async with chat_limiter:          cached = await trio.to_thread.run_sync(lambda: keyword_extraction(chat_mdl, d["content_with_weight"], topn))        set_llm_cache(chat_mdl.llm_name, d["content_with_weight"], cached, "keywords", {"topn": topn})      if cached:        d["important_kwd"] = cached.split(",")        d["important_tks"] = rag_tokenizer.tokenize(" ".join(d["important_kwd"]))      return
    # 启动并发任务,为每个文本块生成关键词    async with trio.open_nursery() as nursery:      for d in docs:        nursery.start_soon(doc_keyword_extraction, chat_mdl, d, task["parser_config"]["auto_keywords"])    

关键词提取的提示词比较简单,如下:

### 角色你是一名文本分析员。
### 任务提取给定文本内容中最重要的关键词/短语。
### 要求- 总结文本内容,并给出排名前 {{ topn }} 的重要关键词/短语。- 关键词必须与给定文本内容的语言一致。- 关键词之间用英文逗号分隔。- 仅输出关键词。
---
## 文本内容{{ content }}

生成的关键词可以在文本块列表中查看或更新(双击文本块):

自动问题提取



这个参数的作用是自动为每个文本块提取 N 个问题,当用户问题和这些问题比较类似时,可以提高文本块的排名。一般情况下,如果分块大小在 1000 字符左右,那么推荐提取 1-2 个问题即可;如果你的分块较大,可以适当提高这个值,最多 10 个。

问题提取逻辑和关键词提取几乎一模一样,同样位于任务执行器的 build_chunks() 方法中:

async def build_chunks(task, progress_callback):
  # ...  if task["parser_config"].get("auto_questions"0):
    # 绑定大模型    chat_mdl = LLMBundle(task["tenant_id"], LLMType.CHAT, llm_name=task["llm_id"], lang=task["language"])
    # 调用大模型,为指定文本块生成 N 个问题    async def doc_question_proposal(chat_mdl, d, topn):
      # 缓存机制      cached = get_llm_cache(chat_mdl.llm_name, d["content_with_weight"], "question", {"topn": topn})      if not cached:        # 限制大模型并发路数,默认 10 路        async with chat_limiter:          cached = await trio.to_thread.run_sync(lambda: question_proposal(chat_mdl, d["content_with_weight"], topn))        set_llm_cache(chat_mdl.llm_name, d["content_with_weight"], cached, "question", {"topn": topn})      if cached:        d["question_kwd"] = cached.split("\n")        d["question_tks"] = rag_tokenizer.tokenize("\n".join(d["question_kwd"]))
    # 启动并发任务,为每个文本块生成问题    async with trio.open_nursery() as nursery:      for d in docs:        nursery.start_soon(doc_question_proposal, chat_mdl, d, task["parser_config"]["auto_questions"])

问题提取的提示词如下:

角色你是一名文本分析员。
任务就给定的一段文本内容提出{{ topn }}个问题。
要求- 理解并总结文本内容,提出最重要的{{ topn }}个问题。- 问题之间不应有含义重叠。- 问题应尽可能涵盖文本的主要内容。- 问题必须与给定文本内容的语言一致。- 每行一个问题。- 仅输出问题。
---
文本内容{{ content }}

生成的问题可以在文本块列表中查看或更新(双击文本块):

自动关键词提取和自动问题提取的数值和知识库分块大小密切相关,如果你是第一次使用此功能且不确定从哪个数值开始,可以参考下面这份从社区收集的推荐值:

表格转 HTML



该参数只对 Excel 或 CSV 表格文件生效,并与 General 分块方法一起使用。当禁用时,文件将被解析为键值对;当启用时,文件将被解析为 HTML 表格,按照每 12 行进行拆分;实现代码位于 rag/app/naive.py 文件中:

def chunk(filename, binary=None, from_page=0, to_page=100000, ...):
  # ...  elif re.search(r"\.(csv|xlsx?)$", filename, re.IGNORECASE):    excel_parser = ExcelParser()    if parser_config.get("html4excel"):      sections = [(_, ""for _ in excel_parser.html(binary, 12if _]    else:      sections = [(_, ""for _ in excel_parser(binary) if _]

该参数默认禁用,表格内容被解析成 “表头1: 内容1;表头2:内容2;” 的键值对格式,如下所示:

这种格式适用于一些比较简单的表格,当表格比较复杂时,比如层次结构标题、合并单元格和投影行标题等,建议解析成 HTML 格式。比如下面这样的表格:

开启表格转 HTML 之后,解析结果如下所示:

页面上显示的是渲染后的结果,实际上存储的是 HTML 代码。

可以看到,HTML 代码还不是那么完美,并没有完全保留原表格的样式,比如这里无法体现出合并单元格。另外,值得注意的是,RAGFlow 在处理 DOCX 和 PDF 文件中的表格时,并没有按这个参数来,而是各自处理的,默认都是解析成 HTML 格式,我觉得这块的逻辑可以统一。

小结



今天我们学习了 RAGFlow 知识库的几个高级配置选项,这些功能可以帮助我们进一步优化 RAG 应用的检索效果和处理能力。主要包括:

  • 页面排名:通过为知识库设置不同的权重,实现对检索结果的优先级排序。

  • 自动关键词提取:利用大模型为每个文本块自动提取核心关键词,提升相关查询的召回率。

  • 自动问题提取:同样利用大模型,为文本块生成可能的问题,增强对问答式查询的理解和匹配。

  • 表格转 HTML:为 Excel 和 CSV 文件提供两种不同的解析方式,通过转换为 HTML 格式更好地处理复杂表格。

至此,我们已经系统地学习了 RAGFlow 知识库的大部分配置。掌握这些配置,可以让我们根据不同的业务场景和文档类型,灵活地构建出高质量的 RAG 应用。在知识库的高级配置中,还剩下一个标签集的功能,我们明天再来学习它。

53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询