首页 > 教程攻略 > ai资讯 >WeKnow-RAG:结合网络搜索和知识图谱的自适应检索增强生成方法

WeKnow-RAG:结合网络搜索和知识图谱的自适应检索增强生成方法

来源:互联网 时间:2026-08-23 14:10:44

最近有一篇名为"WeKnow-RAG: An Adaptive Approach for Retrieval-Augmented Generation Integrating Web Search and Knowledge Graphs"的论文,提出了一个挺有意思的思路——把网络搜索和知识图谱结合起来,做成一种新的检索增强生成(RAG)方法。

WeKnow-RAG:网络搜索与知识图谱融合的自适应检索增强生成方法

1. 引言

大语言模型(LLMs)这几年的进步有目共睹,甚至被视为通往通用人工智能(AGI)的一条重要路径。但话说回来,它们也有一个绕不开的麻烦:容易产生事实性错误,严重时还会"编造"内容,也就是所谓的幻觉。这个问题直接影响了LLMs在实际应用中的可信度,尤其是在那些对准确性要求极高的场景里。

为了解决这个痛点,研究人员想出了检索增强生成(RAG)这个办法——通过引入外部数据库和信息检索机制,给LLM装上"外设"。而本文要聊的WeKnow-RAG,则是在这个基础上更进一步:它把网络搜索和知识图谱都整合进了RAG系统,目标是讓LLM的响应更准确、更靠谱。

2. WeKnow-RAG方法概述

WeKnow-RAG的核心想法很简单:把知识图谱那种结构化的表示能力,跟密集向量检索的灵活性结合起来。具体来说,它由以下几个关键组件构成:

  1. 基于网络的RAG
  2. 基于知识图谱的RAG
  3. 集成方法

下面我们来逐个拆解,看看它们是怎么工作的。

2.1 基于网络的RAG

基于网络的RAG,是WeKnow-RAG这套体系里的重要一环。它主要包含四个步骤。

2.1.1 网页内容解析

第一步,当然是把网页内容先解析出来,不然没法处理。这里直接用BeautifulSoup就能搞定:

from bs4 import BeautifulSoup

def parse_html(html_content):
    soup = BeautifulSoup(html_content, 'html.parser')
    # 提取需要的内容
    text = soup.get_text()
    return text

2.1.2 分块

分块就是把一篇长文档切成若干小段。WeKnow-RAG采用的是基于token的分块方式。举个例子,一个朴素的分块函数可能长这样:

def chunk_text(text, chunk_size=500):
    tokens = text.split()
    chunks = []
    for i in range(0, len(tokens), chunk_size):
        chunk = ' '.join(tokens[i:i+chunk_size])
        chunks.append(chunk)
    return chunks

2.1.3 多阶段检索

WeKnow-RAG在检索环节用了多阶段策略,主要是稀疏检索和密集检索两轮:

  1. 第一阶段:先用BM25算法做一次稀疏检索,打个底。
  2. 第二阶段:把稀疏检索(BM25)和密集检索(基于embedding的相似度)结合起来,做二次筛选。

这里要提一下BM25算法的评分函数,它长这样:

Score(query, C_i) = ∑(q_j ∈ query) IDF(q_j) · (f(q_j, C_i) · (k_1 + 1)) / (f(q_j, C_i) + k_1 · (1 - b + b · |C_i| / a vg_dl))

其中:

  • q_j 是查询中的一个词
  • IDF(q_j) 是词 q_j 的逆文档频率
  • f(q_j, C_i) 是词 q_j 在文档 C_i 中的词频
  • k_1 和 b 是参数(通常取 k_1 = 1.5, b = 0.75)
  • |C_i| 是文档 C_i 的长度
  • a vg_dl 是语料库中的平均文档长度

2.1.4 答案生成与自评估

为了尽量减少幻觉,WeKnow-RAG引入了一个自评估机制——让LLM自己给自己的答案打个置信度分:

def generate_answer_with_confidence(query, context):
    prompt = f"""
    Question: {query}
    Context: {context}

    Answer the question and provide your confidence level (high, medium, low).
    """
    response = llm.generate(prompt)
    # 解析响应,提取答案和置信度
    return answer, confidence

2.2 基于知识图谱的RAG

知识图谱(KG)在这套方法里也扮演着重要角色。主要分成三个环节:

2.2.1 领域分类

收到一个问题,系统首先要判断它属于哪个领域:

def classify_domain(query):
    prompt = f"Classify the domain of this query: {query}"
    domain = llm.generate(prompt)
    return domain

2.2.2 查询生成

根据领域分类结果,系统会生成对应的知识图谱查询语句。比如对音乐类问题,它会调用一些预设的音乐领域知识函数:

def generate_kg_query(query, domain):
    if domain == "music":
        prompt = f"""
        Generate a KG query for this music-related question: {query}
        A vailable functions:
        - get_artist_info(artist_name, info_type)
        - get_song_info(song_name, info_type)
        ...
        """
    # 其他领域的处理逻辑
    kg_query = llm.generate(prompt)
    return kg_query

2.2.3 答案检索与后处理

系统通过API调用知识图谱拿到原始结果,然后再做个后处理:

def retrieve_and_postprocess(kg_query):
    raw_result = kg_api.call(kg_query)
    processed_result = postprocess(raw_result)
    return processed_result

2.3 集成方法

WeKnow-RAG的巧妙之处在于,它采用了一个自适应框架,根据问题的所属领域以及该领域信息变化的快慢,智能地决定到底用KG还是Web来做主要检索,或者两者结合:

def adaptive_rag(query):
    domain = classify_domain(query)
    if domain in ["encyclopedia", "open_domain"]:
        return kg_based_rag(query)
    elif domain in ["music", "movies"]:
        kg_result = kg_based_rag(query)
        web_result = web_based_rag(query)
        return integrate_results(kg_result, web_result)
    else:
        return web_based_rag(query)

3. 实验结果

这套方法在CRAG(Comprehensive RAG Benchmark)数据集上做了评估。关键数据如下:

模型版本 准确率 幻觉率 缺失率 得分
版本1 0.393 0.319 0.288 0.0743
版本2 0.409 0.316 0.276 0.0929

从数据来看,版本2相比版本1有了明显的提升,尤其在准确率和综合得分方面,改善幅度是实打实的。

4. 结论与未来展望

WeKnow-RAG通过把网络搜索和知识图谱融合到一起,提供了一种新颖的检索增强生成方案。它在提升LLM响应的准确性和可靠性方面,成效显著。其核心贡献可以归纳为以下几点:

  1. 开发了一个能适配不同查询类型和领域的、带特定领域知识图谱的RAG系统。
  2. 引入了结合稀疏检索与密集检索的多阶段网页检索方法,打了一套组合拳。
  3. 实现了LLM的自评估机制,有效降低了幻觉的出现频率。
  4. 提出了一个自适应框架,能根据情况灵活地组合KG和Web检索。

至于未来的方向,有几个值得关注的点:

  • 进一步优化知识图谱的构建和更新策略,让数据更鲜活。
  • 探索更高效的多模态检索方法,毕竟现实世界的信息远不止文本。
  • 研究如何把WeKnow-RAG扩展到更广泛的领域和任务,看看这套思路的通用性有多强。