RAG 开发的痛点及解决方案

受 Barnett 等人撰写的论文《 设计 RAG 系统时的七个失败点 》的启发,在本文中探讨论文中提到的七个失败点以及开发 RAG 流水线过程中的另外五个常见痛点。更重要的是,我们将深入探讨这些 RAG 痛点的解决方案,以便在日常 RAG 开发中更好地解决这些痛点。

本文使用 " 痛点 " 而不是 " 失败点 " ,主要是因为这些痛点都有相应的解决方案。让我们在它们成为我们 RAG 流水线中的失败点之前,设法解决它们。

首先,让我们检查上述论文中提到的七个痛点;见下图。然后,我们将添加另外五个痛点及建议的解决方案。

痛点 1 :内容缺失

知识库中缺少上下文。当实际答案不在知识库中时, RAG 系统会提供一个似是而非的错误答案,而不是说它不知道。用户会收到误导性信息,从而产生挫败感。有两个解决方案:

清理数据

垃圾进,垃圾出。如果你的源数据质量很差,例如包含相互矛盾的信息,那么无论你建立了多么完善的 RAG 流水线,它也无法从你输入的垃圾中神奇地输出黄金。本文提出的解决方案不仅可以解决这一痛点,还可以解决本文列出的所有痛点。干净的数据是任何运行良好的 RAG 流水线的先决条件。

有一些常见的数据清理策略,仅举几例:

  • 去除噪音和无关信息:这包括删除特殊字符、停止词( "the " 和 "a " 等常用词 )和 HTML 标记。

  • 识别并纠正错误:这包括拼写错误、错别字和语法错误。拼写检查程序和语言模型等工具都能在这方面提供帮助。

  • 重复数据删除:删除可能影响检索过程的重复记录或类似记录。

Unstructured.io 在其核心库中提供了一系列清理功能,可帮助满足此类数据清理需求。值得一试。

更好的提示词

由于知识库中缺乏信息,系统可能会提供一个似是而非但不正确的答案,在这种情况下,更好的提示词功能可以提供很大帮助。通过 " 如果你不确定答案,请告诉我你不知道 " 等提示来指导系统,可以鼓励模型承认其局限性,并更透明地传达不确定性。虽然不能保证百分之百的准确性,但在清理数据之后,精心设计提示语是最好的方法之一。

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

在初始检索过程中丢失内容。重要文档可能不会出现在系统检索组件返回的最前结果中。正确答案被忽略,导致系统无法提供准确的回复。Barnett 的论文暗示: “ 问题的答案就在文档中,但排名不够靠前,无法返回给用户 ” 。有两个建议的解决方案:

chunk_size 和 similarity_top_k 超参微调

在 RAG 模型中, chunk_size 和 similarity_top_k 都是用于管理数据检索过程的效率和效果的参数。调整这些参数会影响计算效率和检索信息质量之间的权衡。文章《 使用 LlamaIndex 自动调整超参数 》中探讨了调整chunk_size 和similarity_top_k 这两个参数的细节。请参阅下面的示例代码片段:

`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 ,以及相应的建议值:

 `# contains the parameters that need to be tuned` `param _ dict = {  "chunk _ size" :  [ 256 , 512 , 1024  ] ,  "top _ k" :  [ 1 , 2 , 5  ]  }``   ` `# contains parameters remaining fixed across all runs of the tuning process` `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"  ]` `   ` `# build index` `index = _ build _ index ( chunk _ size , docs )``   ` `# query engine` `query _ engine = index.as _ query _ engine ( similarity _ top _ k=top _ k )``   ` `# get predicted responses` `pred _ response _ objs = get _ responses  (` `eval _ qs , query _ engine , show _ progress= True`  `)` `   ` `# run evaluator` `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`  `)` `   ` `# get semantic similarity metric` `mean _ score = np.array  (`  `[  r.score for r in eval _ results  [  "semantic _ similarity"  ]  ]`  `).mean  (  )` `   ``return RunResult ( score=mean _ score , params=params _ dict )`

更多详情,请参阅 LlamaIndex 关于 RAG 超参优化的完整笔记。

重新排序

