Machine Learning Mastery

Evaluating Graph-RAG vs. Standard RAG: A Hallucination Benchmark on Fact-Dense Queries

7.1内容质量

TL;DR · AI 摘要

Evaluating Graph-RAG vs. Standard RAG: A Hallucination Benchmark on Fact-Dense Queries - MachineLearningMastery.com Eval...

核心要点

  • 主题聚焦:Evaluating Graph-RAG vs. Standard RAG: A Halluci
  • 来源:Machine Learning Mastery,建议结合原文判断细节。
  • AI 分析暂不可用,本条为保底评分与摘要。
#AI#编程#后端#产品
打开原文

评估 Graph-RAG 与标准 RAG:针对事实密集型查询的幻觉基准测试 - MachineLearningMastery.com

评估 Graph-RAG 与标准 RAG:针对事实密集型查询的幻觉基准测试

作者:

Iván Palomares Carrascosa

日期:

2026年10月8日

分类:

语言模型

0

分享

文章

在本文中,你将学习如何在事实密集型查询上对确定性 3 层 Graph-RAG 系统与标准向量 RAG 管道进行基准测试,并了解结果如何揭示匹配提示复杂性与模型容量之间的关系。

我们将涵盖的主题包括:

  • 如何构建一个合成的事实密集型体育数据集,该数据集故意将噪声和矛盾文本引入向量数据库,同时将真实数据保留在图存储中。
  • 如何使用 ChromaDB 和本地 Flan-T5 模型实现并比较两种检索函数——一种用于标准向量 RAG,另一种用于 3 层 Graph-RAG。
  • 为什么容量较小的本地 LLM 在处理复杂冲突解决提示时可能表现不佳,这对生产环境 RAG 系统设计意味着什么。

引言

在之前的文章中,提出了一种确定性的 3 层 Graph-RAG 系统架构,用于解决在处理原子事实时密集向量数据库的“信息丢失”问题。由于语义相似性搜索和检索依赖于相似性,经典 RAG 管道在潜在空间中存在多个相似实体时,常常会混淆数字数据、历史统计数据或实体关系。

该架构通过分层方法解决了这一限制,包括:

  • 基于 SPOC(主语-谓语-对象-上下文)模式的轻量级 QuadStore 知识图谱。
  • 能够管理模糊和长尾上下文的标准 ChromaDB 向量数据库。

然而,在面向生产的工程实践中,精确数字至关重要。因此,我们现在展示标准 Vector RAG 与我们的 3 层 Graph-RAG 之间的基准测试,以衡量在事实密集型数据集上查询时幻觉减少的程度。

先决条件和设置

要运行本文中的示例基准测试,如果你的 IDE 中没有安装这些库,需要安装以下库——如果你在 Google Colab 笔记本中尝试该示例,请按如下方式安装所有库:

!pip install -q chromadb transformers

1

!

pip

install

-

q

chromadb

transformers

接下来,我们导入所有需要的模块和函数,并设置本地 LLM,特别是 Hugging Face 的 transformers 库提供的 google/flan-t5-base 模型:

import chromadb from transformers import AutoModelForSeq2SeqLM, AutoTokenizer import random print("Initializing local, free-tier LLM (flan-t5-base)...") tokenizer = AutoTokenizer.from_pretrained("google/flan-t5-base") model = AutoModelForSeq2SeqLM.from_pretrained("google/flan-t5-base") def llm(prompt): """Wrapper to generate text directly from the local model""" inputs = tokenizer(prompt, return_tensors="pt") outputs = model.generate(**inputs, max_new_tokens=15) return tokenizer.decode(outputs[0], skip_special_tokens=True)

2

3

4

5

6

7

8

9

10

11

12

13

import

from

AutoModelForSeq2SeqLM

,

AutoTokenizer

random

print

(

"Initializing local, free-tier LLM (flan-t5-base)..."

)

tokenizer

=

.

from_pretrained

"google/flan-t5-base"

model

def

llm

prompt

:

""

"Wrapper to generate text directly from the local model"

inputs

return_tensors

"pt"

outputs

generate

*

max_new_tokens

15

return

decode

[

]

skip_special_tokens

True

接下来,我们构建一个简单的QuadStore,遵循与上一篇文章中展示的相同原则和指南:

class SimpleQuadStore: def __init__(self): self.facts = set() def add(self, subject, predicate, obj, context): self.facts.add((subject, predicate, str(obj), context)) def query(self, subject): return [f for f in self.facts if f[0] == subject] qs = SimpleQuadStore()

class

SimpleQuadStore

__init__

self

facts

set

add

subject

predicate

obj

context

str

query

f

for

if

==

qs

同样,我们需要初始化一个向量数据库。我们通过实例化一个本地ChromaDB集合来实现,该集合将处理非结构化的文本块。

chroma_client = chromadb.Client() collection = chroma_client.create_collection(name="sports_stats")

chroma_client

Client

collection

create_collection

name

"sports_stats"

接下来,我们获取一些最新数据——对于这个示例来说,数据的新鲜程度再高不过了:我们直接从零开始合成生成数据。以下代码生成一个包含50名篮球运动员表现信息的合成数据集。它被设计为将准确的事实注入图数据库,同时故意将混乱的、相互矛盾的段落输入向量数据库,这与RAG系统所处理的真实世界文本情况完全一致。

