2560 字
约 8 分钟
5
RAG 系统性能瓶颈在哪里?一篇讲清楚如何优化

RAG 系统性能瓶颈在哪里?一篇讲清楚如何优化

很多人第一次做 RAG(Retrieval-Augmented Generation,检索增强生成)时,会觉得它的流程很简单:

用户提问 → 检索资料 → 把资料交给大模型 → 生成答案。

但真正上线之后,经常会遇到几个问题:

  • 响应越来越慢
  • 并发一高就扛不住
  • 检索结果很多,但答案反而变差
  • Token 消耗越来越大
  • 向量数据库明明很快,系统整体却还是很慢

原因很简单:

RAG 的性能问题通常不是出在某一个点,而是整条链路共同造成的。

一个典型的 RAG 请求大致可以拆成:

用户请求 → Query 处理 → Embedding → 向量检索 → Rerank → Prompt 拼接 → LLM 推理 → 返回结果

真正需要优化的,也是这几步。


一、最大的瓶颈:LLM 推理

大多数 RAG 系统里,真正最耗时间的通常不是向量检索,而是 大模型生成答案

例如:

向量数据库可能几十毫秒就能返回结果,但大模型生成一段几百字的回答,可能需要几秒。

尤其是当你把大量检索结果全部塞进 Prompt:

用户问题
+
10 段文档
+
历史聊天记录
+
系统提示词

Prompt 可能瞬间膨胀到几千甚至几万个 Token。

Prompt 越长:

推理越慢、成本越高、模型越容易被无关信息干扰。

优化方法

第一件事不是换 GPU,而是:

减少送给 LLM 的 Token。

比如原来:

TopK = 20

一次检索 20 个 Chunk 全塞进去。

可以调整成:

Retrieve Top 20
↓
Rerank
↓
只保留 Top 3~5
↓
交给 LLM

本质上就是一句话:

多检索,少输入。

检索阶段可以稍微宽松,但真正送进大模型的内容必须精简。


二、第二个瓶颈:检索质量,而不是检索速度

很多人优化 RAG 时会盯着:

Vector Search = 100ms

然后花大量时间把它优化到:

30ms

但实际上,如果整个请求要 4 秒,这 70ms 通常不是最重要的问题。

真正影响体验的是:

检索出来的东西到底对不对。

例如用户问:

退款期限是多少?

结果检索出来:

Chunk 1:退款规则
Chunk 2:公司简介
Chunk 3:支付方式
Chunk 4:会员协议
Chunk 5:售后地址

虽然搜索很快,但只有第一条真正有用。

如果这些内容全部塞给模型,就会造成:

无关上下文
↓
Prompt 变长
↓
LLM 推理变慢
↓
答案准确率下降

因此 RAG 优化里一个非常重要的原则是:

检索准确率比单纯追求检索速度更重要。


三、Chunk 切分不合理

RAG 系统里一个非常容易被低估的问题,就是:

文档怎么切。

Chunk 太大,例如:

每块 3000 Token

优点是上下文完整。

但缺点也很明显:

  • 检索粒度太粗
  • 无关信息多
  • Prompt 很长
  • Token 成本高

Chunk 太小,例如:

每块 50 Token

又可能导致语义被切碎。

例如原文:

退款申请需要在购买后 30 天内提交。
超过 30 天将不支持退款。

如果刚好被切成两个 Chunk,就可能导致检索结果缺少完整语义。

比较常见的做法是:

Chunk Size:300~800 Token
Overlap:10%~20%

但这里没有万能数字。

技术文档、合同、代码、客服知识库,适合的 Chunk 大小都不同。

所以真正正确的思路是:

按照语义结构切,而不是机械地按照字符数切。

例如优先按照:

标题
段落
章节
函数
FAQ
表格

进行切分。


四、TopK 过大

这是很多 RAG 系统最常见的问题。

为了防止“漏掉答案”,直接:

TopK = 20

甚至:

TopK = 50

结果就是:

检索更多内容
↓
Prompt 更长
↓
LLM 更慢
↓
Token 成本更高
↓
噪声更多

实际上很多场景:

最终 TopK = 3~5

已经足够。

一个比较好的架构是:

Vector Search Top 20
        ↓
      Rerank
        ↓
      Top 5
        ↓
       LLM

这样既保证召回率,又不会让 Prompt 过度膨胀。


五、Rerank 可能成为隐藏瓶颈

为了提升检索质量,现在很多 RAG 会使用:

向量召回
+
Reranker

例如:

Query
↓
向量搜索 Top 50
↓
Cross Encoder Rerank
↓
Top 5

准确率通常会明显提高。

但是问题也来了:

Rerank 本身也是模型推理。

如果每次都对几十甚至上百个文档进行重排序,并发一高,Reranker 就可能成为新的性能瓶颈。

解决方法一般是控制候选集,例如:

错误:

Top 100
↓
全部 Rerank

更合理:

Top 20
↓
Rerank
↓
Top 5

不要让 Reranker 干向量数据库应该干的活。


六、Embedding 重复计算

另一个很常见的问题是:

相同内容被重复 Embedding。

比如用户反复查询类似问题:

退款时间多久?
退款期限是多少?
多久可以申请退款?

如果每次都重新计算 Embedding,就会产生重复开销。

优化方法主要有两个:

文档 Embedding 离线计算

文档上传之后:

文档
↓
Chunk
↓
Embedding
↓
写入 Vector DB

这一步应该提前完成。

不要用户查询时才临时计算文档向量。

Query Embedding 加缓存

对于高频问题,可以缓存:

Query → Embedding

如果 Query 高度重复,可以直接复用。


七、数据库不是越高级越好

很多团队一遇到 RAG 性能问题,就开始换:

FAISS
↓
Milvus
↓
Pinecone
↓
Weaviate
↓
Elasticsearch

但实际上,大部分早期 RAG 系统的问题并不在数据库。

如果只有:

10 万
100 万
甚至几百万 Chunk

很多成熟的向量数据库都能轻松处理。

真正应该关注的是:

索引类型
Embedding 维度
TopK
过滤条件
数据量
并发量

比如:

HNSW
IVF
PQ

不同索引在:

速度
内存
召回率

之间存在不同取舍。

核心不是“哪个数据库最强”,而是:

你的规模到底需不需要这么复杂。


八、缓存通常是最便宜的性能优化

RAG 系统里有很多东西都可以缓存。

例如:

Query Embedding
检索结果
Rerank 结果
最终回答

假设大量用户都在问:

如何退款?

完全没必要:

Embedding
↓
Search
↓
Rerank
↓
LLM

每次全部重新执行。

可以直接:

Query
↓
Cache
↓
Answer

从几秒下降到几十毫秒都有可能。

因此很多高并发 RAG 系统最终都会大量使用:

Redis
+
Semantic Cache

普通缓存针对完全相同的问题。

Semantic Cache 则可以处理:

怎么退款?

如何申请退款?

退款流程是什么?

这种语义相似的问题。


九、并发问题往往比单次延迟更重要

开发阶段可能觉得系统很快:

一个用户:2 秒

但上线以后:

100 个用户同时请求

情况就完全不同。

瓶颈可能出现在:

Embedding API
Vector DB
Reranker
LLM API
数据库连接池
网络 IO

因此生产级 RAG 一般会使用:

异步调用
连接池
批量 Embedding
Batch Rerank
请求队列
限流
缓存

目标不是只优化:

单请求延迟

还要优化:

吞吐量
QPS
P95
P99

因为平均 2 秒没有意义。

如果:

P50 = 2 秒
P99 = 20 秒

用户依然会觉得系统很慢。


十、RAG 性能优化的正确顺序

很多人一开始就优化数据库,实际上顺序往往反了。

更推荐按照下面的顺序排查:

1. 看总延迟
↓
2. 拆分每个阶段耗时
↓
3. 看 Prompt Token
↓
4. 看 TopK
↓
5. 看 Chunk
↓
6. 看 Rerank
↓
7. 加缓存
↓
8. 最后优化基础设施

例如记录:

Embedding      80ms
Vector Search  60ms
Rerank         300ms
LLM            2800ms

这时候非常明显:

LLM = 2800ms

才是真正的大头。

如果你花两天把:

Vector Search

60ms → 30ms

用户基本感觉不到。

但如果通过减少 Prompt:

LLM

2800ms → 1500ms

体验就会明显提升。


总结

RAG 系统的性能瓶颈,通常集中在几个地方:

LLM 推理、Prompt 太长、检索噪声、Chunk 不合理、TopK 太大、Rerank 太重、重复计算以及高并发。

真正有效的优化思路可以概括成一句话:

尽可能早地过滤无关信息,尽可能少地把内容送给大模型。

所以一个比较合理的生产级 RAG 流程通常是:

User Query
    ↓
Query Rewrite
    ↓
Embedding
    ↓
Vector Search
Top 20
    ↓
Metadata Filter
    ↓
Rerank
Top 5
    ↓
Context Compression
    ↓
LLM
    ↓
Answer

再配合:

Cache
Async
Batch
Monitoring

基本就是一套比较完整的 RAG 性能优化思路。

最终真正要关注的,不是:

“我的向量数据库够不够快?”

而是:

“一次请求里,到底哪一步最慢、哪一步最贵、哪一步产生了最多无用信息?”

先把链路测清楚,再针对最大瓶颈优化,往往比盲目换模型、换数据库有效得多。

RAG 系统性能瓶颈在哪里?一篇讲清楚如何优化
http://clxhxhhr.top/posts/579/
作者
clxstart
发布于
2026-09-11
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。