在将检索结果发送到 LLM 之前对其重新排序可显著提高 RAG 性能。LlamaIndex 笔记展示了这两者之间的区别:

  • 不使用重新排序器直接检索前 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 ) # return top 2 nodes from reranker` `   ``query _ engine = index.as _ query _ engine  (` `similarity _ top _ k=10 ,  # we can set a high top _ k here to ensure maximum relevant retrieval` `node _ postprocessors= [ cohere _ rerank ],  # pass the reranker to node _ postprocessors`  `)` `   ``response = query _ engine.query  (`  `"What did Sam Altman do in this essay?" ,`  `)` 

还可以使用各种嵌入和重定级器来评估和提高检索器的性能,详见《 提升 RAG :挑选最佳嵌入和重定级器模型》( Boosting RAG : Picking the Best Embedding & Reranker models ),作者:Ravi Theja 。

此外,还可以微调自定义重排序器,以获得更好的检索性能,具体实现方法详见 Ravi Theja 所著的《利用 LlamaIndex 微调 Cohere 重排序器以提高检索性能》( Improving Retrieval Performance by Fine-tuning Cohere Reranker with LlamaIndex )。

痛点 3 :不符合上下文 – 整合策略的局限性

重新排序后上下文缺失。Barnett的论文对这一点进行了定义: “ 从数据库中检索到了包含答案的文档,但没有将其纳入生成答案的上下文中。当从数据库中返回许多文档时,就会出现这种情况,这时就需要进行整合以检索答案 ” 。

除了上节所述的添加重排器和微调重排器外,我们还可以探索以下建议的解决方案:

调整检索策略

LlamaIndex 提供了一系列从基本到高级的检索策略,帮助我们在 RAG 流水线中实现精确检索。请查看检索模块指南,了解所有检索策略的综合列表,这些策略分为不同的类别。

  • 每个索引的基本检索

  • 高级检索和搜索

  • 自动检索

  • 知识图谱检索器

  • 合成 / 分层检索器

  • 以及其他策略类别

微调嵌入

如果你使用的是开源嵌入模型,对嵌入模型进行微调是实现更精确检索的好方法。LlamaIndex 提供了对开源嵌入模型进行微调的分步指南,证明对嵌入模型进行微调可以持续改善评估指标套件中的各项指标。

请参阅下面的示例代码片段,了解如何创建微调引擎、运行微调并获取微调后的模型:

