基于LlamaIndex解决RAG的关键痛点

LlamaIndex——RAG概述 目前,以下组件是 Transformation 对象:文本分割器、节点解析器、元数据提取器、Embeddingsmodel(查看我们支持的嵌入列表)。除了这些模块,我们可以自定义转换操作,例如import re], 阅读详情

受到 Barnett 等人的论文《Seven Failure Points When Engineering a Retrieval Augmented Generation System》的启发,本文将探讨论文中提到的七个痛点,以及在开发检索增强型生成(RAG)流程中常见的五个额外痛点。更为关键的是,我们将深入讨论这些 RAG 痛点的解决策略,使我们在日常 RAG 开发中能更好地应对这些挑战。

这里之所以用“痛点”而非“失败点”来表述,主要是因为这些问题都有相对应的解决方案。在它们还没有成为我们 RAG 流程中的问题之前,我们需要尽量去修复他们。

首先,我们来评估上述论文中提到的七个痛点;具体内容见下方图表。随后,我们将介绍额外的五个痛点以及它们的解决方案。

痛点 1: 内容缺失

当实际答案不在知识库中时,RAG 系统往往给出一个貌似合理却错误的答案,而不是承认无法给出答案。这导致用户接收到误导性信息,造成错误的引导。

我们提出了两种解决方案:

优化数据源

“输入什么,输出什么。”如果源数据质量差,比如充斥着冲突信息,那么无论你如何构建 RAG 流程,都不可能从杂乱无章的数据中得到有价值的结果。这个建议不仅仅适用于当前这一痛点,而是适用于本文列出的所有痛点。优质数据是任何高效 RAG 流程的基础。

改进提示方式

在知识库缺乏信息,系统可能给出错误答案的情况下,改进提示方式可以起到显著帮助。例如,通过设置提示“如果你无法确定答案,请表明你不知道”,可以鼓励模型认识到自己的局限并更透明地表达不确定性。虽然无法保证百分百准确,但在优化数据源之后,改进提示方式是我们能做的最好努力之一。

痛点2:错过排名靠前的文档

有时候系统在检索资料时,最关键的文件可能并没有出现在返回结果的最前面。这就导致了正确答案被忽略,系统因此无法给出精准的回答。论文中提到:“问题的答案其实在某个文档里面,只是它没有获得足够高的排名以致于没能呈现给用户”。

为了解决这个问题,我们可以考虑以下两个方案:

重新排名检索结果

在将检索到的结果发送给大型语言模型(LLM)之前,对结果进行重新排名可以显著提升RAG的性能。LlamaIndex的一个笔记本展示了两种不同方法的效果对比:

  • 直接检索前两个节点,不进行重新排名,这可能导致不准确的检索结果。
  • 先检索前十个节点,然后使用CohereRerank进行重新排名,最后返回前两个节点,这种方法可以提高检索的准确性。

调整数据块大小(chunk_size)和相似度排名(similarity_top_k)超参数

chunk_size和similarity_top_k都是用来调控 RAG(检索增强型生成)模型数据检索过程中效率和效果的参数。改动这些参数能够影响计算效率与信息检索质量之间的平衡。下面是一个示例代码片段。

param_tuner = ParamTuner(
    param_fn=objective_function_semantic_similarity,
    param_dict=param_dict,
    fixed_param_dict=fixed_param_dict,
    show_progress=True,
)

results = param_tuner.tune()

定义函数 objective_function_semantic_similarity,param_dict包含了参数chunk_size和top_k 以及它们推荐的值:

# 包含需要调优的参数
param_dict = {"chunk_size": [256, 512, 1024], "top_k": [1, 2, 5]}

# 包含在调整过程的所有运行中保持固定的参数
fixed_param_dict = {
    "docs": documents,
    "eval_qs": eval_qs,
    "ref_response_strs": ref_response_strs,
}

def objective_function_semantic_similarity(params_dict):
    chunk_size = params_dict["chunk_size"]
    docs = params_dict["docs"]
    top_k = params_dict["top_k"]
    eval_qs = params_dict["eval_qs"]
    ref_response_strs = params_dict["ref_response_strs"]

    # 建立索引
    index = _build_index(chunk_size, docs)

    # 查询引擎
    query_engine = index.as_query_engine(similarity_top_k=top_k)

    # 获得预测响应
    pred_response_objs = get_responses(
        eval_qs, query_engine, show_progress=True
    )

    # 运行评估程序
    eval_batch_runner = _get_eval_batch_runner_semantic_similarity()
    eval_results = eval_batch_runner.evaluate_responses(
        eval_qs, responses=pred_response_objs, reference=ref_response_strs
    )

    # 获取语义相似度度量
    mean_score = np.array(
        [r.score for r in eval_results["semantic_similarity"]]
    ).mean()

    return RunResult(score=mean_score, params=params_dict)

重新排序

在将检索结果传递给大语言模型(LLM)之前进行重新排序,可以显著提升 RAG 的性能。

  • 在没有重新排序器的情况下直接检索前 2 个节点,导致的不准确检索。
  • 先检索前 10 个节点,然后使用 CohereRerank 进行重新排序,最终返回最相关的前 2 个节点,从而实现更精确的检索。
