📰 来源:Towards Data Science | 📅 翻译日期:2026年6月14日
🔗 原文:查看原文
🤖 翻译:DeepSeek AI · 仅供参考
TL;DR
我构建了一个数据集问答系统,并且相信了一个错误率超过一半的RAG答案。
我对 7 种查询类型和 5 种上下文大小 进行了测量,覆盖了 100,000 行数据。
修复方案:将计算类查询完全从 RAG 中分离出来。
我信任了一个错误的数字
上个月,我埋头为 EmiTechLogic 构建一个新功能。用户现在可以上传他们杂乱的 CSV 文件,并用自然语言提问关于数据的问题。这听起来非常适合 RAG,所以我全力以赴——嵌入、检索、漂亮的回复。
最初的几个演示看起来很棒。清晰的表格、自信的数字、专业的格式。在内部测试中,我甚至开始信任这个系统。
然后我挑选了一个数字进行双重验证。
数据集中的实际食品杂货支出:$1,140,033.24。
模型给出了一个漂亮的分类细分。看起来合情合理。我把返回的数字加起来。
不到实际的一半。
我坐在那里盯着屏幕,心想“这不可能是对的”。所以我做了任何工程师都会做的事。我增加了上下文窗口:4k… 16k… 32k… 128k tokens。每次答案都变得更长、更详细,并且更加自信地错误。
那一刻我终于明白了。这不是检索问题。我在让一个检索系统对只部分看到的数据进行繁重计算。而且模型没有表现出不确定或信息缺失,而是生成了打磨过的、结构化的答案,看起来正确无误。
为什么 RAG 无法聚合
RAG 管道并不能真正理解结构化数据。它所做的只是将每一行 CSV 展平为纯文本。仅此而已。对模型来说,一行看起来像这样:
2019-01-01 grocery_pos 107.23 F NC Jennifer Banks ...对于诸如“按类别计算总支出?”这样的查询,RAG 管道会执行以下步骤:
- 分词:["total", "spend", "category"]
- 根据关键词重叠对所有 100,000 行进行评分
- 返回前 N 行作为序列化纯文本
- 让 LLM 从该文本中求和并分组
第 4 步是系统失败的地方。 LLM 并没有执行 SUM。它只是在文本块中匹配数字模式,并生成一个模仿聚合的回复。
模型在大规模数值精度上存在问题 [1],但真正的问题在于呈现方式。模型给出了所有类别的详细细分。这是一个典型的陷阱。输出看起来很专业。它模仿真实报告的结构如此之好,以至于你的大脑认为内容有效。你无法验证 92% 的数据都缺失了。
RAG 是检索工具,不是计算引擎。检索找到相关片段。计算需要完整的数据集扫描。当你将 RAG 用于数学计算时,你会得到一个看起来权威的错误答案。这个区别至关重要。部分答案表明数据缺失。而一个看起来完整的错误答案只表明虚假的自信。
完整代码:https://github.com/Emmimal/context-window-engine/
基准测试:两条管道,同一查询
为了精确测量这个问题,我构建了一个基准测试,对每个查询同时运行两条管道。
第一条管道是 RAG 模拟。它模拟了朴素向量管道在五种上下文大小下传递给 LLM 的内容。我测试了五种上下文大小,从 5 行 到 8,000 行。这相当于从 325 tokens 到 500,000 tokens。对于每种大小,我跟踪了三个指标:LLM 看到的数据量、从该特定切片计算出的总和,以及读者能否实际发现错误。
第二条管道是 语义引擎,它将相同的查询作为确定性全扫描在整个 100,000 行上执行,并返回精确的正确答案。
该模拟并不再现精确的 LLM 输出。它保留的是关键的结构属性:将部分数据切片输入到一个返回完整形式答案的系统中。正是这个属性导致了问题,而基准测试测量的正是这个。
我选择了 7 种查询类型 来覆盖结构化数据系统可能遇到的所有聚合模式:
| 查询 | 操作 | 为什么破坏 RAG |
|---|---|---|
| 按类别的总支出 | SUM + GROUP BY | 需要对所有 14 个组的所有行求和 |
| 按类别的最高平均交易额 | AVG + GROUP BY | 平均值随每行缺失而改变 |
| grocery_pos 的总支出 | SUM + 分类过滤 | 过滤需要看到所有匹配的行 |
| 女性客户交易次数 | COUNT + 过滤 | 计数在部分扫描中没有意义 |
| 金额 > $500 的总支出 | SUM + 数值比较 | 阈值逻辑需要完整数据 |
| 支出最低的州 | MIN + 跨 50 个州分组 | 只有在所有组都存在时才能找到最小值 |
| 欺诈交易百分比 | COUNT + 比率 | 分母部分缺失时比率无定义 |
这些查询并不独特或复杂。它们是任何分析师查看新数据集时都会问的标准问题。这正是这个失败如此关键的原因。
错误可观测性崩溃
以下是引发这一切的查询的完整基准测试输出。我将其完整展示,因为数字使得问题无法忽视。
GROUND TRUTH (Semantic Engine)
SUM(amt) GROUP BY category → 14 groups
#1 grocery_pos 1,140,033.24
#2 shopping_net 773,527.93
#3 shopping_pos 725,766.14
#4 gas_transport 648,804.24
#5 home 556,526.53
Latency: 100.47ms | Rows scanned: 100,000
RAG SIMULATION — what the LLM receives at each context size
Context Rows Coverage Partial sum Error detectable?
tiny (~325 tokens) 5 0.0050% 197.73 EASY
small (~3K tokens) 50 0.0500% 2,003.56 MODERATE
medium (~32K tokens) 500 0.5000% 31,023.21 HARD
large (~130K tokens) 2,000 2.0000% 140,093.16 VERY HARD
xlarge (~520K tokens) 8,000 8.0000% 569,368.22 NEAR IMPOSSIBLE我盯着这些结果看了好一会儿。最令人不安的部分不仅仅是答案是错误的,而是错误的可检测性如何随着更大的上下文窗口而 崩溃。
参考资料
[1] Lu, X. et al. (2023). "Large Language Models Are Not Reliable for Numerical Reasoning". arXiv:2310.03032.
评论已关闭