`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 :未提取

未提取上下文。系统难以从提供的上下文中提取正确答案,尤其是在信息量过大的情况下。关键细节被遗漏,影响了答案的质量。Barnett的论文暗示 " 当上下文中存在过多噪音或相互矛盾的信息时,就会出现这种情况。让我们来探讨三个建议的解决方案:

清理数据

这个痛点是不良数据的另一个典型受害者。我们怎么强调清洁数据的重要性都不为过!在指责 RAG 流水线之前,请先花时间清理数据。

提示词压缩

LongLLMLingua 研究项目 / 论文介绍了长上下文设置中的提示词压缩。通过将其集成到 LlamaIndex 中,我们现在可以将 LongLLMLingua 作为节点后处理器来实现,它将在检索步骤后压缩上下文,然后再将其输入 LLM 。LongLLMLingua 压缩提示可以以更低的成本获得更高的性能。此外,整个系统的运行速度也会更快。

from llama _ index.core.query _ engine import RetrieverQueryEngine` `from llama _ index.core.response _ synthesizers import CompactAndRefine` `from llama _ index.postprocessor.longllmlingua import LongLLMLinguaPostprocessor` `from llama _ index.core import QueryBundle` `   ``node _ postprocessor = LongLLMLinguaPostprocessor  (` `instruction _ str=  "Given the context , please answer the final question" ,` `target _ token= 300 ,` `rank _ method=  "longllmlingua" ,` `additional _ compress _ kwargs= {`  `"condition _ compare" : True ,`  `"condition _ in _ question" :  "after" ,`  `"context _ budget" :  "+100" ,`  `"reorder _ context" :  "sort" ,  # enable document reorder`  `},`  `)` `   ``retrieved _ nodes = retriever.retrieve ( query _ str )``synthesizer = CompactAndRefine  (  )` `   ` `# outline steps in RetrieverQueryEngine for clarity :`  `# postprocess ( compress ), synthesize` `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 就是为了解决这个 " 中间丢失 " 的问题而设计的,它可以对检索到的节点重新排序,这在需要大量 top-k 的情况下很有帮助。

请参阅下面的示例代码片段,了解如何在构建查询引擎时将 LongContextReorder 定义为节点后处理器。更多详情,请参阅 LlamaIndex 关于 LongContextReorder 的完整笔记本。

`from llama _ index.core.postprocessor import LongContextReorder` `   ``reorder = LongContextReorder  (  )` `   ``reorder _ engine = index.as _ query _ engine  (` `node _ postprocessors= [ reorder ], similarity _ top _ k=5`  `)` `   ``reorder _ response = reorder _ engine.query  (  "Did the author meet Sam Altman?"  )` 

痛点 5 :格式错误

输出格式错误。当以特定格式( 如表格或列表 )提取信息的指令被 LLM 忽视时,我们提出了四种解决方案供大家探讨:

更好的提示词

可以采用几种策略来改进提示并纠正这一问题:

  • 明确说明。

  • 简化要求并使用关键词。

  • 举例说明。

  • 迭代提示并提出后续问题。

输出解析

输出解析可用于以下方面,以帮助确保获得所需的输出:

  • 为任何提示 / 查询提供格式说明

  • 为 LLM 输出提供 “ 解析 ”

LlamaIndex 支持与其他框架( 如 Guardrails 和 LangChain )提供的输出解析模块集成。

下面是 LangChain 输出解析模块的示例代码片段,可以在 LlamaIndex 中使用这些模块。更多详情,请查看 LlamaIndex 有关输出解析模块的文档。

from llama _ index.core import VectorStoreIndex , SimpleDirectoryReader` `from llama _ index.core.output _ parsers import LangchainOutputParser` `from llama _ index.llms.openai import OpenAI` `from langchain.output _ parsers import StructuredOutputParser , ResponseSchema` `   ` `# load documents , build index` `documents = SimpleDirectoryReader  (  " .. /paul _ graham _ essay/data"  ).load _ data  (  )` `index = VectorStoreIndex.from _ documents ( documents )``   ` `# define output schema` `response _ schemas =  [` `ResponseSchema  (` `name=  "Education" ,` `description=  "Describes the author's educational experience/background." ,`  `) ,` `ResponseSchema  (` `name=  "Work" ,` `description=  "Describes the author's work experience/background." ,`  `) ,`  `]` `   ` `# define output parser` `lc _ output _ parser = StructuredOutputParser.from _ response _ schemas  (` `response _ schemas`  `)` `output _ parser = LangchainOutputParser ( lc _ output _ parser )``   ` `# Attach output parser to LLM` `llm = OpenAI ( output _ parser=output _ parser )``   ` `# obtain a structured response` `query _ engine = index.as _ query _ engine ( llm=llm )``response = query _ engine.query  (`  `"What are a few things the author did growing up?" ,`  `)` `print ( str ( response ))

Pydantic 程序

Pydantic 程序是一个多功能框架,可将输入字符串转换为结构化的 Pydantic 对象。LlamaIndex 提供几类 Pydantic 程序:

  • LLM 文本补全 Pydantic 程序:这些程序处理输入文本,并将其转换为用户定义的结构化对象,利用文本补全 API 结合输出解析。

  • LLM 函数调用 Pydantic 程序:这些程序利用 LLM 函数调用 API 获取输入文本,并将其转换为用户指定的结构化对象。

  • 预包装 Pydantic 程序:这些程序旨在将输入文本转换为预定义的结构化对象。

下面是 OpenAI pydantic 程序的示例代码片段。欲了解更多详情,请查看 LlamaIndex 的 pydantic 程序文档,其中包含不同 pydantic 程序的笔记 / 指南链接。

`from pydantic import BaseModel` `from typing import List` `   ``from llama _ index.program.openai import OpenAIPydanticProgram` `   ` `# Define output schema ( without docstring )``class Song  (  BaseModel  ) :` `title : str` `length _ seconds : int` `   ``   ``class Album  (  BaseModel  ) :` `name : str` `artist : str` `songs : List [ Song ]``   ` `# Define openai pydantic program` `prompt _ template _ str =  """\` `Generate an example album , with an artist and a list of songs.\` `Using the movie { movie _ name } as inspiration.\`  `"""` `program = OpenAIPydanticProgram.from _ defaults  (` `output _ cls=Album , prompt _ template _ str=prompt _ template _ str , verbose= True`  `)` `   ` `# Run program to get structured output` `output = program  (` `movie _ name=  "The Shining" , description=  "Data model for an album."`  `)` 

