1,377
社区成员
发帖
与我相关
我的任务
分享很多RAG项目的第一版都非常相似:
PDF → 切块 → 向量化 → FAISS → Top5 → 大模型
代码很快就能运行。
但真正上线之后,开发者很容易发现:
用户问的问题明明在PDF里,系统却找不到。
这时候最容易出现的误区,就是不断更换大模型。
实际上,大量RAG问题发生在模型看到Prompt之前。
假设原文为:
NX系统中,拉伸特征可以通过草图轮廓形成实体。拉伸距离支持对称、单向以及直至选定对象等方式。
如果采用固定长度切块,有可能出现:
Chunk A:
NX系统中,拉伸特征可以通过草图轮廓形成实体。
拉伸距离支持
Chunk B:
对称、单向以及直至选定对象等方式。
当用户询问:
“NX拉伸支持哪些终止方式?”
Chunk B虽然包含答案,但是缺少“拉伸”这一主体。
这就是典型的语义断裂。
例如:
chunk_size = 500
chunk_overlap = 100
优点:
缺点:
利用:
标题
章节
自然段
Markdown Heading
进行切分。
这种方式更加符合人类阅读结构。
通过Embedding判断前后句语义是否发生明显变化。
如果语义变化较大,就建立新的Chunk。
假设:
Chunk1 = 第1~500字
Chunk2 = 第401~900字
中间存在100字重叠。
目的就是尽量避免关键信息恰好落在Chunk边界。
flowchart LR
A[Chunk1<br/>1-500] --> B[Overlap<br/>401-500]
B --> C[Chunk2<br/>401-900]
Overlap不是越大越好。
因为重叠过大意味着:
关键词检索关注的是:
有没有相同词。
向量检索更加关注:
表达的意思是不是相似。
例如:
用户:
“电脑突然没电了怎么办?”
文档:
“当笔记本出现无法供电时,应首先检查电源适配器。”
两句话字面差异很大,但语义相关。
Embedding正是用来解决这种问题。
假设向量数据库检索出20条结果:
Top20
↓
Reranker
↓
Top5
↓
LLM
向量数据库负责:
快速找到“可能相关”的内容。
Reranker负责:
精细判断“到底谁最相关”。
flowchart LR
A[用户Query] --> B[Vector Search]
B --> C[Top 20]
C --> D[Reranker]
D --> E[Top 5]
E --> F[LLM]
因此两者不是替代关系。
更加合理的工程方案通常是:
粗排 + 精排。
向量检索并非任何场景都占优势。
比如用户搜索:
ERROR_CODE_0X8021
这种精确编号使用关键词搜索通常更加可靠。
因此可以组合:
BM25结果
+
Vector Search结果
↓
融合排序
↓
Reranker
这种方式叫做Hybrid Search。
适合:
混合出现的知识库。
flowchart TD
A[用户问题]
--> B[Query Rewrite]
B --> C[BM25]
B --> D[Vector Search]
C --> E[Result Fusion]
D --> E
E --> F[Reranker]
F --> G[Context Compression]
G --> H[LLM]
H --> I[答案]
这个结构比:
Vector Search → LLM
虽然复杂一些,但工程效果往往更加稳定。
RAG效果不好时,可以按照以下顺序排查:
1. 文档有没有清洗干净?
2. Chunk是否合理?
3. Embedding是否适合?
4. Query是否需要改写?
5. 检索结果是否准确?
6. 是否需要Hybrid Search?
7. 是否需要Rerank?
8. 最后再考虑更换LLM。
从这个角度看:
检索质量决定模型能够看到什么,大模型只是决定怎样利用看到的信息。