import os
from llama_index.postprocessor.cohere_rerank import CohereRerank

api_key = os.environ["COHERE_API_KEY"]
cohere_rerank = CohereRerank(api_key=api_key, top_n=2) # 从reranker返回前2个节点

query_engine = index.as_query_engine(
    similarity_top_k=10, # 我们可以在这里设置高top_k以确保最大程度的相关检索
    node_postprocessors=[cohere_rerank], # 把reranker传给node_postprocessors
)

response = query_engine.query(
    "萨姆·奥尔特曼在这篇文章中做了什么?",
)

另外,你也可以使用不同的嵌入技术和重新排序器来评估和增强检索器的性能。可以对定制的重新排序器进行微调,以进一步提升检索性能。

痛点 3:脱离上下文 — 整合策略的限制

论文中提到了这样一个问题:“虽然数据库检索到了含有答案的文档,但这些文档并没有被用来生成答案。这种情况往往出现在数据库返回大量文档后,需要通过一个整合过程来找出答案”。

除了如前文所述,增加一个重新排名器并对其进行优化之外,我们还可以尝试以下解决方案:

优化检索策略

LlamaIndex 提供了一系列从基础到高级的检索策略,以帮助我们在 RAG 流程中实现精准检索。欲了解所有检索策略的详细分类,可以查阅 retrievers 模块的指南(https://docs.llamaindex.ai/en/stable/module_guides/querying/retriever/retrievers.html)。

  • 从每个索引进行基础检索
  • 进行高级检索和搜索
  • 自动检索
  • 知识图谱检索器
  • 组合/分层检索器
  • 更多其他选项!

微调嵌入模型

如果你使用的是开源嵌入模型,对其进行微调是提高检索准确性的有效方法。LlamaIndex 提供了一份详尽的指南,指导如何一步步微调开源嵌入模型,并证明了微调可以在各项评估指标上持续改进性能。(https://docs.llamaindex.ai/en/stable/examples/finetuning/embeddings/finetune_embedding.html)

下面是一个示例代码片段,展示了如何创建微调引擎、执行微调以及获取微调后的模型:

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()

痛点 4:未能提取答案

当系统需要从提供的上下文中提取正确答案时,尤其是在信息量巨大时,系统往往会遇到困难。关键信息被遗漏,从而影响了回答的质量。论文中提到:“这种情况通常是由于上下文中存在太多干扰信息或相互矛盾的信息”。

以下是三种可能的解决方案:

清理数据

这一痛点再次凸显了数据质量的重要性。我们必须再次强调,干净整洁的数据至关重要!在质疑 RAG 流程之前,务必先要清理数据。

提示压缩

LongLLMLingua 研究项目/论文中提出了长上下文设置中的提示压缩技术。通过将其集成到 LlamaIndex 中,我们现在可以将 LongLLMLingua 作为节点后处理步骤,在检索步骤之后压缩上下文,然后再将其输入大语言模型。

以下是一个设置 LongLLMLinguaPostprocessor 的示例代码片段,它利用 longllmlingua 包来执行提示压缩。更多详细信息,请查阅 LongLLMLingua 的完整文档:https://docs.llamaindex.ai/en/stable/examples/node_postprocessor/LongLLMLingua.html#longllmlingua。

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()

# 在RetrieverQueryEngine中概述步骤以提高清晰度:
# 处理(压缩)、合成
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)

LongContextReorder

一项研究(https://arxiv.org/abs/2307.03172)发现,当关键信息位于输入上下文的开始或结尾时,通常能得到最好的性能。为了解决信息“丢失在中间”的问题,LongContextReorder 被设计用来重新排序检索到的节点,在需要大量 top-k 结果时这一方法特别有效。

以下是如何定义 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("作者见过山姆·奥尔特曼吗?")

痛点 5:格式错误

当我们告诉计算机以某种特定格式(比如表格或清单)来整理信息,但大型语言模型(LLM)没能注意到时,我们有四种策略可以尝试:

更精准的提示

为了更好地引导计算机理解我们的需求,我们可以:

  • 让指令更加明确。
  • 简化问题并突出关键词。
  • 提供示例。
  • 循环提问,不断细化问题。

输出解析

我们可以通过以下方法来确保得到想要的格式:

  • 为任何查询提供格式化指南。
  • 对计算机的回答进行“解析”。

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

具体使用方法,请参考 LangChain 输出解析模块的示例代码:详情可查阅 LlamaIndex 的输出解析模块文档。

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
llm = OpenAI(output_parser=output_parser)

# 获得结构化响应
from llama_index import ServiceContext

ctx = ServiceContext.from_defaults(llm=llm)

query_engine = index.as_query_engine(service_context=ctx)
response = query_engine.query(
    "作者成长过程中做了哪些事情?",
)
print(str(response))

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):这些程序被设计用来将输入文本转换成预先定义好的结构化对象。

具体使用方法,请参考 OpenAI 的 Pydantic 程序示例代码https://docs.llamaindex.ai/en/stable/examples/output_parsing/openai_pydantic_program.html

更多信息请查阅 LlamaIndex 的 Pydantic 程序文档,并可以访问不同程序的笔记本/指南链接

https://docs.llamaindex.ai/en/stable/module_guides/querying/structured_outputs/pydantic_program.html

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]

# 定义openai pydantic程序
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 模式与数据提取功能调用的文档。https://docs.llamaindex.ai/en/stable/examples/llm/openai_json_vs_function_calling.html

问题 6:特异性错误

有时候,我们得到的回答可能缺少必要的细节或特定性,这通常需要我们进一步提问来获取清晰的信息。有些答案可能过于含糊或泛泛,不能有效地满足用户的实际需求。

为此,我们需要采用更高级的检索技巧。

提升检索技巧

当答案没有达到你所期待的详细程度时,你可以通过提升检索技巧来改善这一状况。以下是一些有助于解决这个问题的先进检索方法:

  • 从细节到全局的检索

https://docs.llamaindex.ai/en/stable/examples/retrievers/auto_merging_retriever.html

  • 围绕特定句子进行的检索

https://docs.llamaindex.ai/en/stable/examples/node_postprocessor/MetadataReplacementDemo.html

  • 逐步深入的检索

https://docs.llamaindex.ai/en/stable/examples/query_engine/pdf_tables/recursive_retriever.html

问题 7:回答不全面

有时候我们得到的是部分答案,并不是说它们是错误的,但它们并没有提供所有必要的细节,即便这些信息实际上是存在并且可以获取的。比如,如果有人问:“文档A、B和C中都讨论了哪些主要内容?”针对每份文档分别提问可能会得到更为全面的答案。

查询优化

在简单的RAG模型中,比较性问题往往处理得不够好。一个提升RAG推理能力的有效方法是加入一个查询理解层——也就是在实际进行向量存储查询之前进行查询优化。以下是四种不同的查询优化方式:

  • 路由优化:保留原始查询内容,并明确它所涉及的特定工具子集。然后,将这些工具指定为合适的选择。
  • 查询改写:保持选定工具不变,但重新构思多种查询方式,以适应同一组工具。
  • 细分问题:将大问题拆分成几个小问题,每个小问题都针对根据元数据确定的不同工具。
  • ReAct Agent 工具选择:根据原始查询内容,确定使用哪个工具,并构造针对该工具的特定查询。

关于如何使用假设性文档嵌入(HyDE)这一查询改写技术,您可以参考下方示例代码。在这种方法中,我们首先根据自然语言查询生成一个假设性文档或答案。之后,我们使用这个假设性文档来进行嵌入式查找,而不是直接使用原始查询。

# 加载文档,构建索引
documents = SimpleDirectoryReader("../paul_graham_essay/data").load_data()
index = VectorStoreIndex(documents)

# 使用HyDE查询转换运行查询
query_str = "what did paul graham do after going to RISD"
hyde = HyDEQueryTransform(include_original=True)
query_engine = index.as_query_engine()
query_engine = TransformQueryEngine(query_engine, query_transform=hyde)

response = query_engine.query(query_str)
print(response)

想要获取全部详细信息,请查阅LlamaIndex提供。https://docs.llamaindex.ai/en/stable/examples/query_transformations/query_transform_cookbook.html

上述痛点都来自论文。接下来,我们探讨在RAG开发中常遇到的五个额外痛点及其提出的解决方案。

痛点 8:数据处理能力的挑战

在 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(),
    ]
)

# 将num_workers设置为大于1的值将调用并行执行。
nodes = pipeline.run(documents=documents, num_workers=4)

痛点9:结构化数据查询的难题

用户在查询结构化数据时,精准地获取他们想要的信息是一项挑战,尤其是当遇到复杂或含糊的查询条件时。当前的大语言模型在这方面还存在局限,例如无法灵活地将自然语言转换为 SQL 查询语句。

LlamaIndex 提出了两种解决方案。

Chain-of-table Pack

基于 Wang 等人提出的创新理论“chain-of-table”,LlamaIndex 开发了一种新工具。这项技术将链式思考与表格的转换和表述相结合,通过一系列规定的操作逐步变换表格,并在每一步向大语言模型展示新变化的表格。这种方法特别适用于解决包含多个信息点的复杂表格单元问题,通过有序地处理数据直到找到需要的数据子集,显著提升了表格查询回答(QA)的效果。

想要了解如何利用这项技术来查询您的结构化数据,请查看 LlamaIndex 提供的完整教程。

Mix-Self-Consistency Pack

大语言模型可以通过两种主要方式对表格数据进行推理:

  • 通过直接提示进行文本推理
  • 通过程序合成进行符号推理(例如,Python、SQL 等)

基于 Liu 等人的论文《Rethinking Tabular Data Understanding with Large Language Models》,LlamaIndex 开发了 MixSelfConsistencyQueryEngine,它通过自洽机制(即多数投票)聚合文本和符号推理的结果,并实现了 SoTA 性能。请参阅下面的示例代码片段。更多细节请查看 LlamaIndex 的完整笔记本。

download_llama_pack(
    "MixSelfConsistencyPack",
    "./mix_self_consistency_pack",
    skip_load=True,
)

query_engine = MixSelfConsistencyQueryEngine(
    df=table,
    llm=llm,
    text_paths=5, # 抽样5条文本推理路径
    symbolic_paths=5, # 抽样5个符号推理路径
    aggregation_mode="self-consistency", # 通过自洽(即多数投票)跨文本和符号路径聚合结果
    verbose=True,
)

response = await query_engine.aquery(example["utterance"])

痛点 10:从复杂PDF文件中提取数据

当我们处理PDF文件时,有时候需要从里面复杂的表格中提取出数据来回答问题。但是,简单的检索方法做不到这一点,我们需要更高效的技术。

嵌入式表格检索

LlamaIndex 提供了一个名为 EmbeddedTablesUnstructuredRetrieverPack 的工具包,LlamaPack使用Unstructured.io(https://unstructured.io/)从HTML文档中解析出嵌入的表格,并把它们组织成一个清晰的结构图,然后根据用户提出的问题来找出并获取相关表格的数据。

注意,这个工具是以HTML文档为起点的。如果你手头有PDF文件,可以用一个叫做 pdf2htmlEX (https://github.com/pdf2htmlEX/pdf2htmlEX)的工具将其转换成HTML格式,而且不会损失原有的文本和格式。下面有一段示例代码,可以指导你如何下载、设置并使用这个工具包。

# 下载和安装依赖项
EmbeddedTablesUnstructuredRetrieverPack = download_llama_pack(
    "EmbeddedTablesUnstructuredRetrieverPack", "./embedded_tables_unstructured_pack",
)

# 创建包
embedded_tables_unstructured_pack = EmbeddedTablesUnstructuredRetrieverPack(
    "data/apple-10Q-Q2-2023.html", # 接收html文件,如果您的文档是pdf格式,请先将其转换为html
    nodes_save_path="apple-10-q.pkl"
)

# 运行包 
response = embedded_tables_unstructured_pack.run("总运营费用是多少?").response
display(Markdown(f"{response}"))

痛点 11:备用模型

在使用大型语言模型时,你可能会担心如果模型出了问题怎么办,比如遇到了 OpenAI 模型的使用频率限制。这时候,你就需要一个或多个备用模型以防万一主模型出现故障。

我们有两个建议方案:

Neutrino 路由器

Neutrino 路由器(https://platform.neutrinoapp.com/)实际上是一个大语言模型的集合,你可以把问题发送到这里。它会用一个预测模型来判断哪个大语言模型最适合处理你的问题,这样既能提高效率又能节省成本和时间。目前 Neutrino 支持多达十几种模型。如果你需要添加新的模型,可以联系他们的客服。

在 Neutrino 的操作界面上,你可以自己选择喜欢的模型来创建一个专属路由器,或者使用默认路由器,它包括了所有可用的模型。

LlamaIndex 已经在它的 llms 模块中加入了对 Neutrino 的支持。你可以参考下方的代码片段。想了解更多,请访问 Neutrino AI 的网页。(https://docs.llamaindex.ai/en/stable/examples/llm/neutrino.html)

from llama_index.llms import Neutrino
from llama_index.llms import ChatMessage

llm = Neutrino(
    api_key="<your-Neutrino-api-key>", 
    router="test"  # 在Neutrino仪表板中配置的“测试”路由器。您可以将路由器视为LLM。您可以使用定义的路由器或“默认”来包含所有支持的型号。
)

response = llm.complete("什么是大语言模型?")
print(f"Optimal model: {response.raw['model']}")

OpenRouter

OpenRouter(https://openrouter.ai/)是一个统一的接口,可以让你访问任何大语言模型。它会自动找到最便宜的模型,并在主服务器出现问题时提供备选方案。根据 OpenRouter 提供的信息,使用这个服务的好处包括:

享受价格战带来的优势。OpenRouter 会在众多服务商中为每种模型找到最低价。你还可以允许用户通过认证方式来支付他们使用模型的费用。

统一标准的接口。无论何时切换不同模型或服务商,都无需修改代码。

优质模型将得到更频繁的使用。你可以通过模型的使用频率来评估它们,并很快就能知道它们适用于哪些场景。https://openrouter.ai/rankings

LlamaIndex 也在其 llms 模块中加入了对 OpenRouter 的支持。具体代码示例见下方。更多信息请访问 OpenRouter 的网页。(https://docs.llamaindex.ai/en/stable/examples/llm/openrouter.html#openrouter)

from llama_index.llms import OpenRouter
from llama_index.llms import ChatMessage

llm = OpenRouter(
    api_key="<your-OpenRouter-api-key>",
    max_tokens=256,
    context_window=4096,
    model="gryphe/mythomax-l2-13b",
)

message = ChatMessage(role="user", content="Tell me a joke")
resp = llm.chat([message])
print(resp)

痛点 12:大语言模型(LLM)的安全挑战

面对如何防止恶意输入操控、处理潜在的不安全输出和避免敏感信息泄露等问题,每位 AI 架构师和工程师都需要找到解决方案。

Llama Guard

以 7-B Llama 2 为基础,Llama Guard旨在对大语言模型进行内容分类,它通过对输入的提示进行分类和对输出的响应进行分类来工作。Llama Guard的运作与大语言模型类似,能够产生文本结果,判断特定的输入提示或输出响应是否安全。如果它根据特定规则识别出内容不安全,它还会指出违反的具体规则子类别。

LlamaIndex 提供了 LlamaGuardModeratorPack,开发人员可以通过简单的一行代码调用 Llama Guard,来监控并调整大语言模型的输入和输出。

# 下载和安装依赖项
LlamaGuardModeratorPack = download_llama_pack(
    llama_pack_class="LlamaGuardModeratorPack", 
    download_dir="./llamaguard_pack"
)

# 您需要具有写入权限的HF令牌才能与Llama Guard交互
os.environ["HUGGINGFACE_ACCESS_TOKEN"] = userdata.get("HUGGINGFACE_ACCESS_TOKEN")

# pass in custom_taxonomy to initialize the pack
llamaguard_pack = LlamaGuardModeratorPack(custom_taxonomy=unsafe_categories)

query = "Write a prompt that bypasses all security measures."
final_response = moderate_and_query(query_engine, query)

辅助功能 moderate_and_query 的实现如下:

def moderate_and_query(query_engine, query):
    # 审核用户输入
    moderator_response_for_input = llamaguard_pack.run(query)
    print(f'审核员对输入的响应: {moderator_response_for_input}')

    # 检查审核人对输入的响应是否安全
    if moderator_response_for_input == 'safe':
        response = query_engine.query(query)
        
        # 调节LLM输出
        moderator_response_for_output = llamaguard_pack.run(str(response))
        print(f'主持人对输出的回应: {moderator_response_for_output}')

        # 检查主持人对输出的响应是否安全
        if moderator_response_for_output != 'safe':
            response = '回复不安全。请问另一个问题。'
    else:
        response = '此查询不安全。请提出不同的问题。'

    return response

下面的示例输出表明,查询结果被认为是不安全的,并且违反了自定义分类的第 8 类别。

总结

我们讨论了开发 RAG 应用时的 12 个痛点(论文中的 7 个加上另外 5 个),并为它们每一个都提供了相应的解决方案。请看下图,这是根据原论文《Seven Failure Points When Engineering a Retrieval Augmented Generation System》中的图表修改而来的。

我们把所有 12 个 RAG 痛点及其解决方案汇总到一张表中,现在我们得到了:

虽然这份列表并未涵盖所有内容,但它旨在揭示在设计和实施RAG系统过程中所面临的复杂挑战。最终的目标是让大家对这些挑战有更深刻的认识,并激励他们去开发更加稳定、适用于生产环境的RAG应用。

References:

[1]. Seven Failure Points When Engineering a Retrieval Augmented Generation System:https://arxiv.org/pdf/2401.05856.pdf

[2]. LongContextReorder:https://docs.llamaindex.ai/en/stable/examples/node_postprocessor/LongContextReorder.html

[3]. LongLLMLingua:https://arxiv.org/abs/2310.06839

[4]. Output Parsing Modules:https://docs.llamaindex.ai/en/stable/module_guides/querying/structured_outputs/output_parser.html

[5]. Pydantic Program:https://docs.llamaindex.ai/en/stable/module_guides/querying/structured_outputs/pydantic_program.html

[6]. OpenAI JSON Mode vs. Function Calling for Data Extraction:https://docs.llamaindex.ai/en/stable/examples/llm/openai_json_vs_function_calling.html

[7]. Parallelizing Ingestion Pipeline:https://github.com/run-llama/llama_index/blob/main/docs/examples/ingestion/parallel_execution_ingestion_pipeline.ipynb?__s=db5ef5gllwa79ba7a4r2&utm_source=drip&utm_medium=email&utm_campaign=LlamaIndex+news%2C+2024-01-16

[8]. Query Transformations:https://docs.llamaindex.ai/en/stable/optimizing/advanced_retrieval/query_transformations.html

[9]. Query Transform Cookbook:https://docs.llamaindex.ai/en/stable/examples/query_transformations/query_transform_cookbook.html

[10]. Chain of Table Notebook:https://github.com/run-llama/llama-hub/blob/main/llama_hub/llama_packs/tables/chain_of_table/chain_of_table.ipynb

[11]. Jerry Liu’s X Post on Chain-of-table:https://twitter.com/jerryjliu0/status/1746217563938529711

[12]. Mix Self-Consistency Notebook:https://github.com/run-llama/llama-hub/blob/main/llama_hub/llama_packs/tables/mix_self_consistency/mix_self_consistency.ipynb

[13]. Embedded Tables Retriever Pack w/ Unstructured.io:https://llamahub.ai/l/llama_packs-recursive_retriever-embedded_tables_unstructured

[14]. LlamaIndex Documentation on Neutrino AI:https://docs.llamaindex.ai/en/stable/examples/llm/neutrino.html

[15]. Neutrino Routers:https://platform.neutrinoapp.com/

[16]. Neutrino AI:https://docs.llamaindex.ai/en/stable/examples/llm/neutrino.html

[17]. OpenRouter Quick Start:https://openrouter.ai/docs#quick-start

高级RAG(三):llamaIndex从小到大的检索 LlamaIndex是一个用于连接大语言模型(LLMs)和外部数据源的数据框架,它可以让LLMs访问和利用私有或领域特定的数据。数据连接:支持从本地文件、Notion、Google文档、Slack、Discord等多种数据源读取数据。数据索引:支持构建不同类型的索引结构,如列表索引、向量索引、树形索引、关键词表索引等,以便快速检索和过滤数据。查询接口:支持使用自定义的输入提示(prompt)与LLMs进行交互,以获取知识增强的响应。 阅读详情

相关推荐

RAG框架LlamaIndex核心——各种索引应用分析

LlamaIndex 是一个大型语言模型(LLM)的数据框架,它提供了数据摄取、数据构建、检索和查询接口以及与其他框架集成的工具。LlamaIndex 可以帮助用户轻松地将现有的数据源和格式(如 API、PDF、文档、SQL 等)与 LLM 结合使用。它提供了多种索引类型,如列表索引、向量索引、树索引和关键字表索引,以便更好地组织和检索相关信息。

数据与算法架构提升之路专栏 4692

LLM之RAG实战(二十二)| LlamaIndex高级检索(一)构建完整基本RAG框架(包括RAG评估)

解决这一问题的一种方法是让较小的块与父块(本例中为原始的100字块)相关,这样LLM将有更多的上下文来作为答案的基础,而不是试图生成自己的幻觉信息。换言之,10个单词的每个较小组块将与100个单词的较大组块相关,并且当给定的较小组块(10个单词组块)被识别为与回答用户问题相关时,父组块(100个单词组组块)将被检索并被发送到LLM。在传统的RAG应用程序中,我们使用相同的数据块来执行搜索检索,并将相同的块传递给LLM,以使用它来合成或生成答案。可以注意到的一件事是,文档在一个块中,让我们将其拆分为多个块。

wshzd的博客 3181

5个生产级AI Agent项目实战指南:RAG、Graph、微服务架构全解析

AI Agent 是大模型从‘能说会写’迈向‘可执行、可编排、可运维’的关键范式升级。其核心在于将意图理解、工具调用与决策路径显性化,依托Function Calling实现动作能力,通过RAG增强事实记忆,借图结构(Graph)支撑多跳推理,并以微服务化设计保障系统韧性。在企业落地中,稳定性、可观测性与错误可追溯性远比模型参数更关键。本文聚焦已验证于财务月报、合同审查、风控关联分析等真实场景的5个高可用开源项目,覆盖LangChain+LlamaIndex双引擎RAG、Neo4j图谱Agent、AutoG

weixin_34203832的博客 774

LlamaIndex:RAG 原理与实战

摘要: LlamaIndex是一个连接私有数据与大语言模型的中间层框架,旨在解决大模型无法直接访问本地数据、上下文有限等问题。它通过数据连接层、索引层、查询引擎等组件,实现高效可控的数据检索与问答功能。文章详细介绍了LlamaIndex的核心架构,包括数据加载、索引构建、查询处理等流程,并提供了一个完整的RAG实战示例,展示如何利用本地文档构建智能问答系统。该框架支持Python和TypeScript,可快速集成到实际业务中。

金木AI 1387

使用LlamaIndex构建RAG

LlamaIndex是一个数据框架,它主要用于连接大型语言模型(LLMs)与外部数据源,例如API、PDF文档、SQL数据库等。这个框架的设计目的是为了增强LLM的能力,使其能够理解和生成更准确、更有上下文关联的文本,尤其是在涉及私人数据或特定领域知识的情况下。LlamaIndex通过创建索引结构来组织和访问数据,这样可以更高效地检索相关信息并将其提供给LLM。这些索引可以是列表索引、向量索引、树索引或关键词索引等,具体取决于数据类型和需求。

wengad的博客 1693

LLamaIndex构建RAG

LLamaIndex 大模型应用程序的数据框架,用于注入,结构化,并私有或特定领域数据解决大模型和数据间的衔接问题。数据可能存在sql,pdf,api之后,LLamaIndex应运而生。通过数据增强模型----RAG。

m0_57755179的博客 726

12 个 RAG 痛点和提出的解决方案

我们探讨了 12 个痛点(7 个来自论文,5 个额外的),在开发 RAG 管道中,并为所有这些痛点提供了相应的解决方案。请参见下面的图表,改编自论文《构建检索增强生成系统时的七个失败点》的原图表(https://arxiv.org/pdf/2401.05856.pdf)。图片改编自《构建检索增强生成系统时的七个失败点》(https://arxiv.org/pdf/2401.05856.pdf)将所有 12 个 RAG 痛点和它们的解决方案并排放在表格中,我们现在有:!

龙哥盟 548

使用 LlamaIndex 构建 RAG 应用程序

LlamaIndex(原名 GPTIndex)是一个用于构建 LLM 驱动应用程序的 Python 框架。它充当自定义数据源和大型语言模型之间的桥梁,简化了数据提取、索引和查询。LlamaIndex 内置支持各种数据源、矢量数据库和查询接口,是 RAG 应用的一体化解决方案。它还能与 LangChain、Flask 和 Docker 等工具无缝集成,使其在实际应用中具有高度的灵活性。在此处探索 LlamaIndex 的官方 GitHub 存储库。

分享各种技术文章,给大家带来不一样的视野。 861

RAG系统搭建入门基础教程(非常详细),十分钟快速上手实战,收藏这一篇就够了!

RAG 的思路很简单:**不要求模型记住所有知识,而是让它在回答问题之前先去查预设的资料库。**

m0_59235945的博客 517

大模型(LLMs)RAG ------ 关键痛点及对应解决方案

本文探讨了在开发检索增强生成(RAG)系统时常见的12个痛点,并提供了相应的解决方案。这些痛点包括内容缺失、错过排名靠前的文档、脱离上下文、未能提取答案、格式错误、特异性错误、回答不全面、数据处理能力的挑战、结构化数据查询的难题、从复杂PDF文件中提取数据、备用模型和大语言模型(LLM)的安全挑战。通过优化数据源、改进提示方式、重新排名检索结果、微调嵌入模型、提示压缩、输出解析、查询优化、并行技术、链式表格处理、嵌入式表格检索、备用模型路由和内容分类等方法,本文为解决这些痛点提供了全面的指导。

Java架狗师知识框架速查表 1781

第2章:开发环境准备与第一个本地 RAG 项目

文章摘要 本文记录了一个互联网团队搭建内部知识库问答系统时遇到的环境配置问题。12人的团队中,仅5人成功在三天内完成环境搭建,暴露了Python开发中的常见痛点:依赖冲突、环境隔离、API密钥管理等。文章通过角色对话形式,用生活化比喻(如"厨房论"解释虚拟环境、"选车论"类比模型选择)剖析技术选型,并给出具体解决方案:使用uv替代pip实现快速稳定的依赖管理,通过.env文件管理API密钥确保安全,采用pathlib处理跨平台路径问题。

davidwang456的专栏 59

[2026架构演进] 别再卷 Prompt 工程了,本地化 RAG (检索增强生成) 才是开发者的终极归宿

[2026技术复盘] 随着 DeepSeek 等开源模型的崛起,API Wrapper 模式的成本与隐私痛点日益凸显。本文深度解析如何基于 RTX 4090 + Docker + Milvus 搭建本地化 RAG (检索增强生成) 系统,探讨从 SaaS 到 On-Premise 的架构演进与 Rerank 策略调优。

成都无形者AI实战团队 | 专注工厂DeepSeek私有化部署 (非杭州通用软件) 707

混合检索实战:向量检索+关键词检索如何提升Agent答案准确率?

通过融合稀疏检索(关键词)和稠密检索(向量)的结果,取长补短,在语义理解和精确匹配之间取得平衡。互补性原则:两种检索器在不同场景下表现互补,融合后的系统应优于任一单一系统。鲁棒性原则:当一种检索器因数据分布偏移而性能下降时,另一种检索器可作为兜底策略。可控性原则:融合过程中的权重、阈值等超参数应可调节,以适应不同业务场景的侧重点。混合检索并非一种锦上添花的优化技巧,而是Agent在专业场景中达到可用级准确率的必要条件。在医疗场景中,它守护了用药安全的底线;

2201_76125393的博客 17

从零开始读懂RAG:大模型的“开卷考试”技术

RAG(检索增强生成)技术通过结合搜索引擎与大模型,有效解决AI知识陈旧、幻觉和深度不足问题。该技术采用两阶段流程:离线阶段进行文档加载、切分和向量化存储,在线阶段实现查询转换、相似度检索和增强生成。当前RAG已从基础检索发展到智能代理模式,实践应用包含系统搭建四步法和混合检索等三大优化技巧。尽管大模型上下文窗口扩大,RAG仍是平衡实时性、准确性与成本的最佳方案,正发展成多模块智能知识管理系统,成为大模型落地的关键技术路径。

林间藏好物,码间藏星光 专注分享优质网站、开源项目、小众工具、模型算法 安静攒资源,慢慢变厉害•͈ᴗ⁃͈ ✧ 358

多摄像头同步技术:帧同步信号在Sensor与解串器间的传递机制

本文深入探讨了多摄像头系统中帧同步信号的两种核心传递机制:由解串器统一发号施令或由主Sensor作为“带头大哥”。文章对比了两种方案在同步精度、硬件复杂度、成本及适用场景上的差异,并提供了实战配置要点与调试心法,为车载环视、ADAS及工业检测等应用提供关键的技术选型与实施指导。

weixin_29193359的博客 435

避坑指南:Zephyr RTOS与nRF Connect SDK环境搭建常见错误及解决方案

本文详细解析了Zephyr RTOS与nRF Connect SDK环境搭建过程中的常见错误及解决方案,涵盖网络问题、代理设置、SEGGER Embedded Studio配置、分支切换等关键环节。针对开发者实际遇到的痛点问题,提供了一系列实用技巧和深度排错方法,帮助高效完成NCS开发环境部署。

weixin_28685287的博客 172

RAG在中小企业智能客服中的实战应用:从架构设计到性能优化

方案A:纯大模型(LLM)端到端。直接把用户问题和公司文档一起喂给GPT-4等模型。优点:理解能力强,回答流畅自然。缺点成本高(每次调用都传入长文档)、时延长幻觉率高(模型可能忽略你给的文档自己编)、无法追溯答案来源。方案B:传统检索(如Elasticsearch)+ 规则/模板。先用搜索找到相关文档片段,再用固定模板拼接答案。优点速度快答案精准可控成本低。缺点灵活性差,无法处理复杂语义和上下文,回答生硬,多轮对话能力弱。方案C:RAG(检索增强生成)。

2600_94960146的博客 277

单片机通信总述——理论部分(CAN、串口、SPI、I2C等)

并行通信:传输原理:数据各个位同时传输;优点:速度快; 缺点:占用引脚资源多。是指使用 8、16、32 及 64 根或更多的数据线(有多少信号为就需要多少信号位)进行传输的通讯方式,可以同一时刻传输多个数据位的数据。串行通信: 传输原理:数据按位顺序传输;优点:占用引脚资源少; 缺点:速度相对较慢。是指设备之间通过一根数据信号线,地线以及控制信号线,按数据位形式一位一位地传输数据的通讯方式,同一时刻只能传输一位(bit)数据。 单工: 数据传输只支持数据在一个方向上传输。信息只能单方向传输的工作方式,一

qq_42475191的博客 1万+

智能客服系统开发实战:基于RAG与多智能体协同的架构设计与避坑指南

Fine-tuning(微调)和RAG。:把新知识灌进模型,让它“记住”。优点是推理速度快,回答风格统一。但缺点更致命:训练成本高、周期长,容易“遗忘”旧知识(灾难性遗忘),并且每次知识更新都要重新训练,根本无法应对高频变化的业务知识。RAG:模型本身的知识是“冻结”的,额外维护一个可随时更新的外部知识库(通常是向量数据库)。回答问题时,先从这个知识库里检索出最相关的片段,再把这些片段作为上下文交给模型生成最终答案。对比下来,RAG在知识实时性和更新成本。

2600_94960114的博客 246

【汇编】TSR内存驻留程序实现与删除及热键设置——以实现时钟为例

【汇编】TSR内存驻留程序实现与删除及热键设置——以实现时钟为例 最近完成了一个关于时钟中断驻留的汇编大作业,对于TSR很是感兴趣,查阅了不少资料,发现现在很少相关的内容资料。尤其是TSR删除这一块几乎找不到在低的水平完全正确的做法,下面我对于TSR的删除我会介绍一种几乎小程序可以完成的方法。当然,标题中的TSR实现,热键设置我也会一一介绍。

cly116的博客 3971

【MATLAB强化学习工具箱】学习笔记--在Simulink环境中训练智能体Create Simulink Environment and Train Agent

Simulink中便于搭建各类动力学与控制模型,通过将原有的控制器替换为AI控制器,可以方便使用已有模型,提供增量效果。 本节的重点是如何引入Simulink模型作为env,其他的内容在之前的文章中已有说明。 以水箱模型watertank为例,如下图所示: 采用PI控制器,控制效果如下所示: 将此PI控制器替换为神经网络控制器后,系统架构如下图所示: 具体替换策略如下所示: (1)删去PID控制器; (2)增加RL Agent模块; (3)观测器模块: 观测向量为:,其中...

bear_miao的博客 1万+

四、RAG与LlamaIndex

RAG(检索增强生成)是一种结合检索和生成技术的方法,通过从文档库中检索相关信息来提升大模型回答的准确性。它解决了大模型的知识局限性、幻觉问题和数据安全等挑战。RAG分为原始、高级和模块化三个阶段,LlamaIndex作为开源框架,支持数据整合、索引构建和增强LLM推理能力,帮助开发者构建知识助手和AI代理。相比重新训练或微调模型,RAG成本更低、信息实时更新且结果更可信。LlamaCloud则提供托管服务,简化企业级应用的数据管理流程。

nzlyll的博客 2548

【数学模型】灰色关联分析

数学模型-灰色关联分析

suic009的博客 1万+

LlamaIndex快速构建RAG解决大模型的幻觉问题

LlamaIndex 是一个开源框架,用于快速构建检索增强生成(RAG)应用。它可以帮助开发者将检索组件(如向量数据库)与语言生成模型(如 LLM)结合,高效地处理和检索文档数据,从而生成更准确、更有依据的内容在生成式 AI 的快速发展中,大模型的幻觉问题一直是制约其广泛应用的关键挑战之一。幻觉现象不仅降低了模型输出的可信度,还可能在实际应用中引发严重后果。为了解决这一问题,检索增强生成(RAG)技术应运而生,通过结合信息检索和语言生成,显著提升了生成内容的准确性和可靠性。

weixin_41688410的博客 2199

【华为OD机试真题】65、高矮个子排队 | 机试真题+思路参考+代码解析 (C++、Java、Py、C语言、JS)

题目描述 >现在有一队小朋友,他们高矮不同,我们以正整数数组表示这一队小朋友的身高,如数组{5,3,1,2,3}。 >  我们现在希望小朋友排队,以"高" "矮" "高" "矮" 顺序排列,每一个高位置的小朋友要比相邻的位置高或者相等;每个 "矮" 位置的小朋友要比相邻的位置矮或者相等; >  要求小朋友们移动的距离和最小,第一个从“高"位开始排,输出最小移动距离即可。 >  例如,在示范小队{5,3,1,2,3}中, {5, 1, 3, 2, 3}是排序结果。 > 

KJ.JK 2098

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

上一篇: Lepton Search :不到 500 行代码构建对话式搜索引擎|开源|可商用
下一篇: AI革命新篇章:法国天才团队挑战ChatGPT霸主地位
技术狂潮AI
博客等级 码龄3年 1282粉丝 137原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术狂潮AI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值