OpenAI JSON 模式

OpenAI JSON 模式使我们能够将 response _ format 设置为{ “type” : “json _ object” }以启用响应的 JSON 模式。启用 JSON 模式后,模型将受限于只能生成解析为有效 JSON 对象的字符串。JSON 模式会强制执行输出格式,但无助于根据指定模式进行验证。更多详情,请查看 LlamaIndex 关于 OpenAI JSON 模式与数据提取函数调用的文档。

痛点 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种高级检索 LlamaPacks 的更多详情,请参阅文章《 Jump-start Your RAG Pipelines with Advanced Retrieval LlamaPacks and Benchmark with Lighthouz AI 》。

痛点 7 :不完整

输出不完整。部分回答并没有错;但是,它们并没有提供所有的细节,尽管信息已经存在并且可以在上下文中获取。例如,如果有人问: “ 文档 A 、 B 和 C 中讨论的主要方面是什么? ” 为了确保答案的全面性,对每份文档进行单独查询可能会更有效。

查询转换

比较问题在最原始的 RAG 方法中表现尤为糟糕。提高 RAG 推理能力的一个好方法是添加查询理解层 – 在实际查询向量存储之前添加查询转换。下面是四种不同的查询转换:

  • 路由:保留初始查询,同时找出与之相关的适当工具子集。然后,将这些工具指定为合适的选项。

  • 查询重写:保留选定的工具,但以多种方式重新制定查询,以便在同一组工具中应用。

  • 子问题:将查询分解成几个较小的问题,每个问题针对不同的工具,由其元数据决定。

  • ReAct Agent 工具选择:根据原始查询,确定要使用的工具,并制定在该工具上运行的特定查询。

请参阅下面的示例代码片段,了解如何使用 HyDE ( 假设文档嵌入 )这一查询重写技术。给定一个自然语言查询,首先生成一个假设文档 / 答案。然后使用该假设文档进行嵌入查找,而不是原始查询。

 `# load documents , build index` `documents = SimpleDirectoryReader  (  " .. /paul _ graham _ essay/data"  ).load _ data  (  )` `index = VectorStoreIndex ( documents )``   ` `# run query with HyDE query transform` `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 的查询转换 Cookbook ,了解所有详细信息。

此外,还可以查看I ulia Brezean u 的文章《 高级查询转换以改进 RAG 》,以获取关于查询转换技术的详细信息。


以上痛点均来自论文。现在,让我们来探讨 RAG 开发中常见的另外五个痛点及其建议的解决方案。

痛点 8 :数据摄取可扩展性

摄取流水线无法扩展到更大的数据量。RAG 流水线中的数据摄取可扩展性问题是指当系统难以有效管理和处理大量数据时出现的挑战,从而导致性能瓶颈和潜在的系统故障。此类数据摄取可扩展性问题会导致摄取时间延长、系统过载、数据质量问题和可用性受限。

摄取流水线并行化

LlamaIndex 提供摄取流水线并行处理功能,该功能可使 LlamaIndex 的文档处理速度提高 15 倍。请参阅下面的示例代码片段,了解如何创建摄取流水线( IngestionPipeline )并指定 num _ workers 以调用并行处理。查看 LlamaIndex 的完整笔记本,了解更多详情。

 `# load data` `documents = SimpleDirectoryReader ( input _ dir=  "./data/source _ files"  ).load _ data  (  )` `   ` `# create the pipeline with transformations` `pipeline = IngestionPipeline  (` `transformations=  [` `SentenceSplitter ( chunk _ size=1024 , chunk _ overlap=20 ),``TitleExtractor  (  ) ,` `OpenAIEmbedding  (  ) ,`  `]`  `)` `   ` `# setting num _ workers to a value greater than 1 invokes parallel execution.``nodes = pipeline.run ( documents=documents , num _ workers=4 )`

痛点 9 :结构化数据质量保证

