一、RAG流程拆解
1.1 流程图
二、数据处理阶段
2.1 复杂文档解析困难
- 问题:企业数据往往存在于PDF、PPT、Word、图片等非结构化文档中,尤其是带有复杂表格、多栏排版、公式或图片的文档,传统的文本提取工具很容易破坏原有结构,导致信息混乱。
- 解决方案:
- 使用专门的高级解析工具:如LlamaParse,Unstructured.io,阿里云/腾讯云的文档解析API;
- 多模态处理:针对包含图片或图表的文档,使用视觉大模型(如 GPT-4o, Claude 3.5 Sonnet)先对图片和表格进行总结,将生成的文本摘要与其原始图像一起存入向量数据库,实现多模态RAG。
2.2 分块(Chunking)策略不当
- 问题:如果Chunk太大,包含的无关信息太多,会稀释核心内容并消耗大量Token;如果Chunk太小,又会丢失上下文语境(例如一句话被生硬截断)。
- 解决方案:
- 语义分块:基于句号、段落等自然语义边界进行切割,而不是简单的固定字数;
- 父子块检索(Small-to-Big Retrieval):在向量库中存储较小的子块用于精准检索,但同时保留其指向的大段落(父块)。当命中子块时,将完整的父块喂给LLM,以保证上下文完整;
- 滑动窗口(Sentence Window Retrieval):检索单句话,但向LLM提供该句前后的几句话。
2.3 数据质量差
- 问题:上传的文档数据可能存在重复或噪声数据、内容过时或不完整、格式不一致等问题,影响检索和答案生成。
- 解决方案:
- 去重算法 + 噪声过滤规则:去重并筛除无意义的信息;
- 定期刷新 + 完整性检查:保证向量库中数据的可靠性;
- 标准化预处理 + 多模态解析:将图片、表格或其他格式的数据转换成统一格式。
2.4 数据摄取的可扩展性
- 问题:如何从“跑通几十篇文档的 Demo”走向“处理企业级千万篇文档的生产环境”?
- 解决方案:
三、检索阶段(召回→重排)
3.1 用户提问意图不清或口语化
- 问题:用户的查询(Query)往往是短文本、口语化或是存在错别字,甚至需要结合历史对话历史才能理解(如:“它为什么会报错?”),直接用原问题去向量检索效果极差。
- 解决方案:
- 查询扩展(HyDE):HyDE(假设性文档嵌入)技术是指让LLM先根据问题“凭空”生成一段假设性答案,然后用这个答案去向量库检索真实的文档;
- 查询重写(子问题):让LLM先把用户的口语化、含糊的问题改写为清晰明确的陈述句或多个子问题;
- 多步骤查询转换:让LLM充当“思考者”,把复杂问题拆解、改写或分步执行,然后再进行多次检索;
- 路由查询引擎:LLM根据不同的用户问题选择不同的查询方法(查询扩展、子问题、多步骤查询转换)。
- 参阅:https://towardsdatascience.com/advanced-query-transformations-to-improve-rag-11adca9b19d1/
3.2 检索精度低(错过匹配度高的文档)
- 问题:单纯依赖向量相似度往往无法精准匹配专有名词、产品型号、工号等特定的关键词。
- 解决方案:
- 混合检索:将向量检索(矢量算法、理解语义)和传统关键词检索(如 BM25、匹配字面)结合起来,赋予不同的权重;
- 元数据过滤:在存入数据时打上标签(如日期、文档类型、部门),检索前先通过条件过滤掉无关数据,缩小范围;
- 优化Query:优化用户查询的问题。
3.3 检索出来的文档过多
- 问题:如果检索出10个文档直接丢给LLM,由于LLM存在“注意力机制衰减”的问题,往往会忽略处于中间位置的上下文,且检索回来的初步排序未必是最符合用户问题的。
- 解决方案:
- 重排:引入专门的重排(Reranker)模型(如Cohere Rerank、BGE-Reranker);流程是:先粗排召回20-30篇文档,然后用Reranker模型根据Query和Document的相关性进行精排,最后只取Top 3-5输入给LLM。
3.4 重排过滤了关键文档
- 问题:在系统的检索组件返回的结果中,关键性文档可能并不靠前。
- 解决方案:调整参数similarity_top_k和chunk_size。
四、生成阶段
4.1 幻觉问题(内容缺失)
- 问题:大模型没有依赖检索到的上下文,而是根据自身的预训练知识开始“胡编乱造”,或者在上下文中找不到答案时仍然强行回答。
- 解决方案:
- 严格的Prompt工程:在系统提示词中强化指令,例如:“你是一个知识问答助手,请仅根据以下提供的背景信息回答问题;如果背景信息中没有答案,请直接回答‘我不知道’,严禁编造。”
- 提供引用来源(Citation):强制要求LLM在回答时标出引用了哪一个文档的哪一段,这不仅能降低幻觉,还能提升用户的信任度。
4.2 延迟过高
- 问题:RAG引入了“意图识别 => 召回 => 重排 => LLM生成”等长链路,导致系统响应时间变长。
- 解决方案:
- 流式输出:在LLM生成阶段开启流式响应,让用户能立刻看到字一个一个蹦出来,缓解等待焦虑;
- 缓存机制:使用Redis或GPTCache,当用户提出相同或语义高度相似的问题时,直接返回之前的答案,跳过检索和生成步骤;因此还需要用到类似LlamaIndex的memory和chat_engine组件记住上下文。
4.3 输出格式错误
- 问题:LLM忽略了提取特定格式的信息(如表格或列表)。
- 解决方案:
- 提示词设计:清晰地说明指令、简化请求并使用关键词、给出示例、使用迭代式的prompt并询问后续问题;
- 输出解析:LlamaIndex支持整合Guardrails和LangChain等其他框架提供的输出解析模块;
- OpenAI Pydantic程序:Pydantic程序是一个多功能框架,可将输出的字符串转换为结构化的Pydantic对象;
- OpenAI JSON模式:OpenAI JSON模式可以让我们将response_format设置成{"type":"json_object"}来启用JSON模式的响应。
4.4 大模型无法提取出答案
- 问题:当分片过大或噪音过多时,LLM可能难以从检索或重排后的分片中提取出正确的答案,即使答案就在其中。
- 解决方案:
- 清洗数据:常见原因是投喂的数据质量差;
- 内容压缩:使用longllmlingua压缩分片。
- from llama_index.postprocessor.longllmlingua import LongLLMLinguaPostprocessor
复制代码 4.5 输出答案不全
- 问题:输出的答案没有错误,但是只有一部分,未能提供全部细节。
- 解决方案:
五、其他问题
5.1 记住上下文
- 问题:LlamaIndex的query_engine没有记住上下文的能力。
- 解决方案:
- 引入LlamaIndex的memory和chat_engine组件。
- from llama_index.core.memory import ChatMemoryBuffer
- memory = ChatMemoryBuffer.from_defaults(token_limit=3900)
- chat_engine = index.as_chat_engine(
- chat_mode="context",
- memory=memory,
- system_prompt="prompt",
- similarity_top_k=5
- )
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |