跳到主要内容RAG 应用落地关键痛点与解决策略分析 | 极客日志PythonAI算法
RAG 应用落地关键痛点与解决策略分析
RAG 应用落地面临格式错误、内容缺失、检索排名低、上下文整合限制、答案提取失败、回答宽泛及不全面、数据处理能力不足等八大痛点。针对格式问题可通过精准 Prompt、输出解析器及 Pydantic 模式规范;内容缺失需优化数据源与提示词引导模型承认未知;检索问题涉及重排序、调整 chunk 参数及微调 Embedding 模型;上下文整合与答案提取依赖清理数据、压缩长文本及重排节点;回答质量提升需结合高级检索策略与查询优化技术如 HyDE;数据处理则利用并行管道加速。基于 LlamaIndex 框架提供具体代码示例与解决方案。
www17 浏览 受 Barnett 等人所著的《Seven Failure Points When Engineering a Retrieval Augmented Generation System》一文启发,本文将探讨其中提到的几个关键问题。更重要的是,我们将深入探讨如何应对这些 RAG 系统中的挑战,以便在日常开发中更好地解决这些问题。
格式错误
当我们告诉计算机以某种特定格式(比如表格或 JSON)来整理信息,但大型语言模型(LLM)没能按照预期输出。为了更好地引导计算机理解我们的需求,我们可以通过以下方法来确保得到想要的格式:
更精准的 Prompt
让指令更加明确。
简化问题并突出关键词。
提供示例。
循环提问,不断细化问题。
解析输出
为任何查询提供格式化指南。
对计算机的回答进行'解析'。
LlamaIndex 支持与其他框架如 Guardrails 和 LangChain 提供的输出解析模块集成。
Guardrails: https://docs.llamaindex.ai/en/stable/module_guides/querying/structured_outputs/output_parser.html#guardrails
LangChain: https://docs.llamaindex.ai/en/stable/module_guides/querying/structured_outputs/output_parser.html#langchain
具体使用方法,可参考:https://docs.llamaindex.ai/en/stable/module_guides/querying/structured_outputs/output_parser.html
from llama_index import VectorStoreIndex, SimpleDirectoryReader
from llama_index.output_parsers import LangchainOutputParser
from llama_index.llms import OpenAI
from langchain.output_parsers import StructuredOutputParser, ResponseSchema
documents = SimpleDirectoryReader("../paul_graham_essay/data").load_data()
index = VectorStoreIndex.from_documents(documents)
response_schemas = [
ResponseSchema(
name="Education",
description="描述作者的教育经历/背景。",
),
ResponseSchema(
name="Work",
description="描述作者的工作经验/背景。",
),
]
lc_output_parser = StructuredOutputParser.from_response_schemas(response_schemas)
output_parser = LangchainOutputParser(lc_output_parser)
llm = OpenAI(output_parser=output_parser)
llama_index ServiceContext
ctx = ServiceContext.from_defaults(llm=llm)
query_engine = index.as_query_engine(service_context=ctx)
response = query_engine.query()
((response))
from
import
"作者成长过程中做了哪些事情?"
print
str
Pydantic
Pydantic 程序是一个多用途框架,它可以把输入的文字串转换成结构化的 Pydantic 对象。LlamaIndex 提供了多种 Pydantic 程序:
- LLM 文本完成 Pydantic 程序(LLM Text Completion Pydantic Programs):这些程序处理输入文本,并将其变成用户定义的结构化对象,它结合了文本完成 API 和输出解析功能。
- LLM 函数调用 Pydantic 程序(LLM Function Calling Pydantic Programs):这些程序根据用户的需求,将输入文本转换成特定的结构化对象,这一过程依赖于 LLM 函数调用 API。
- 预设的 Pydantic 程序(Prepackaged Pydantic Programs):这些程序被设计用来将输入文本转换成预先定义好的结构化对象。
from pydantic import BaseModel
from typing import List
from llama_index.program import OpenAIPydanticProgram
class Song(BaseModel):
title: str
length_seconds: int
class Album(BaseModel):
name: str
artist: str
songs: List[Song]
prompt_template_str = """
生成一个示例专辑,其中包含艺术家和歌曲列表。
以电影 movie_name 为灵感
"""
program = OpenAIPydanticProgram.from_defaults(
output_cls=Album,
prompt_template_str=prompt_template_str,
verbose=True
)
output = program(
movie_name="The Shining",
description="专辑的数据模型。"
)
OpenAI JSON 模式
OpenAI 的 JSON 模式允许我们设置 response_format 为 { 'type': 'json_object' },以此激活响应的 JSON 模式。一旦启用了 JSON 模式,计算机就只会生成能够被解析为有效 JSON 对象的字符串。尽管 JSON 模式规定了输出的格式,但它并不确保输出内容符合特定的规范。想了解更多,请查看 LlamaIndex 关于 OpenAI JSON 模式与数据提取功能调用的文档。
内容缺失问题
当实际答案不在知识库中时,RAG 系统往往给出一个貌似合理却错误的答案,而不是承认无法给出答案。这导致用户接收到误导性信息,造成错误的引导。如何解决内容缺失问题?
'输入什么,输出什么。'如果源数据质量差,比如充斥着冲突信息,那么无论你如何构建 RAG 流程,都不可能从杂乱无章的数据中得到有价值的结果。
在知识库缺乏信息,系统可能给出错误答案的情况下,改进提示方式可以起到显著帮助。例如,通过设置提示'如果你无法确定答案,请表明你不知道', 可以鼓励模型认识到自己的局限并更透明地表达不确定性。虽然无法保证百分百准确,但在优化数据源之后,改进提示方式是我们能做的最好努力之一。
错过排名靠前的文档
有时候系统在检索资料时,最关键的文件可能并没有出现在返回结果的最前面。这就导致了正确答案被忽略,系统因此无法给出精准的回答。
即:'问题的答案其实在某个文档里面,只是它没有获得足够高的排名以致于没能呈现给用户'
1. 重新排名检索结果
在将检索到的结果发送给大型语言模型(LLM)之前,对结果进行重新排名可以显著提升 RAG 的性能。LlamaIndex 的一个笔记本展示了两种不同方法的效果对比:
- 直接检索前两个节点,不进行重新排名,这可能导致不准确的检索结果
- 先检索前十个节点,然后使用 CohereRerank 进行重新排名,最后返回前两个节点,这种方法可以提高检索的准确性
2. 调整 chunk_size 和相似度排名 similarity_top_k
chunk_size 和 similarity_top_k 都是用来调控 RAG(检索增强型生成)模型数据检索过程中效率和效果的参数。改动这些参数能够影响计算效率与信息检索质量之间的平衡。
脱离上下文 — 整合策略的限制
论文中提到了这样一个问题:'虽然数据库检索到了含有答案的文档,但这些文档并没有被用来生成答案。这种情况往往出现在数据库返回大量文档后,需要通过一个整合过程来找出答案'。那么我们的解决方案有哪些呢?
1. 优化检索策略
以 LlamaIndex 为例,LlamaIndex 提供了一系列从基础到高级的检索策略,以帮助我们在 RAG 流程中实现精准检索。欲了解所有检索策略的详细分类,可以查阅 retrievers 模块的指南
- 从每个索引进行基础检索
- 进行高级检索和搜索
- 自动检索
- 知识图谱检索器
- 组合/分层检索器
- 更多其他选项!
2. 微调 Embedding 模型
finetune_engine = SentenceTransformersFinetuneEngine(
train_dataset,
model_id="BAAI/bge-small-en",
model_output_path="test_model",
val_dataset=val_dataset,
)
finetune_engine.finetune()
embed_model = finetune_engine.get_finetuned_model()
未能提取答案
当系统需要从提供的上下文中提取正确答案时,尤其是在信息量巨大时,系统往往会遇到困难。关键信息被遗漏,从而影响了回答的质量。论文中提到:'这种情况通常是由于上下文中存在太多干扰信息或相互矛盾的信息'。如何解决未能提取答案问题呢?
1. 清理数据
这一痛点再次凸显了数据质量的重要性。我们必须再次强调,干净整洁的数据至关重要!在质疑 RAG 流程之前,务必先要清理数据。
2. 上下文压缩
from llama_index.query_engine import RetrieverQueryEngine
from llama_index.response_synthesizers import CompactAndRefine
from llama_index.postprocessor import LongLLMLinguaPostprocessor
from llama_index.schema import QueryBundle
node_postprocessor = LongLLMLinguaPostprocessor(
instruction_str="鉴于上下文,请回答最后一个问题",
target_token=300,
rank_method="longllmlingua",
additional_compress_kwargs={
"condition_compare": True,
"condition_in_question": "after",
"context_budget": "+100",
"reorder_context": "sort",
},
)
retrieved_nodes = retriever.retrieve(query_str)
synthesizer = CompactAndRefine()
new_retrieved_nodes = node_postprocessor.postprocess_nodes(
retrieved_nodes, query_bundle=QueryBundle(query_str=query_str)
)
print("\n\n".join([n.get_content() for n in new_retrieved_nodes]))
response = synthesizer.synthesize(query_str, new_retrieved_nodes)
3. LongContextReorder 重排
from llama_index.postprocessor import LongContextReorder
reorder = LongContextReorder()
reorder_engine = index.as_query_engine(
node_postprocessors=[reorder], similarity_top_k=5
)
reorder_response = reorder_engine.query("作者见过山姆·奥尔特曼吗?")
回答过于宽泛
有时候,我们得到的回答可能缺少必要的细节或特定性,这通常需要我们进一步提问来获取清晰的信息。有些答案可能过于含糊或泛泛,不能有效地满足用户的实际需求。为此,我们需要采用更高级的检索技巧。
当答案没有达到你所期待的详细程度时,你可以通过提升检索技巧来改善这一状况。以下是一些有助于解决这个问题的先进检索方法:
回答不全面
有时候我们得到的是部分答案,并不是说它们是错误的,但它们并没有提供所有必要的细节,即便这些信息实际上是存在并且可以获取的。比如,如果有人问:'文档 A、B 和 C 中都讨论了哪些主要内容?'针对每份文档分别提问可能会得到更为全面的答案。那么如何解决回答不全面问题呢?
在简单的 RAG 模型中,比较性问题往往处理得不够好。一个提升 RAG 推理能力的有效方法是加入一个查询理解层——也就是在实际进行向量存储查询之前进行查询优化。以下是四种不同的查询优化方式:
- 路由优化:保留原始查询内容,并明确它所涉及的特定工具子集。然后,将这些工具指定为合适的选择。
- 查询改写:保持选定工具不变,但重新构思多种查询方式,以适应同一组工具。
- 细分问题:将大问题拆分成几个小问题,每个小问题都针对根据元数据确定的不同工具
- ReAct Agent 工具选择:根据原始查询内容,确定使用哪个工具,并构造针对该工具的特定查询。
数据处理能力的挑战
在 RAG 技术流程中,处理大量数据时常会遇到一个难题:系统若无法高效地管理和加工这些数据,就可能导致性能瓶颈甚至系统崩溃。这种处理能力上的挑战可能会让数据处理的时间大幅拉长,系统超负荷运转,数据质量下降,以及服务的可用性降低。
LlamaIndex 推出了一种数据处理的并行技术,能够使文档处理速度最多提升 15 倍。下面的代码示例展示了如何创建数据处理流程并设置 num_workers,以实现并行处理。
documents = SimpleDirectoryReader(input_dir="./data/source_files").load_data()
pipeline = IngestionPipeline(
transformations=[
SentenceSplitter(chunk_size=1024, chunk_overlap=20),
TitleExtractor(),
OpenAIEmbedding(),
]
)
nodes = pipeline.run(documents=documents, num_workers=4)
总结
在开发 RAG 应用时,面临诸多痛点。本文重点分析了八大核心问题及其应对方案:格式错误可通过精准 Prompt 和输出解析器解决;内容缺失需依赖高质量数据源及明确的提示词约束;检索排名问题涉及重排序算法及参数调优;上下文整合限制要求优化检索策略与微调 Embedding 模型;答案提取困难需结合数据清洗与上下文压缩技术;回答宽泛或不全面则需引入高级检索策略与查询优化机制;数据处理能力不足可通过并行管道缓解。每一个痛点都值得深入探讨,开发者应根据实际场景选择合适的技术栈与配置,以确保 RAG 系统的稳定性与准确性。
相关免费在线工具
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- RSA密钥对生成器
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
- Mermaid 预览与可视化编辑
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
- 随机西班牙地址生成器
随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online
- Gemini 图片去水印
基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online
- curl 转代码
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online