无法对结构化数据进行质量保证。准确解释用户查询以检索相关结构化数据可能很困难,尤其是在查询复杂或模糊、文本到 SQL 不灵活以及当前 LLM 在有效处理这些任务方面存在局限性的情况下。LlamaIndex 提供了两种解决方案:

Chain-of-table

ChainOfTablePack 是基于 Wang 等人的创新性 " chain-of-table " 论文的 LlamaPack 。 " 表链 " 将思维链的概念与表转换和表示方法整合在一起。它使用一组受限的操作逐步转换表格,并在每个阶段将修改后的表格呈现给 LLM 。这种方法的一个显著优势是,它能够有条不紊地切割数据,直到识别出适当的子集,从而解决涉及包含多种信息的复杂表格单元格的问题,提高了表格质量保证的有效性。

有关如何使用 ChainOfTablePack 查询结构化数据的详细信息,请查看 LlamaIndex 的完整笔记(https : //github.com/run-llama/llama-hub/blob/main/llama _ hub/llama _ packs/tables/chain _ of _ table/chain _ of _ table.ipynb )。

混合自一致性包

LLM 可以通过两种主要方式对表格数据进行推理:

  • 通过直接提示进行文本推理

  • 通过程序合成( 如 Python 、 SQL 等 )进行符号推理

LlamaIndex 根据 Liu 等人撰写的论文《 Rethinking Tabular Data Understanding with Large Language Models 》,开发了混合自一致性查询引擎( MixSelfConsistencyQueryEngine ),通过自一致性机制(即多数票表决)汇总文本推理和符号推理的结果,并实现 SoTA 性能。请看下面的示例代码片段。查看 LlamaIndex 的完整笔记( https : //github.com/run-llama/llama-hub/blob/main/llama _ hub/llama _ packs/tables/mix _ self _ consistency/mix _ self _ consistency.ipynb ),了解更多详情。

`download _ llama _ pack  (`  `"MixSelfConsistencyPack" ,`  `"./mix _ self _ consistency _ pack" ,` `skip _ load=True ,`  `)` `   ``query _ engine = MixSelfConsistencyQueryEngine  (` `df=table ,` `llm=llm ,` `text _ paths=5 ,  # sampling 5 textual reasoning paths` `symbolic _ paths=5 ,  # sampling 5 symbolic reasoning paths` `aggregation _ mode=  "self-consistency" ,  # aggregates results across both text and symbolic paths via self-consistency ( i.e.majority voting )``verbose=True ,`  `)` `   ``response = await query _ engine.aquery ( example [ "utterance"  ]  )` 

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

你可能需要从复杂的 PDF 文档中提取数据,例如从嵌入式表格中提取数据,用于问答。简单的检索无法从这些嵌入式表格中获取数据。需要一种更好的方法来检索此类复杂的 PDF 数据。

嵌入式表格检索

LlamaIndex 在 EmbeddedTablesUnstructuredRetrieverPack 中提供了一种解决方案,该 LlamaPack 使用 Unstructured.io 从 HTML 文档中解析出嵌入式表格,构建节点图,然后根据用户问题使用递归检索来索引 / 检索表格。

请注意,该程序包将 HTML 文档作为输入。如果你有 PDF 文档,可以使用 pdf2htmlEX 将 PDF 转换为 HTML ,而不会丢失文本或格式。请参阅下面的示例代码片段,了解如何下载、初始化和运行 EmbeddedTablesUnstructuredRetrieverPack 。

 `# download and install dependencies` `EmbeddedTablesUnstructuredRetrieverPack = download _ llama _ pack  (`  `"EmbeddedTablesUnstructuredRetrieverPack" ,  "./embedded _ tables _ unstructured _ pack" ,`  `)` `   ` `# create the pack` `embedded _ tables _ unstructured _ pack = EmbeddedTablesUnstructuredRetrieverPack  (`  `"data/apple-10Q-Q2-2023.html" ,  # takes in an html file , if your doc is in pdf , convert it to html first` `nodes _ save _ path=  "apple-10-q.pkl"`  `)` `   ` `# run the pack` `response = embedded _ tables _ unstructured _ pack.run  (  "What's the total operating expenses?"  ).response` `display ( Markdown ( f  " { response } "  )  )` 

痛点 11 :回退模型

在使用 LLM 时,你可能会想,如果模型遇到问题怎么办,例如 OpenAI 模型的速率限制错误。你需要一个或多个回退模型作为备份,以防主要模型出现故障。我们提出了两种解决方案:

Neutrino 路由器

Neutrino路由器是 LLM 的集合,你可以将查询路由到它。它使用预测模型将查询智能地路由到最适合提示的 LLM ,在优化成本和延迟的同时最大限度地提高性能。Neutrino 目前支持十几种模型。如果你希望在支持的机型列表中添加新的机型,请联系他们的支持人员。

你可以创建一个路由器,在 Neutrino 面板上手动选择你喜欢的型号,或者使用 " 默认 " 路由器,其中包括所有支持的型号。

LlamaIndex 通过 llms 模块中的 Neutrino 类集成了对 Neutrino 的支持。请看下面的代码片段。更多详情,请访问 Neutrino AI 页面。

`from llama _ index.llms.neutrino import Neutrino` `from llama _ index.core.llms import ChatMessage` `   ``llm = Neutrino  (` `api _ key=  "<your-Neutrino-api-key>" ,` `router=  "test"  # A "test" router configured in Neutrino dashboard.You treat a router as a LLM.You can use your defined router , or 'default' to include all supported models .` `)` `   ``response = llm.complete  (  "What is large language model?"  )` `print  ( f"Optimal model : { response.raw  [  'model'  ]  } "  )` 

OpenRouter

OpenRouter 是访问任何 LLM 的统一 API 。它能找到任何型号的最低价格,并在主主机宕机时提供后备服务。根据 OpenRouter 的文档,使用 OpenRouter 的主要好处包括:

  • 从低价竞争中获益。OpenRouter 可以在数十家供应商中为每种型号找到最低价格。还可以让用户通过 OAuth PKCE 为自己的模型付费。

  • 标准化 API 。在模型或提供商之间切换时,无需更改代码。

  • 最好的模型将得到最广泛的使用。根据模型的使用频率和使用目的进行比较。

LlamaIndex 通过 llms 模块中的 OpenRouter 类集成了 OpenRouter 支持。请看下面的代码片段。查看 OpenRouter 页面上的更多详细信息。

from llama _ index.llms.openrouter import OpenRouter` `from llama _ index.core.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 安全

如何对抗提示词注入、处理不安全输出、防止敏感信息泄露,这些都是每个人工智能架构师和工程师需要回答的迫切问题。

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

NeMo Guardrails

NeMo Guardrails 是终极的开源 LLM 安全工具集,提供了一套广泛的可编程护栏,用于控制和引导 LLM 的输入和输出,包括内容节制、话题引导、幻觉预防和响应整形。该工具集有一组轨道:

  • 输入轨道:可以拒绝输入、停止进一步处理或修改输入( 例如,通过隐藏敏感信息或重新措辞 )。

  • 输出轨道:可以拒绝输出,阻止将其发送给用户,也可以修改输出。

  • 对话轨道:以规范形式处理信息,并决定是否执行操作、传唤 LLM 进行下一步操作或回复,或选择预定义的答案。

  • 检索轨道:可以拒绝一个信息块,防止它被用于提示 LLM ,或更改相关信息块。

  • 执行轨道:适用于 LLM 需要调用的自定义操作( 也称为工具 )的输入和输出。

根据使用情况,你可能需要配置一个或多个轨道。在 config 目录中添加 config.yml 、 prompts.yml 、定义 rails 流程的 Colang 文件等配置文件。然后,我们加载 guardrails 配置并创建一个 LLMRails 实例,它为 LLM 提供了一个接口,可自动应用配置的 guardrails 。请参阅下面的代码片段。通过加载配置目录, NeMo Guardrails 会激活操作、整理 rails 流程并为调用做好准备。

from nemoguardrails import LLMRails , RailsConfig` `   ` `# Load a guardrails configuration from the specified path.``config = RailsConfig.from _ path  (  "./config"  )` `rails = LLMRails ( config )``   ``res = await rails.generate _ async ( prompt=  "What does NVIDIA AI Enterprise enable?"  )` `print ( res )

请看下面的截图,了解对话栏是如何防止提问偏离主题的。

有关如何使用 NeMo Guardrails 的详细信息,请查看我的文章 NeMo Guardrails , the Ultimate Open-Source LLM Security Toolkit 。

Llama Guard

Llama Guard 基于 7-B Llama 2 ,旨在通过检查输入( 通过提示分类 )和输出( 通过响应分类 )对 LLM 内容进行分类。Llama Guard 的功能与 LLM 相似,它生成的文本结果可确定特定提示或回复是安全的还是不安全的。此外,如果它根据某些策略将内容确定为不安全,它还会列举出内容违反的具体子类别。

LlamaIndex 提供 LlamaGuardModeratorPack ,使开发人员能够在下载和初始化 LlamaGuardModeratorPack 后,调用 LlamaGuard 来控制 LLM 输入 / 输出。

 `# download and install dependencies` `LlamaGuardModeratorPack = download _ llama _ pack  (` `llama _ pack _ class=  "LlamaGuardModeratorPack" ,` `download _ dir=  "./llamaguard _ pack"`  `)` `   ` `# you need HF token with write privileges for interactions with 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  ) :`  `# Moderate the user input` `moderator _ response _ for _ input = llamaguard _ pack.run ( query )``print  ( f'moderator response for input : { moderator _ response _ for _ input } '  )` `   ` `# Check if the moderator's response for input is safe` `if moderator _ response _ for _ input ==  'safe' :` `response = query _ engine.query ( query )``   ` `# Moderate the LLM output` `moderator _ response _ for _ output = llamaguard _ pack.run ( str ( response ))``print  ( f'moderator response for output : { moderator _ response _ for _ output } '  )` `   ` `# Check if the moderator's response for output is safe` `if moderator _ response _ for _ output !=  'safe' :` `response =  'The response is not safe.Please ask a different question.'` `else :` `response =  'This query is not safe.Please ask a different question.'` `   ``return response` 

下面的示例输出显示,该查询不安全,违反了自定义分类法中的类别 8 。

总结

本文探讨了开发 RAG 流水线过程中的 12 个痛点( 论文中的 7 个痛点和另外 5 个痛点 ),并针对所有痛点提出了相应的解决方案。请参阅下图,该图改编自论文《 设计检索增强生成系统时的七个故障点 》中的原图:

将所有 12 个 RAG 痛点及其建议的解决方案并列在一张表格中,我们就得出了以下结果:

如何学习大模型 AI ?

由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。

但是具体到个人,只能说是:

“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。

这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

在这里插入图片描述

第一阶段(10天):初阶应用

该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。

  • 大模型 AI 能干什么?
  • 大模型是怎样获得「智能」的?
  • 用好 AI 的核心心法
  • 大模型应用业务架构
  • 大模型应用技术架构
  • 代码示例:向 GPT-3.5 灌入新知识
  • 提示工程的意义和核心思想
  • Prompt 典型构成
  • 指令调优方法论
  • 思维链和思维树
  • Prompt 攻击和防范

第二阶段(30天):高阶应用

该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。

  • 为什么要做 RAG
  • 搭建一个简单的 ChatPDF
  • 检索的基础概念
  • 什么是向量表示(Embeddings)
  • 向量数据库与向量检索
  • 基于向量检索的 RAG
  • 搭建 RAG 系统的扩展知识
  • 混合检索与 RAG-Fusion 简介
  • 向量模型本地部署

第三阶段(30天):模型训练

恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。

到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?

  • 为什么要做 RAG
  • 什么是模型
  • 什么是模型训练
  • 求解器 & 损失函数简介
  • 小实验2:手写一个简单的神经网络并训练它
  • 什么是训练/预训练/微调/轻量化微调
  • Transformer结构简介
  • 轻量化微调
  • 实验数据集的构建

第四阶段(20天):商业闭环

对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。

  • 硬件选型
  • 带你了解全球大模型
  • 使用国产大模型服务
  • 搭建 OpenAI 代理
  • 热身:基于阿里云 PAI 部署 Stable Diffusion
  • 在本地计算机运行大模型
  • 大模型的私有化部署
  • 基于 vLLM 部署大模型
  • 案例:如何优雅地在阿里云私有部署开源大模型
  • 部署一套开源 LLM 项目
  • 内容安全
  • 互联网信息服务算法备案

学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。

如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

在这里插入图片描述

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值