benchmark_queries = [] print("Populating databases with synthetic sports data...") for i in range(50): player = f"Player_{i}" real_ppg = str(random.randint(15, 30)) fake_half = str(random.randint(2, 10)) fake_career = str(random.randint(11, 14)) # 图数据库接收绝对真相 qs.add(player, "season_ppg", real_ppg, "Sports_DB") # 向量数据库接收包含多个数字的杂乱非结构化文本 text = ( f"在最近的比赛中,{player}上半场表现糟糕,仅得到{fake_half}分。 " f"从历史数据来看,他的职业生涯平均得分约为{fake_career}。 " f"然而,他目前官方的赛季平均得分是{real_ppg}。" ) collection.add(documents=[text], ids=[f"doc_{i}"]) benchmark_queries.append({ "question": f"{player}的官方赛季平均得分是多少?", "entity": player, "true_answer": real_ppg })

14

16

17

18

19

20

21

22

23

24

25

benchmark_queries

"Populating databases with synthetic sports data..."

i

range

50

player

"Player_{i}"

real_ppg

randint

30

fake_half

fake_career

图数据库接收绝对真相

"season_ppg"

"Sports_DB"

向量数据库接收包含多个数字的杂乱非结构化文本

text

"在最近的比赛中,{player}上半场表现糟糕,仅得到{fake_half}分。 "

"从历史数据来看,他的职业生涯平均得分约为{fake_career}。 "

"然而,他目前官方的赛季平均得分是{real_ppg}。"

documents

ids

"doc_{i}"

append

{

"question"

"{player}的官方赛季平均得分是多少?"

"entity"

"true_answer"

real

_

ppg

}

我们已经接近完成。在运行基准测试流程之前,还需要补充两个部分:检索函数——每个系统各一个。标准RAG使用简单的上下文提示,而三级图-RAG则采用严格的基于规则的提示,强制LLM优先考虑图事实,而非向量后备方案。

def standard_vector_rag(q): # 通过检索最相似的3个片段来模拟现实中的上下文污染 results = collection.query(query_texts=[q], n_results=3) context = " ".join(results["documents"][0]) # 合并3个段落 prompt = f"Context: {context}\nQuestion: {q}\nAnswer strictly with the exact number:" return llm(prompt) def deterministic_3_tier_rag(q, entity): graph_res = qs.query(entity) p1_context = f"{entity} season average PPG is {graph_res[0][2]}" if graph_res else "None" p3_context = collection.query(query_texts=[q], n_results=1)["documents"][0][0] prompt = f"""Context 1 (Absolute Truth): {p1_context} Context 2 (Fallback Text): {p3_context} Question: {q} Answer strictly using Context 1 with the exact number:""" return llm(prompt)

standard_vector_rag

通过检索最相似的3个片段来模拟现实中的上下文污染

results

query_texts

n_results

" "

join

"documents"

合并3个段落

"Context: {context}\nQuestion: {q}\nAnswer strictly with the exact number:"

deterministic_3_tier_rag

entity

graph_res

p1_context

"{entity} season average PPG is {graph_res[0][2]}"

else

"None"

p3_context

"Context 1 (Absolute Truth): {p1_context}

Context 2 (Fallback Text): {p3_context}

Question: {q}

Answer strictly using Context 1 with the exact number:"

要运行基准测试,我们遍历数据集中的所有50个测试查询,检查模型生成的文本是否包含精确的目标数字,并计算整体准确率。

print("\n--- RUNNING EVALUATION ---") v_correct, g_correct = 0, 0 for item in benchmark_queries: # 检查真实数字字符串是否出现在语言模型的输出中 if item["true_answer"] in standard_vector_rag(item["question"]): v_correct += 1 if item["true_answer"] in deterministic_3_tier_rag(item["question"], item["entity"]): g_correct += 1 print(f"Standard Vector-RAG Accuracy: {(v_correct / 50) * 100:.1f}%") print(f"3-Tiered Graph-RAG Accuracy: {(g_correct / 50) * 100:.1f}%")

"\n--- RUNNING EVALUATION ---"

v_correct

g_correct

item

检查真实数字字符串是否出现在语言模型的输出中

+=

"Standard Vector-RAG Accuracy: {(v_correct / 50) * 100:.1f}%"

"3-Tiered Graph-RAG Accuracy: {(g_correct / 50) * 100:.1f}%"

最终结果:

--- RUNNING EVALUATION --- Standard Vector-RAG Accuracy: 96.0% 3-Tiered Graph-RAG Accuracy: 92.0%

--

RUNNING

EVALUATION

Standard

Vector

RAG

Accuracy

96.0

%

Tiered

Graph

92.0

结果总结与结论

这些结果为RAG系统的生产工程实践提供了重要启示:提示复杂度与模型容量必须相匹配。google/flan-t5-base模型虽然优化良好但相对较小(2.5亿参数)。在实际应用中,这意味着它在标准RAG流水线的简单阅读理解任务中表现优异,但在需要处理冲突数据源的复杂指令遵循任务中会遇到困难——这正是Graph-RAG提示中常见的场景。准确率的轻微下降表明,通过提示强制执行基于图的规则需要更大规模的推理模型,如Llama 3或GPT-4。将复杂的冲突解决提示强加给轻量级本地LLM可能会以意想不到的方式影响性能。这些结果可能与预期不符,但它们揭示了不同RAG方法在现实场景中的权衡取舍。

更多相关内容

  • RAG幻觉检测技术
  • MinMax vs Standard vs Robust Scaler:哪种方法更胜一筹…
  • 用于不平衡数据的标准机器学习数据集
  • 标准机器学习数据集的最佳结果
  • 如何加载和可视化标准计算机视觉数据集
  • 标准人类活动识别的简明入门

/.entry /think